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
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
97 ;; Other random patterns
106 UNSPEC_LD_MPIC ; load_macho_picbase
108 UNSPEC_DIV_ALREADY_SPLIT
109 UNSPEC_MS_TO_SYSV_CALL
115 ;; For SSE/MMX support:
123 ;; Generic math support
125 UNSPEC_IEEE_MIN ; not commutative
126 UNSPEC_IEEE_MAX ; not commutative
128 ;; x87 Floating point
144 UNSPEC_FRNDINT_MASK_PM
148 ;; x87 Double output FP
183 (define_c_enum "unspecv" [
186 UNSPECV_PROBE_STACK_RANGE
189 UNSPECV_SPLIT_STACK_RETURN
195 UNSPECV_LLWP_INTRINSIC
196 UNSPECV_SLWP_INTRINSIC
197 UNSPECV_LWPVAL_INTRINSIC
198 UNSPECV_LWPINS_INTRINSIC
214 ;; For atomic compound assignments.
220 ;; For RDRAND support
223 ;; For RDSEED support
235 ;; Constants to represent rounding modes in the ROUND instruction
244 ;; Constants to represent pcomtrue/pcomfalse variants
254 ;; Constants used in the XOP pperm instruction
256 [(PPERM_SRC 0x00) /* copy source */
257 (PPERM_INVERT 0x20) /* invert source */
258 (PPERM_REVERSE 0x40) /* bit reverse source */
259 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
260 (PPERM_ZERO 0x80) /* all 0's */
261 (PPERM_ONES 0xa0) /* all 1's */
262 (PPERM_SIGN 0xc0) /* propagate sign bit */
263 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
264 (PPERM_SRC1 0x00) /* use first source byte */
265 (PPERM_SRC2 0x10) /* use second source byte */
268 ;; Registers by name.
347 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
350 ;; In C guard expressions, put expressions which may be compile-time
351 ;; constants first. This allows for better optimization. For
352 ;; example, write "TARGET_64BIT && reload_completed", not
353 ;; "reload_completed && TARGET_64BIT".
357 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
358 atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
360 (const (symbol_ref "ix86_schedule")))
362 ;; A basic instruction type. Refinements due to arguments to be
363 ;; provided in other attributes.
366 alu,alu1,negnot,imov,imovx,lea,
367 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
368 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
369 push,pop,call,callv,leave,
371 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
372 fxch,fistp,fisttp,frndint,
373 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
374 ssemul,sseimul,ssediv,sselog,sselog1,
375 sseishft,sseishft1,ssecmp,ssecomi,
376 ssecvt,ssecvt1,sseicvt,sseins,
377 sseshuf,sseshuf1,ssemuladd,sse4arg,
379 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
380 (const_string "other"))
382 ;; Main data type used by the insn
384 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
386 (const_string "unknown"))
388 ;; The CPU unit operations uses.
389 (define_attr "unit" "integer,i387,sse,mmx,unknown"
390 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
391 fxch,fistp,fisttp,frndint")
392 (const_string "i387")
393 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
394 ssemul,sseimul,ssediv,sselog,sselog1,
395 sseishft,sseishft1,ssecmp,ssecomi,
396 ssecvt,ssecvt1,sseicvt,sseins,
397 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
399 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
401 (eq_attr "type" "other")
402 (const_string "unknown")]
403 (const_string "integer")))
405 ;; The minimum required alignment of vector mode memory operands of the SSE
406 ;; (non-VEX/EVEX) instruction in bits, if it is different from
407 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has
408 ;; multiple alternatives, this should be conservative maximum of those minimum
409 ;; required alignments.
410 (define_attr "ssememalign" "" (const_int 0))
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")
417 (eq_attr "unit" "i387,sse,mmx")
419 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
420 rotate,rotatex,rotate1,imul,icmp,push,pop")
421 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
422 (eq_attr "type" "imov,test")
423 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
424 (eq_attr "type" "call")
425 (if_then_else (match_operand 0 "constant_call_address_operand")
428 (eq_attr "type" "callv")
429 (if_then_else (match_operand 1 "constant_call_address_operand")
432 ;; We don't know the size before shorten_branches. Expect
433 ;; the instruction to fit for better scheduling.
434 (eq_attr "type" "ibr")
437 (symbol_ref "/* Update immediate_length and other attributes! */
438 gcc_unreachable (),1")))
440 ;; The (bounding maximum) length of an instruction address.
441 (define_attr "length_address" ""
442 (cond [(eq_attr "type" "str,other,multi,fxch")
444 (and (eq_attr "type" "call")
445 (match_operand 0 "constant_call_address_operand"))
447 (and (eq_attr "type" "callv")
448 (match_operand 1 "constant_call_address_operand"))
451 (symbol_ref "ix86_attr_length_address_default (insn)")))
453 ;; Set when length prefix is used.
454 (define_attr "prefix_data16" ""
455 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
457 (eq_attr "mode" "HI")
459 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
464 ;; Set when string REP prefix is used.
465 (define_attr "prefix_rep" ""
466 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
468 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
473 ;; Set when 0f opcode prefix is used.
474 (define_attr "prefix_0f" ""
476 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
477 (eq_attr "unit" "sse,mmx"))
481 ;; Set when REX opcode prefix is used.
482 (define_attr "prefix_rex" ""
483 (cond [(not (match_test "TARGET_64BIT"))
485 (and (eq_attr "mode" "DI")
486 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
487 (eq_attr "unit" "!mmx")))
489 (and (eq_attr "mode" "QI")
490 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
492 (match_test "x86_extended_reg_mentioned_p (insn)")
494 (and (eq_attr "type" "imovx")
495 (match_operand:QI 1 "ext_QIreg_operand"))
500 ;; There are also additional prefixes in 3DNOW, SSSE3.
501 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
502 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
503 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
504 (define_attr "prefix_extra" ""
505 (cond [(eq_attr "type" "ssemuladd,sse4arg")
507 (eq_attr "type" "sseiadd1,ssecvt1")
512 ;; Prefix used: original, VEX or maybe VEX.
513 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
514 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
516 (eq_attr "mode" "XI,V16SF,V8DF")
517 (const_string "evex")
519 (const_string "orig")))
521 ;; VEX W bit is used.
522 (define_attr "prefix_vex_w" "" (const_int 0))
524 ;; The length of VEX prefix
525 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
526 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
527 ;; still prefix_0f 1, with prefix_extra 1.
528 (define_attr "length_vex" ""
529 (if_then_else (and (eq_attr "prefix_0f" "1")
530 (eq_attr "prefix_extra" "0"))
531 (if_then_else (eq_attr "prefix_vex_w" "1")
532 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
533 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
534 (if_then_else (eq_attr "prefix_vex_w" "1")
535 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
536 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
538 ;; 4-bytes evex prefix and 1 byte opcode.
539 (define_attr "length_evex" "" (const_int 5))
541 ;; Set when modrm byte is used.
542 (define_attr "modrm" ""
543 (cond [(eq_attr "type" "str,leave")
545 (eq_attr "unit" "i387")
547 (and (eq_attr "type" "incdec")
548 (and (not (match_test "TARGET_64BIT"))
549 (ior (match_operand:SI 1 "register_operand")
550 (match_operand:HI 1 "register_operand"))))
552 (and (eq_attr "type" "push")
553 (not (match_operand 1 "memory_operand")))
555 (and (eq_attr "type" "pop")
556 (not (match_operand 0 "memory_operand")))
558 (and (eq_attr "type" "imov")
559 (and (not (eq_attr "mode" "DI"))
560 (ior (and (match_operand 0 "register_operand")
561 (match_operand 1 "immediate_operand"))
562 (ior (and (match_operand 0 "ax_reg_operand")
563 (match_operand 1 "memory_displacement_only_operand"))
564 (and (match_operand 0 "memory_displacement_only_operand")
565 (match_operand 1 "ax_reg_operand"))))))
567 (and (eq_attr "type" "call")
568 (match_operand 0 "constant_call_address_operand"))
570 (and (eq_attr "type" "callv")
571 (match_operand 1 "constant_call_address_operand"))
573 (and (eq_attr "type" "alu,alu1,icmp,test")
574 (match_operand 0 "ax_reg_operand"))
575 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
579 ;; The (bounding maximum) length of an instruction in bytes.
580 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
581 ;; Later we may want to split them and compute proper length as for
583 (define_attr "length" ""
584 (cond [(eq_attr "type" "other,multi,fistp,frndint")
586 (eq_attr "type" "fcmp")
588 (eq_attr "unit" "i387")
590 (plus (attr "prefix_data16")
591 (attr "length_address")))
592 (ior (eq_attr "prefix" "evex")
593 (and (ior (eq_attr "prefix" "maybe_evex")
594 (eq_attr "prefix" "maybe_vex"))
595 (match_test "TARGET_AVX512F")))
596 (plus (attr "length_evex")
597 (plus (attr "length_immediate")
599 (attr "length_address"))))
600 (ior (eq_attr "prefix" "vex")
601 (and (ior (eq_attr "prefix" "maybe_vex")
602 (eq_attr "prefix" "maybe_evex"))
603 (match_test "TARGET_AVX")))
604 (plus (attr "length_vex")
605 (plus (attr "length_immediate")
607 (attr "length_address"))))]
608 (plus (plus (attr "modrm")
609 (plus (attr "prefix_0f")
610 (plus (attr "prefix_rex")
611 (plus (attr "prefix_extra")
613 (plus (attr "prefix_rep")
614 (plus (attr "prefix_data16")
615 (plus (attr "length_immediate")
616 (attr "length_address")))))))
618 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
619 ;; `store' if there is a simple memory reference therein, or `unknown'
620 ;; if the instruction is complex.
622 (define_attr "memory" "none,load,store,both,unknown"
623 (cond [(eq_attr "type" "other,multi,str,lwp")
624 (const_string "unknown")
625 (eq_attr "type" "lea,fcmov,fpspc")
626 (const_string "none")
627 (eq_attr "type" "fistp,leave")
628 (const_string "both")
629 (eq_attr "type" "frndint")
630 (const_string "load")
631 (eq_attr "type" "push")
632 (if_then_else (match_operand 1 "memory_operand")
633 (const_string "both")
634 (const_string "store"))
635 (eq_attr "type" "pop")
636 (if_then_else (match_operand 0 "memory_operand")
637 (const_string "both")
638 (const_string "load"))
639 (eq_attr "type" "setcc")
640 (if_then_else (match_operand 0 "memory_operand")
641 (const_string "store")
642 (const_string "none"))
643 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
644 (if_then_else (ior (match_operand 0 "memory_operand")
645 (match_operand 1 "memory_operand"))
646 (const_string "load")
647 (const_string "none"))
648 (eq_attr "type" "ibr")
649 (if_then_else (match_operand 0 "memory_operand")
650 (const_string "load")
651 (const_string "none"))
652 (eq_attr "type" "call")
653 (if_then_else (match_operand 0 "constant_call_address_operand")
654 (const_string "none")
655 (const_string "load"))
656 (eq_attr "type" "callv")
657 (if_then_else (match_operand 1 "constant_call_address_operand")
658 (const_string "none")
659 (const_string "load"))
660 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
661 (match_operand 1 "memory_operand"))
662 (const_string "both")
663 (and (match_operand 0 "memory_operand")
664 (match_operand 1 "memory_operand"))
665 (const_string "both")
666 (match_operand 0 "memory_operand")
667 (const_string "store")
668 (match_operand 1 "memory_operand")
669 (const_string "load")
671 "!alu1,negnot,ishift1,
672 imov,imovx,icmp,test,bitmanip,
674 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
675 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
676 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
677 (match_operand 2 "memory_operand"))
678 (const_string "load")
679 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
680 (match_operand 3 "memory_operand"))
681 (const_string "load")
683 (const_string "none")))
685 ;; Indicates if an instruction has both an immediate and a displacement.
687 (define_attr "imm_disp" "false,true,unknown"
688 (cond [(eq_attr "type" "other,multi")
689 (const_string "unknown")
690 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
691 (and (match_operand 0 "memory_displacement_operand")
692 (match_operand 1 "immediate_operand")))
693 (const_string "true")
694 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
695 (and (match_operand 0 "memory_displacement_operand")
696 (match_operand 2 "immediate_operand")))
697 (const_string "true")
699 (const_string "false")))
701 ;; Indicates if an FP operation has an integer source.
703 (define_attr "fp_int_src" "false,true"
704 (const_string "false"))
706 ;; Defines rounding mode of an FP operation.
708 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
709 (const_string "any"))
711 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
712 (define_attr "use_carry" "0,1" (const_string "0"))
714 ;; Define attribute to indicate unaligned ssemov insns
715 (define_attr "movu" "0,1" (const_string "0"))
717 ;; Used to control the "enabled" attribute on a per-instruction basis.
718 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
719 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
720 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,fma_avx512f"
721 (const_string "base"))
723 (define_attr "enabled" ""
724 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
725 (eq_attr "isa" "x64_sse4")
726 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
727 (eq_attr "isa" "x64_sse4_noavx")
728 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
729 (eq_attr "isa" "x64_avx")
730 (symbol_ref "TARGET_64BIT && TARGET_AVX")
731 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
732 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
733 (eq_attr "isa" "sse2_noavx")
734 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
735 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
736 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
737 (eq_attr "isa" "sse4_noavx")
738 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
739 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
740 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
741 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
742 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
743 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
744 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
745 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
746 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
747 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
748 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
749 (eq_attr "isa" "fma_avx512f")
750 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
754 ;; Describe a user's asm statement.
755 (define_asm_attributes
756 [(set_attr "length" "128")
757 (set_attr "type" "multi")])
759 (define_code_iterator plusminus [plus minus])
761 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
763 (define_code_iterator multdiv [mult div])
765 ;; Base name for define_insn
766 (define_code_attr plusminus_insn
767 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
768 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
770 ;; Base name for insn mnemonic.
771 (define_code_attr plusminus_mnemonic
772 [(plus "add") (ss_plus "adds") (us_plus "addus")
773 (minus "sub") (ss_minus "subs") (us_minus "subus")])
774 (define_code_attr plusminus_carry_mnemonic
775 [(plus "adc") (minus "sbb")])
776 (define_code_attr multdiv_mnemonic
777 [(mult "mul") (div "div")])
779 ;; Mark commutative operators as such in constraints.
780 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
781 (minus "") (ss_minus "") (us_minus "")])
783 ;; Mapping of max and min
784 (define_code_iterator maxmin [smax smin umax umin])
786 ;; Mapping of signed max and min
787 (define_code_iterator smaxmin [smax smin])
789 ;; Mapping of unsigned max and min
790 (define_code_iterator umaxmin [umax umin])
792 ;; Base name for integer and FP insn mnemonic
793 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
794 (umax "maxu") (umin "minu")])
795 (define_code_attr maxmin_float [(smax "max") (smin "min")])
797 ;; Mapping of logic operators
798 (define_code_iterator any_logic [and ior xor])
799 (define_code_iterator any_or [ior xor])
800 (define_code_iterator fpint_logic [and xor])
802 ;; Base name for insn mnemonic.
803 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
805 ;; Mapping of logic-shift operators
806 (define_code_iterator any_lshift [ashift lshiftrt])
808 ;; Mapping of shift-right operators
809 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
811 ;; Mapping of all shift operators
812 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
814 ;; Base name for define_insn
815 (define_code_attr shift_insn
816 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
818 ;; Base name for insn mnemonic.
819 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
820 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
822 ;; Mapping of rotate operators
823 (define_code_iterator any_rotate [rotate rotatert])
825 ;; Base name for define_insn
826 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
828 ;; Base name for insn mnemonic.
829 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
831 ;; Mapping of abs neg operators
832 (define_code_iterator absneg [abs neg])
834 ;; Base name for x87 insn mnemonic.
835 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
837 ;; Used in signed and unsigned widening multiplications.
838 (define_code_iterator any_extend [sign_extend zero_extend])
840 ;; Prefix for insn menmonic.
841 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
843 ;; Prefix for define_insn
844 (define_code_attr u [(sign_extend "") (zero_extend "u")])
845 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
846 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
848 ;; Used in signed and unsigned truncations.
849 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
850 ;; Instruction suffix for truncations.
851 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
853 ;; Used in signed and unsigned fix.
854 (define_code_iterator any_fix [fix unsigned_fix])
855 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
857 ;; All integer modes.
858 (define_mode_iterator SWI1248x [QI HI SI DI])
860 ;; All integer modes without QImode.
861 (define_mode_iterator SWI248x [HI SI DI])
863 ;; All integer modes without QImode and HImode.
864 (define_mode_iterator SWI48x [SI DI])
866 ;; All integer modes without SImode and DImode.
867 (define_mode_iterator SWI12 [QI HI])
869 ;; All integer modes without DImode.
870 (define_mode_iterator SWI124 [QI HI SI])
872 ;; All integer modes without QImode and DImode.
873 (define_mode_iterator SWI24 [HI SI])
875 ;; Single word integer modes.
876 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
878 ;; Single word integer modes without QImode.
879 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
881 ;; Single word integer modes without QImode and HImode.
882 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
884 ;; All math-dependant single and double word integer modes.
885 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
886 (HI "TARGET_HIMODE_MATH")
887 SI DI (TI "TARGET_64BIT")])
889 ;; Math-dependant single word integer modes.
890 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
891 (HI "TARGET_HIMODE_MATH")
892 SI (DI "TARGET_64BIT")])
894 ;; Math-dependant integer modes without DImode.
895 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
896 (HI "TARGET_HIMODE_MATH")
899 ;; Math-dependant single word integer modes without QImode.
900 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
901 SI (DI "TARGET_64BIT")])
903 ;; Double word integer modes.
904 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
905 (TI "TARGET_64BIT")])
907 ;; Double word integer modes as mode attribute.
908 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
909 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
911 ;; Half mode for double word integer modes.
912 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
913 (DI "TARGET_64BIT")])
915 ;; Instruction suffix for integer modes.
916 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
918 ;; Pointer size prefix for integer modes (Intel asm dialect)
919 (define_mode_attr iptrsize [(QI "BYTE")
924 ;; Register class for integer modes.
925 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
927 ;; Immediate operand constraint for integer modes.
928 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
930 ;; General operand constraint for word modes.
931 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
933 ;; Immediate operand constraint for double integer modes.
934 (define_mode_attr di [(SI "nF") (DI "e")])
936 ;; Immediate operand constraint for shifts.
937 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
939 ;; General operand predicate for integer modes.
940 (define_mode_attr general_operand
941 [(QI "general_operand")
942 (HI "general_operand")
943 (SI "x86_64_general_operand")
944 (DI "x86_64_general_operand")
945 (TI "x86_64_general_operand")])
947 ;; General sign/zero extend operand predicate for integer modes.
948 (define_mode_attr general_szext_operand
949 [(QI "general_operand")
950 (HI "general_operand")
951 (SI "x86_64_szext_general_operand")
952 (DI "x86_64_szext_general_operand")])
954 ;; Immediate operand predicate for integer modes.
955 (define_mode_attr immediate_operand
956 [(QI "immediate_operand")
957 (HI "immediate_operand")
958 (SI "x86_64_immediate_operand")
959 (DI "x86_64_immediate_operand")])
961 ;; Nonmemory operand predicate for integer modes.
962 (define_mode_attr nonmemory_operand
963 [(QI "nonmemory_operand")
964 (HI "nonmemory_operand")
965 (SI "x86_64_nonmemory_operand")
966 (DI "x86_64_nonmemory_operand")])
968 ;; Operand predicate for shifts.
969 (define_mode_attr shift_operand
970 [(QI "nonimmediate_operand")
971 (HI "nonimmediate_operand")
972 (SI "nonimmediate_operand")
973 (DI "shiftdi_operand")
974 (TI "register_operand")])
976 ;; Operand predicate for shift argument.
977 (define_mode_attr shift_immediate_operand
978 [(QI "const_1_to_31_operand")
979 (HI "const_1_to_31_operand")
980 (SI "const_1_to_31_operand")
981 (DI "const_1_to_63_operand")])
983 ;; Input operand predicate for arithmetic left shifts.
984 (define_mode_attr ashl_input_operand
985 [(QI "nonimmediate_operand")
986 (HI "nonimmediate_operand")
987 (SI "nonimmediate_operand")
988 (DI "ashldi_input_operand")
989 (TI "reg_or_pm1_operand")])
991 ;; SSE and x87 SFmode and DFmode floating point modes
992 (define_mode_iterator MODEF [SF DF])
994 ;; All x87 floating point modes
995 (define_mode_iterator X87MODEF [SF DF XF])
997 ;; SSE instruction suffix for various modes
998 (define_mode_attr ssemodesuffix
1000 (V16SF "ps") (V8DF "pd")
1001 (V8SF "ps") (V4DF "pd")
1002 (V4SF "ps") (V2DF "pd")
1003 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1004 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1005 (V64QI "b") (V16SI "d") (V8DI "q")])
1007 ;; SSE vector suffix for floating point modes
1008 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1010 ;; SSE vector mode corresponding to a scalar mode
1011 (define_mode_attr ssevecmode
1012 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1013 (define_mode_attr ssevecmodelower
1014 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1016 ;; Instruction suffix for REX 64bit operators.
1017 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1019 ;; This mode iterator allows :P to be used for patterns that operate on
1020 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1021 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1023 ;; This mode iterator allows :W to be used for patterns that operate on
1024 ;; word_mode sized quantities.
1025 (define_mode_iterator W
1026 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1028 ;; This mode iterator allows :PTR to be used for patterns that operate on
1029 ;; ptr_mode sized quantities.
1030 (define_mode_iterator PTR
1031 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1033 ;; Scheduling descriptions
1035 (include "pentium.md")
1038 (include "athlon.md")
1039 (include "bdver1.md")
1040 (include "bdver3.md")
1041 (include "btver2.md")
1042 (include "geode.md")
1045 (include "core2.md")
1048 ;; Operand and operator predicates and constraints
1050 (include "predicates.md")
1051 (include "constraints.md")
1054 ;; Compare and branch/compare and store instructions.
1056 (define_expand "cbranch<mode>4"
1057 [(set (reg:CC FLAGS_REG)
1058 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1059 (match_operand:SDWIM 2 "<general_operand>")))
1060 (set (pc) (if_then_else
1061 (match_operator 0 "ordered_comparison_operator"
1062 [(reg:CC FLAGS_REG) (const_int 0)])
1063 (label_ref (match_operand 3))
1067 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1068 operands[1] = force_reg (<MODE>mode, operands[1]);
1069 ix86_expand_branch (GET_CODE (operands[0]),
1070 operands[1], operands[2], operands[3]);
1074 (define_expand "cstore<mode>4"
1075 [(set (reg:CC FLAGS_REG)
1076 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1077 (match_operand:SWIM 3 "<general_operand>")))
1078 (set (match_operand:QI 0 "register_operand")
1079 (match_operator 1 "ordered_comparison_operator"
1080 [(reg:CC FLAGS_REG) (const_int 0)]))]
1083 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1084 operands[2] = force_reg (<MODE>mode, operands[2]);
1085 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1086 operands[2], operands[3]);
1090 (define_expand "cmp<mode>_1"
1091 [(set (reg:CC FLAGS_REG)
1092 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1093 (match_operand:SWI48 1 "<general_operand>")))])
1095 (define_insn "*cmp<mode>_ccno_1"
1096 [(set (reg FLAGS_REG)
1097 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1098 (match_operand:SWI 1 "const0_operand")))]
1099 "ix86_match_ccmode (insn, CCNOmode)"
1101 test{<imodesuffix>}\t%0, %0
1102 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1103 [(set_attr "type" "test,icmp")
1104 (set_attr "length_immediate" "0,1")
1105 (set_attr "mode" "<MODE>")])
1107 (define_insn "*cmp<mode>_1"
1108 [(set (reg FLAGS_REG)
1109 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1110 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1111 "ix86_match_ccmode (insn, CCmode)"
1112 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1113 [(set_attr "type" "icmp")
1114 (set_attr "mode" "<MODE>")])
1116 (define_insn "*cmp<mode>_minus_1"
1117 [(set (reg FLAGS_REG)
1119 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1120 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1122 "ix86_match_ccmode (insn, CCGOCmode)"
1123 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1124 [(set_attr "type" "icmp")
1125 (set_attr "mode" "<MODE>")])
1127 (define_insn "*cmpqi_ext_1"
1128 [(set (reg FLAGS_REG)
1130 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1133 (match_operand 1 "ext_register_operand" "Q,Q")
1135 (const_int 8)) 0)))]
1136 "ix86_match_ccmode (insn, CCmode)"
1137 "cmp{b}\t{%h1, %0|%0, %h1}"
1138 [(set_attr "isa" "*,nox64")
1139 (set_attr "type" "icmp")
1140 (set_attr "mode" "QI")])
1142 (define_insn "*cmpqi_ext_2"
1143 [(set (reg FLAGS_REG)
1147 (match_operand 0 "ext_register_operand" "Q")
1150 (match_operand:QI 1 "const0_operand")))]
1151 "ix86_match_ccmode (insn, CCNOmode)"
1153 [(set_attr "type" "test")
1154 (set_attr "length_immediate" "0")
1155 (set_attr "mode" "QI")])
1157 (define_expand "cmpqi_ext_3"
1158 [(set (reg:CC FLAGS_REG)
1162 (match_operand 0 "ext_register_operand")
1165 (match_operand:QI 1 "const_int_operand")))])
1167 (define_insn "*cmpqi_ext_3"
1168 [(set (reg FLAGS_REG)
1172 (match_operand 0 "ext_register_operand" "Q,Q")
1175 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1176 "ix86_match_ccmode (insn, CCmode)"
1177 "cmp{b}\t{%1, %h0|%h0, %1}"
1178 [(set_attr "isa" "*,nox64")
1179 (set_attr "type" "icmp")
1180 (set_attr "modrm" "1")
1181 (set_attr "mode" "QI")])
1183 (define_insn "*cmpqi_ext_4"
1184 [(set (reg FLAGS_REG)
1188 (match_operand 0 "ext_register_operand" "Q")
1193 (match_operand 1 "ext_register_operand" "Q")
1195 (const_int 8)) 0)))]
1196 "ix86_match_ccmode (insn, CCmode)"
1197 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1198 [(set_attr "type" "icmp")
1199 (set_attr "mode" "QI")])
1201 ;; These implement float point compares.
1202 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1203 ;; which would allow mix and match FP modes on the compares. Which is what
1204 ;; the old patterns did, but with many more of them.
1206 (define_expand "cbranchxf4"
1207 [(set (reg:CC FLAGS_REG)
1208 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1209 (match_operand:XF 2 "nonmemory_operand")))
1210 (set (pc) (if_then_else
1211 (match_operator 0 "ix86_fp_comparison_operator"
1214 (label_ref (match_operand 3))
1218 ix86_expand_branch (GET_CODE (operands[0]),
1219 operands[1], operands[2], operands[3]);
1223 (define_expand "cstorexf4"
1224 [(set (reg:CC FLAGS_REG)
1225 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1226 (match_operand:XF 3 "nonmemory_operand")))
1227 (set (match_operand:QI 0 "register_operand")
1228 (match_operator 1 "ix86_fp_comparison_operator"
1233 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1234 operands[2], operands[3]);
1238 (define_expand "cbranch<mode>4"
1239 [(set (reg:CC FLAGS_REG)
1240 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1241 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1242 (set (pc) (if_then_else
1243 (match_operator 0 "ix86_fp_comparison_operator"
1246 (label_ref (match_operand 3))
1248 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1250 ix86_expand_branch (GET_CODE (operands[0]),
1251 operands[1], operands[2], operands[3]);
1255 (define_expand "cstore<mode>4"
1256 [(set (reg:CC FLAGS_REG)
1257 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1258 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1259 (set (match_operand:QI 0 "register_operand")
1260 (match_operator 1 "ix86_fp_comparison_operator"
1263 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1265 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1266 operands[2], operands[3]);
1270 (define_expand "cbranchcc4"
1271 [(set (pc) (if_then_else
1272 (match_operator 0 "comparison_operator"
1273 [(match_operand 1 "flags_reg_operand")
1274 (match_operand 2 "const0_operand")])
1275 (label_ref (match_operand 3))
1279 ix86_expand_branch (GET_CODE (operands[0]),
1280 operands[1], operands[2], operands[3]);
1284 (define_expand "cstorecc4"
1285 [(set (match_operand:QI 0 "register_operand")
1286 (match_operator 1 "comparison_operator"
1287 [(match_operand 2 "flags_reg_operand")
1288 (match_operand 3 "const0_operand")]))]
1291 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1292 operands[2], operands[3]);
1297 ;; FP compares, step 1:
1298 ;; Set the FP condition codes.
1300 ;; CCFPmode compare with exceptions
1301 ;; CCFPUmode compare with no exceptions
1303 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1304 ;; used to manage the reg stack popping would not be preserved.
1306 (define_insn "*cmp<mode>_0_i387"
1307 [(set (match_operand:HI 0 "register_operand" "=a")
1310 (match_operand:X87MODEF 1 "register_operand" "f")
1311 (match_operand:X87MODEF 2 "const0_operand"))]
1314 "* return output_fp_compare (insn, operands, false, false);"
1315 [(set_attr "type" "multi")
1316 (set_attr "unit" "i387")
1317 (set_attr "mode" "<MODE>")])
1319 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1320 [(set (reg:CCFP FLAGS_REG)
1322 (match_operand:X87MODEF 1 "register_operand" "f")
1323 (match_operand:X87MODEF 2 "const0_operand")))
1324 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1325 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1327 "&& reload_completed"
1330 [(compare:CCFP (match_dup 1)(match_dup 2))]
1332 (set (reg:CC FLAGS_REG)
1333 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1335 [(set_attr "type" "multi")
1336 (set_attr "unit" "i387")
1337 (set_attr "mode" "<MODE>")])
1339 (define_insn "*cmpxf_i387"
1340 [(set (match_operand:HI 0 "register_operand" "=a")
1343 (match_operand:XF 1 "register_operand" "f")
1344 (match_operand:XF 2 "register_operand" "f"))]
1347 "* return output_fp_compare (insn, operands, false, false);"
1348 [(set_attr "type" "multi")
1349 (set_attr "unit" "i387")
1350 (set_attr "mode" "XF")])
1352 (define_insn_and_split "*cmpxf_cc_i387"
1353 [(set (reg:CCFP FLAGS_REG)
1355 (match_operand:XF 1 "register_operand" "f")
1356 (match_operand:XF 2 "register_operand" "f")))
1357 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1358 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1360 "&& reload_completed"
1363 [(compare:CCFP (match_dup 1)(match_dup 2))]
1365 (set (reg:CC FLAGS_REG)
1366 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1368 [(set_attr "type" "multi")
1369 (set_attr "unit" "i387")
1370 (set_attr "mode" "XF")])
1372 (define_insn "*cmp<mode>_i387"
1373 [(set (match_operand:HI 0 "register_operand" "=a")
1376 (match_operand:MODEF 1 "register_operand" "f")
1377 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1380 "* return output_fp_compare (insn, operands, false, false);"
1381 [(set_attr "type" "multi")
1382 (set_attr "unit" "i387")
1383 (set_attr "mode" "<MODE>")])
1385 (define_insn_and_split "*cmp<mode>_cc_i387"
1386 [(set (reg:CCFP FLAGS_REG)
1388 (match_operand:MODEF 1 "register_operand" "f")
1389 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1390 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1391 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1393 "&& reload_completed"
1396 [(compare:CCFP (match_dup 1)(match_dup 2))]
1398 (set (reg:CC FLAGS_REG)
1399 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1401 [(set_attr "type" "multi")
1402 (set_attr "unit" "i387")
1403 (set_attr "mode" "<MODE>")])
1405 (define_insn "*cmpu<mode>_i387"
1406 [(set (match_operand:HI 0 "register_operand" "=a")
1409 (match_operand:X87MODEF 1 "register_operand" "f")
1410 (match_operand:X87MODEF 2 "register_operand" "f"))]
1413 "* return output_fp_compare (insn, operands, false, true);"
1414 [(set_attr "type" "multi")
1415 (set_attr "unit" "i387")
1416 (set_attr "mode" "<MODE>")])
1418 (define_insn_and_split "*cmpu<mode>_cc_i387"
1419 [(set (reg:CCFPU FLAGS_REG)
1421 (match_operand:X87MODEF 1 "register_operand" "f")
1422 (match_operand:X87MODEF 2 "register_operand" "f")))
1423 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1424 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1426 "&& reload_completed"
1429 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1431 (set (reg:CC FLAGS_REG)
1432 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1434 [(set_attr "type" "multi")
1435 (set_attr "unit" "i387")
1436 (set_attr "mode" "<MODE>")])
1438 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1439 [(set (match_operand:HI 0 "register_operand" "=a")
1442 (match_operand:X87MODEF 1 "register_operand" "f")
1443 (match_operator:X87MODEF 3 "float_operator"
1444 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1447 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1448 || optimize_function_for_size_p (cfun))"
1449 "* return output_fp_compare (insn, operands, false, false);"
1450 [(set_attr "type" "multi")
1451 (set_attr "unit" "i387")
1452 (set_attr "fp_int_src" "true")
1453 (set_attr "mode" "<SWI24:MODE>")])
1455 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1456 [(set (reg:CCFP FLAGS_REG)
1458 (match_operand:X87MODEF 1 "register_operand" "f")
1459 (match_operator:X87MODEF 3 "float_operator"
1460 [(match_operand:SWI24 2 "memory_operand" "m")])))
1461 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1462 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1463 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1464 || optimize_function_for_size_p (cfun))"
1466 "&& reload_completed"
1471 (match_op_dup 3 [(match_dup 2)]))]
1473 (set (reg:CC FLAGS_REG)
1474 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1476 [(set_attr "type" "multi")
1477 (set_attr "unit" "i387")
1478 (set_attr "fp_int_src" "true")
1479 (set_attr "mode" "<SWI24:MODE>")])
1481 ;; FP compares, step 2
1482 ;; Move the fpsw to ax.
1484 (define_insn "x86_fnstsw_1"
1485 [(set (match_operand:HI 0 "register_operand" "=a")
1486 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1489 [(set (attr "length")
1490 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1491 (set_attr "mode" "SI")
1492 (set_attr "unit" "i387")])
1494 ;; FP compares, step 3
1495 ;; Get ax into flags, general case.
1497 (define_insn "x86_sahf_1"
1498 [(set (reg:CC FLAGS_REG)
1499 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1503 #ifndef HAVE_AS_IX86_SAHF
1505 return ASM_BYTE "0x9e";
1510 [(set_attr "length" "1")
1511 (set_attr "athlon_decode" "vector")
1512 (set_attr "amdfam10_decode" "direct")
1513 (set_attr "bdver1_decode" "direct")
1514 (set_attr "mode" "SI")])
1516 ;; Pentium Pro can do steps 1 through 3 in one go.
1517 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1518 ;; (these i387 instructions set flags directly)
1520 (define_mode_iterator FPCMP [CCFP CCFPU])
1521 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1523 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1524 [(set (reg:FPCMP FLAGS_REG)
1526 (match_operand:MODEF 0 "register_operand" "f,x")
1527 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1528 "TARGET_MIX_SSE_I387
1529 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1530 "* return output_fp_compare (insn, operands, true,
1531 <FPCMP:MODE>mode == CCFPUmode);"
1532 [(set_attr "type" "fcmp,ssecomi")
1533 (set_attr "prefix" "orig,maybe_vex")
1534 (set_attr "mode" "<MODEF:MODE>")
1535 (set (attr "prefix_rep")
1536 (if_then_else (eq_attr "type" "ssecomi")
1538 (const_string "*")))
1539 (set (attr "prefix_data16")
1540 (cond [(eq_attr "type" "fcmp")
1542 (eq_attr "mode" "DF")
1545 (const_string "0")))
1546 (set_attr "athlon_decode" "vector")
1547 (set_attr "amdfam10_decode" "direct")
1548 (set_attr "bdver1_decode" "double")])
1550 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1551 [(set (reg:FPCMP FLAGS_REG)
1553 (match_operand:MODEF 0 "register_operand" "x")
1554 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1556 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1557 "* return output_fp_compare (insn, operands, true,
1558 <FPCMP:MODE>mode == CCFPUmode);"
1559 [(set_attr "type" "ssecomi")
1560 (set_attr "prefix" "maybe_vex")
1561 (set_attr "mode" "<MODEF:MODE>")
1562 (set_attr "prefix_rep" "0")
1563 (set (attr "prefix_data16")
1564 (if_then_else (eq_attr "mode" "DF")
1566 (const_string "0")))
1567 (set_attr "athlon_decode" "vector")
1568 (set_attr "amdfam10_decode" "direct")
1569 (set_attr "bdver1_decode" "double")])
1571 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1572 [(set (reg:FPCMP FLAGS_REG)
1574 (match_operand:X87MODEF 0 "register_operand" "f")
1575 (match_operand:X87MODEF 1 "register_operand" "f")))]
1576 "TARGET_80387 && TARGET_CMOVE
1577 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1578 "* return output_fp_compare (insn, operands, true,
1579 <FPCMP:MODE>mode == CCFPUmode);"
1580 [(set_attr "type" "fcmp")
1581 (set_attr "mode" "<X87MODEF:MODE>")
1582 (set_attr "athlon_decode" "vector")
1583 (set_attr "amdfam10_decode" "direct")
1584 (set_attr "bdver1_decode" "double")])
1586 ;; Push/pop instructions.
1588 (define_insn "*push<mode>2"
1589 [(set (match_operand:DWI 0 "push_operand" "=<")
1590 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1593 [(set_attr "type" "multi")
1594 (set_attr "mode" "<MODE>")])
1597 [(set (match_operand:TI 0 "push_operand")
1598 (match_operand:TI 1 "general_operand"))]
1599 "TARGET_64BIT && reload_completed
1600 && !SSE_REG_P (operands[1])"
1602 "ix86_split_long_move (operands); DONE;")
1604 (define_insn "*pushdi2_rex64"
1605 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1606 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1611 [(set_attr "type" "push,multi")
1612 (set_attr "mode" "DI")])
1614 ;; Convert impossible pushes of immediate to existing instructions.
1615 ;; First try to get scratch register and go through it. In case this
1616 ;; fails, push sign extended lower part first and then overwrite
1617 ;; upper part by 32bit move.
1619 [(match_scratch:DI 2 "r")
1620 (set (match_operand:DI 0 "push_operand")
1621 (match_operand:DI 1 "immediate_operand"))]
1622 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1623 && !x86_64_immediate_operand (operands[1], DImode)"
1624 [(set (match_dup 2) (match_dup 1))
1625 (set (match_dup 0) (match_dup 2))])
1627 ;; We need to define this as both peepholer and splitter for case
1628 ;; peephole2 pass is not run.
1629 ;; "&& 1" is needed to keep it from matching the previous pattern.
1631 [(set (match_operand:DI 0 "push_operand")
1632 (match_operand:DI 1 "immediate_operand"))]
1633 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1634 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1635 [(set (match_dup 0) (match_dup 1))
1636 (set (match_dup 2) (match_dup 3))]
1638 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1640 operands[1] = gen_lowpart (DImode, operands[2]);
1641 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1646 [(set (match_operand:DI 0 "push_operand")
1647 (match_operand:DI 1 "immediate_operand"))]
1648 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1649 ? epilogue_completed : reload_completed)
1650 && !symbolic_operand (operands[1], DImode)
1651 && !x86_64_immediate_operand (operands[1], DImode)"
1652 [(set (match_dup 0) (match_dup 1))
1653 (set (match_dup 2) (match_dup 3))]
1655 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1657 operands[1] = gen_lowpart (DImode, operands[2]);
1658 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1663 [(set (match_operand:DI 0 "push_operand")
1664 (match_operand:DI 1 "general_operand"))]
1665 "!TARGET_64BIT && reload_completed
1666 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1668 "ix86_split_long_move (operands); DONE;")
1670 (define_insn "*pushsi2"
1671 [(set (match_operand:SI 0 "push_operand" "=<")
1672 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1675 [(set_attr "type" "push")
1676 (set_attr "mode" "SI")])
1678 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1679 ;; "push a byte/word". But actually we use pushl, which has the effect
1680 ;; of rounding the amount pushed up to a word.
1682 ;; For TARGET_64BIT we always round up to 8 bytes.
1683 (define_insn "*push<mode>2_rex64"
1684 [(set (match_operand:SWI124 0 "push_operand" "=X")
1685 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1688 [(set_attr "type" "push")
1689 (set_attr "mode" "DI")])
1691 (define_insn "*push<mode>2"
1692 [(set (match_operand:SWI12 0 "push_operand" "=X")
1693 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1696 [(set_attr "type" "push")
1697 (set_attr "mode" "SI")])
1699 (define_insn "*push<mode>2_prologue"
1700 [(set (match_operand:W 0 "push_operand" "=<")
1701 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1702 (clobber (mem:BLK (scratch)))]
1704 "push{<imodesuffix>}\t%1"
1705 [(set_attr "type" "push")
1706 (set_attr "mode" "<MODE>")])
1708 (define_insn "*pop<mode>1"
1709 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1710 (match_operand:W 1 "pop_operand" ">"))]
1712 "pop{<imodesuffix>}\t%0"
1713 [(set_attr "type" "pop")
1714 (set_attr "mode" "<MODE>")])
1716 (define_insn "*pop<mode>1_epilogue"
1717 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1718 (match_operand:W 1 "pop_operand" ">"))
1719 (clobber (mem:BLK (scratch)))]
1721 "pop{<imodesuffix>}\t%0"
1722 [(set_attr "type" "pop")
1723 (set_attr "mode" "<MODE>")])
1725 ;; Move instructions.
1727 (define_expand "movxi"
1728 [(set (match_operand:XI 0 "nonimmediate_operand")
1729 (match_operand:XI 1 "general_operand"))]
1731 "ix86_expand_move (XImode, operands); DONE;")
1733 ;; Reload patterns to support multi-word load/store
1734 ;; with non-offsetable address.
1735 (define_expand "reload_noff_store"
1736 [(parallel [(match_operand 0 "memory_operand" "=m")
1737 (match_operand 1 "register_operand" "r")
1738 (match_operand:DI 2 "register_operand" "=&r")])]
1741 rtx mem = operands[0];
1742 rtx addr = XEXP (mem, 0);
1744 emit_move_insn (operands[2], addr);
1745 mem = replace_equiv_address_nv (mem, operands[2]);
1747 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1751 (define_expand "reload_noff_load"
1752 [(parallel [(match_operand 0 "register_operand" "=r")
1753 (match_operand 1 "memory_operand" "m")
1754 (match_operand:DI 2 "register_operand" "=r")])]
1757 rtx mem = operands[1];
1758 rtx addr = XEXP (mem, 0);
1760 emit_move_insn (operands[2], addr);
1761 mem = replace_equiv_address_nv (mem, operands[2]);
1763 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1767 (define_expand "movoi"
1768 [(set (match_operand:OI 0 "nonimmediate_operand")
1769 (match_operand:OI 1 "general_operand"))]
1771 "ix86_expand_move (OImode, operands); DONE;")
1773 (define_expand "movti"
1774 [(set (match_operand:TI 0 "nonimmediate_operand")
1775 (match_operand:TI 1 "nonimmediate_operand"))]
1776 "TARGET_64BIT || TARGET_SSE"
1779 ix86_expand_move (TImode, operands);
1780 else if (push_operand (operands[0], TImode))
1781 ix86_expand_push (TImode, operands[1]);
1783 ix86_expand_vector_move (TImode, operands);
1787 ;; This expands to what emit_move_complex would generate if we didn't
1788 ;; have a movti pattern. Having this avoids problems with reload on
1789 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1790 ;; to have around all the time.
1791 (define_expand "movcdi"
1792 [(set (match_operand:CDI 0 "nonimmediate_operand")
1793 (match_operand:CDI 1 "general_operand"))]
1796 if (push_operand (operands[0], CDImode))
1797 emit_move_complex_push (CDImode, operands[0], operands[1]);
1799 emit_move_complex_parts (operands[0], operands[1]);
1803 (define_expand "mov<mode>"
1804 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1805 (match_operand:SWI1248x 1 "general_operand"))]
1807 "ix86_expand_move (<MODE>mode, operands); DONE;")
1809 (define_insn "*mov<mode>_xor"
1810 [(set (match_operand:SWI48 0 "register_operand" "=r")
1811 (match_operand:SWI48 1 "const0_operand"))
1812 (clobber (reg:CC FLAGS_REG))]
1815 [(set_attr "type" "alu1")
1816 (set_attr "mode" "SI")
1817 (set_attr "length_immediate" "0")])
1819 (define_insn "*mov<mode>_or"
1820 [(set (match_operand:SWI48 0 "register_operand" "=r")
1821 (match_operand:SWI48 1 "const_int_operand"))
1822 (clobber (reg:CC FLAGS_REG))]
1824 && operands[1] == constm1_rtx"
1825 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1826 [(set_attr "type" "alu1")
1827 (set_attr "mode" "<MODE>")
1828 (set_attr "length_immediate" "1")])
1830 (define_insn "*movxi_internal_avx512f"
1831 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1832 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1833 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1835 switch (which_alternative)
1838 return standard_sse_constant_opcode (insn, operands[1]);
1841 if (misaligned_operand (operands[0], XImode)
1842 || misaligned_operand (operands[1], XImode))
1843 return "vmovdqu32\t{%1, %0|%0, %1}";
1845 return "vmovdqa32\t{%1, %0|%0, %1}";
1850 [(set_attr "type" "sselog1,ssemov,ssemov")
1851 (set_attr "prefix" "evex")
1852 (set_attr "mode" "XI")])
1854 (define_insn "*movoi_internal_avx"
1855 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1856 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1857 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1859 switch (get_attr_type (insn))
1862 return standard_sse_constant_opcode (insn, operands[1]);
1865 if (misaligned_operand (operands[0], OImode)
1866 || misaligned_operand (operands[1], OImode))
1868 if (get_attr_mode (insn) == MODE_V8SF)
1869 return "vmovups\t{%1, %0|%0, %1}";
1871 return "vmovdqu\t{%1, %0|%0, %1}";
1875 if (get_attr_mode (insn) == MODE_V8SF)
1876 return "vmovaps\t{%1, %0|%0, %1}";
1878 return "vmovdqa\t{%1, %0|%0, %1}";
1885 [(set_attr "type" "sselog1,ssemov,ssemov")
1886 (set_attr "prefix" "vex")
1888 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1889 (const_string "V8SF")
1890 (and (eq_attr "alternative" "2")
1891 (match_test "TARGET_SSE_TYPELESS_STORES"))
1892 (const_string "V8SF")
1894 (const_string "OI")))])
1896 (define_insn "*movti_internal"
1897 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1898 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1899 "(TARGET_64BIT || TARGET_SSE)
1900 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1902 switch (get_attr_type (insn))
1908 return standard_sse_constant_opcode (insn, operands[1]);
1911 /* TDmode values are passed as TImode on the stack. Moving them
1912 to stack may result in unaligned memory access. */
1913 if (misaligned_operand (operands[0], TImode)
1914 || misaligned_operand (operands[1], TImode))
1916 if (get_attr_mode (insn) == MODE_V4SF)
1917 return "%vmovups\t{%1, %0|%0, %1}";
1919 return "%vmovdqu\t{%1, %0|%0, %1}";
1923 if (get_attr_mode (insn) == MODE_V4SF)
1924 return "%vmovaps\t{%1, %0|%0, %1}";
1926 return "%vmovdqa\t{%1, %0|%0, %1}";
1933 [(set_attr "isa" "x64,x64,*,*,*")
1934 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
1935 (set (attr "prefix")
1936 (if_then_else (eq_attr "type" "sselog1,ssemov")
1937 (const_string "maybe_vex")
1938 (const_string "orig")))
1940 (cond [(eq_attr "alternative" "0,1")
1942 (ior (not (match_test "TARGET_SSE2"))
1943 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1944 (const_string "V4SF")
1945 (and (eq_attr "alternative" "4")
1946 (match_test "TARGET_SSE_TYPELESS_STORES"))
1947 (const_string "V4SF")
1948 (match_test "TARGET_AVX")
1950 (match_test "optimize_function_for_size_p (cfun)")
1951 (const_string "V4SF")
1953 (const_string "TI")))])
1956 [(set (match_operand:TI 0 "nonimmediate_operand")
1957 (match_operand:TI 1 "general_operand"))]
1959 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1961 "ix86_split_long_move (operands); DONE;")
1963 (define_insn "*movdi_internal"
1964 [(set (match_operand:DI 0 "nonimmediate_operand"
1965 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
1966 (match_operand:DI 1 "general_operand"
1967 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,*v,r ,*Yj ,*Yn"))]
1968 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1970 switch (get_attr_type (insn))
1976 return "pxor\t%0, %0";
1979 /* Handle broken assemblers that require movd instead of movq. */
1980 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
1981 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
1982 return "movd\t{%1, %0|%0, %1}";
1983 return "movq\t{%1, %0|%0, %1}";
1986 if (GENERAL_REG_P (operands[0]))
1987 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
1989 return standard_sse_constant_opcode (insn, operands[1]);
1992 switch (get_attr_mode (insn))
1995 /* Handle broken assemblers that require movd instead of movq. */
1996 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
1997 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
1998 return "%vmovd\t{%1, %0|%0, %1}";
1999 return "%vmovq\t{%1, %0|%0, %1}";
2001 return "%vmovdqa\t{%1, %0|%0, %1}";
2003 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2006 gcc_assert (!TARGET_AVX);
2007 return "movlps\t{%1, %0|%0, %1}";
2009 return "%vmovaps\t{%1, %0|%0, %1}";
2016 if (SSE_REG_P (operands[0]))
2017 return "movq2dq\t{%1, %0|%0, %1}";
2019 return "movdq2q\t{%1, %0|%0, %1}";
2022 return "lea{q}\t{%E1, %0|%0, %E1}";
2025 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2026 if (get_attr_mode (insn) == MODE_SI)
2027 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2028 else if (which_alternative == 4)
2029 return "movabs{q}\t{%1, %0|%0, %1}";
2030 else if (ix86_use_lea_for_mov (insn, operands))
2031 return "lea{q}\t{%E1, %0|%0, %E1}";
2033 return "mov{q}\t{%1, %0|%0, %1}";
2040 (cond [(eq_attr "alternative" "0,1")
2041 (const_string "nox64")
2042 (eq_attr "alternative" "2,3,4,5,10,11,16,18")
2043 (const_string "x64")
2044 (eq_attr "alternative" "17")
2045 (const_string "x64_sse4")
2047 (const_string "*")))
2049 (cond [(eq_attr "alternative" "0,1")
2050 (const_string "multi")
2051 (eq_attr "alternative" "6")
2052 (const_string "mmx")
2053 (eq_attr "alternative" "7,8,9,10,11")
2054 (const_string "mmxmov")
2055 (eq_attr "alternative" "12,17")
2056 (const_string "sselog1")
2057 (eq_attr "alternative" "13,14,15,16,18")
2058 (const_string "ssemov")
2059 (eq_attr "alternative" "19,20")
2060 (const_string "ssecvt")
2061 (match_operand 1 "pic_32bit_operand")
2062 (const_string "lea")
2064 (const_string "imov")))
2067 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2069 (const_string "*")))
2070 (set (attr "length_immediate")
2071 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2073 (eq_attr "alternative" "17")
2076 (const_string "*")))
2077 (set (attr "prefix_rex")
2078 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2080 (const_string "*")))
2081 (set (attr "prefix_extra")
2082 (if_then_else (eq_attr "alternative" "17")
2084 (const_string "*")))
2085 (set (attr "prefix")
2086 (if_then_else (eq_attr "type" "sselog1,ssemov")
2087 (const_string "maybe_vex")
2088 (const_string "orig")))
2089 (set (attr "prefix_data16")
2090 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2092 (const_string "*")))
2094 (cond [(eq_attr "alternative" "2")
2096 (eq_attr "alternative" "12,13")
2097 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2098 (match_operand 1 "ext_sse_reg_operand"))
2100 (ior (not (match_test "TARGET_SSE2"))
2101 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2102 (const_string "V4SF")
2103 (match_test "TARGET_AVX")
2105 (match_test "optimize_function_for_size_p (cfun)")
2106 (const_string "V4SF")
2108 (const_string "TI"))
2110 (and (eq_attr "alternative" "14,15")
2111 (not (match_test "TARGET_SSE2")))
2112 (const_string "V2SF")
2113 (eq_attr "alternative" "17")
2116 (const_string "DI")))])
2119 [(set (match_operand:DI 0 "nonimmediate_operand")
2120 (match_operand:DI 1 "general_operand"))]
2121 "!TARGET_64BIT && reload_completed
2122 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2123 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2125 "ix86_split_long_move (operands); DONE;")
2127 (define_insn "*movsi_internal"
2128 [(set (match_operand:SI 0 "nonimmediate_operand"
2129 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi")
2130 (match_operand:SI 1 "general_operand"
2131 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r"))]
2132 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2134 switch (get_attr_type (insn))
2137 if (GENERAL_REG_P (operands[0]))
2138 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2140 return standard_sse_constant_opcode (insn, operands[1]);
2143 switch (get_attr_mode (insn))
2146 return "%vmovd\t{%1, %0|%0, %1}";
2148 return "%vmovdqa\t{%1, %0|%0, %1}";
2150 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2153 return "%vmovaps\t{%1, %0|%0, %1}";
2156 gcc_assert (!TARGET_AVX);
2157 return "movss\t{%1, %0|%0, %1}";
2164 return "pxor\t%0, %0";
2167 switch (get_attr_mode (insn))
2170 return "movq\t{%1, %0|%0, %1}";
2172 return "movd\t{%1, %0|%0, %1}";
2179 return "lea{l}\t{%E1, %0|%0, %E1}";
2182 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2183 if (ix86_use_lea_for_mov (insn, operands))
2184 return "lea{l}\t{%E1, %0|%0, %E1}";
2186 return "mov{l}\t{%1, %0|%0, %1}";
2193 (if_then_else (eq_attr "alternative" "11")
2194 (const_string "sse4")
2195 (const_string "*")))
2197 (cond [(eq_attr "alternative" "2")
2198 (const_string "mmx")
2199 (eq_attr "alternative" "3,4,5")
2200 (const_string "mmxmov")
2201 (eq_attr "alternative" "6,11")
2202 (const_string "sselog1")
2203 (eq_attr "alternative" "7,8,9,10,12")
2204 (const_string "ssemov")
2205 (match_operand 1 "pic_32bit_operand")
2206 (const_string "lea")
2208 (const_string "imov")))
2209 (set (attr "length_immediate")
2210 (if_then_else (eq_attr "alternative" "11")
2212 (const_string "*")))
2213 (set (attr "prefix_extra")
2214 (if_then_else (eq_attr "alternative" "11")
2216 (const_string "*")))
2217 (set (attr "prefix")
2218 (if_then_else (eq_attr "type" "sselog1,ssemov")
2219 (const_string "maybe_vex")
2220 (const_string "orig")))
2221 (set (attr "prefix_data16")
2222 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2224 (const_string "*")))
2226 (cond [(eq_attr "alternative" "2,3")
2228 (eq_attr "alternative" "6,7")
2229 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2230 (match_operand 1 "ext_sse_reg_operand"))
2232 (ior (not (match_test "TARGET_SSE2"))
2233 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2234 (const_string "V4SF")
2235 (match_test "TARGET_AVX")
2237 (match_test "optimize_function_for_size_p (cfun)")
2238 (const_string "V4SF")
2240 (const_string "TI"))
2242 (and (eq_attr "alternative" "8,9")
2243 (not (match_test "TARGET_SSE2")))
2245 (eq_attr "alternative" "11")
2248 (const_string "SI")))])
2250 (define_insn "*movhi_internal"
2251 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,Yk,Yk,rm")
2252 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,Yk,Yk"))]
2253 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2255 switch (get_attr_type (insn))
2258 /* movzwl is faster than movw on p2 due to partial word stalls,
2259 though not as fast as an aligned movl. */
2260 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2263 switch (which_alternative)
2265 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2266 case 5: return "kmovw\t{%1, %0|%0, %1}";
2267 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2268 default: gcc_unreachable ();
2272 if (get_attr_mode (insn) == MODE_SI)
2273 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2275 return "mov{w}\t{%1, %0|%0, %1}";
2279 (cond [(match_test "optimize_function_for_size_p (cfun)")
2280 (const_string "imov")
2281 (and (eq_attr "alternative" "0")
2282 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2283 (not (match_test "TARGET_HIMODE_MATH"))))
2284 (const_string "imov")
2285 (and (eq_attr "alternative" "1,2")
2286 (match_operand:HI 1 "aligned_operand"))
2287 (const_string "imov")
2288 (eq_attr "alternative" "4,5,6")
2289 (const_string "mskmov")
2290 (and (match_test "TARGET_MOVX")
2291 (eq_attr "alternative" "0,2"))
2292 (const_string "imovx")
2294 (const_string "imov")))
2295 (set (attr "prefix")
2296 (if_then_else (eq_attr "alternative" "4,5,6")
2297 (const_string "vex")
2298 (const_string "orig")))
2300 (cond [(eq_attr "type" "imovx")
2302 (and (eq_attr "alternative" "1,2")
2303 (match_operand:HI 1 "aligned_operand"))
2305 (and (eq_attr "alternative" "0")
2306 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2307 (not (match_test "TARGET_HIMODE_MATH"))))
2310 (const_string "HI")))])
2312 ;; Situation is quite tricky about when to choose full sized (SImode) move
2313 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2314 ;; partial register dependency machines (such as AMD Athlon), where QImode
2315 ;; moves issue extra dependency and for partial register stalls machines
2316 ;; that don't use QImode patterns (and QImode move cause stall on the next
2319 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2320 ;; register stall machines with, where we use QImode instructions, since
2321 ;; partial register stall can be caused there. Then we use movzx.
2323 (define_insn "*movqi_internal"
2324 [(set (match_operand:QI 0 "nonimmediate_operand"
2325 "=q,q ,q ,r,r ,?r,m ,Yk,Yk,r")
2326 (match_operand:QI 1 "general_operand"
2327 "q ,qn,qm,q,rn,qm,qn,r ,Yk,Yk"))]
2328 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2330 switch (get_attr_type (insn))
2333 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2334 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2337 switch (which_alternative)
2339 case 7: return "kmovw\t{%k1, %0|%0, %k1}";
2340 case 8: return "kmovw\t{%1, %0|%0, %1}";
2341 case 9: return "kmovw\t{%1, %k0|%k0, %1}";
2342 default: gcc_unreachable ();
2346 if (get_attr_mode (insn) == MODE_SI)
2347 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2349 return "mov{b}\t{%1, %0|%0, %1}";
2353 (cond [(and (eq_attr "alternative" "5")
2354 (not (match_operand:QI 1 "aligned_operand")))
2355 (const_string "imovx")
2356 (match_test "optimize_function_for_size_p (cfun)")
2357 (const_string "imov")
2358 (and (eq_attr "alternative" "3")
2359 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2360 (not (match_test "TARGET_QIMODE_MATH"))))
2361 (const_string "imov")
2362 (eq_attr "alternative" "3,5")
2363 (const_string "imovx")
2364 (eq_attr "alternative" "7,8,9")
2365 (const_string "mskmov")
2366 (and (match_test "TARGET_MOVX")
2367 (eq_attr "alternative" "2"))
2368 (const_string "imovx")
2370 (const_string "imov")))
2371 (set (attr "prefix")
2372 (if_then_else (eq_attr "alternative" "7,8,9")
2373 (const_string "vex")
2374 (const_string "orig")))
2376 (cond [(eq_attr "alternative" "3,4,5")
2378 (eq_attr "alternative" "6")
2380 (eq_attr "type" "imovx")
2382 (and (eq_attr "type" "imov")
2383 (and (eq_attr "alternative" "0,1")
2384 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2385 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2386 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2388 ;; Avoid partial register stalls when not using QImode arithmetic
2389 (and (eq_attr "type" "imov")
2390 (and (eq_attr "alternative" "0,1")
2391 (and (match_test "TARGET_PARTIAL_REG_STALL")
2392 (not (match_test "TARGET_QIMODE_MATH")))))
2395 (const_string "QI")))])
2397 ;; Stores and loads of ax to arbitrary constant address.
2398 ;; We fake an second form of instruction to force reload to load address
2399 ;; into register when rax is not available
2400 (define_insn "*movabs<mode>_1"
2401 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2402 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2403 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2405 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2406 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2407 [(set_attr "type" "imov")
2408 (set_attr "modrm" "0,*")
2409 (set_attr "length_address" "8,0")
2410 (set_attr "length_immediate" "0,*")
2411 (set_attr "memory" "store")
2412 (set_attr "mode" "<MODE>")])
2414 (define_insn "*movabs<mode>_2"
2415 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2416 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2417 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2419 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2420 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2421 [(set_attr "type" "imov")
2422 (set_attr "modrm" "0,*")
2423 (set_attr "length_address" "8,0")
2424 (set_attr "length_immediate" "0")
2425 (set_attr "memory" "load")
2426 (set_attr "mode" "<MODE>")])
2428 (define_insn "swap<mode>"
2429 [(set (match_operand:SWI48 0 "register_operand" "+r")
2430 (match_operand:SWI48 1 "register_operand" "+r"))
2434 "xchg{<imodesuffix>}\t%1, %0"
2435 [(set_attr "type" "imov")
2436 (set_attr "mode" "<MODE>")
2437 (set_attr "pent_pair" "np")
2438 (set_attr "athlon_decode" "vector")
2439 (set_attr "amdfam10_decode" "double")
2440 (set_attr "bdver1_decode" "double")])
2442 (define_insn "*swap<mode>_1"
2443 [(set (match_operand:SWI12 0 "register_operand" "+r")
2444 (match_operand:SWI12 1 "register_operand" "+r"))
2447 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2449 [(set_attr "type" "imov")
2450 (set_attr "mode" "SI")
2451 (set_attr "pent_pair" "np")
2452 (set_attr "athlon_decode" "vector")
2453 (set_attr "amdfam10_decode" "double")
2454 (set_attr "bdver1_decode" "double")])
2456 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2457 ;; is disabled for AMDFAM10
2458 (define_insn "*swap<mode>_2"
2459 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2460 (match_operand:SWI12 1 "register_operand" "+<r>"))
2463 "TARGET_PARTIAL_REG_STALL"
2464 "xchg{<imodesuffix>}\t%1, %0"
2465 [(set_attr "type" "imov")
2466 (set_attr "mode" "<MODE>")
2467 (set_attr "pent_pair" "np")
2468 (set_attr "athlon_decode" "vector")])
2470 (define_expand "movstrict<mode>"
2471 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2472 (match_operand:SWI12 1 "general_operand"))]
2475 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2477 if (GET_CODE (operands[0]) == SUBREG
2478 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2480 /* Don't generate memory->memory moves, go through a register */
2481 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2482 operands[1] = force_reg (<MODE>mode, operands[1]);
2485 (define_insn "*movstrict<mode>_1"
2486 [(set (strict_low_part
2487 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2488 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2489 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2490 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2491 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2492 [(set_attr "type" "imov")
2493 (set_attr "mode" "<MODE>")])
2495 (define_insn "*movstrict<mode>_xor"
2496 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2497 (match_operand:SWI12 1 "const0_operand"))
2498 (clobber (reg:CC FLAGS_REG))]
2500 "xor{<imodesuffix>}\t%0, %0"
2501 [(set_attr "type" "alu1")
2502 (set_attr "mode" "<MODE>")
2503 (set_attr "length_immediate" "0")])
2505 (define_insn "*mov<mode>_extv_1"
2506 [(set (match_operand:SWI24 0 "register_operand" "=R")
2507 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2511 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2512 [(set_attr "type" "imovx")
2513 (set_attr "mode" "SI")])
2515 (define_insn "*movqi_extv_1"
2516 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2517 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2522 switch (get_attr_type (insn))
2525 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2527 return "mov{b}\t{%h1, %0|%0, %h1}";
2530 [(set_attr "isa" "*,*,nox64")
2532 (if_then_else (and (match_operand:QI 0 "register_operand")
2533 (ior (not (match_operand:QI 0 "QIreg_operand"))
2534 (match_test "TARGET_MOVX")))
2535 (const_string "imovx")
2536 (const_string "imov")))
2538 (if_then_else (eq_attr "type" "imovx")
2540 (const_string "QI")))])
2542 (define_insn "*mov<mode>_extzv_1"
2543 [(set (match_operand:SWI48 0 "register_operand" "=R")
2544 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2548 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2549 [(set_attr "type" "imovx")
2550 (set_attr "mode" "SI")])
2552 (define_insn "*movqi_extzv_2"
2553 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2555 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2560 switch (get_attr_type (insn))
2563 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2565 return "mov{b}\t{%h1, %0|%0, %h1}";
2568 [(set_attr "isa" "*,*,nox64")
2570 (if_then_else (and (match_operand:QI 0 "register_operand")
2571 (ior (not (match_operand:QI 0 "QIreg_operand"))
2572 (match_test "TARGET_MOVX")))
2573 (const_string "imovx")
2574 (const_string "imov")))
2576 (if_then_else (eq_attr "type" "imovx")
2578 (const_string "QI")))])
2580 (define_insn "mov<mode>_insv_1"
2581 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2584 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2587 if (CONST_INT_P (operands[1]))
2588 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2589 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2591 [(set_attr "isa" "*,nox64")
2592 (set_attr "type" "imov")
2593 (set_attr "mode" "QI")])
2595 (define_insn "*movqi_insv_2"
2596 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2599 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2602 "mov{b}\t{%h1, %h0|%h0, %h1}"
2603 [(set_attr "type" "imov")
2604 (set_attr "mode" "QI")])
2606 ;; Floating point push instructions.
2608 (define_insn "*pushtf"
2609 [(set (match_operand:TF 0 "push_operand" "=<,<")
2610 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2611 "TARGET_64BIT || TARGET_SSE"
2613 /* This insn should be already split before reg-stack. */
2616 [(set_attr "isa" "*,x64")
2617 (set_attr "type" "multi")
2618 (set_attr "unit" "sse,*")
2619 (set_attr "mode" "TF,DI")])
2621 ;; %%% Kill this when call knows how to work this out.
2623 [(set (match_operand:TF 0 "push_operand")
2624 (match_operand:TF 1 "sse_reg_operand"))]
2625 "TARGET_SSE && reload_completed"
2626 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2627 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2629 (define_insn "*pushxf"
2630 [(set (match_operand:XF 0 "push_operand" "=<,<")
2631 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2634 /* This insn should be already split before reg-stack. */
2637 [(set_attr "type" "multi")
2638 (set_attr "unit" "i387,*")
2640 (cond [(eq_attr "alternative" "1")
2641 (if_then_else (match_test "TARGET_64BIT")
2643 (const_string "SI"))
2645 (const_string "XF")))])
2647 ;; %%% Kill this when call knows how to work this out.
2649 [(set (match_operand:XF 0 "push_operand")
2650 (match_operand:XF 1 "fp_register_operand"))]
2652 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2653 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2654 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2656 (define_insn "*pushdf"
2657 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2658 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2661 /* This insn should be already split before reg-stack. */
2664 [(set_attr "isa" "*,nox64,x64,sse2")
2665 (set_attr "type" "multi")
2666 (set_attr "unit" "i387,*,*,sse")
2667 (set_attr "mode" "DF,SI,DI,DF")])
2669 ;; %%% Kill this when call knows how to work this out.
2671 [(set (match_operand:DF 0 "push_operand")
2672 (match_operand:DF 1 "any_fp_register_operand"))]
2674 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2675 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2677 (define_insn "*pushsf_rex64"
2678 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2679 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2682 /* Anything else should be already split before reg-stack. */
2683 gcc_assert (which_alternative == 1);
2684 return "push{q}\t%q1";
2686 [(set_attr "type" "multi,push,multi")
2687 (set_attr "unit" "i387,*,*")
2688 (set_attr "mode" "SF,DI,SF")])
2690 (define_insn "*pushsf"
2691 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2692 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2695 /* Anything else should be already split before reg-stack. */
2696 gcc_assert (which_alternative == 1);
2697 return "push{l}\t%1";
2699 [(set_attr "type" "multi,push,multi")
2700 (set_attr "unit" "i387,*,*")
2701 (set_attr "mode" "SF,SI,SF")])
2703 ;; %%% Kill this when call knows how to work this out.
2705 [(set (match_operand:SF 0 "push_operand")
2706 (match_operand:SF 1 "any_fp_register_operand"))]
2708 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2709 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2710 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2713 [(set (match_operand:SF 0 "push_operand")
2714 (match_operand:SF 1 "memory_operand"))]
2716 && (operands[2] = find_constant_src (insn))"
2717 [(set (match_dup 0) (match_dup 2))])
2720 [(set (match_operand 0 "push_operand")
2721 (match_operand 1 "general_operand"))]
2723 && (GET_MODE (operands[0]) == TFmode
2724 || GET_MODE (operands[0]) == XFmode
2725 || GET_MODE (operands[0]) == DFmode)
2726 && !ANY_FP_REG_P (operands[1])"
2728 "ix86_split_long_move (operands); DONE;")
2730 ;; Floating point move instructions.
2732 (define_expand "movtf"
2733 [(set (match_operand:TF 0 "nonimmediate_operand")
2734 (match_operand:TF 1 "nonimmediate_operand"))]
2735 "TARGET_64BIT || TARGET_SSE"
2736 "ix86_expand_move (TFmode, operands); DONE;")
2738 (define_expand "mov<mode>"
2739 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2740 (match_operand:X87MODEF 1 "general_operand"))]
2742 "ix86_expand_move (<MODE>mode, operands); DONE;")
2744 (define_insn "*movtf_internal"
2745 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2746 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2747 "(TARGET_64BIT || TARGET_SSE)
2748 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2749 && (!can_create_pseudo_p ()
2750 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2751 || GET_CODE (operands[1]) != CONST_DOUBLE
2752 || (optimize_function_for_size_p (cfun)
2753 && standard_sse_constant_p (operands[1])
2754 && !memory_operand (operands[0], TFmode))
2755 || (!TARGET_MEMORY_MISMATCH_STALL
2756 && memory_operand (operands[0], TFmode)))"
2758 switch (get_attr_type (insn))
2761 return standard_sse_constant_opcode (insn, operands[1]);
2764 /* Handle misaligned load/store since we
2765 don't have movmisaligntf pattern. */
2766 if (misaligned_operand (operands[0], TFmode)
2767 || misaligned_operand (operands[1], TFmode))
2769 if (get_attr_mode (insn) == MODE_V4SF)
2770 return "%vmovups\t{%1, %0|%0, %1}";
2772 return "%vmovdqu\t{%1, %0|%0, %1}";
2776 if (get_attr_mode (insn) == MODE_V4SF)
2777 return "%vmovaps\t{%1, %0|%0, %1}";
2779 return "%vmovdqa\t{%1, %0|%0, %1}";
2789 [(set_attr "isa" "*,*,*,x64,x64")
2790 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2791 (set (attr "prefix")
2792 (if_then_else (eq_attr "type" "sselog1,ssemov")
2793 (const_string "maybe_vex")
2794 (const_string "orig")))
2796 (cond [(eq_attr "alternative" "3,4")
2798 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2799 (const_string "V4SF")
2800 (and (eq_attr "alternative" "2")
2801 (match_test "TARGET_SSE_TYPELESS_STORES"))
2802 (const_string "V4SF")
2803 (match_test "TARGET_AVX")
2805 (ior (not (match_test "TARGET_SSE2"))
2806 (match_test "optimize_function_for_size_p (cfun)"))
2807 (const_string "V4SF")
2809 (const_string "TI")))])
2811 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2812 (define_insn "*movxf_internal"
2813 [(set (match_operand:XF 0 "nonimmediate_operand"
2814 "=f,m,f,?Yx*r ,!o ,!o")
2815 (match_operand:XF 1 "general_operand"
2816 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2817 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2818 && (!can_create_pseudo_p ()
2819 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2820 || GET_CODE (operands[1]) != CONST_DOUBLE
2821 || (optimize_function_for_size_p (cfun)
2822 && standard_80387_constant_p (operands[1]) > 0
2823 && !memory_operand (operands[0], XFmode))
2824 || (!TARGET_MEMORY_MISMATCH_STALL
2825 && memory_operand (operands[0], XFmode)))"
2827 switch (get_attr_type (insn))
2830 if (which_alternative == 2)
2831 return standard_80387_constant_opcode (operands[1]);
2832 return output_387_reg_move (insn, operands);
2841 [(set_attr "isa" "*,*,*,*,nox64,x64")
2842 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2844 (cond [(eq_attr "alternative" "3,4,5")
2845 (if_then_else (match_test "TARGET_64BIT")
2847 (const_string "SI"))
2849 (const_string "XF")))])
2851 ;; Possible store forwarding (partial memory) stall in alternative 4.
2852 (define_insn "*movdf_internal"
2853 [(set (match_operand:DF 0 "nonimmediate_operand"
2854 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
2855 (match_operand:DF 1 "general_operand"
2856 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
2857 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2858 && (!can_create_pseudo_p ()
2859 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2860 || GET_CODE (operands[1]) != CONST_DOUBLE
2861 || (optimize_function_for_size_p (cfun)
2862 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2863 && standard_80387_constant_p (operands[1]) > 0)
2864 || (TARGET_SSE2 && TARGET_SSE_MATH
2865 && standard_sse_constant_p (operands[1])))
2866 && !memory_operand (operands[0], DFmode))
2867 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2868 && memory_operand (operands[0], DFmode)))"
2870 switch (get_attr_type (insn))
2873 if (which_alternative == 2)
2874 return standard_80387_constant_opcode (operands[1]);
2875 return output_387_reg_move (insn, operands);
2881 if (get_attr_mode (insn) == MODE_SI)
2882 return "mov{l}\t{%1, %k0|%k0, %1}";
2883 else if (which_alternative == 8)
2884 return "movabs{q}\t{%1, %0|%0, %1}";
2886 return "mov{q}\t{%1, %0|%0, %1}";
2889 return standard_sse_constant_opcode (insn, operands[1]);
2892 switch (get_attr_mode (insn))
2895 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2896 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2897 return "%vmovsd\t{%1, %0|%0, %1}";
2900 return "%vmovaps\t{%1, %0|%0, %1}";
2902 return "vmovapd\t{%g1, %g0|%g0, %g1}";
2904 return "%vmovapd\t{%1, %0|%0, %1}";
2907 gcc_assert (!TARGET_AVX);
2908 return "movlps\t{%1, %0|%0, %1}";
2910 gcc_assert (!TARGET_AVX);
2911 return "movlpd\t{%1, %0|%0, %1}";
2914 /* Handle broken assemblers that require movd instead of movq. */
2915 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2916 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2917 return "%vmovd\t{%1, %0|%0, %1}";
2918 return "%vmovq\t{%1, %0|%0, %1}";
2929 (cond [(eq_attr "alternative" "3,4")
2930 (const_string "nox64")
2931 (eq_attr "alternative" "5,6,7,8,17,18")
2932 (const_string "x64")
2933 (eq_attr "alternative" "9,10,11,12")
2934 (const_string "sse2")
2936 (const_string "*")))
2938 (cond [(eq_attr "alternative" "0,1,2")
2939 (const_string "fmov")
2940 (eq_attr "alternative" "3,4")
2941 (const_string "multi")
2942 (eq_attr "alternative" "5,6,7,8")
2943 (const_string "imov")
2944 (eq_attr "alternative" "9,13")
2945 (const_string "sselog1")
2947 (const_string "ssemov")))
2949 (if_then_else (eq_attr "alternative" "8")
2951 (const_string "*")))
2952 (set (attr "length_immediate")
2953 (if_then_else (eq_attr "alternative" "8")
2955 (const_string "*")))
2956 (set (attr "prefix")
2957 (if_then_else (eq_attr "type" "sselog1,ssemov")
2958 (const_string "maybe_vex")
2959 (const_string "orig")))
2960 (set (attr "prefix_data16")
2962 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2963 (eq_attr "mode" "V1DF"))
2965 (const_string "*")))
2967 (cond [(eq_attr "alternative" "3,4,7")
2969 (eq_attr "alternative" "5,6,8,17,18")
2972 /* xorps is one byte shorter for non-AVX targets. */
2973 (eq_attr "alternative" "9,13")
2974 (cond [(not (match_test "TARGET_SSE2"))
2975 (const_string "V4SF")
2976 (match_test "TARGET_AVX512F")
2978 (match_test "TARGET_AVX")
2979 (const_string "V2DF")
2980 (match_test "optimize_function_for_size_p (cfun)")
2981 (const_string "V4SF")
2982 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
2985 (const_string "V2DF"))
2987 /* For architectures resolving dependencies on
2988 whole SSE registers use movapd to break dependency
2989 chains, otherwise use short move to avoid extra work. */
2991 /* movaps is one byte shorter for non-AVX targets. */
2992 (eq_attr "alternative" "10,14")
2993 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2994 (match_operand 1 "ext_sse_reg_operand"))
2995 (const_string "V8DF")
2996 (ior (not (match_test "TARGET_SSE2"))
2997 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2998 (const_string "V4SF")
2999 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3000 (const_string "V2DF")
3001 (match_test "TARGET_AVX")
3003 (match_test "optimize_function_for_size_p (cfun)")
3004 (const_string "V4SF")
3006 (const_string "DF"))
3008 /* For architectures resolving dependencies on register
3009 parts we may avoid extra work to zero out upper part
3011 (eq_attr "alternative" "11,15")
3012 (cond [(not (match_test "TARGET_SSE2"))
3013 (const_string "V2SF")
3014 (match_test "TARGET_AVX")
3016 (match_test "TARGET_SSE_SPLIT_REGS")
3017 (const_string "V1DF")
3019 (const_string "DF"))
3021 (and (eq_attr "alternative" "12,16")
3022 (not (match_test "TARGET_SSE2")))
3023 (const_string "V2SF")
3025 (const_string "DF")))])
3027 (define_insn "*movsf_internal"
3028 [(set (match_operand:SF 0 "nonimmediate_operand"
3029 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3030 (match_operand:SF 1 "general_operand"
3031 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3032 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3033 && (!can_create_pseudo_p ()
3034 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3035 || GET_CODE (operands[1]) != CONST_DOUBLE
3036 || (optimize_function_for_size_p (cfun)
3037 && ((!TARGET_SSE_MATH
3038 && standard_80387_constant_p (operands[1]) > 0)
3040 && standard_sse_constant_p (operands[1]))))
3041 || memory_operand (operands[0], SFmode))"
3043 switch (get_attr_type (insn))
3046 if (which_alternative == 2)
3047 return standard_80387_constant_opcode (operands[1]);
3048 return output_387_reg_move (insn, operands);
3051 return "mov{l}\t{%1, %0|%0, %1}";
3054 return standard_sse_constant_opcode (insn, operands[1]);
3057 switch (get_attr_mode (insn))
3060 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3061 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3062 return "%vmovss\t{%1, %0|%0, %1}";
3065 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3067 return "%vmovaps\t{%1, %0|%0, %1}";
3070 return "%vmovd\t{%1, %0|%0, %1}";
3077 switch (get_attr_mode (insn))
3080 return "movq\t{%1, %0|%0, %1}";
3082 return "movd\t{%1, %0|%0, %1}";
3093 (cond [(eq_attr "alternative" "0,1,2")
3094 (const_string "fmov")
3095 (eq_attr "alternative" "3,4")
3096 (const_string "imov")
3097 (eq_attr "alternative" "5")
3098 (const_string "sselog1")
3099 (eq_attr "alternative" "11,12,13,14,15")
3100 (const_string "mmxmov")
3102 (const_string "ssemov")))
3103 (set (attr "prefix")
3104 (if_then_else (eq_attr "type" "sselog1,ssemov")
3105 (const_string "maybe_vex")
3106 (const_string "orig")))
3107 (set (attr "prefix_data16")
3108 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3110 (const_string "*")))
3112 (cond [(eq_attr "alternative" "3,4,9,10,14,15")
3114 (eq_attr "alternative" "11")
3116 (eq_attr "alternative" "5")
3117 (cond [(not (match_test "TARGET_SSE2"))
3118 (const_string "V4SF")
3119 (match_test "TARGET_AVX512F")
3120 (const_string "V16SF")
3121 (match_test "TARGET_AVX")
3122 (const_string "V4SF")
3123 (match_test "optimize_function_for_size_p (cfun)")
3124 (const_string "V4SF")
3125 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3128 (const_string "V4SF"))
3130 /* For architectures resolving dependencies on
3131 whole SSE registers use APS move to break dependency
3132 chains, otherwise use short move to avoid extra work.
3134 Do the same for architectures resolving dependencies on
3135 the parts. While in DF mode it is better to always handle
3136 just register parts, the SF mode is different due to lack
3137 of instructions to load just part of the register. It is
3138 better to maintain the whole registers in single format
3139 to avoid problems on using packed logical operations. */
3140 (eq_attr "alternative" "6")
3141 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3142 (match_operand 1 "ext_sse_reg_operand"))
3143 (const_string "V16SF")
3144 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3145 (match_test "TARGET_SSE_SPLIT_REGS"))
3146 (const_string "V4SF")
3148 (const_string "SF"))
3150 (const_string "SF")))])
3153 [(set (match_operand 0 "any_fp_register_operand")
3154 (match_operand 1 "memory_operand"))]
3156 && (GET_MODE (operands[0]) == TFmode
3157 || GET_MODE (operands[0]) == XFmode
3158 || GET_MODE (operands[0]) == DFmode
3159 || GET_MODE (operands[0]) == SFmode)
3160 && (operands[2] = find_constant_src (insn))"
3161 [(set (match_dup 0) (match_dup 2))]
3163 rtx c = operands[2];
3164 int r = REGNO (operands[0]);
3166 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3167 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3172 [(set (match_operand 0 "any_fp_register_operand")
3173 (float_extend (match_operand 1 "memory_operand")))]
3175 && (GET_MODE (operands[0]) == TFmode
3176 || GET_MODE (operands[0]) == XFmode
3177 || GET_MODE (operands[0]) == DFmode)
3178 && (operands[2] = find_constant_src (insn))"
3179 [(set (match_dup 0) (match_dup 2))]
3181 rtx c = operands[2];
3182 int r = REGNO (operands[0]);
3184 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3185 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3189 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3191 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3192 (match_operand:X87MODEF 1 "immediate_operand"))]
3194 && (standard_80387_constant_p (operands[1]) == 8
3195 || standard_80387_constant_p (operands[1]) == 9)"
3196 [(set (match_dup 0)(match_dup 1))
3198 (neg:X87MODEF (match_dup 0)))]
3202 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3203 if (real_isnegzero (&r))
3204 operands[1] = CONST0_RTX (<MODE>mode);
3206 operands[1] = CONST1_RTX (<MODE>mode);
3210 [(set (match_operand 0 "nonimmediate_operand")
3211 (match_operand 1 "general_operand"))]
3213 && (GET_MODE (operands[0]) == TFmode
3214 || GET_MODE (operands[0]) == XFmode
3215 || GET_MODE (operands[0]) == DFmode)
3216 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3218 "ix86_split_long_move (operands); DONE;")
3220 (define_insn "swapxf"
3221 [(set (match_operand:XF 0 "register_operand" "+f")
3222 (match_operand:XF 1 "register_operand" "+f"))
3227 if (STACK_TOP_P (operands[0]))
3232 [(set_attr "type" "fxch")
3233 (set_attr "mode" "XF")])
3235 (define_insn "*swap<mode>"
3236 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3237 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3240 "TARGET_80387 || reload_completed"
3242 if (STACK_TOP_P (operands[0]))
3247 [(set_attr "type" "fxch")
3248 (set_attr "mode" "<MODE>")])
3250 ;; Zero extension instructions
3252 (define_expand "zero_extendsidi2"
3253 [(set (match_operand:DI 0 "nonimmediate_operand")
3254 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3256 (define_insn "*zero_extendsidi2"
3257 [(set (match_operand:DI 0 "nonimmediate_operand"
3258 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3260 (match_operand:SI 1 "x86_64_zext_operand"
3261 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3264 switch (get_attr_type (insn))
3267 if (ix86_use_lea_for_mov (insn, operands))
3268 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3270 return "mov{l}\t{%1, %k0|%k0, %1}";
3276 return "movd\t{%1, %0|%0, %1}";
3279 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3282 if (GENERAL_REG_P (operands[0]))
3283 return "%vmovd\t{%1, %k0|%k0, %1}";
3285 return "%vmovd\t{%1, %0|%0, %1}";
3292 (cond [(eq_attr "alternative" "0,1,2")
3293 (const_string "nox64")
3294 (eq_attr "alternative" "3,7")
3295 (const_string "x64")
3296 (eq_attr "alternative" "8")
3297 (const_string "x64_sse4")
3298 (eq_attr "alternative" "10")
3299 (const_string "sse2")
3301 (const_string "*")))
3303 (cond [(eq_attr "alternative" "0,1,2,4")
3304 (const_string "multi")
3305 (eq_attr "alternative" "5,6")
3306 (const_string "mmxmov")
3307 (eq_attr "alternative" "7,9,10")
3308 (const_string "ssemov")
3309 (eq_attr "alternative" "8")
3310 (const_string "sselog1")
3312 (const_string "imovx")))
3313 (set (attr "prefix_extra")
3314 (if_then_else (eq_attr "alternative" "8")
3316 (const_string "*")))
3317 (set (attr "length_immediate")
3318 (if_then_else (eq_attr "alternative" "8")
3320 (const_string "*")))
3321 (set (attr "prefix")
3322 (if_then_else (eq_attr "type" "ssemov,sselog1")
3323 (const_string "maybe_vex")
3324 (const_string "orig")))
3325 (set (attr "prefix_0f")
3326 (if_then_else (eq_attr "type" "imovx")
3328 (const_string "*")))
3330 (cond [(eq_attr "alternative" "5,6")
3332 (eq_attr "alternative" "7,8,9")
3335 (const_string "SI")))])
3338 [(set (match_operand:DI 0 "memory_operand")
3339 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3341 [(set (match_dup 4) (const_int 0))]
3342 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3345 [(set (match_operand:DI 0 "register_operand")
3346 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3347 "!TARGET_64BIT && reload_completed
3348 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3349 && true_regnum (operands[0]) == true_regnum (operands[1])"
3350 [(set (match_dup 4) (const_int 0))]
3351 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3354 [(set (match_operand:DI 0 "nonimmediate_operand")
3355 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3356 "!TARGET_64BIT && reload_completed
3357 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3358 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3359 [(set (match_dup 3) (match_dup 1))
3360 (set (match_dup 4) (const_int 0))]
3361 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3363 (define_insn "zero_extend<mode>di2"
3364 [(set (match_operand:DI 0 "register_operand" "=r")
3366 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3368 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3369 [(set_attr "type" "imovx")
3370 (set_attr "mode" "SI")])
3372 (define_expand "zero_extend<mode>si2"
3373 [(set (match_operand:SI 0 "register_operand")
3374 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3377 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3379 operands[1] = force_reg (<MODE>mode, operands[1]);
3380 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3385 (define_insn_and_split "zero_extend<mode>si2_and"
3386 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3388 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3389 (clobber (reg:CC FLAGS_REG))]
3390 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3392 "&& reload_completed"
3393 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3394 (clobber (reg:CC FLAGS_REG))])]
3396 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3398 ix86_expand_clear (operands[0]);
3400 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3401 emit_insn (gen_movstrict<mode>
3402 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3406 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3408 [(set_attr "type" "alu1")
3409 (set_attr "mode" "SI")])
3411 (define_insn "*zero_extend<mode>si2"
3412 [(set (match_operand:SI 0 "register_operand" "=r")
3414 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3415 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3416 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3417 [(set_attr "type" "imovx")
3418 (set_attr "mode" "SI")])
3420 (define_expand "zero_extendqihi2"
3421 [(set (match_operand:HI 0 "register_operand")
3422 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3425 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3427 operands[1] = force_reg (QImode, operands[1]);
3428 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3433 (define_insn_and_split "zero_extendqihi2_and"
3434 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3435 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3436 (clobber (reg:CC FLAGS_REG))]
3437 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3439 "&& reload_completed"
3440 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3441 (clobber (reg:CC FLAGS_REG))])]
3443 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3445 ix86_expand_clear (operands[0]);
3447 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3448 emit_insn (gen_movstrictqi
3449 (gen_lowpart (QImode, operands[0]), operands[1]));
3453 operands[0] = gen_lowpart (SImode, operands[0]);
3455 [(set_attr "type" "alu1")
3456 (set_attr "mode" "SI")])
3458 ; zero extend to SImode to avoid partial register stalls
3459 (define_insn "*zero_extendqihi2"
3460 [(set (match_operand:HI 0 "register_operand" "=r")
3461 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3462 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3463 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3464 [(set_attr "type" "imovx")
3465 (set_attr "mode" "SI")])
3467 ;; Sign extension instructions
3469 (define_expand "extendsidi2"
3470 [(set (match_operand:DI 0 "register_operand")
3471 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3476 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3481 (define_insn "*extendsidi2_rex64"
3482 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3483 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3487 movs{lq|x}\t{%1, %0|%0, %1}"
3488 [(set_attr "type" "imovx")
3489 (set_attr "mode" "DI")
3490 (set_attr "prefix_0f" "0")
3491 (set_attr "modrm" "0,1")])
3493 (define_insn "extendsidi2_1"
3494 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3495 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3496 (clobber (reg:CC FLAGS_REG))
3497 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3501 ;; Split the memory case. If the source register doesn't die, it will stay
3502 ;; this way, if it does die, following peephole2s take care of it.
3504 [(set (match_operand:DI 0 "memory_operand")
3505 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3506 (clobber (reg:CC FLAGS_REG))
3507 (clobber (match_operand:SI 2 "register_operand"))]
3511 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3513 emit_move_insn (operands[3], operands[1]);
3515 /* Generate a cltd if possible and doing so it profitable. */
3516 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3517 && true_regnum (operands[1]) == AX_REG
3518 && true_regnum (operands[2]) == DX_REG)
3520 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3524 emit_move_insn (operands[2], operands[1]);
3525 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3527 emit_move_insn (operands[4], operands[2]);
3531 ;; Peepholes for the case where the source register does die, after
3532 ;; being split with the above splitter.
3534 [(set (match_operand:SI 0 "memory_operand")
3535 (match_operand:SI 1 "register_operand"))
3536 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3537 (parallel [(set (match_dup 2)
3538 (ashiftrt:SI (match_dup 2) (const_int 31)))
3539 (clobber (reg:CC FLAGS_REG))])
3540 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3541 "REGNO (operands[1]) != REGNO (operands[2])
3542 && peep2_reg_dead_p (2, operands[1])
3543 && peep2_reg_dead_p (4, operands[2])
3544 && !reg_mentioned_p (operands[2], operands[3])"
3545 [(set (match_dup 0) (match_dup 1))
3546 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3547 (clobber (reg:CC FLAGS_REG))])
3548 (set (match_dup 3) (match_dup 1))])
3551 [(set (match_operand:SI 0 "memory_operand")
3552 (match_operand:SI 1 "register_operand"))
3553 (parallel [(set (match_operand:SI 2 "register_operand")
3554 (ashiftrt:SI (match_dup 1) (const_int 31)))
3555 (clobber (reg:CC FLAGS_REG))])
3556 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3557 "/* cltd is shorter than sarl $31, %eax */
3558 !optimize_function_for_size_p (cfun)
3559 && true_regnum (operands[1]) == AX_REG
3560 && true_regnum (operands[2]) == DX_REG
3561 && peep2_reg_dead_p (2, operands[1])
3562 && peep2_reg_dead_p (3, operands[2])
3563 && !reg_mentioned_p (operands[2], operands[3])"
3564 [(set (match_dup 0) (match_dup 1))
3565 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3566 (clobber (reg:CC FLAGS_REG))])
3567 (set (match_dup 3) (match_dup 1))])
3569 ;; Extend to register case. Optimize case where source and destination
3570 ;; registers match and cases where we can use cltd.
3572 [(set (match_operand:DI 0 "register_operand")
3573 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3574 (clobber (reg:CC FLAGS_REG))
3575 (clobber (match_scratch:SI 2))]
3579 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3581 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3582 emit_move_insn (operands[3], operands[1]);
3584 /* Generate a cltd if possible and doing so it profitable. */
3585 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3586 && true_regnum (operands[3]) == AX_REG
3587 && true_regnum (operands[4]) == DX_REG)
3589 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3593 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3594 emit_move_insn (operands[4], operands[1]);
3596 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3600 (define_insn "extend<mode>di2"
3601 [(set (match_operand:DI 0 "register_operand" "=r")
3603 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3605 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3606 [(set_attr "type" "imovx")
3607 (set_attr "mode" "DI")])
3609 (define_insn "extendhisi2"
3610 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3611 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3614 switch (get_attr_prefix_0f (insn))
3617 return "{cwtl|cwde}";
3619 return "movs{wl|x}\t{%1, %0|%0, %1}";
3622 [(set_attr "type" "imovx")
3623 (set_attr "mode" "SI")
3624 (set (attr "prefix_0f")
3625 ;; movsx is short decodable while cwtl is vector decoded.
3626 (if_then_else (and (eq_attr "cpu" "!k6")
3627 (eq_attr "alternative" "0"))
3629 (const_string "1")))
3631 (if_then_else (eq_attr "prefix_0f" "0")
3633 (const_string "1")))])
3635 (define_insn "*extendhisi2_zext"
3636 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3639 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3642 switch (get_attr_prefix_0f (insn))
3645 return "{cwtl|cwde}";
3647 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3650 [(set_attr "type" "imovx")
3651 (set_attr "mode" "SI")
3652 (set (attr "prefix_0f")
3653 ;; movsx is short decodable while cwtl is vector decoded.
3654 (if_then_else (and (eq_attr "cpu" "!k6")
3655 (eq_attr "alternative" "0"))
3657 (const_string "1")))
3659 (if_then_else (eq_attr "prefix_0f" "0")
3661 (const_string "1")))])
3663 (define_insn "extendqisi2"
3664 [(set (match_operand:SI 0 "register_operand" "=r")
3665 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3667 "movs{bl|x}\t{%1, %0|%0, %1}"
3668 [(set_attr "type" "imovx")
3669 (set_attr "mode" "SI")])
3671 (define_insn "*extendqisi2_zext"
3672 [(set (match_operand:DI 0 "register_operand" "=r")
3674 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3676 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3677 [(set_attr "type" "imovx")
3678 (set_attr "mode" "SI")])
3680 (define_insn "extendqihi2"
3681 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3682 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3685 switch (get_attr_prefix_0f (insn))
3688 return "{cbtw|cbw}";
3690 return "movs{bw|x}\t{%1, %0|%0, %1}";
3693 [(set_attr "type" "imovx")
3694 (set_attr "mode" "HI")
3695 (set (attr "prefix_0f")
3696 ;; movsx is short decodable while cwtl is vector decoded.
3697 (if_then_else (and (eq_attr "cpu" "!k6")
3698 (eq_attr "alternative" "0"))
3700 (const_string "1")))
3702 (if_then_else (eq_attr "prefix_0f" "0")
3704 (const_string "1")))])
3706 ;; Conversions between float and double.
3708 ;; These are all no-ops in the model used for the 80387.
3709 ;; So just emit moves.
3711 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3713 [(set (match_operand:DF 0 "push_operand")
3714 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3716 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3717 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3720 [(set (match_operand:XF 0 "push_operand")
3721 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3723 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3724 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3725 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3727 (define_expand "extendsfdf2"
3728 [(set (match_operand:DF 0 "nonimmediate_operand")
3729 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3730 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3732 /* ??? Needed for compress_float_constant since all fp constants
3733 are TARGET_LEGITIMATE_CONSTANT_P. */
3734 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3736 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3737 && standard_80387_constant_p (operands[1]) > 0)
3739 operands[1] = simplify_const_unary_operation
3740 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3741 emit_move_insn_1 (operands[0], operands[1]);
3744 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3748 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3750 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3752 We do the conversion post reload to avoid producing of 128bit spills
3753 that might lead to ICE on 32bit target. The sequence unlikely combine
3756 [(set (match_operand:DF 0 "register_operand")
3758 (match_operand:SF 1 "nonimmediate_operand")))]
3759 "TARGET_USE_VECTOR_FP_CONVERTS
3760 && optimize_insn_for_speed_p ()
3761 && reload_completed && SSE_REG_P (operands[0])"
3766 (parallel [(const_int 0) (const_int 1)]))))]
3768 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3769 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3770 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3771 Try to avoid move when unpacking can be done in source. */
3772 if (REG_P (operands[1]))
3774 /* If it is unsafe to overwrite upper half of source, we need
3775 to move to destination and unpack there. */
3776 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3777 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3778 && true_regnum (operands[0]) != true_regnum (operands[1]))
3780 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3781 emit_move_insn (tmp, operands[1]);
3784 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3785 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3789 emit_insn (gen_vec_setv4sf_0 (operands[3],
3790 CONST0_RTX (V4SFmode), operands[1]));
3793 ;; It's more profitable to split and then extend in the same register.
3795 [(set (match_operand:DF 0 "register_operand")
3797 (match_operand:SF 1 "memory_operand")))]
3798 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3799 && optimize_insn_for_speed_p ()
3800 && SSE_REG_P (operands[0])"
3801 [(set (match_dup 2) (match_dup 1))
3802 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3803 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3805 (define_insn "*extendsfdf2_mixed"
3806 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3808 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3809 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3811 switch (which_alternative)
3815 return output_387_reg_move (insn, operands);
3818 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3824 [(set_attr "type" "fmov,fmov,ssecvt")
3825 (set_attr "prefix" "orig,orig,maybe_vex")
3826 (set_attr "mode" "SF,XF,DF")])
3828 (define_insn "*extendsfdf2_sse"
3829 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3830 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3831 "TARGET_SSE2 && TARGET_SSE_MATH"
3832 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3833 [(set_attr "type" "ssecvt")
3834 (set_attr "prefix" "maybe_vex")
3835 (set_attr "mode" "DF")])
3837 (define_insn "*extendsfdf2_i387"
3838 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3839 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3841 "* return output_387_reg_move (insn, operands);"
3842 [(set_attr "type" "fmov")
3843 (set_attr "mode" "SF,XF")])
3845 (define_expand "extend<mode>xf2"
3846 [(set (match_operand:XF 0 "nonimmediate_operand")
3847 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3850 /* ??? Needed for compress_float_constant since all fp constants
3851 are TARGET_LEGITIMATE_CONSTANT_P. */
3852 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3854 if (standard_80387_constant_p (operands[1]) > 0)
3856 operands[1] = simplify_const_unary_operation
3857 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3858 emit_move_insn_1 (operands[0], operands[1]);
3861 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3865 (define_insn "*extend<mode>xf2_i387"
3866 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3868 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3870 "* return output_387_reg_move (insn, operands);"
3871 [(set_attr "type" "fmov")
3872 (set_attr "mode" "<MODE>,XF")])
3874 ;; %%% This seems bad bad news.
3875 ;; This cannot output into an f-reg because there is no way to be sure
3876 ;; of truncating in that case. Otherwise this is just like a simple move
3877 ;; insn. So we pretend we can output to a reg in order to get better
3878 ;; register preferencing, but we really use a stack slot.
3880 ;; Conversion from DFmode to SFmode.
3882 (define_expand "truncdfsf2"
3883 [(set (match_operand:SF 0 "nonimmediate_operand")
3885 (match_operand:DF 1 "nonimmediate_operand")))]
3886 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3888 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3890 else if (flag_unsafe_math_optimizations)
3894 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3895 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3900 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3902 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3904 We do the conversion post reload to avoid producing of 128bit spills
3905 that might lead to ICE on 32bit target. The sequence unlikely combine
3908 [(set (match_operand:SF 0 "register_operand")
3910 (match_operand:DF 1 "nonimmediate_operand")))]
3911 "TARGET_USE_VECTOR_FP_CONVERTS
3912 && optimize_insn_for_speed_p ()
3913 && reload_completed && SSE_REG_P (operands[0])"
3916 (float_truncate:V2SF
3920 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3921 operands[3] = CONST0_RTX (V2SFmode);
3922 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3923 /* Use movsd for loading from memory, unpcklpd for registers.
3924 Try to avoid move when unpacking can be done in source, or SSE3
3925 movddup is available. */
3926 if (REG_P (operands[1]))
3929 && true_regnum (operands[0]) != true_regnum (operands[1])
3930 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3931 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3933 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3934 emit_move_insn (tmp, operands[1]);
3937 else if (!TARGET_SSE3)
3938 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3939 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3942 emit_insn (gen_sse2_loadlpd (operands[4],
3943 CONST0_RTX (V2DFmode), operands[1]));
3946 ;; It's more profitable to split and then extend in the same register.
3948 [(set (match_operand:SF 0 "register_operand")
3950 (match_operand:DF 1 "memory_operand")))]
3951 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3952 && optimize_insn_for_speed_p ()
3953 && SSE_REG_P (operands[0])"
3954 [(set (match_dup 2) (match_dup 1))
3955 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
3956 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
3958 (define_expand "truncdfsf2_with_temp"
3959 [(parallel [(set (match_operand:SF 0)
3960 (float_truncate:SF (match_operand:DF 1)))
3961 (clobber (match_operand:SF 2))])])
3963 (define_insn "*truncdfsf_fast_mixed"
3964 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
3966 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
3967 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3969 switch (which_alternative)
3972 return output_387_reg_move (insn, operands);
3974 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
3979 [(set_attr "type" "fmov,ssecvt")
3980 (set_attr "prefix" "orig,maybe_vex")
3981 (set_attr "mode" "SF")])
3983 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3984 ;; because nothing we do here is unsafe.
3985 (define_insn "*truncdfsf_fast_sse"
3986 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
3988 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3989 "TARGET_SSE2 && TARGET_SSE_MATH"
3990 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
3991 [(set_attr "type" "ssecvt")
3992 (set_attr "prefix" "maybe_vex")
3993 (set_attr "mode" "SF")])
3995 (define_insn "*truncdfsf_fast_i387"
3996 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3998 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3999 "TARGET_80387 && flag_unsafe_math_optimizations"
4000 "* return output_387_reg_move (insn, operands);"
4001 [(set_attr "type" "fmov")
4002 (set_attr "mode" "SF")])
4004 (define_insn "*truncdfsf_mixed"
4005 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4007 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4008 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4009 "TARGET_MIX_SSE_I387"
4011 switch (which_alternative)
4014 return output_387_reg_move (insn, operands);
4016 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4022 [(set_attr "isa" "*,sse2,*,*,*")
4023 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4024 (set_attr "unit" "*,*,i387,i387,i387")
4025 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4026 (set_attr "mode" "SF")])
4028 (define_insn "*truncdfsf_i387"
4029 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4031 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4032 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4035 switch (which_alternative)
4038 return output_387_reg_move (insn, operands);
4044 [(set_attr "type" "fmov,multi,multi,multi")
4045 (set_attr "unit" "*,i387,i387,i387")
4046 (set_attr "mode" "SF")])
4048 (define_insn "*truncdfsf2_i387_1"
4049 [(set (match_operand:SF 0 "memory_operand" "=m")
4051 (match_operand:DF 1 "register_operand" "f")))]
4053 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4054 && !TARGET_MIX_SSE_I387"
4055 "* return output_387_reg_move (insn, operands);"
4056 [(set_attr "type" "fmov")
4057 (set_attr "mode" "SF")])
4060 [(set (match_operand:SF 0 "register_operand")
4062 (match_operand:DF 1 "fp_register_operand")))
4063 (clobber (match_operand 2))]
4065 [(set (match_dup 2) (match_dup 1))
4066 (set (match_dup 0) (match_dup 2))]
4067 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4069 ;; Conversion from XFmode to {SF,DF}mode
4071 (define_expand "truncxf<mode>2"
4072 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4073 (float_truncate:MODEF
4074 (match_operand:XF 1 "register_operand")))
4075 (clobber (match_dup 2))])]
4078 if (flag_unsafe_math_optimizations)
4080 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4081 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4082 if (reg != operands[0])
4083 emit_move_insn (operands[0], reg);
4087 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4090 (define_insn "*truncxfsf2_mixed"
4091 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4093 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4094 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4097 gcc_assert (!which_alternative);
4098 return output_387_reg_move (insn, operands);
4100 [(set_attr "type" "fmov,multi,multi,multi")
4101 (set_attr "unit" "*,i387,i387,i387")
4102 (set_attr "mode" "SF")])
4104 (define_insn "*truncxfdf2_mixed"
4105 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4107 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4108 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4111 gcc_assert (!which_alternative);
4112 return output_387_reg_move (insn, operands);
4114 [(set_attr "isa" "*,*,sse2,*")
4115 (set_attr "type" "fmov,multi,multi,multi")
4116 (set_attr "unit" "*,i387,i387,i387")
4117 (set_attr "mode" "DF")])
4119 (define_insn "truncxf<mode>2_i387_noop"
4120 [(set (match_operand:MODEF 0 "register_operand" "=f")
4121 (float_truncate:MODEF
4122 (match_operand:XF 1 "register_operand" "f")))]
4123 "TARGET_80387 && flag_unsafe_math_optimizations"
4124 "* return output_387_reg_move (insn, operands);"
4125 [(set_attr "type" "fmov")
4126 (set_attr "mode" "<MODE>")])
4128 (define_insn "*truncxf<mode>2_i387"
4129 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4130 (float_truncate:MODEF
4131 (match_operand:XF 1 "register_operand" "f")))]
4133 "* return output_387_reg_move (insn, operands);"
4134 [(set_attr "type" "fmov")
4135 (set_attr "mode" "<MODE>")])
4138 [(set (match_operand:MODEF 0 "register_operand")
4139 (float_truncate:MODEF
4140 (match_operand:XF 1 "register_operand")))
4141 (clobber (match_operand:MODEF 2 "memory_operand"))]
4142 "TARGET_80387 && reload_completed"
4143 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4144 (set (match_dup 0) (match_dup 2))])
4147 [(set (match_operand:MODEF 0 "memory_operand")
4148 (float_truncate:MODEF
4149 (match_operand:XF 1 "register_operand")))
4150 (clobber (match_operand:MODEF 2 "memory_operand"))]
4152 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4154 ;; Signed conversion to DImode.
4156 (define_expand "fix_truncxfdi2"
4157 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4158 (fix:DI (match_operand:XF 1 "register_operand")))
4159 (clobber (reg:CC FLAGS_REG))])]
4164 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4169 (define_expand "fix_trunc<mode>di2"
4170 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4171 (fix:DI (match_operand:MODEF 1 "register_operand")))
4172 (clobber (reg:CC FLAGS_REG))])]
4173 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4176 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4178 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4181 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4183 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4184 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4185 if (out != operands[0])
4186 emit_move_insn (operands[0], out);
4191 ;; Signed conversion to SImode.
4193 (define_expand "fix_truncxfsi2"
4194 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4195 (fix:SI (match_operand:XF 1 "register_operand")))
4196 (clobber (reg:CC FLAGS_REG))])]
4201 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4206 (define_expand "fix_trunc<mode>si2"
4207 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4208 (fix:SI (match_operand:MODEF 1 "register_operand")))
4209 (clobber (reg:CC FLAGS_REG))])]
4210 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4213 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4215 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4218 if (SSE_FLOAT_MODE_P (<MODE>mode))
4220 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4221 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4222 if (out != operands[0])
4223 emit_move_insn (operands[0], out);
4228 ;; Signed conversion to HImode.
4230 (define_expand "fix_trunc<mode>hi2"
4231 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4232 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4233 (clobber (reg:CC FLAGS_REG))])]
4235 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4239 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4244 ;; Unsigned conversion to SImode.
4246 (define_expand "fixuns_trunc<mode>si2"
4248 [(set (match_operand:SI 0 "register_operand")
4250 (match_operand:MODEF 1 "nonimmediate_operand")))
4252 (clobber (match_scratch:<ssevecmode> 3))
4253 (clobber (match_scratch:<ssevecmode> 4))])]
4254 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4256 enum machine_mode mode = <MODE>mode;
4257 enum machine_mode vecmode = <ssevecmode>mode;
4258 REAL_VALUE_TYPE TWO31r;
4261 if (optimize_insn_for_size_p ())
4264 real_ldexp (&TWO31r, &dconst1, 31);
4265 two31 = const_double_from_real_value (TWO31r, mode);
4266 two31 = ix86_build_const_vector (vecmode, true, two31);
4267 operands[2] = force_reg (vecmode, two31);
4270 (define_insn_and_split "*fixuns_trunc<mode>_1"
4271 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4273 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4274 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4275 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4276 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4277 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4278 && optimize_function_for_speed_p (cfun)"
4280 "&& reload_completed"
4283 ix86_split_convert_uns_si_sse (operands);
4287 ;; Unsigned conversion to HImode.
4288 ;; Without these patterns, we'll try the unsigned SI conversion which
4289 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4291 (define_expand "fixuns_trunc<mode>hi2"
4293 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4294 (set (match_operand:HI 0 "nonimmediate_operand")
4295 (subreg:HI (match_dup 2) 0))]
4296 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4297 "operands[2] = gen_reg_rtx (SImode);")
4299 ;; When SSE is available, it is always faster to use it!
4300 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4301 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4302 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4303 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4304 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4305 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4306 [(set_attr "type" "sseicvt")
4307 (set_attr "prefix" "maybe_vex")
4308 (set (attr "prefix_rex")
4310 (match_test "<SWI48:MODE>mode == DImode")
4312 (const_string "*")))
4313 (set_attr "mode" "<MODEF:MODE>")
4314 (set_attr "athlon_decode" "double,vector")
4315 (set_attr "amdfam10_decode" "double,double")
4316 (set_attr "bdver1_decode" "double,double")])
4318 ;; Avoid vector decoded forms of the instruction.
4320 [(match_scratch:MODEF 2 "x")
4321 (set (match_operand:SWI48 0 "register_operand")
4322 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4323 "TARGET_AVOID_VECTOR_DECODE
4324 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4325 && optimize_insn_for_speed_p ()"
4326 [(set (match_dup 2) (match_dup 1))
4327 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4329 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4330 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4331 (fix:SWI248x (match_operand 1 "register_operand")))]
4332 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4334 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4335 && (TARGET_64BIT || <MODE>mode != DImode))
4337 && can_create_pseudo_p ()"
4342 if (memory_operand (operands[0], VOIDmode))
4343 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4346 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4347 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4353 [(set_attr "type" "fisttp")
4354 (set_attr "mode" "<MODE>")])
4356 (define_insn "fix_trunc<mode>_i387_fisttp"
4357 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4358 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4359 (clobber (match_scratch:XF 2 "=&1f"))]
4360 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4362 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4363 && (TARGET_64BIT || <MODE>mode != DImode))
4364 && TARGET_SSE_MATH)"
4365 "* return output_fix_trunc (insn, operands, true);"
4366 [(set_attr "type" "fisttp")
4367 (set_attr "mode" "<MODE>")])
4369 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4370 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4371 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4372 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4373 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4374 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4376 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4377 && (TARGET_64BIT || <MODE>mode != DImode))
4378 && TARGET_SSE_MATH)"
4380 [(set_attr "type" "fisttp")
4381 (set_attr "mode" "<MODE>")])
4384 [(set (match_operand:SWI248x 0 "register_operand")
4385 (fix:SWI248x (match_operand 1 "register_operand")))
4386 (clobber (match_operand:SWI248x 2 "memory_operand"))
4387 (clobber (match_scratch 3))]
4389 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4390 (clobber (match_dup 3))])
4391 (set (match_dup 0) (match_dup 2))])
4394 [(set (match_operand:SWI248x 0 "memory_operand")
4395 (fix:SWI248x (match_operand 1 "register_operand")))
4396 (clobber (match_operand:SWI248x 2 "memory_operand"))
4397 (clobber (match_scratch 3))]
4399 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4400 (clobber (match_dup 3))])])
4402 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4403 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4404 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4405 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4406 ;; function in i386.c.
4407 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4408 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4409 (fix:SWI248x (match_operand 1 "register_operand")))
4410 (clobber (reg:CC FLAGS_REG))]
4411 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4413 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4414 && (TARGET_64BIT || <MODE>mode != DImode))
4415 && can_create_pseudo_p ()"
4420 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4422 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4423 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4424 if (memory_operand (operands[0], VOIDmode))
4425 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4426 operands[2], operands[3]));
4429 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4430 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4431 operands[2], operands[3],
4436 [(set_attr "type" "fistp")
4437 (set_attr "i387_cw" "trunc")
4438 (set_attr "mode" "<MODE>")])
4440 (define_insn "fix_truncdi_i387"
4441 [(set (match_operand:DI 0 "memory_operand" "=m")
4442 (fix:DI (match_operand 1 "register_operand" "f")))
4443 (use (match_operand:HI 2 "memory_operand" "m"))
4444 (use (match_operand:HI 3 "memory_operand" "m"))
4445 (clobber (match_scratch:XF 4 "=&1f"))]
4446 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4448 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4449 "* return output_fix_trunc (insn, operands, false);"
4450 [(set_attr "type" "fistp")
4451 (set_attr "i387_cw" "trunc")
4452 (set_attr "mode" "DI")])
4454 (define_insn "fix_truncdi_i387_with_temp"
4455 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4456 (fix:DI (match_operand 1 "register_operand" "f,f")))
4457 (use (match_operand:HI 2 "memory_operand" "m,m"))
4458 (use (match_operand:HI 3 "memory_operand" "m,m"))
4459 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4460 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4461 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4463 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4465 [(set_attr "type" "fistp")
4466 (set_attr "i387_cw" "trunc")
4467 (set_attr "mode" "DI")])
4470 [(set (match_operand:DI 0 "register_operand")
4471 (fix:DI (match_operand 1 "register_operand")))
4472 (use (match_operand:HI 2 "memory_operand"))
4473 (use (match_operand:HI 3 "memory_operand"))
4474 (clobber (match_operand:DI 4 "memory_operand"))
4475 (clobber (match_scratch 5))]
4477 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4480 (clobber (match_dup 5))])
4481 (set (match_dup 0) (match_dup 4))])
4484 [(set (match_operand:DI 0 "memory_operand")
4485 (fix:DI (match_operand 1 "register_operand")))
4486 (use (match_operand:HI 2 "memory_operand"))
4487 (use (match_operand:HI 3 "memory_operand"))
4488 (clobber (match_operand:DI 4 "memory_operand"))
4489 (clobber (match_scratch 5))]
4491 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4494 (clobber (match_dup 5))])])
4496 (define_insn "fix_trunc<mode>_i387"
4497 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4498 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4499 (use (match_operand:HI 2 "memory_operand" "m"))
4500 (use (match_operand:HI 3 "memory_operand" "m"))]
4501 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4503 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4504 "* return output_fix_trunc (insn, operands, false);"
4505 [(set_attr "type" "fistp")
4506 (set_attr "i387_cw" "trunc")
4507 (set_attr "mode" "<MODE>")])
4509 (define_insn "fix_trunc<mode>_i387_with_temp"
4510 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4511 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4512 (use (match_operand:HI 2 "memory_operand" "m,m"))
4513 (use (match_operand:HI 3 "memory_operand" "m,m"))
4514 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4515 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4517 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4519 [(set_attr "type" "fistp")
4520 (set_attr "i387_cw" "trunc")
4521 (set_attr "mode" "<MODE>")])
4524 [(set (match_operand:SWI24 0 "register_operand")
4525 (fix:SWI24 (match_operand 1 "register_operand")))
4526 (use (match_operand:HI 2 "memory_operand"))
4527 (use (match_operand:HI 3 "memory_operand"))
4528 (clobber (match_operand:SWI24 4 "memory_operand"))]
4530 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4532 (use (match_dup 3))])
4533 (set (match_dup 0) (match_dup 4))])
4536 [(set (match_operand:SWI24 0 "memory_operand")
4537 (fix:SWI24 (match_operand 1 "register_operand")))
4538 (use (match_operand:HI 2 "memory_operand"))
4539 (use (match_operand:HI 3 "memory_operand"))
4540 (clobber (match_operand:SWI24 4 "memory_operand"))]
4542 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4544 (use (match_dup 3))])])
4546 (define_insn "x86_fnstcw_1"
4547 [(set (match_operand:HI 0 "memory_operand" "=m")
4548 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4551 [(set (attr "length")
4552 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4553 (set_attr "mode" "HI")
4554 (set_attr "unit" "i387")
4555 (set_attr "bdver1_decode" "vector")])
4557 (define_insn "x86_fldcw_1"
4558 [(set (reg:HI FPCR_REG)
4559 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4562 [(set (attr "length")
4563 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4564 (set_attr "mode" "HI")
4565 (set_attr "unit" "i387")
4566 (set_attr "athlon_decode" "vector")
4567 (set_attr "amdfam10_decode" "vector")
4568 (set_attr "bdver1_decode" "vector")])
4570 ;; Conversion between fixed point and floating point.
4572 ;; Even though we only accept memory inputs, the backend _really_
4573 ;; wants to be able to do this between registers.
4575 (define_expand "floathi<mode>2"
4576 [(set (match_operand:X87MODEF 0 "register_operand")
4577 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4579 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4580 || TARGET_MIX_SSE_I387)")
4582 ;; Pre-reload splitter to add memory clobber to the pattern.
4583 (define_insn_and_split "*floathi<mode>2_1"
4584 [(set (match_operand:X87MODEF 0 "register_operand")
4585 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4587 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4588 || TARGET_MIX_SSE_I387)
4589 && can_create_pseudo_p ()"
4592 [(parallel [(set (match_dup 0)
4593 (float:X87MODEF (match_dup 1)))
4594 (clobber (match_dup 2))])]
4595 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4597 (define_insn "*floathi<mode>2_i387_with_temp"
4598 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4599 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4600 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4602 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4603 || TARGET_MIX_SSE_I387)"
4605 [(set_attr "type" "fmov,multi")
4606 (set_attr "mode" "<MODE>")
4607 (set_attr "unit" "*,i387")
4608 (set_attr "fp_int_src" "true")])
4610 (define_insn "*floathi<mode>2_i387"
4611 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4612 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4614 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4615 || TARGET_MIX_SSE_I387)"
4617 [(set_attr "type" "fmov")
4618 (set_attr "mode" "<MODE>")
4619 (set_attr "fp_int_src" "true")])
4622 [(set (match_operand:X87MODEF 0 "register_operand")
4623 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4624 (clobber (match_operand:HI 2 "memory_operand"))]
4626 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4627 || TARGET_MIX_SSE_I387)
4628 && reload_completed"
4629 [(set (match_dup 2) (match_dup 1))
4630 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4633 [(set (match_operand:X87MODEF 0 "register_operand")
4634 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4635 (clobber (match_operand:HI 2 "memory_operand"))]
4637 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4638 || TARGET_MIX_SSE_I387)
4639 && reload_completed"
4640 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4642 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4643 [(set (match_operand:X87MODEF 0 "register_operand")
4645 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4647 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4648 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4650 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4651 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4652 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4654 rtx reg = gen_reg_rtx (XFmode);
4655 rtx (*insn)(rtx, rtx);
4657 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4659 if (<X87MODEF:MODE>mode == SFmode)
4660 insn = gen_truncxfsf2;
4661 else if (<X87MODEF:MODE>mode == DFmode)
4662 insn = gen_truncxfdf2;
4666 emit_insn (insn (operands[0], reg));
4671 ;; Pre-reload splitter to add memory clobber to the pattern.
4672 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4673 [(set (match_operand:X87MODEF 0 "register_operand")
4674 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4676 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4677 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4678 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4679 || TARGET_MIX_SSE_I387))
4680 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4681 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4682 && ((<SWI48x:MODE>mode == SImode
4683 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4684 && optimize_function_for_speed_p (cfun)
4685 && flag_trapping_math)
4686 || !(TARGET_INTER_UNIT_CONVERSIONS
4687 || optimize_function_for_size_p (cfun)))))
4688 && can_create_pseudo_p ()"
4691 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4692 (clobber (match_dup 2))])]
4694 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4696 /* Avoid store forwarding (partial memory) stall penalty
4697 by passing DImode value through XMM registers. */
4698 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4699 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4700 && optimize_function_for_speed_p (cfun))
4702 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4709 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4710 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4712 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4713 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4714 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4715 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4717 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4718 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4719 (set_attr "unit" "*,i387,*,*,*")
4720 (set_attr "athlon_decode" "*,*,double,direct,double")
4721 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4722 (set_attr "bdver1_decode" "*,*,double,direct,double")
4723 (set_attr "fp_int_src" "true")])
4725 (define_insn "*floatsi<mode>2_vector_mixed"
4726 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4727 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4728 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4729 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4733 [(set_attr "type" "fmov,sseicvt")
4734 (set_attr "mode" "<MODE>,<ssevecmode>")
4735 (set_attr "unit" "i387,*")
4736 (set_attr "athlon_decode" "*,direct")
4737 (set_attr "amdfam10_decode" "*,double")
4738 (set_attr "bdver1_decode" "*,direct")
4739 (set_attr "fp_int_src" "true")])
4741 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4742 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4744 (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4745 (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4746 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4748 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4749 (set_attr "mode" "<MODEF:MODE>")
4750 (set_attr "unit" "*,i387,*,*")
4751 (set_attr "athlon_decode" "*,*,double,direct")
4752 (set_attr "amdfam10_decode" "*,*,vector,double")
4753 (set_attr "bdver1_decode" "*,*,double,direct")
4754 (set_attr "fp_int_src" "true")])
4757 [(set (match_operand:MODEF 0 "register_operand")
4758 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4759 (clobber (match_operand:SWI48 2 "memory_operand"))]
4760 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4761 && TARGET_INTER_UNIT_CONVERSIONS
4762 && reload_completed && SSE_REG_P (operands[0])"
4763 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4766 [(set (match_operand:MODEF 0 "register_operand")
4767 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4768 (clobber (match_operand:SWI48 2 "memory_operand"))]
4769 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4770 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4771 && reload_completed && SSE_REG_P (operands[0])"
4772 [(set (match_dup 2) (match_dup 1))
4773 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4775 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4776 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4778 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4779 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4780 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4783 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4784 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4785 [(set_attr "type" "fmov,sseicvt,sseicvt")
4786 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4787 (set_attr "mode" "<MODEF:MODE>")
4788 (set (attr "prefix_rex")
4790 (and (eq_attr "prefix" "maybe_vex")
4791 (match_test "<SWI48:MODE>mode == DImode"))
4793 (const_string "*")))
4794 (set_attr "unit" "i387,*,*")
4795 (set_attr "athlon_decode" "*,double,direct")
4796 (set_attr "amdfam10_decode" "*,vector,double")
4797 (set_attr "bdver1_decode" "*,double,direct")
4798 (set_attr "fp_int_src" "true")])
4800 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4801 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4803 (match_operand:SWI48 1 "memory_operand" "m,m")))]
4804 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4805 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4808 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4809 [(set_attr "type" "fmov,sseicvt")
4810 (set_attr "prefix" "orig,maybe_vex")
4811 (set_attr "mode" "<MODEF:MODE>")
4812 (set (attr "prefix_rex")
4814 (and (eq_attr "prefix" "maybe_vex")
4815 (match_test "<SWI48:MODE>mode == DImode"))
4817 (const_string "*")))
4818 (set_attr "athlon_decode" "*,direct")
4819 (set_attr "amdfam10_decode" "*,double")
4820 (set_attr "bdver1_decode" "*,direct")
4821 (set_attr "fp_int_src" "true")])
4823 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4824 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4826 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4827 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4828 "TARGET_SSE2 && TARGET_SSE_MATH
4829 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4831 [(set_attr "type" "sseicvt")
4832 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4833 (set_attr "athlon_decode" "double,direct,double")
4834 (set_attr "amdfam10_decode" "vector,double,double")
4835 (set_attr "bdver1_decode" "double,direct,double")
4836 (set_attr "fp_int_src" "true")])
4838 (define_insn "*floatsi<mode>2_vector_sse"
4839 [(set (match_operand:MODEF 0 "register_operand" "=x")
4840 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4841 "TARGET_SSE2 && TARGET_SSE_MATH
4842 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4844 [(set_attr "type" "sseicvt")
4845 (set_attr "mode" "<MODE>")
4846 (set_attr "athlon_decode" "direct")
4847 (set_attr "amdfam10_decode" "double")
4848 (set_attr "bdver1_decode" "direct")
4849 (set_attr "fp_int_src" "true")])
4852 [(set (match_operand:MODEF 0 "register_operand")
4853 (float:MODEF (match_operand:SI 1 "register_operand")))
4854 (clobber (match_operand:SI 2 "memory_operand"))]
4855 "TARGET_SSE2 && TARGET_SSE_MATH
4856 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4857 && reload_completed && SSE_REG_P (operands[0])"
4860 rtx op1 = operands[1];
4862 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4864 if (GET_CODE (op1) == SUBREG)
4865 op1 = SUBREG_REG (op1);
4867 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES_TO_VEC)
4869 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4870 emit_insn (gen_sse2_loadld (operands[4],
4871 CONST0_RTX (V4SImode), operands[1]));
4873 /* We can ignore possible trapping value in the
4874 high part of SSE register for non-trapping math. */
4875 else if (SSE_REG_P (op1) && !flag_trapping_math)
4876 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4879 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4880 emit_move_insn (operands[2], operands[1]);
4881 emit_insn (gen_sse2_loadld (operands[4],
4882 CONST0_RTX (V4SImode), operands[2]));
4884 if (<ssevecmode>mode == V4SFmode)
4885 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4887 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4892 [(set (match_operand:MODEF 0 "register_operand")
4893 (float:MODEF (match_operand:SI 1 "memory_operand")))
4894 (clobber (match_operand:SI 2 "memory_operand"))]
4895 "TARGET_SSE2 && TARGET_SSE_MATH
4896 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4897 && reload_completed && SSE_REG_P (operands[0])"
4900 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4902 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4904 emit_insn (gen_sse2_loadld (operands[4],
4905 CONST0_RTX (V4SImode), operands[1]));
4906 if (<ssevecmode>mode == V4SFmode)
4907 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4909 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4914 [(set (match_operand:MODEF 0 "register_operand")
4915 (float:MODEF (match_operand:SI 1 "register_operand")))]
4916 "TARGET_SSE2 && TARGET_SSE_MATH
4917 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4918 && reload_completed && SSE_REG_P (operands[0])"
4921 rtx op1 = operands[1];
4923 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4925 if (GET_CODE (op1) == SUBREG)
4926 op1 = SUBREG_REG (op1);
4928 if (GENERAL_REG_P (op1))
4930 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4931 if (TARGET_INTER_UNIT_MOVES_TO_VEC)
4932 emit_insn (gen_sse2_loadld (operands[4],
4933 CONST0_RTX (V4SImode), operands[1]));
4936 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
4938 emit_insn (gen_sse2_loadld (operands[4],
4939 CONST0_RTX (V4SImode), operands[5]));
4940 ix86_free_from_memory (GET_MODE (operands[1]));
4943 /* We can ignore possible trapping value in the
4944 high part of SSE register for non-trapping math. */
4945 else if (SSE_REG_P (op1) && !flag_trapping_math)
4946 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4949 if (<ssevecmode>mode == V4SFmode)
4950 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4952 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4957 [(set (match_operand:MODEF 0 "register_operand")
4958 (float:MODEF (match_operand:SI 1 "memory_operand")))]
4959 "TARGET_SSE2 && TARGET_SSE_MATH
4960 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4961 && reload_completed && SSE_REG_P (operands[0])"
4964 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4966 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4968 emit_insn (gen_sse2_loadld (operands[4],
4969 CONST0_RTX (V4SImode), operands[1]));
4970 if (<ssevecmode>mode == V4SFmode)
4971 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4973 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4977 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
4978 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4980 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
4981 (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
4982 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4984 [(set_attr "type" "sseicvt")
4985 (set_attr "mode" "<MODEF:MODE>")
4986 (set_attr "athlon_decode" "double,direct")
4987 (set_attr "amdfam10_decode" "vector,double")
4988 (set_attr "bdver1_decode" "double,direct")
4989 (set_attr "btver2_decode" "double,double")
4990 (set_attr "fp_int_src" "true")])
4992 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
4993 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4995 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
4996 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4997 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4998 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4999 [(set_attr "type" "sseicvt")
5000 (set_attr "prefix" "maybe_vex")
5001 (set_attr "mode" "<MODEF:MODE>")
5002 (set (attr "prefix_rex")
5004 (and (eq_attr "prefix" "maybe_vex")
5005 (match_test "<SWI48:MODE>mode == DImode"))
5007 (const_string "*")))
5008 (set_attr "athlon_decode" "double,direct")
5009 (set_attr "amdfam10_decode" "vector,double")
5010 (set_attr "bdver1_decode" "double,direct")
5011 (set_attr "btver2_decode" "double,double")
5012 (set_attr "fp_int_src" "true")])
5015 [(set (match_operand:MODEF 0 "register_operand")
5016 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
5017 (clobber (match_operand:SWI48 2 "memory_operand"))]
5018 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5019 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5020 && reload_completed && SSE_REG_P (operands[0])"
5021 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5023 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
5024 [(set (match_operand:MODEF 0 "register_operand" "=x")
5026 (match_operand:SWI48 1 "memory_operand" "m")))]
5027 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5028 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5029 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5030 [(set_attr "type" "sseicvt")
5031 (set_attr "prefix" "maybe_vex")
5032 (set_attr "mode" "<MODEF:MODE>")
5033 (set (attr "prefix_rex")
5035 (and (eq_attr "prefix" "maybe_vex")
5036 (match_test "<SWI48:MODE>mode == DImode"))
5038 (const_string "*")))
5039 (set_attr "athlon_decode" "direct")
5040 (set_attr "amdfam10_decode" "double")
5041 (set_attr "bdver1_decode" "direct")
5042 (set_attr "fp_int_src" "true")])
5045 [(set (match_operand:MODEF 0 "register_operand")
5046 (float:MODEF (match_operand:SWI48 1 "register_operand")))
5047 (clobber (match_operand:SWI48 2 "memory_operand"))]
5048 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5049 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5050 && reload_completed && SSE_REG_P (operands[0])"
5051 [(set (match_dup 2) (match_dup 1))
5052 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5055 [(set (match_operand:MODEF 0 "register_operand")
5056 (float:MODEF (match_operand:SWI48 1 "memory_operand")))
5057 (clobber (match_operand:SWI48 2 "memory_operand"))]
5058 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5059 && reload_completed && SSE_REG_P (operands[0])"
5060 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5062 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5063 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5065 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5066 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5068 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5072 [(set_attr "type" "fmov,multi")
5073 (set_attr "mode" "<X87MODEF:MODE>")
5074 (set_attr "unit" "*,i387")
5075 (set_attr "fp_int_src" "true")])
5077 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5078 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5080 (match_operand:SWI48x 1 "memory_operand" "m")))]
5082 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5084 [(set_attr "type" "fmov")
5085 (set_attr "mode" "<X87MODEF:MODE>")
5086 (set_attr "fp_int_src" "true")])
5089 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5090 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5091 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5093 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5094 && reload_completed"
5095 [(set (match_dup 2) (match_dup 1))
5096 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5099 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5100 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5101 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5103 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5104 && reload_completed"
5105 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5107 ;; Avoid partial SSE register dependency stalls
5110 [(set (match_operand:MODEF 0 "register_operand")
5111 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5112 "TARGET_SSE2 && TARGET_SSE_MATH
5113 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5114 && optimize_function_for_speed_p (cfun)
5115 && reload_completed && SSE_REG_P (operands[0])"
5117 (vec_merge:<ssevecmode>
5118 (vec_duplicate:<ssevecmode>
5119 (float:MODEF (match_dup 1)))
5123 operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5125 emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5129 [(set (match_operand:MODEF 0 "register_operand")
5130 (float:MODEF (match_operand:DI 1 "nonimmediate_operand")))]
5131 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5132 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5133 && optimize_function_for_speed_p (cfun)
5134 && reload_completed && SSE_REG_P (operands[0])"
5136 (vec_merge:<ssevecmode>
5137 (vec_duplicate:<ssevecmode>
5138 (float:MODEF (match_dup 1)))
5142 operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5144 emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5147 ;; Break partial reg stall for cvtsd2ss.
5150 [(set (match_operand:SF 0 "register_operand")
5152 (match_operand:DF 1 "nonimmediate_operand")))]
5153 "TARGET_SSE2 && TARGET_SSE_MATH
5154 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5155 && optimize_function_for_speed_p (cfun)
5156 && SSE_REG_P (operands[0])
5157 && (!SSE_REG_P (operands[1])
5158 || REGNO (operands[0]) != REGNO (operands[1]))"
5162 (float_truncate:V2SF
5167 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
5169 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
5171 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5174 ;; Break partial reg stall for cvtss2sd.
5177 [(set (match_operand:DF 0 "register_operand")
5179 (match_operand:SF 1 "nonimmediate_operand")))]
5180 "TARGET_SSE2 && TARGET_SSE_MATH
5181 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5182 && optimize_function_for_speed_p (cfun)
5183 && SSE_REG_P (operands[0])
5184 && (!SSE_REG_P (operands[1])
5185 || REGNO (operands[0]) != REGNO (operands[1]))"
5191 (parallel [(const_int 0) (const_int 1)])))
5195 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5197 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5199 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5202 ;; Avoid store forwarding (partial memory) stall penalty
5203 ;; by passing DImode value through XMM registers. */
5205 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5206 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5208 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5209 (clobber (match_scratch:V4SI 3 "=X,x"))
5210 (clobber (match_scratch:V4SI 4 "=X,x"))
5211 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5212 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5213 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5214 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5216 [(set_attr "type" "multi")
5217 (set_attr "mode" "<X87MODEF:MODE>")
5218 (set_attr "unit" "i387")
5219 (set_attr "fp_int_src" "true")])
5222 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5223 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5224 (clobber (match_scratch:V4SI 3))
5225 (clobber (match_scratch:V4SI 4))
5226 (clobber (match_operand:DI 2 "memory_operand"))]
5227 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5228 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5229 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5230 && reload_completed"
5231 [(set (match_dup 2) (match_dup 3))
5232 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5234 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5235 Assemble the 64-bit DImode value in an xmm register. */
5236 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5237 gen_rtx_SUBREG (SImode, operands[1], 0)));
5238 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5239 gen_rtx_SUBREG (SImode, operands[1], 4)));
5240 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5243 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5247 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5248 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5249 (clobber (match_scratch:V4SI 3))
5250 (clobber (match_scratch:V4SI 4))
5251 (clobber (match_operand:DI 2 "memory_operand"))]
5252 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5253 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5254 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5255 && reload_completed"
5256 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5258 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5259 [(set (match_operand:MODEF 0 "register_operand")
5260 (unsigned_float:MODEF
5261 (match_operand:SWI12 1 "nonimmediate_operand")))]
5263 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5265 operands[1] = convert_to_mode (SImode, operands[1], 1);
5266 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5270 ;; Avoid store forwarding (partial memory) stall penalty by extending
5271 ;; SImode value to DImode through XMM register instead of pushing two
5272 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES_TO_VEC
5273 ;; targets benefit from this optimization. Also note that fild
5274 ;; loads from memory only.
5276 (define_insn "*floatunssi<mode>2_1"
5277 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5278 (unsigned_float:X87MODEF
5279 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5280 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5281 (clobber (match_scratch:SI 3 "=X,x"))]
5283 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5286 [(set_attr "type" "multi")
5287 (set_attr "mode" "<MODE>")])
5290 [(set (match_operand:X87MODEF 0 "register_operand")
5291 (unsigned_float:X87MODEF
5292 (match_operand:SI 1 "register_operand")))
5293 (clobber (match_operand:DI 2 "memory_operand"))
5294 (clobber (match_scratch:SI 3))]
5296 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5298 && reload_completed"
5299 [(set (match_dup 2) (match_dup 1))
5301 (float:X87MODEF (match_dup 2)))]
5302 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5305 [(set (match_operand:X87MODEF 0 "register_operand")
5306 (unsigned_float:X87MODEF
5307 (match_operand:SI 1 "memory_operand")))
5308 (clobber (match_operand:DI 2 "memory_operand"))
5309 (clobber (match_scratch:SI 3))]
5311 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5313 && reload_completed"
5314 [(set (match_dup 2) (match_dup 3))
5316 (float:X87MODEF (match_dup 2)))]
5318 emit_move_insn (operands[3], operands[1]);
5319 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5322 (define_expand "floatunssi<mode>2"
5324 [(set (match_operand:X87MODEF 0 "register_operand")
5325 (unsigned_float:X87MODEF
5326 (match_operand:SI 1 "nonimmediate_operand")))
5327 (clobber (match_dup 2))
5328 (clobber (match_scratch:SI 3))])]
5330 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5332 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5334 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5336 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5340 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5343 (define_expand "floatunsdisf2"
5344 [(use (match_operand:SF 0 "register_operand"))
5345 (use (match_operand:DI 1 "nonimmediate_operand"))]
5346 "TARGET_64BIT && TARGET_SSE_MATH"
5347 "x86_emit_floatuns (operands); DONE;")
5349 (define_expand "floatunsdidf2"
5350 [(use (match_operand:DF 0 "register_operand"))
5351 (use (match_operand:DI 1 "nonimmediate_operand"))]
5352 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5353 && TARGET_SSE2 && TARGET_SSE_MATH"
5356 x86_emit_floatuns (operands);
5358 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5362 ;; Load effective address instructions
5364 (define_insn_and_split "*lea<mode>"
5365 [(set (match_operand:SWI48 0 "register_operand" "=r")
5366 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5369 if (SImode_address_operand (operands[1], VOIDmode))
5371 gcc_assert (TARGET_64BIT);
5372 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5375 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5377 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5380 enum machine_mode mode = <MODE>mode;
5383 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5384 change operands[] array behind our back. */
5385 pat = PATTERN (curr_insn);
5387 operands[0] = SET_DEST (pat);
5388 operands[1] = SET_SRC (pat);
5390 /* Emit all operations in SImode for zero-extended addresses. Recall
5391 that x86_64 inheretly zero-extends SImode operations to DImode. */
5392 if (SImode_address_operand (operands[1], VOIDmode))
5395 ix86_split_lea_for_addr (curr_insn, operands, mode);
5398 [(set_attr "type" "lea")
5401 (match_operand 1 "SImode_address_operand")
5403 (const_string "<MODE>")))])
5407 (define_expand "add<mode>3"
5408 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5409 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5410 (match_operand:SDWIM 2 "<general_operand>")))]
5412 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5414 (define_insn_and_split "*add<dwi>3_doubleword"
5415 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5417 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5418 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5419 (clobber (reg:CC FLAGS_REG))]
5420 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5423 [(parallel [(set (reg:CC FLAGS_REG)
5424 (unspec:CC [(match_dup 1) (match_dup 2)]
5427 (plus:DWIH (match_dup 1) (match_dup 2)))])
5428 (parallel [(set (match_dup 3)
5432 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5434 (clobber (reg:CC FLAGS_REG))])]
5435 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5437 (define_insn "*add<mode>3_cc"
5438 [(set (reg:CC FLAGS_REG)
5440 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5441 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5443 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5444 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5445 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5446 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5447 [(set_attr "type" "alu")
5448 (set_attr "mode" "<MODE>")])
5450 (define_insn "addqi3_cc"
5451 [(set (reg:CC FLAGS_REG)
5453 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5454 (match_operand:QI 2 "general_operand" "qn,qm")]
5456 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5457 (plus:QI (match_dup 1) (match_dup 2)))]
5458 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5459 "add{b}\t{%2, %0|%0, %2}"
5460 [(set_attr "type" "alu")
5461 (set_attr "mode" "QI")])
5463 (define_insn "*add<mode>_1"
5464 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5466 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5467 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5468 (clobber (reg:CC FLAGS_REG))]
5469 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5471 switch (get_attr_type (insn))
5477 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5478 if (operands[2] == const1_rtx)
5479 return "inc{<imodesuffix>}\t%0";
5482 gcc_assert (operands[2] == constm1_rtx);
5483 return "dec{<imodesuffix>}\t%0";
5487 /* For most processors, ADD is faster than LEA. This alternative
5488 was added to use ADD as much as possible. */
5489 if (which_alternative == 2)
5492 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5495 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5496 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5497 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5499 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5503 (cond [(eq_attr "alternative" "3")
5504 (const_string "lea")
5505 (match_operand:SWI48 2 "incdec_operand")
5506 (const_string "incdec")
5508 (const_string "alu")))
5509 (set (attr "length_immediate")
5511 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5513 (const_string "*")))
5514 (set_attr "mode" "<MODE>")])
5516 ;; It may seem that nonimmediate operand is proper one for operand 1.
5517 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5518 ;; we take care in ix86_binary_operator_ok to not allow two memory
5519 ;; operands so proper swapping will be done in reload. This allow
5520 ;; patterns constructed from addsi_1 to match.
5522 (define_insn "addsi_1_zext"
5523 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5525 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5526 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5527 (clobber (reg:CC FLAGS_REG))]
5528 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5530 switch (get_attr_type (insn))
5536 if (operands[2] == const1_rtx)
5537 return "inc{l}\t%k0";
5540 gcc_assert (operands[2] == constm1_rtx);
5541 return "dec{l}\t%k0";
5545 /* For most processors, ADD is faster than LEA. This alternative
5546 was added to use ADD as much as possible. */
5547 if (which_alternative == 1)
5550 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5553 if (x86_maybe_negate_const_int (&operands[2], SImode))
5554 return "sub{l}\t{%2, %k0|%k0, %2}";
5556 return "add{l}\t{%2, %k0|%k0, %2}";
5560 (cond [(eq_attr "alternative" "2")
5561 (const_string "lea")
5562 (match_operand:SI 2 "incdec_operand")
5563 (const_string "incdec")
5565 (const_string "alu")))
5566 (set (attr "length_immediate")
5568 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5570 (const_string "*")))
5571 (set_attr "mode" "SI")])
5573 (define_insn "*addhi_1"
5574 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5575 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5576 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5577 (clobber (reg:CC FLAGS_REG))]
5578 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5580 switch (get_attr_type (insn))
5586 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5587 if (operands[2] == const1_rtx)
5588 return "inc{w}\t%0";
5591 gcc_assert (operands[2] == constm1_rtx);
5592 return "dec{w}\t%0";
5596 /* For most processors, ADD is faster than LEA. This alternative
5597 was added to use ADD as much as possible. */
5598 if (which_alternative == 2)
5601 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5604 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5605 if (x86_maybe_negate_const_int (&operands[2], HImode))
5606 return "sub{w}\t{%2, %0|%0, %2}";
5608 return "add{w}\t{%2, %0|%0, %2}";
5612 (cond [(eq_attr "alternative" "3")
5613 (const_string "lea")
5614 (match_operand:HI 2 "incdec_operand")
5615 (const_string "incdec")
5617 (const_string "alu")))
5618 (set (attr "length_immediate")
5620 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5622 (const_string "*")))
5623 (set_attr "mode" "HI,HI,HI,SI")])
5625 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5626 (define_insn "*addqi_1"
5627 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5628 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5629 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5630 (clobber (reg:CC FLAGS_REG))]
5631 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5633 bool widen = (which_alternative == 3 || which_alternative == 4);
5635 switch (get_attr_type (insn))
5641 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5642 if (operands[2] == const1_rtx)
5643 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5646 gcc_assert (operands[2] == constm1_rtx);
5647 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5651 /* For most processors, ADD is faster than LEA. These alternatives
5652 were added to use ADD as much as possible. */
5653 if (which_alternative == 2 || which_alternative == 4)
5656 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5659 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5660 if (x86_maybe_negate_const_int (&operands[2], QImode))
5663 return "sub{l}\t{%2, %k0|%k0, %2}";
5665 return "sub{b}\t{%2, %0|%0, %2}";
5668 return "add{l}\t{%k2, %k0|%k0, %k2}";
5670 return "add{b}\t{%2, %0|%0, %2}";
5674 (cond [(eq_attr "alternative" "5")
5675 (const_string "lea")
5676 (match_operand:QI 2 "incdec_operand")
5677 (const_string "incdec")
5679 (const_string "alu")))
5680 (set (attr "length_immediate")
5682 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5684 (const_string "*")))
5685 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5687 (define_insn "*addqi_1_slp"
5688 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5689 (plus:QI (match_dup 0)
5690 (match_operand:QI 1 "general_operand" "qn,qm")))
5691 (clobber (reg:CC FLAGS_REG))]
5692 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5693 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5695 switch (get_attr_type (insn))
5698 if (operands[1] == const1_rtx)
5699 return "inc{b}\t%0";
5702 gcc_assert (operands[1] == constm1_rtx);
5703 return "dec{b}\t%0";
5707 if (x86_maybe_negate_const_int (&operands[1], QImode))
5708 return "sub{b}\t{%1, %0|%0, %1}";
5710 return "add{b}\t{%1, %0|%0, %1}";
5714 (if_then_else (match_operand:QI 1 "incdec_operand")
5715 (const_string "incdec")
5716 (const_string "alu1")))
5717 (set (attr "memory")
5718 (if_then_else (match_operand 1 "memory_operand")
5719 (const_string "load")
5720 (const_string "none")))
5721 (set_attr "mode" "QI")])
5723 ;; Split non destructive adds if we cannot use lea.
5725 [(set (match_operand:SWI48 0 "register_operand")
5726 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5727 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5728 (clobber (reg:CC FLAGS_REG))]
5729 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5730 [(set (match_dup 0) (match_dup 1))
5731 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5732 (clobber (reg:CC FLAGS_REG))])])
5734 ;; Convert add to the lea pattern to avoid flags dependency.
5736 [(set (match_operand:SWI 0 "register_operand")
5737 (plus:SWI (match_operand:SWI 1 "register_operand")
5738 (match_operand:SWI 2 "<nonmemory_operand>")))
5739 (clobber (reg:CC FLAGS_REG))]
5740 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5743 enum machine_mode mode = <MODE>mode;
5746 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5749 operands[0] = gen_lowpart (mode, operands[0]);
5750 operands[1] = gen_lowpart (mode, operands[1]);
5751 operands[2] = gen_lowpart (mode, operands[2]);
5754 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5756 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5760 ;; Split non destructive adds if we cannot use lea.
5762 [(set (match_operand:DI 0 "register_operand")
5764 (plus:SI (match_operand:SI 1 "register_operand")
5765 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5766 (clobber (reg:CC FLAGS_REG))]
5768 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5769 [(set (match_dup 3) (match_dup 1))
5770 (parallel [(set (match_dup 0)
5771 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5772 (clobber (reg:CC FLAGS_REG))])]
5773 "operands[3] = gen_lowpart (SImode, operands[0]);")
5775 ;; Convert add to the lea pattern to avoid flags dependency.
5777 [(set (match_operand:DI 0 "register_operand")
5779 (plus:SI (match_operand:SI 1 "register_operand")
5780 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5781 (clobber (reg:CC FLAGS_REG))]
5782 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5784 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5786 (define_insn "*add<mode>_2"
5787 [(set (reg FLAGS_REG)
5790 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5791 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5793 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5794 (plus:SWI (match_dup 1) (match_dup 2)))]
5795 "ix86_match_ccmode (insn, CCGOCmode)
5796 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5798 switch (get_attr_type (insn))
5801 if (operands[2] == const1_rtx)
5802 return "inc{<imodesuffix>}\t%0";
5805 gcc_assert (operands[2] == constm1_rtx);
5806 return "dec{<imodesuffix>}\t%0";
5810 if (which_alternative == 2)
5813 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5816 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5817 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5818 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5820 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5824 (if_then_else (match_operand:SWI 2 "incdec_operand")
5825 (const_string "incdec")
5826 (const_string "alu")))
5827 (set (attr "length_immediate")
5829 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5831 (const_string "*")))
5832 (set_attr "mode" "<MODE>")])
5834 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5835 (define_insn "*addsi_2_zext"
5836 [(set (reg FLAGS_REG)
5838 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5839 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5841 (set (match_operand:DI 0 "register_operand" "=r,r")
5842 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5843 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5844 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5846 switch (get_attr_type (insn))
5849 if (operands[2] == const1_rtx)
5850 return "inc{l}\t%k0";
5853 gcc_assert (operands[2] == constm1_rtx);
5854 return "dec{l}\t%k0";
5858 if (which_alternative == 1)
5861 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5864 if (x86_maybe_negate_const_int (&operands[2], SImode))
5865 return "sub{l}\t{%2, %k0|%k0, %2}";
5867 return "add{l}\t{%2, %k0|%k0, %2}";
5871 (if_then_else (match_operand:SI 2 "incdec_operand")
5872 (const_string "incdec")
5873 (const_string "alu")))
5874 (set (attr "length_immediate")
5876 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5878 (const_string "*")))
5879 (set_attr "mode" "SI")])
5881 (define_insn "*add<mode>_3"
5882 [(set (reg FLAGS_REG)
5884 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5885 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5886 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5887 "ix86_match_ccmode (insn, CCZmode)
5888 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5890 switch (get_attr_type (insn))
5893 if (operands[2] == const1_rtx)
5894 return "inc{<imodesuffix>}\t%0";
5897 gcc_assert (operands[2] == constm1_rtx);
5898 return "dec{<imodesuffix>}\t%0";
5902 if (which_alternative == 1)
5905 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5908 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5909 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5910 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5912 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5916 (if_then_else (match_operand:SWI 2 "incdec_operand")
5917 (const_string "incdec")
5918 (const_string "alu")))
5919 (set (attr "length_immediate")
5921 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5923 (const_string "*")))
5924 (set_attr "mode" "<MODE>")])
5926 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5927 (define_insn "*addsi_3_zext"
5928 [(set (reg FLAGS_REG)
5930 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5931 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5932 (set (match_operand:DI 0 "register_operand" "=r,r")
5933 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5934 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5935 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5937 switch (get_attr_type (insn))
5940 if (operands[2] == const1_rtx)
5941 return "inc{l}\t%k0";
5944 gcc_assert (operands[2] == constm1_rtx);
5945 return "dec{l}\t%k0";
5949 if (which_alternative == 1)
5952 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5955 if (x86_maybe_negate_const_int (&operands[2], SImode))
5956 return "sub{l}\t{%2, %k0|%k0, %2}";
5958 return "add{l}\t{%2, %k0|%k0, %2}";
5962 (if_then_else (match_operand:SI 2 "incdec_operand")
5963 (const_string "incdec")
5964 (const_string "alu")))
5965 (set (attr "length_immediate")
5967 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5969 (const_string "*")))
5970 (set_attr "mode" "SI")])
5972 ; For comparisons against 1, -1 and 128, we may generate better code
5973 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5974 ; is matched then. We can't accept general immediate, because for
5975 ; case of overflows, the result is messed up.
5976 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5977 ; only for comparisons not depending on it.
5979 (define_insn "*adddi_4"
5980 [(set (reg FLAGS_REG)
5982 (match_operand:DI 1 "nonimmediate_operand" "0")
5983 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5984 (clobber (match_scratch:DI 0 "=rm"))]
5986 && ix86_match_ccmode (insn, CCGCmode)"
5988 switch (get_attr_type (insn))
5991 if (operands[2] == constm1_rtx)
5992 return "inc{q}\t%0";
5995 gcc_assert (operands[2] == const1_rtx);
5996 return "dec{q}\t%0";
6000 if (x86_maybe_negate_const_int (&operands[2], DImode))
6001 return "add{q}\t{%2, %0|%0, %2}";
6003 return "sub{q}\t{%2, %0|%0, %2}";
6007 (if_then_else (match_operand:DI 2 "incdec_operand")
6008 (const_string "incdec")
6009 (const_string "alu")))
6010 (set (attr "length_immediate")
6012 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6014 (const_string "*")))
6015 (set_attr "mode" "DI")])
6017 ; For comparisons against 1, -1 and 128, we may generate better code
6018 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6019 ; is matched then. We can't accept general immediate, because for
6020 ; case of overflows, the result is messed up.
6021 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6022 ; only for comparisons not depending on it.
6024 (define_insn "*add<mode>_4"
6025 [(set (reg FLAGS_REG)
6027 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6028 (match_operand:SWI124 2 "const_int_operand" "n")))
6029 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6030 "ix86_match_ccmode (insn, CCGCmode)"
6032 switch (get_attr_type (insn))
6035 if (operands[2] == constm1_rtx)
6036 return "inc{<imodesuffix>}\t%0";
6039 gcc_assert (operands[2] == const1_rtx);
6040 return "dec{<imodesuffix>}\t%0";
6044 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6045 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6047 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6051 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6052 (const_string "incdec")
6053 (const_string "alu")))
6054 (set (attr "length_immediate")
6056 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6058 (const_string "*")))
6059 (set_attr "mode" "<MODE>")])
6061 (define_insn "*add<mode>_5"
6062 [(set (reg FLAGS_REG)
6065 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6066 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6068 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6069 "ix86_match_ccmode (insn, CCGOCmode)
6070 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6072 switch (get_attr_type (insn))
6075 if (operands[2] == const1_rtx)
6076 return "inc{<imodesuffix>}\t%0";
6079 gcc_assert (operands[2] == constm1_rtx);
6080 return "dec{<imodesuffix>}\t%0";
6084 if (which_alternative == 1)
6087 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6090 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6091 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6092 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6094 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6098 (if_then_else (match_operand:SWI 2 "incdec_operand")
6099 (const_string "incdec")
6100 (const_string "alu")))
6101 (set (attr "length_immediate")
6103 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6105 (const_string "*")))
6106 (set_attr "mode" "<MODE>")])
6108 (define_insn "addqi_ext_1"
6109 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6114 (match_operand 1 "ext_register_operand" "0,0")
6117 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
6118 (clobber (reg:CC FLAGS_REG))]
6121 switch (get_attr_type (insn))
6124 if (operands[2] == const1_rtx)
6125 return "inc{b}\t%h0";
6128 gcc_assert (operands[2] == constm1_rtx);
6129 return "dec{b}\t%h0";
6133 return "add{b}\t{%2, %h0|%h0, %2}";
6136 [(set_attr "isa" "*,nox64")
6138 (if_then_else (match_operand:QI 2 "incdec_operand")
6139 (const_string "incdec")
6140 (const_string "alu")))
6141 (set_attr "modrm" "1")
6142 (set_attr "mode" "QI")])
6144 (define_insn "*addqi_ext_2"
6145 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6150 (match_operand 1 "ext_register_operand" "%0")
6154 (match_operand 2 "ext_register_operand" "Q")
6157 (clobber (reg:CC FLAGS_REG))]
6159 "add{b}\t{%h2, %h0|%h0, %h2}"
6160 [(set_attr "type" "alu")
6161 (set_attr "mode" "QI")])
6163 ;; Add with jump on overflow.
6164 (define_expand "addv<mode>4"
6165 [(parallel [(set (reg:CCO FLAGS_REG)
6168 (match_operand:SWI 1 "nonimmediate_operand"))
6170 (match_operand:SWI 2 "<general_operand>")))
6172 (plus:SWI (match_dup 1) (match_dup 2)))))
6173 (set (match_operand:SWI 0 "register_operand")
6174 (plus:SWI (match_dup 1) (match_dup 2)))])
6175 (set (pc) (if_then_else
6176 (eq (reg:CCO FLAGS_REG) (const_int 0))
6177 (label_ref (match_operand 3))
6180 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6182 (define_insn "*addv<mode>4"
6183 [(set (reg:CCO FLAGS_REG)
6186 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6188 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>")))
6190 (plus:SWI (match_dup 1) (match_dup 2)))))
6191 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6192 (plus:SWI (match_dup 1) (match_dup 2)))]
6193 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6194 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6195 [(set_attr "type" "alu")
6196 (set_attr "mode" "<MODE>")])
6198 ;; The lea patterns for modes less than 32 bits need to be matched by
6199 ;; several insns converted to real lea by splitters.
6201 (define_insn_and_split "*lea_general_1"
6202 [(set (match_operand 0 "register_operand" "=r")
6203 (plus (plus (match_operand 1 "index_register_operand" "l")
6204 (match_operand 2 "register_operand" "r"))
6205 (match_operand 3 "immediate_operand" "i")))]
6206 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6207 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6208 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6209 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6210 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6211 || GET_MODE (operands[3]) == VOIDmode)"
6213 "&& reload_completed"
6216 enum machine_mode mode = SImode;
6219 operands[0] = gen_lowpart (mode, operands[0]);
6220 operands[1] = gen_lowpart (mode, operands[1]);
6221 operands[2] = gen_lowpart (mode, operands[2]);
6222 operands[3] = gen_lowpart (mode, operands[3]);
6224 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6227 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6230 [(set_attr "type" "lea")
6231 (set_attr "mode" "SI")])
6233 (define_insn_and_split "*lea_general_2"
6234 [(set (match_operand 0 "register_operand" "=r")
6235 (plus (mult (match_operand 1 "index_register_operand" "l")
6236 (match_operand 2 "const248_operand" "n"))
6237 (match_operand 3 "nonmemory_operand" "ri")))]
6238 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6239 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6240 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6241 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6242 || GET_MODE (operands[3]) == VOIDmode)"
6244 "&& reload_completed"
6247 enum machine_mode mode = SImode;
6250 operands[0] = gen_lowpart (mode, operands[0]);
6251 operands[1] = gen_lowpart (mode, operands[1]);
6252 operands[3] = gen_lowpart (mode, operands[3]);
6254 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6257 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6260 [(set_attr "type" "lea")
6261 (set_attr "mode" "SI")])
6263 (define_insn_and_split "*lea_general_3"
6264 [(set (match_operand 0 "register_operand" "=r")
6265 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6266 (match_operand 2 "const248_operand" "n"))
6267 (match_operand 3 "register_operand" "r"))
6268 (match_operand 4 "immediate_operand" "i")))]
6269 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6270 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6271 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6272 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6274 "&& reload_completed"
6277 enum machine_mode mode = SImode;
6280 operands[0] = gen_lowpart (mode, operands[0]);
6281 operands[1] = gen_lowpart (mode, operands[1]);
6282 operands[3] = gen_lowpart (mode, operands[3]);
6283 operands[4] = gen_lowpart (mode, operands[4]);
6285 pat = gen_rtx_PLUS (mode,
6287 gen_rtx_MULT (mode, operands[1],
6292 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6295 [(set_attr "type" "lea")
6296 (set_attr "mode" "SI")])
6298 (define_insn_and_split "*lea_general_4"
6299 [(set (match_operand 0 "register_operand" "=r")
6301 (match_operand 1 "index_register_operand" "l")
6302 (match_operand 2 "const_int_operand" "n"))
6303 (match_operand 3 "const_int_operand" "n")))]
6304 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6305 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6306 || GET_MODE (operands[0]) == SImode
6307 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6308 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6309 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6310 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6311 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6313 "&& reload_completed"
6316 enum machine_mode mode = GET_MODE (operands[0]);
6319 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6322 operands[0] = gen_lowpart (mode, operands[0]);
6323 operands[1] = gen_lowpart (mode, operands[1]);
6326 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6328 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6329 INTVAL (operands[3]));
6331 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6334 [(set_attr "type" "lea")
6336 (if_then_else (match_operand:DI 0)
6338 (const_string "SI")))])
6340 ;; Subtract instructions
6342 (define_expand "sub<mode>3"
6343 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6344 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6345 (match_operand:SDWIM 2 "<general_operand>")))]
6347 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6349 (define_insn_and_split "*sub<dwi>3_doubleword"
6350 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6352 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6353 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6354 (clobber (reg:CC FLAGS_REG))]
6355 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6358 [(parallel [(set (reg:CC FLAGS_REG)
6359 (compare:CC (match_dup 1) (match_dup 2)))
6361 (minus:DWIH (match_dup 1) (match_dup 2)))])
6362 (parallel [(set (match_dup 3)
6366 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6368 (clobber (reg:CC FLAGS_REG))])]
6369 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6371 (define_insn "*sub<mode>_1"
6372 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6374 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6375 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6376 (clobber (reg:CC FLAGS_REG))]
6377 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6378 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6379 [(set_attr "type" "alu")
6380 (set_attr "mode" "<MODE>")])
6382 (define_insn "*subsi_1_zext"
6383 [(set (match_operand:DI 0 "register_operand" "=r")
6385 (minus:SI (match_operand:SI 1 "register_operand" "0")
6386 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6387 (clobber (reg:CC FLAGS_REG))]
6388 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6389 "sub{l}\t{%2, %k0|%k0, %2}"
6390 [(set_attr "type" "alu")
6391 (set_attr "mode" "SI")])
6393 (define_insn "*subqi_1_slp"
6394 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6395 (minus:QI (match_dup 0)
6396 (match_operand:QI 1 "general_operand" "qn,qm")))
6397 (clobber (reg:CC FLAGS_REG))]
6398 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6399 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6400 "sub{b}\t{%1, %0|%0, %1}"
6401 [(set_attr "type" "alu1")
6402 (set_attr "mode" "QI")])
6404 (define_insn "*sub<mode>_2"
6405 [(set (reg FLAGS_REG)
6408 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6409 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6411 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6412 (minus:SWI (match_dup 1) (match_dup 2)))]
6413 "ix86_match_ccmode (insn, CCGOCmode)
6414 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6415 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6416 [(set_attr "type" "alu")
6417 (set_attr "mode" "<MODE>")])
6419 (define_insn "*subsi_2_zext"
6420 [(set (reg FLAGS_REG)
6422 (minus:SI (match_operand:SI 1 "register_operand" "0")
6423 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6425 (set (match_operand:DI 0 "register_operand" "=r")
6427 (minus:SI (match_dup 1)
6429 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6430 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6431 "sub{l}\t{%2, %k0|%k0, %2}"
6432 [(set_attr "type" "alu")
6433 (set_attr "mode" "SI")])
6435 ;; Subtract with jump on overflow.
6436 (define_expand "subv<mode>4"
6437 [(parallel [(set (reg:CCO FLAGS_REG)
6438 (eq:CCO (minus:<DWI>
6440 (match_operand:SWI 1 "nonimmediate_operand"))
6442 (match_operand:SWI 2 "<general_operand>")))
6444 (minus:SWI (match_dup 1) (match_dup 2)))))
6445 (set (match_operand:SWI 0 "register_operand")
6446 (minus:SWI (match_dup 1) (match_dup 2)))])
6447 (set (pc) (if_then_else
6448 (eq (reg:CCO FLAGS_REG) (const_int 0))
6449 (label_ref (match_operand 3))
6452 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6454 (define_insn "*subv<mode>4"
6455 [(set (reg:CCO FLAGS_REG)
6456 (eq:CCO (minus:<DWI>
6458 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6460 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6462 (minus:SWI (match_dup 1) (match_dup 2)))))
6463 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6464 (minus:SWI (match_dup 1) (match_dup 2)))]
6465 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6466 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6467 [(set_attr "type" "alu")
6468 (set_attr "mode" "<MODE>")])
6470 (define_insn "*sub<mode>_3"
6471 [(set (reg FLAGS_REG)
6472 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6473 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6474 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6475 (minus:SWI (match_dup 1) (match_dup 2)))]
6476 "ix86_match_ccmode (insn, CCmode)
6477 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6478 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6479 [(set_attr "type" "alu")
6480 (set_attr "mode" "<MODE>")])
6482 (define_insn "*subsi_3_zext"
6483 [(set (reg FLAGS_REG)
6484 (compare (match_operand:SI 1 "register_operand" "0")
6485 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6486 (set (match_operand:DI 0 "register_operand" "=r")
6488 (minus:SI (match_dup 1)
6490 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6491 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6492 "sub{l}\t{%2, %1|%1, %2}"
6493 [(set_attr "type" "alu")
6494 (set_attr "mode" "SI")])
6496 ;; Add with carry and subtract with borrow
6498 (define_expand "<plusminus_insn><mode>3_carry"
6500 [(set (match_operand:SWI 0 "nonimmediate_operand")
6502 (match_operand:SWI 1 "nonimmediate_operand")
6503 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6504 [(match_operand 3 "flags_reg_operand")
6506 (match_operand:SWI 2 "<general_operand>"))))
6507 (clobber (reg:CC FLAGS_REG))])]
6508 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6510 (define_insn "*<plusminus_insn><mode>3_carry"
6511 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6513 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6515 (match_operator 3 "ix86_carry_flag_operator"
6516 [(reg FLAGS_REG) (const_int 0)])
6517 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6518 (clobber (reg:CC FLAGS_REG))]
6519 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6520 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6521 [(set_attr "type" "alu")
6522 (set_attr "use_carry" "1")
6523 (set_attr "pent_pair" "pu")
6524 (set_attr "mode" "<MODE>")])
6526 (define_insn "*addsi3_carry_zext"
6527 [(set (match_operand:DI 0 "register_operand" "=r")
6529 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6530 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6531 [(reg FLAGS_REG) (const_int 0)])
6532 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6533 (clobber (reg:CC FLAGS_REG))]
6534 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6535 "adc{l}\t{%2, %k0|%k0, %2}"
6536 [(set_attr "type" "alu")
6537 (set_attr "use_carry" "1")
6538 (set_attr "pent_pair" "pu")
6539 (set_attr "mode" "SI")])
6541 (define_insn "*subsi3_carry_zext"
6542 [(set (match_operand:DI 0 "register_operand" "=r")
6544 (minus:SI (match_operand:SI 1 "register_operand" "0")
6545 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6546 [(reg FLAGS_REG) (const_int 0)])
6547 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6548 (clobber (reg:CC FLAGS_REG))]
6549 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6550 "sbb{l}\t{%2, %k0|%k0, %2}"
6551 [(set_attr "type" "alu")
6552 (set_attr "pent_pair" "pu")
6553 (set_attr "mode" "SI")])
6557 (define_insn "adcx<mode>3"
6558 [(set (reg:CCC FLAGS_REG)
6561 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6563 (match_operator 4 "ix86_carry_flag_operator"
6564 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6565 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6567 (set (match_operand:SWI48 0 "register_operand" "=r")
6568 (plus:SWI48 (match_dup 1)
6569 (plus:SWI48 (match_op_dup 4
6570 [(match_dup 3) (const_int 0)])
6572 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6573 "adcx\t{%2, %0|%0, %2}"
6574 [(set_attr "type" "alu")
6575 (set_attr "use_carry" "1")
6576 (set_attr "mode" "<MODE>")])
6578 ;; Overflow setting add instructions
6580 (define_insn "*add<mode>3_cconly_overflow"
6581 [(set (reg:CCC FLAGS_REG)
6584 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6585 (match_operand:SWI 2 "<general_operand>" "<g>"))
6587 (clobber (match_scratch:SWI 0 "=<r>"))]
6588 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6589 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6590 [(set_attr "type" "alu")
6591 (set_attr "mode" "<MODE>")])
6593 (define_insn "*add<mode>3_cc_overflow"
6594 [(set (reg:CCC FLAGS_REG)
6597 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6598 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6600 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6601 (plus:SWI (match_dup 1) (match_dup 2)))]
6602 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6603 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6604 [(set_attr "type" "alu")
6605 (set_attr "mode" "<MODE>")])
6607 (define_insn "*addsi3_zext_cc_overflow"
6608 [(set (reg:CCC FLAGS_REG)
6611 (match_operand:SI 1 "nonimmediate_operand" "%0")
6612 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6614 (set (match_operand:DI 0 "register_operand" "=r")
6615 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6616 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6617 "add{l}\t{%2, %k0|%k0, %2}"
6618 [(set_attr "type" "alu")
6619 (set_attr "mode" "SI")])
6621 ;; The patterns that match these are at the end of this file.
6623 (define_expand "<plusminus_insn>xf3"
6624 [(set (match_operand:XF 0 "register_operand")
6626 (match_operand:XF 1 "register_operand")
6627 (match_operand:XF 2 "register_operand")))]
6630 (define_expand "<plusminus_insn><mode>3"
6631 [(set (match_operand:MODEF 0 "register_operand")
6633 (match_operand:MODEF 1 "register_operand")
6634 (match_operand:MODEF 2 "nonimmediate_operand")))]
6635 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6636 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6638 ;; Multiply instructions
6640 (define_expand "mul<mode>3"
6641 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6643 (match_operand:SWIM248 1 "register_operand")
6644 (match_operand:SWIM248 2 "<general_operand>")))
6645 (clobber (reg:CC FLAGS_REG))])])
6647 (define_expand "mulqi3"
6648 [(parallel [(set (match_operand:QI 0 "register_operand")
6650 (match_operand:QI 1 "register_operand")
6651 (match_operand:QI 2 "nonimmediate_operand")))
6652 (clobber (reg:CC FLAGS_REG))])]
6653 "TARGET_QIMODE_MATH")
6656 ;; IMUL reg32/64, reg32/64, imm8 Direct
6657 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6658 ;; IMUL reg32/64, reg32/64, imm32 Direct
6659 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6660 ;; IMUL reg32/64, reg32/64 Direct
6661 ;; IMUL reg32/64, mem32/64 Direct
6663 ;; On BDVER1, all above IMULs use DirectPath
6665 (define_insn "*mul<mode>3_1"
6666 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6668 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6669 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6670 (clobber (reg:CC FLAGS_REG))]
6671 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6673 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6674 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6675 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6676 [(set_attr "type" "imul")
6677 (set_attr "prefix_0f" "0,0,1")
6678 (set (attr "athlon_decode")
6679 (cond [(eq_attr "cpu" "athlon")
6680 (const_string "vector")
6681 (eq_attr "alternative" "1")
6682 (const_string "vector")
6683 (and (eq_attr "alternative" "2")
6684 (match_operand 1 "memory_operand"))
6685 (const_string "vector")]
6686 (const_string "direct")))
6687 (set (attr "amdfam10_decode")
6688 (cond [(and (eq_attr "alternative" "0,1")
6689 (match_operand 1 "memory_operand"))
6690 (const_string "vector")]
6691 (const_string "direct")))
6692 (set_attr "bdver1_decode" "direct")
6693 (set_attr "mode" "<MODE>")])
6695 (define_insn "*mulsi3_1_zext"
6696 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6698 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6699 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6700 (clobber (reg:CC FLAGS_REG))]
6702 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6704 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6705 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6706 imul{l}\t{%2, %k0|%k0, %2}"
6707 [(set_attr "type" "imul")
6708 (set_attr "prefix_0f" "0,0,1")
6709 (set (attr "athlon_decode")
6710 (cond [(eq_attr "cpu" "athlon")
6711 (const_string "vector")
6712 (eq_attr "alternative" "1")
6713 (const_string "vector")
6714 (and (eq_attr "alternative" "2")
6715 (match_operand 1 "memory_operand"))
6716 (const_string "vector")]
6717 (const_string "direct")))
6718 (set (attr "amdfam10_decode")
6719 (cond [(and (eq_attr "alternative" "0,1")
6720 (match_operand 1 "memory_operand"))
6721 (const_string "vector")]
6722 (const_string "direct")))
6723 (set_attr "bdver1_decode" "direct")
6724 (set_attr "mode" "SI")])
6727 ;; IMUL reg16, reg16, imm8 VectorPath
6728 ;; IMUL reg16, mem16, imm8 VectorPath
6729 ;; IMUL reg16, reg16, imm16 VectorPath
6730 ;; IMUL reg16, mem16, imm16 VectorPath
6731 ;; IMUL reg16, reg16 Direct
6732 ;; IMUL reg16, mem16 Direct
6734 ;; On BDVER1, all HI MULs use DoublePath
6736 (define_insn "*mulhi3_1"
6737 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6738 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6739 (match_operand:HI 2 "general_operand" "K,n,mr")))
6740 (clobber (reg:CC FLAGS_REG))]
6742 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6744 imul{w}\t{%2, %1, %0|%0, %1, %2}
6745 imul{w}\t{%2, %1, %0|%0, %1, %2}
6746 imul{w}\t{%2, %0|%0, %2}"
6747 [(set_attr "type" "imul")
6748 (set_attr "prefix_0f" "0,0,1")
6749 (set (attr "athlon_decode")
6750 (cond [(eq_attr "cpu" "athlon")
6751 (const_string "vector")
6752 (eq_attr "alternative" "1,2")
6753 (const_string "vector")]
6754 (const_string "direct")))
6755 (set (attr "amdfam10_decode")
6756 (cond [(eq_attr "alternative" "0,1")
6757 (const_string "vector")]
6758 (const_string "direct")))
6759 (set_attr "bdver1_decode" "double")
6760 (set_attr "mode" "HI")])
6762 ;;On AMDFAM10 and BDVER1
6766 (define_insn "*mulqi3_1"
6767 [(set (match_operand:QI 0 "register_operand" "=a")
6768 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6769 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6770 (clobber (reg:CC FLAGS_REG))]
6772 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6774 [(set_attr "type" "imul")
6775 (set_attr "length_immediate" "0")
6776 (set (attr "athlon_decode")
6777 (if_then_else (eq_attr "cpu" "athlon")
6778 (const_string "vector")
6779 (const_string "direct")))
6780 (set_attr "amdfam10_decode" "direct")
6781 (set_attr "bdver1_decode" "direct")
6782 (set_attr "mode" "QI")])
6784 ;; Multiply with jump on overflow.
6785 (define_expand "mulv<mode>4"
6786 [(parallel [(set (reg:CCO FLAGS_REG)
6789 (match_operand:SWI48 1 "register_operand"))
6791 (match_operand:SWI48 2 "<general_operand>")))
6793 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6794 (set (match_operand:SWI48 0 "register_operand")
6795 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6796 (set (pc) (if_then_else
6797 (eq (reg:CCO FLAGS_REG) (const_int 0))
6798 (label_ref (match_operand 3))
6801 (define_insn "*mulv<mode>4"
6802 [(set (reg:CCO FLAGS_REG)
6805 (match_operand:SWI 1 "nonimmediate_operand" "%rm,rm,0"))
6807 (match_operand:SWI 2 "<general_operand>" "K,<i>,mr")))
6809 (mult:SWI (match_dup 1) (match_dup 2)))))
6810 (set (match_operand:SWI 0 "register_operand" "=r,r,r")
6811 (mult:SWI (match_dup 1) (match_dup 2)))]
6812 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6814 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6815 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6816 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6817 [(set_attr "type" "imul")
6818 (set_attr "prefix_0f" "0,0,1")
6819 (set (attr "athlon_decode")
6820 (cond [(eq_attr "cpu" "athlon")
6821 (const_string "vector")
6822 (eq_attr "alternative" "1")
6823 (const_string "vector")
6824 (and (eq_attr "alternative" "2")
6825 (match_operand 1 "memory_operand"))
6826 (const_string "vector")]
6827 (const_string "direct")))
6828 (set (attr "amdfam10_decode")
6829 (cond [(and (eq_attr "alternative" "0,1")
6830 (match_operand 1 "memory_operand"))
6831 (const_string "vector")]
6832 (const_string "direct")))
6833 (set_attr "bdver1_decode" "direct")
6834 (set_attr "mode" "<MODE>")])
6836 (define_expand "<u>mul<mode><dwi>3"
6837 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6840 (match_operand:DWIH 1 "nonimmediate_operand"))
6842 (match_operand:DWIH 2 "register_operand"))))
6843 (clobber (reg:CC FLAGS_REG))])])
6845 (define_expand "<u>mulqihi3"
6846 [(parallel [(set (match_operand:HI 0 "register_operand")
6849 (match_operand:QI 1 "nonimmediate_operand"))
6851 (match_operand:QI 2 "register_operand"))))
6852 (clobber (reg:CC FLAGS_REG))])]
6853 "TARGET_QIMODE_MATH")
6855 (define_insn "*bmi2_umulditi3_1"
6856 [(set (match_operand:DI 0 "register_operand" "=r")
6858 (match_operand:DI 2 "nonimmediate_operand" "%d")
6859 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6860 (set (match_operand:DI 1 "register_operand" "=r")
6863 (mult:TI (zero_extend:TI (match_dup 2))
6864 (zero_extend:TI (match_dup 3)))
6866 "TARGET_64BIT && TARGET_BMI2
6867 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6868 "mulx\t{%3, %0, %1|%1, %0, %3}"
6869 [(set_attr "type" "imulx")
6870 (set_attr "prefix" "vex")
6871 (set_attr "mode" "DI")])
6873 (define_insn "*bmi2_umulsidi3_1"
6874 [(set (match_operand:SI 0 "register_operand" "=r")
6876 (match_operand:SI 2 "nonimmediate_operand" "%d")
6877 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6878 (set (match_operand:SI 1 "register_operand" "=r")
6881 (mult:DI (zero_extend:DI (match_dup 2))
6882 (zero_extend:DI (match_dup 3)))
6884 "!TARGET_64BIT && TARGET_BMI2
6885 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6886 "mulx\t{%3, %0, %1|%1, %0, %3}"
6887 [(set_attr "type" "imulx")
6888 (set_attr "prefix" "vex")
6889 (set_attr "mode" "SI")])
6891 (define_insn "*umul<mode><dwi>3_1"
6892 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6895 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6897 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6898 (clobber (reg:CC FLAGS_REG))]
6899 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6902 mul{<imodesuffix>}\t%2"
6903 [(set_attr "isa" "bmi2,*")
6904 (set_attr "type" "imulx,imul")
6905 (set_attr "length_immediate" "*,0")
6906 (set (attr "athlon_decode")
6907 (cond [(eq_attr "alternative" "1")
6908 (if_then_else (eq_attr "cpu" "athlon")
6909 (const_string "vector")
6910 (const_string "double"))]
6911 (const_string "*")))
6912 (set_attr "amdfam10_decode" "*,double")
6913 (set_attr "bdver1_decode" "*,direct")
6914 (set_attr "prefix" "vex,orig")
6915 (set_attr "mode" "<MODE>")])
6917 ;; Convert mul to the mulx pattern to avoid flags dependency.
6919 [(set (match_operand:<DWI> 0 "register_operand")
6922 (match_operand:DWIH 1 "register_operand"))
6924 (match_operand:DWIH 2 "nonimmediate_operand"))))
6925 (clobber (reg:CC FLAGS_REG))]
6926 "TARGET_BMI2 && reload_completed
6927 && true_regnum (operands[1]) == DX_REG"
6928 [(parallel [(set (match_dup 3)
6929 (mult:DWIH (match_dup 1) (match_dup 2)))
6933 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6934 (zero_extend:<DWI> (match_dup 2)))
6937 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6939 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6942 (define_insn "*mul<mode><dwi>3_1"
6943 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6946 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6948 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6949 (clobber (reg:CC FLAGS_REG))]
6950 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6951 "imul{<imodesuffix>}\t%2"
6952 [(set_attr "type" "imul")
6953 (set_attr "length_immediate" "0")
6954 (set (attr "athlon_decode")
6955 (if_then_else (eq_attr "cpu" "athlon")
6956 (const_string "vector")
6957 (const_string "double")))
6958 (set_attr "amdfam10_decode" "double")
6959 (set_attr "bdver1_decode" "direct")
6960 (set_attr "mode" "<MODE>")])
6962 (define_insn "*<u>mulqihi3_1"
6963 [(set (match_operand:HI 0 "register_operand" "=a")
6966 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6968 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6969 (clobber (reg:CC FLAGS_REG))]
6971 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6972 "<sgnprefix>mul{b}\t%2"
6973 [(set_attr "type" "imul")
6974 (set_attr "length_immediate" "0")
6975 (set (attr "athlon_decode")
6976 (if_then_else (eq_attr "cpu" "athlon")
6977 (const_string "vector")
6978 (const_string "direct")))
6979 (set_attr "amdfam10_decode" "direct")
6980 (set_attr "bdver1_decode" "direct")
6981 (set_attr "mode" "QI")])
6983 (define_expand "<s>mul<mode>3_highpart"
6984 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6989 (match_operand:SWI48 1 "nonimmediate_operand"))
6991 (match_operand:SWI48 2 "register_operand")))
6993 (clobber (match_scratch:SWI48 3))
6994 (clobber (reg:CC FLAGS_REG))])]
6996 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6998 (define_insn "*<s>muldi3_highpart_1"
6999 [(set (match_operand:DI 0 "register_operand" "=d")
7004 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7006 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7008 (clobber (match_scratch:DI 3 "=1"))
7009 (clobber (reg:CC FLAGS_REG))]
7011 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7012 "<sgnprefix>mul{q}\t%2"
7013 [(set_attr "type" "imul")
7014 (set_attr "length_immediate" "0")
7015 (set (attr "athlon_decode")
7016 (if_then_else (eq_attr "cpu" "athlon")
7017 (const_string "vector")
7018 (const_string "double")))
7019 (set_attr "amdfam10_decode" "double")
7020 (set_attr "bdver1_decode" "direct")
7021 (set_attr "mode" "DI")])
7023 (define_insn "*<s>mulsi3_highpart_1"
7024 [(set (match_operand:SI 0 "register_operand" "=d")
7029 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7031 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7033 (clobber (match_scratch:SI 3 "=1"))
7034 (clobber (reg:CC FLAGS_REG))]
7035 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7036 "<sgnprefix>mul{l}\t%2"
7037 [(set_attr "type" "imul")
7038 (set_attr "length_immediate" "0")
7039 (set (attr "athlon_decode")
7040 (if_then_else (eq_attr "cpu" "athlon")
7041 (const_string "vector")
7042 (const_string "double")))
7043 (set_attr "amdfam10_decode" "double")
7044 (set_attr "bdver1_decode" "direct")
7045 (set_attr "mode" "SI")])
7047 (define_insn "*<s>mulsi3_highpart_zext"
7048 [(set (match_operand:DI 0 "register_operand" "=d")
7049 (zero_extend:DI (truncate:SI
7051 (mult:DI (any_extend:DI
7052 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7054 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7056 (clobber (match_scratch:SI 3 "=1"))
7057 (clobber (reg:CC FLAGS_REG))]
7059 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7060 "<sgnprefix>mul{l}\t%2"
7061 [(set_attr "type" "imul")
7062 (set_attr "length_immediate" "0")
7063 (set (attr "athlon_decode")
7064 (if_then_else (eq_attr "cpu" "athlon")
7065 (const_string "vector")
7066 (const_string "double")))
7067 (set_attr "amdfam10_decode" "double")
7068 (set_attr "bdver1_decode" "direct")
7069 (set_attr "mode" "SI")])
7071 ;; The patterns that match these are at the end of this file.
7073 (define_expand "mulxf3"
7074 [(set (match_operand:XF 0 "register_operand")
7075 (mult:XF (match_operand:XF 1 "register_operand")
7076 (match_operand:XF 2 "register_operand")))]
7079 (define_expand "mul<mode>3"
7080 [(set (match_operand:MODEF 0 "register_operand")
7081 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7082 (match_operand:MODEF 2 "nonimmediate_operand")))]
7083 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7084 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7086 ;; Divide instructions
7088 ;; The patterns that match these are at the end of this file.
7090 (define_expand "divxf3"
7091 [(set (match_operand:XF 0 "register_operand")
7092 (div:XF (match_operand:XF 1 "register_operand")
7093 (match_operand:XF 2 "register_operand")))]
7096 (define_expand "divdf3"
7097 [(set (match_operand:DF 0 "register_operand")
7098 (div:DF (match_operand:DF 1 "register_operand")
7099 (match_operand:DF 2 "nonimmediate_operand")))]
7100 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7101 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7103 (define_expand "divsf3"
7104 [(set (match_operand:SF 0 "register_operand")
7105 (div:SF (match_operand:SF 1 "register_operand")
7106 (match_operand:SF 2 "nonimmediate_operand")))]
7107 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7112 && optimize_insn_for_speed_p ()
7113 && flag_finite_math_only && !flag_trapping_math
7114 && flag_unsafe_math_optimizations)
7116 ix86_emit_swdivsf (operands[0], operands[1],
7117 operands[2], SFmode);
7122 ;; Divmod instructions.
7124 (define_expand "divmod<mode>4"
7125 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7127 (match_operand:SWIM248 1 "register_operand")
7128 (match_operand:SWIM248 2 "nonimmediate_operand")))
7129 (set (match_operand:SWIM248 3 "register_operand")
7130 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7131 (clobber (reg:CC FLAGS_REG))])])
7133 ;; Split with 8bit unsigned divide:
7134 ;; if (dividend an divisor are in [0-255])
7135 ;; use 8bit unsigned integer divide
7137 ;; use original integer divide
7139 [(set (match_operand:SWI48 0 "register_operand")
7140 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7141 (match_operand:SWI48 3 "nonimmediate_operand")))
7142 (set (match_operand:SWI48 1 "register_operand")
7143 (mod:SWI48 (match_dup 2) (match_dup 3)))
7144 (clobber (reg:CC FLAGS_REG))]
7145 "TARGET_USE_8BIT_IDIV
7146 && TARGET_QIMODE_MATH
7147 && can_create_pseudo_p ()
7148 && !optimize_insn_for_size_p ()"
7150 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7152 (define_insn_and_split "divmod<mode>4_1"
7153 [(set (match_operand:SWI48 0 "register_operand" "=a")
7154 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7155 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7156 (set (match_operand:SWI48 1 "register_operand" "=&d")
7157 (mod:SWI48 (match_dup 2) (match_dup 3)))
7158 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7159 (clobber (reg:CC FLAGS_REG))]
7163 [(parallel [(set (match_dup 1)
7164 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7165 (clobber (reg:CC FLAGS_REG))])
7166 (parallel [(set (match_dup 0)
7167 (div:SWI48 (match_dup 2) (match_dup 3)))
7169 (mod:SWI48 (match_dup 2) (match_dup 3)))
7171 (clobber (reg:CC FLAGS_REG))])]
7173 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7175 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7176 operands[4] = operands[2];
7179 /* Avoid use of cltd in favor of a mov+shift. */
7180 emit_move_insn (operands[1], operands[2]);
7181 operands[4] = operands[1];
7184 [(set_attr "type" "multi")
7185 (set_attr "mode" "<MODE>")])
7187 (define_insn_and_split "*divmod<mode>4"
7188 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7189 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7190 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7191 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7192 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7193 (clobber (reg:CC FLAGS_REG))]
7197 [(parallel [(set (match_dup 1)
7198 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7199 (clobber (reg:CC FLAGS_REG))])
7200 (parallel [(set (match_dup 0)
7201 (div:SWIM248 (match_dup 2) (match_dup 3)))
7203 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7205 (clobber (reg:CC FLAGS_REG))])]
7207 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7209 if (<MODE>mode != HImode
7210 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7211 operands[4] = operands[2];
7214 /* Avoid use of cltd in favor of a mov+shift. */
7215 emit_move_insn (operands[1], operands[2]);
7216 operands[4] = operands[1];
7219 [(set_attr "type" "multi")
7220 (set_attr "mode" "<MODE>")])
7222 (define_insn "*divmod<mode>4_noext"
7223 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7224 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7225 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7226 (set (match_operand:SWIM248 1 "register_operand" "=d")
7227 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7228 (use (match_operand:SWIM248 4 "register_operand" "1"))
7229 (clobber (reg:CC FLAGS_REG))]
7231 "idiv{<imodesuffix>}\t%3"
7232 [(set_attr "type" "idiv")
7233 (set_attr "mode" "<MODE>")])
7235 (define_expand "divmodqi4"
7236 [(parallel [(set (match_operand:QI 0 "register_operand")
7238 (match_operand:QI 1 "register_operand")
7239 (match_operand:QI 2 "nonimmediate_operand")))
7240 (set (match_operand:QI 3 "register_operand")
7241 (mod:QI (match_dup 1) (match_dup 2)))
7242 (clobber (reg:CC FLAGS_REG))])]
7243 "TARGET_QIMODE_MATH"
7248 tmp0 = gen_reg_rtx (HImode);
7249 tmp1 = gen_reg_rtx (HImode);
7251 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7253 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7254 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7256 /* Extract remainder from AH. */
7257 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7258 insn = emit_move_insn (operands[3], tmp1);
7260 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7261 set_unique_reg_note (insn, REG_EQUAL, mod);
7263 /* Extract quotient from AL. */
7264 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7266 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7267 set_unique_reg_note (insn, REG_EQUAL, div);
7272 ;; Divide AX by r/m8, with result stored in
7275 ;; Change div/mod to HImode and extend the second argument to HImode
7276 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7277 ;; combine may fail.
7278 (define_insn "divmodhiqi3"
7279 [(set (match_operand:HI 0 "register_operand" "=a")
7284 (mod:HI (match_operand:HI 1 "register_operand" "0")
7286 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7290 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7291 (clobber (reg:CC FLAGS_REG))]
7292 "TARGET_QIMODE_MATH"
7294 [(set_attr "type" "idiv")
7295 (set_attr "mode" "QI")])
7297 (define_expand "udivmod<mode>4"
7298 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7300 (match_operand:SWIM248 1 "register_operand")
7301 (match_operand:SWIM248 2 "nonimmediate_operand")))
7302 (set (match_operand:SWIM248 3 "register_operand")
7303 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7304 (clobber (reg:CC FLAGS_REG))])])
7306 ;; Split with 8bit unsigned divide:
7307 ;; if (dividend an divisor are in [0-255])
7308 ;; use 8bit unsigned integer divide
7310 ;; use original integer divide
7312 [(set (match_operand:SWI48 0 "register_operand")
7313 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7314 (match_operand:SWI48 3 "nonimmediate_operand")))
7315 (set (match_operand:SWI48 1 "register_operand")
7316 (umod:SWI48 (match_dup 2) (match_dup 3)))
7317 (clobber (reg:CC FLAGS_REG))]
7318 "TARGET_USE_8BIT_IDIV
7319 && TARGET_QIMODE_MATH
7320 && can_create_pseudo_p ()
7321 && !optimize_insn_for_size_p ()"
7323 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7325 (define_insn_and_split "udivmod<mode>4_1"
7326 [(set (match_operand:SWI48 0 "register_operand" "=a")
7327 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7328 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7329 (set (match_operand:SWI48 1 "register_operand" "=&d")
7330 (umod:SWI48 (match_dup 2) (match_dup 3)))
7331 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7332 (clobber (reg:CC FLAGS_REG))]
7336 [(set (match_dup 1) (const_int 0))
7337 (parallel [(set (match_dup 0)
7338 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7340 (umod:SWI48 (match_dup 2) (match_dup 3)))
7342 (clobber (reg:CC FLAGS_REG))])]
7344 [(set_attr "type" "multi")
7345 (set_attr "mode" "<MODE>")])
7347 (define_insn_and_split "*udivmod<mode>4"
7348 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7349 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7350 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7351 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7352 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7353 (clobber (reg:CC FLAGS_REG))]
7357 [(set (match_dup 1) (const_int 0))
7358 (parallel [(set (match_dup 0)
7359 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7361 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7363 (clobber (reg:CC FLAGS_REG))])]
7365 [(set_attr "type" "multi")
7366 (set_attr "mode" "<MODE>")])
7368 (define_insn "*udivmod<mode>4_noext"
7369 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7370 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7371 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7372 (set (match_operand:SWIM248 1 "register_operand" "=d")
7373 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7374 (use (match_operand:SWIM248 4 "register_operand" "1"))
7375 (clobber (reg:CC FLAGS_REG))]
7377 "div{<imodesuffix>}\t%3"
7378 [(set_attr "type" "idiv")
7379 (set_attr "mode" "<MODE>")])
7381 (define_expand "udivmodqi4"
7382 [(parallel [(set (match_operand:QI 0 "register_operand")
7384 (match_operand:QI 1 "register_operand")
7385 (match_operand:QI 2 "nonimmediate_operand")))
7386 (set (match_operand:QI 3 "register_operand")
7387 (umod:QI (match_dup 1) (match_dup 2)))
7388 (clobber (reg:CC FLAGS_REG))])]
7389 "TARGET_QIMODE_MATH"
7394 tmp0 = gen_reg_rtx (HImode);
7395 tmp1 = gen_reg_rtx (HImode);
7397 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7399 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7400 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7402 /* Extract remainder from AH. */
7403 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7404 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7405 insn = emit_move_insn (operands[3], tmp1);
7407 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7408 set_unique_reg_note (insn, REG_EQUAL, mod);
7410 /* Extract quotient from AL. */
7411 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7413 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7414 set_unique_reg_note (insn, REG_EQUAL, div);
7419 (define_insn "udivmodhiqi3"
7420 [(set (match_operand:HI 0 "register_operand" "=a")
7425 (mod:HI (match_operand:HI 1 "register_operand" "0")
7427 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7431 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7432 (clobber (reg:CC FLAGS_REG))]
7433 "TARGET_QIMODE_MATH"
7435 [(set_attr "type" "idiv")
7436 (set_attr "mode" "QI")])
7438 ;; We cannot use div/idiv for double division, because it causes
7439 ;; "division by zero" on the overflow and that's not what we expect
7440 ;; from truncate. Because true (non truncating) double division is
7441 ;; never generated, we can't create this insn anyway.
7444 ; [(set (match_operand:SI 0 "register_operand" "=a")
7446 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7448 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7449 ; (set (match_operand:SI 3 "register_operand" "=d")
7451 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7452 ; (clobber (reg:CC FLAGS_REG))]
7454 ; "div{l}\t{%2, %0|%0, %2}"
7455 ; [(set_attr "type" "idiv")])
7457 ;;- Logical AND instructions
7459 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7460 ;; Note that this excludes ah.
7462 (define_expand "testsi_ccno_1"
7463 [(set (reg:CCNO FLAGS_REG)
7465 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7466 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7469 (define_expand "testqi_ccz_1"
7470 [(set (reg:CCZ FLAGS_REG)
7471 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7472 (match_operand:QI 1 "nonmemory_operand"))
7475 (define_expand "testdi_ccno_1"
7476 [(set (reg:CCNO FLAGS_REG)
7478 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7479 (match_operand:DI 1 "x86_64_szext_general_operand"))
7481 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7483 (define_insn "*testdi_1"
7484 [(set (reg FLAGS_REG)
7487 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7488 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7490 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7491 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7493 test{l}\t{%k1, %k0|%k0, %k1}
7494 test{l}\t{%k1, %k0|%k0, %k1}
7495 test{q}\t{%1, %0|%0, %1}
7496 test{q}\t{%1, %0|%0, %1}
7497 test{q}\t{%1, %0|%0, %1}"
7498 [(set_attr "type" "test")
7499 (set_attr "modrm" "0,1,0,1,1")
7500 (set_attr "mode" "SI,SI,DI,DI,DI")])
7502 (define_insn "*testqi_1_maybe_si"
7503 [(set (reg FLAGS_REG)
7506 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7507 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7509 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7510 && ix86_match_ccmode (insn,
7511 CONST_INT_P (operands[1])
7512 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7514 if (which_alternative == 3)
7516 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7517 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7518 return "test{l}\t{%1, %k0|%k0, %1}";
7520 return "test{b}\t{%1, %0|%0, %1}";
7522 [(set_attr "type" "test")
7523 (set_attr "modrm" "0,1,1,1")
7524 (set_attr "mode" "QI,QI,QI,SI")
7525 (set_attr "pent_pair" "uv,np,uv,np")])
7527 (define_insn "*test<mode>_1"
7528 [(set (reg FLAGS_REG)
7531 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7532 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7534 "ix86_match_ccmode (insn, CCNOmode)
7535 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7536 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7537 [(set_attr "type" "test")
7538 (set_attr "modrm" "0,1,1")
7539 (set_attr "mode" "<MODE>")
7540 (set_attr "pent_pair" "uv,np,uv")])
7542 (define_expand "testqi_ext_ccno_0"
7543 [(set (reg:CCNO FLAGS_REG)
7547 (match_operand 0 "ext_register_operand")
7550 (match_operand 1 "const_int_operand"))
7553 (define_insn "*testqi_ext_0"
7554 [(set (reg FLAGS_REG)
7558 (match_operand 0 "ext_register_operand" "Q")
7561 (match_operand 1 "const_int_operand" "n"))
7563 "ix86_match_ccmode (insn, CCNOmode)"
7564 "test{b}\t{%1, %h0|%h0, %1}"
7565 [(set_attr "type" "test")
7566 (set_attr "mode" "QI")
7567 (set_attr "length_immediate" "1")
7568 (set_attr "modrm" "1")
7569 (set_attr "pent_pair" "np")])
7571 (define_insn "*testqi_ext_1"
7572 [(set (reg FLAGS_REG)
7576 (match_operand 0 "ext_register_operand" "Q,Q")
7580 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7582 "ix86_match_ccmode (insn, CCNOmode)"
7583 "test{b}\t{%1, %h0|%h0, %1}"
7584 [(set_attr "isa" "*,nox64")
7585 (set_attr "type" "test")
7586 (set_attr "mode" "QI")])
7588 (define_insn "*testqi_ext_2"
7589 [(set (reg FLAGS_REG)
7593 (match_operand 0 "ext_register_operand" "Q")
7597 (match_operand 1 "ext_register_operand" "Q")
7601 "ix86_match_ccmode (insn, CCNOmode)"
7602 "test{b}\t{%h1, %h0|%h0, %h1}"
7603 [(set_attr "type" "test")
7604 (set_attr "mode" "QI")])
7606 ;; Combine likes to form bit extractions for some tests. Humor it.
7607 (define_insn "*testqi_ext_3"
7608 [(set (reg FLAGS_REG)
7609 (compare (zero_extract:SWI48
7610 (match_operand 0 "nonimmediate_operand" "rm")
7611 (match_operand:SWI48 1 "const_int_operand")
7612 (match_operand:SWI48 2 "const_int_operand"))
7614 "ix86_match_ccmode (insn, CCNOmode)
7615 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7616 || GET_MODE (operands[0]) == SImode
7617 || GET_MODE (operands[0]) == HImode
7618 || GET_MODE (operands[0]) == QImode)
7619 /* Ensure that resulting mask is zero or sign extended operand. */
7620 && INTVAL (operands[2]) >= 0
7621 && ((INTVAL (operands[1]) > 0
7622 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7623 || (<MODE>mode == DImode
7624 && INTVAL (operands[1]) > 32
7625 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7629 [(set (match_operand 0 "flags_reg_operand")
7630 (match_operator 1 "compare_operator"
7632 (match_operand 2 "nonimmediate_operand")
7633 (match_operand 3 "const_int_operand")
7634 (match_operand 4 "const_int_operand"))
7636 "ix86_match_ccmode (insn, CCNOmode)"
7637 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7639 rtx val = operands[2];
7640 HOST_WIDE_INT len = INTVAL (operands[3]);
7641 HOST_WIDE_INT pos = INTVAL (operands[4]);
7643 enum machine_mode mode, submode;
7645 mode = GET_MODE (val);
7648 /* ??? Combine likes to put non-volatile mem extractions in QImode
7649 no matter the size of the test. So find a mode that works. */
7650 if (! MEM_VOLATILE_P (val))
7652 mode = smallest_mode_for_size (pos + len, MODE_INT);
7653 val = adjust_address (val, mode, 0);
7656 else if (GET_CODE (val) == SUBREG
7657 && (submode = GET_MODE (SUBREG_REG (val)),
7658 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7659 && pos + len <= GET_MODE_BITSIZE (submode)
7660 && GET_MODE_CLASS (submode) == MODE_INT)
7662 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7664 val = SUBREG_REG (val);
7666 else if (mode == HImode && pos + len <= 8)
7668 /* Small HImode tests can be converted to QImode. */
7670 val = gen_lowpart (QImode, val);
7673 if (len == HOST_BITS_PER_WIDE_INT)
7676 mask = ((HOST_WIDE_INT)1 << len) - 1;
7679 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7682 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7683 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7684 ;; this is relatively important trick.
7685 ;; Do the conversion only post-reload to avoid limiting of the register class
7688 [(set (match_operand 0 "flags_reg_operand")
7689 (match_operator 1 "compare_operator"
7690 [(and (match_operand 2 "register_operand")
7691 (match_operand 3 "const_int_operand"))
7694 && QI_REG_P (operands[2])
7695 && GET_MODE (operands[2]) != QImode
7696 && ((ix86_match_ccmode (insn, CCZmode)
7697 && !(INTVAL (operands[3]) & ~(255 << 8)))
7698 || (ix86_match_ccmode (insn, CCNOmode)
7699 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7702 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7706 operands[2] = gen_lowpart (SImode, operands[2]);
7707 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7711 [(set (match_operand 0 "flags_reg_operand")
7712 (match_operator 1 "compare_operator"
7713 [(and (match_operand 2 "nonimmediate_operand")
7714 (match_operand 3 "const_int_operand"))
7717 && GET_MODE (operands[2]) != QImode
7718 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7719 && ((ix86_match_ccmode (insn, CCZmode)
7720 && !(INTVAL (operands[3]) & ~255))
7721 || (ix86_match_ccmode (insn, CCNOmode)
7722 && !(INTVAL (operands[3]) & ~127)))"
7724 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7727 operands[2] = gen_lowpart (QImode, operands[2]);
7728 operands[3] = gen_lowpart (QImode, operands[3]);
7732 [(set (match_operand:SWI12 0 "mask_reg_operand")
7733 (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand")
7734 (match_operand:SWI12 2 "mask_reg_operand")))
7735 (clobber (reg:CC FLAGS_REG))]
7736 "TARGET_AVX512F && reload_completed"
7738 (any_logic:SWI12 (match_dup 1)
7741 (define_insn "*k<logic><mode>"
7742 [(set (match_operand:SWI12 0 "mask_reg_operand" "=Yk")
7743 (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand" "Yk")
7744 (match_operand:SWI12 2 "mask_reg_operand" "Yk")))]
7746 "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7747 [(set_attr "mode" "<MODE>")
7748 (set_attr "type" "msklog")
7749 (set_attr "prefix" "vex")])
7751 ;; %%% This used to optimize known byte-wide and operations to memory,
7752 ;; and sometimes to QImode registers. If this is considered useful,
7753 ;; it should be done with splitters.
7755 (define_expand "and<mode>3"
7756 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7757 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7758 (match_operand:SWIM 2 "<general_szext_operand>")))]
7761 enum machine_mode mode = <MODE>mode;
7762 rtx (*insn) (rtx, rtx);
7764 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7766 HOST_WIDE_INT ival = INTVAL (operands[2]);
7768 if (ival == (HOST_WIDE_INT) 0xffffffff)
7770 else if (ival == 0xffff)
7772 else if (ival == 0xff)
7776 if (mode == <MODE>mode)
7778 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7782 if (<MODE>mode == DImode)
7783 insn = (mode == SImode)
7784 ? gen_zero_extendsidi2
7786 ? gen_zero_extendhidi2
7787 : gen_zero_extendqidi2;
7788 else if (<MODE>mode == SImode)
7789 insn = (mode == HImode)
7790 ? gen_zero_extendhisi2
7791 : gen_zero_extendqisi2;
7792 else if (<MODE>mode == HImode)
7793 insn = gen_zero_extendqihi2;
7797 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7801 (define_insn "*anddi_1"
7802 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7804 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7805 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7806 (clobber (reg:CC FLAGS_REG))]
7807 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7809 switch (get_attr_type (insn))
7815 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7816 if (get_attr_mode (insn) == MODE_SI)
7817 return "and{l}\t{%k2, %k0|%k0, %k2}";
7819 return "and{q}\t{%2, %0|%0, %2}";
7822 [(set_attr "type" "alu,alu,alu,imovx")
7823 (set_attr "length_immediate" "*,*,*,0")
7824 (set (attr "prefix_rex")
7826 (and (eq_attr "type" "imovx")
7827 (and (match_test "INTVAL (operands[2]) == 0xff")
7828 (match_operand 1 "ext_QIreg_operand")))
7830 (const_string "*")))
7831 (set_attr "mode" "SI,DI,DI,SI")])
7833 (define_insn "*andsi_1"
7834 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7835 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7836 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7837 (clobber (reg:CC FLAGS_REG))]
7838 "ix86_binary_operator_ok (AND, SImode, operands)"
7840 switch (get_attr_type (insn))
7846 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7847 return "and{l}\t{%2, %0|%0, %2}";
7850 [(set_attr "type" "alu,alu,imovx")
7851 (set (attr "prefix_rex")
7853 (and (eq_attr "type" "imovx")
7854 (and (match_test "INTVAL (operands[2]) == 0xff")
7855 (match_operand 1 "ext_QIreg_operand")))
7857 (const_string "*")))
7858 (set_attr "length_immediate" "*,*,0")
7859 (set_attr "mode" "SI")])
7861 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7862 (define_insn "*andsi_1_zext"
7863 [(set (match_operand:DI 0 "register_operand" "=r")
7865 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7866 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7867 (clobber (reg:CC FLAGS_REG))]
7868 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7869 "and{l}\t{%2, %k0|%k0, %2}"
7870 [(set_attr "type" "alu")
7871 (set_attr "mode" "SI")])
7873 (define_insn "*andhi_1"
7874 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!Yk")
7875 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,Yk")
7876 (match_operand:HI 2 "general_operand" "rn,rm,L,Yk")))
7877 (clobber (reg:CC FLAGS_REG))]
7878 "ix86_binary_operator_ok (AND, HImode, operands)"
7880 switch (get_attr_type (insn))
7886 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7889 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7890 return "and{w}\t{%2, %0|%0, %2}";
7893 [(set_attr "type" "alu,alu,imovx,msklog")
7894 (set_attr "length_immediate" "*,*,0,*")
7895 (set (attr "prefix_rex")
7897 (and (eq_attr "type" "imovx")
7898 (match_operand 1 "ext_QIreg_operand"))
7900 (const_string "*")))
7901 (set_attr "mode" "HI,HI,SI,HI")])
7903 ;; %%% Potential partial reg stall on alternative 2. What to do?
7904 (define_insn "*andqi_1"
7905 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!Yk")
7906 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,Yk")
7907 (match_operand:QI 2 "general_operand" "qn,qmn,rn,Yk")))
7908 (clobber (reg:CC FLAGS_REG))]
7909 "ix86_binary_operator_ok (AND, QImode, operands)"
7911 and{b}\t{%2, %0|%0, %2}
7912 and{b}\t{%2, %0|%0, %2}
7913 and{l}\t{%k2, %k0|%k0, %k2}
7914 kandw\t{%2, %1, %0|%0, %1, %2}"
7915 [(set_attr "type" "alu,alu,alu,msklog")
7916 (set_attr "mode" "QI,QI,SI,HI")])
7918 (define_insn "*andqi_1_slp"
7919 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7920 (and:QI (match_dup 0)
7921 (match_operand:QI 1 "general_operand" "qn,qmn")))
7922 (clobber (reg:CC FLAGS_REG))]
7923 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7924 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7925 "and{b}\t{%1, %0|%0, %1}"
7926 [(set_attr "type" "alu1")
7927 (set_attr "mode" "QI")])
7929 (define_insn "kandn<mode>"
7930 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!Yk")
7933 (match_operand:SWI12 1 "register_operand" "r,0,Yk"))
7934 (match_operand:SWI12 2 "register_operand" "r,r,Yk")))
7935 (clobber (reg:CC FLAGS_REG))]
7938 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
7940 kandnw\t{%2, %1, %0|%0, %1, %2}"
7941 [(set_attr "isa" "bmi,*,avx512f")
7942 (set_attr "type" "bitmanip,*,msklog")
7943 (set_attr "prefix" "*,*,vex")
7944 (set_attr "btver2_decode" "direct,*,*")
7945 (set_attr "mode" "<MODE>")])
7948 [(set (match_operand:SWI12 0 "general_reg_operand")
7952 (match_operand:SWI12 1 "general_reg_operand")))
7953 (clobber (reg:CC FLAGS_REG))]
7954 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7956 (not:HI (match_dup 0)))
7957 (parallel [(set (match_dup 0)
7958 (and:HI (match_dup 0)
7960 (clobber (reg:CC FLAGS_REG))])])
7962 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7964 [(set (match_operand:DI 0 "register_operand")
7965 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7966 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7967 (clobber (reg:CC FLAGS_REG))]
7969 [(parallel [(set (match_dup 0)
7970 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7971 (clobber (reg:CC FLAGS_REG))])]
7972 "operands[2] = gen_lowpart (SImode, operands[2]);")
7975 [(set (match_operand:SWI248 0 "register_operand")
7976 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7977 (match_operand:SWI248 2 "const_int_operand")))
7978 (clobber (reg:CC FLAGS_REG))]
7980 && true_regnum (operands[0]) != true_regnum (operands[1])"
7983 HOST_WIDE_INT ival = INTVAL (operands[2]);
7984 enum machine_mode mode;
7985 rtx (*insn) (rtx, rtx);
7987 if (ival == (HOST_WIDE_INT) 0xffffffff)
7989 else if (ival == 0xffff)
7993 gcc_assert (ival == 0xff);
7997 if (<MODE>mode == DImode)
7998 insn = (mode == SImode)
7999 ? gen_zero_extendsidi2
8001 ? gen_zero_extendhidi2
8002 : gen_zero_extendqidi2;
8005 if (<MODE>mode != SImode)
8006 /* Zero extend to SImode to avoid partial register stalls. */
8007 operands[0] = gen_lowpart (SImode, operands[0]);
8009 insn = (mode == HImode)
8010 ? gen_zero_extendhisi2
8011 : gen_zero_extendqisi2;
8013 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8018 [(set (match_operand 0 "register_operand")
8020 (const_int -65536)))
8021 (clobber (reg:CC FLAGS_REG))]
8022 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8023 || optimize_function_for_size_p (cfun)"
8024 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8025 "operands[1] = gen_lowpart (HImode, operands[0]);")
8028 [(set (match_operand 0 "ext_register_operand")
8031 (clobber (reg:CC FLAGS_REG))]
8032 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8033 && reload_completed"
8034 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8035 "operands[1] = gen_lowpart (QImode, operands[0]);")
8038 [(set (match_operand 0 "ext_register_operand")
8040 (const_int -65281)))
8041 (clobber (reg:CC FLAGS_REG))]
8042 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8043 && reload_completed"
8044 [(parallel [(set (zero_extract:SI (match_dup 0)
8048 (zero_extract:SI (match_dup 0)
8051 (zero_extract:SI (match_dup 0)
8054 (clobber (reg:CC FLAGS_REG))])]
8055 "operands[0] = gen_lowpart (SImode, operands[0]);")
8057 (define_insn "*anddi_2"
8058 [(set (reg FLAGS_REG)
8061 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8062 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8064 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8065 (and:DI (match_dup 1) (match_dup 2)))]
8067 && ix86_match_ccmode
8069 /* If we are going to emit andl instead of andq, and the operands[2]
8070 constant might have the SImode sign bit set, make sure the sign
8071 flag isn't tested, because the instruction will set the sign flag
8072 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8073 conservatively assume it might have bit 31 set. */
8074 (satisfies_constraint_Z (operands[2])
8075 && (!CONST_INT_P (operands[2])
8076 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8077 ? CCZmode : CCNOmode)
8078 && ix86_binary_operator_ok (AND, DImode, operands)"
8080 and{l}\t{%k2, %k0|%k0, %k2}
8081 and{q}\t{%2, %0|%0, %2}
8082 and{q}\t{%2, %0|%0, %2}"
8083 [(set_attr "type" "alu")
8084 (set_attr "mode" "SI,DI,DI")])
8086 (define_insn "*andqi_2_maybe_si"
8087 [(set (reg FLAGS_REG)
8089 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8090 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8092 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8093 (and:QI (match_dup 1) (match_dup 2)))]
8094 "ix86_binary_operator_ok (AND, QImode, operands)
8095 && ix86_match_ccmode (insn,
8096 CONST_INT_P (operands[2])
8097 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8099 if (which_alternative == 2)
8101 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8102 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8103 return "and{l}\t{%2, %k0|%k0, %2}";
8105 return "and{b}\t{%2, %0|%0, %2}";
8107 [(set_attr "type" "alu")
8108 (set_attr "mode" "QI,QI,SI")])
8110 (define_insn "*and<mode>_2"
8111 [(set (reg FLAGS_REG)
8112 (compare (and:SWI124
8113 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8114 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8116 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8117 (and:SWI124 (match_dup 1) (match_dup 2)))]
8118 "ix86_match_ccmode (insn, CCNOmode)
8119 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8120 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8121 [(set_attr "type" "alu")
8122 (set_attr "mode" "<MODE>")])
8124 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8125 (define_insn "*andsi_2_zext"
8126 [(set (reg FLAGS_REG)
8128 (match_operand:SI 1 "nonimmediate_operand" "%0")
8129 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8131 (set (match_operand:DI 0 "register_operand" "=r")
8132 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8133 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8134 && ix86_binary_operator_ok (AND, SImode, operands)"
8135 "and{l}\t{%2, %k0|%k0, %2}"
8136 [(set_attr "type" "alu")
8137 (set_attr "mode" "SI")])
8139 (define_insn "*andqi_2_slp"
8140 [(set (reg FLAGS_REG)
8142 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8143 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8145 (set (strict_low_part (match_dup 0))
8146 (and:QI (match_dup 0) (match_dup 1)))]
8147 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8148 && ix86_match_ccmode (insn, CCNOmode)
8149 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8150 "and{b}\t{%1, %0|%0, %1}"
8151 [(set_attr "type" "alu1")
8152 (set_attr "mode" "QI")])
8154 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8155 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8156 ;; for a QImode operand, which of course failed.
8157 (define_insn "andqi_ext_0"
8158 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8163 (match_operand 1 "ext_register_operand" "0")
8166 (match_operand 2 "const_int_operand" "n")))
8167 (clobber (reg:CC FLAGS_REG))]
8169 "and{b}\t{%2, %h0|%h0, %2}"
8170 [(set_attr "type" "alu")
8171 (set_attr "length_immediate" "1")
8172 (set_attr "modrm" "1")
8173 (set_attr "mode" "QI")])
8175 ;; Generated by peephole translating test to and. This shows up
8176 ;; often in fp comparisons.
8177 (define_insn "*andqi_ext_0_cc"
8178 [(set (reg FLAGS_REG)
8182 (match_operand 1 "ext_register_operand" "0")
8185 (match_operand 2 "const_int_operand" "n"))
8187 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8196 "ix86_match_ccmode (insn, CCNOmode)"
8197 "and{b}\t{%2, %h0|%h0, %2}"
8198 [(set_attr "type" "alu")
8199 (set_attr "length_immediate" "1")
8200 (set_attr "modrm" "1")
8201 (set_attr "mode" "QI")])
8203 (define_insn "*andqi_ext_1"
8204 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8209 (match_operand 1 "ext_register_operand" "0,0")
8213 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8214 (clobber (reg:CC FLAGS_REG))]
8216 "and{b}\t{%2, %h0|%h0, %2}"
8217 [(set_attr "isa" "*,nox64")
8218 (set_attr "type" "alu")
8219 (set_attr "length_immediate" "0")
8220 (set_attr "mode" "QI")])
8222 (define_insn "*andqi_ext_2"
8223 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8228 (match_operand 1 "ext_register_operand" "%0")
8232 (match_operand 2 "ext_register_operand" "Q")
8235 (clobber (reg:CC FLAGS_REG))]
8237 "and{b}\t{%h2, %h0|%h0, %h2}"
8238 [(set_attr "type" "alu")
8239 (set_attr "length_immediate" "0")
8240 (set_attr "mode" "QI")])
8242 ;; Convert wide AND instructions with immediate operand to shorter QImode
8243 ;; equivalents when possible.
8244 ;; Don't do the splitting with memory operands, since it introduces risk
8245 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8246 ;; for size, but that can (should?) be handled by generic code instead.
8248 [(set (match_operand 0 "register_operand")
8249 (and (match_operand 1 "register_operand")
8250 (match_operand 2 "const_int_operand")))
8251 (clobber (reg:CC FLAGS_REG))]
8253 && QI_REG_P (operands[0])
8254 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8255 && !(~INTVAL (operands[2]) & ~(255 << 8))
8256 && GET_MODE (operands[0]) != QImode"
8257 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8258 (and:SI (zero_extract:SI (match_dup 1)
8259 (const_int 8) (const_int 8))
8261 (clobber (reg:CC FLAGS_REG))])]
8263 operands[0] = gen_lowpart (SImode, operands[0]);
8264 operands[1] = gen_lowpart (SImode, operands[1]);
8265 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8268 ;; Since AND can be encoded with sign extended immediate, this is only
8269 ;; profitable when 7th bit is not set.
8271 [(set (match_operand 0 "register_operand")
8272 (and (match_operand 1 "general_operand")
8273 (match_operand 2 "const_int_operand")))
8274 (clobber (reg:CC FLAGS_REG))]
8276 && ANY_QI_REG_P (operands[0])
8277 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8278 && !(~INTVAL (operands[2]) & ~255)
8279 && !(INTVAL (operands[2]) & 128)
8280 && GET_MODE (operands[0]) != QImode"
8281 [(parallel [(set (strict_low_part (match_dup 0))
8282 (and:QI (match_dup 1)
8284 (clobber (reg:CC FLAGS_REG))])]
8286 operands[0] = gen_lowpart (QImode, operands[0]);
8287 operands[1] = gen_lowpart (QImode, operands[1]);
8288 operands[2] = gen_lowpart (QImode, operands[2]);
8291 ;; Logical inclusive and exclusive OR instructions
8293 ;; %%% This used to optimize known byte-wide and operations to memory.
8294 ;; If this is considered useful, it should be done with splitters.
8296 (define_expand "<code><mode>3"
8297 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8298 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8299 (match_operand:SWIM 2 "<general_operand>")))]
8301 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8303 (define_insn "*<code><mode>_1"
8304 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
8306 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
8307 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>")))
8308 (clobber (reg:CC FLAGS_REG))]
8309 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8310 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8311 [(set_attr "type" "alu")
8312 (set_attr "mode" "<MODE>")])
8314 (define_insn "*<code>hi_1"
8315 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!Yk")
8317 (match_operand:HI 1 "nonimmediate_operand" "%0,0,Yk")
8318 (match_operand:HI 2 "general_operand" "<g>,r<i>,Yk")))
8319 (clobber (reg:CC FLAGS_REG))]
8320 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8322 <logic>{w}\t{%2, %0|%0, %2}
8323 <logic>{w}\t{%2, %0|%0, %2}
8324 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8325 [(set_attr "type" "alu,alu,msklog")
8326 (set_attr "mode" "HI")])
8328 ;; %%% Potential partial reg stall on alternative 2. What to do?
8329 (define_insn "*<code>qi_1"
8330 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!Yk")
8331 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,Yk")
8332 (match_operand:QI 2 "general_operand" "qmn,qn,rn,Yk")))
8333 (clobber (reg:CC FLAGS_REG))]
8334 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8336 <logic>{b}\t{%2, %0|%0, %2}
8337 <logic>{b}\t{%2, %0|%0, %2}
8338 <logic>{l}\t{%k2, %k0|%k0, %k2}
8339 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8340 [(set_attr "type" "alu,alu,alu,msklog")
8341 (set_attr "mode" "QI,QI,SI,HI")])
8343 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8344 (define_insn "*<code>si_1_zext"
8345 [(set (match_operand:DI 0 "register_operand" "=r")
8347 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8348 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8349 (clobber (reg:CC FLAGS_REG))]
8350 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8351 "<logic>{l}\t{%2, %k0|%k0, %2}"
8352 [(set_attr "type" "alu")
8353 (set_attr "mode" "SI")])
8355 (define_insn "*<code>si_1_zext_imm"
8356 [(set (match_operand:DI 0 "register_operand" "=r")
8358 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8359 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8360 (clobber (reg:CC FLAGS_REG))]
8361 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8362 "<logic>{l}\t{%2, %k0|%k0, %2}"
8363 [(set_attr "type" "alu")
8364 (set_attr "mode" "SI")])
8366 (define_insn "*<code>qi_1_slp"
8367 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8368 (any_or:QI (match_dup 0)
8369 (match_operand:QI 1 "general_operand" "qmn,qn")))
8370 (clobber (reg:CC FLAGS_REG))]
8371 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8372 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8373 "<logic>{b}\t{%1, %0|%0, %1}"
8374 [(set_attr "type" "alu1")
8375 (set_attr "mode" "QI")])
8377 (define_insn "*<code><mode>_2"
8378 [(set (reg FLAGS_REG)
8379 (compare (any_or:SWI
8380 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8381 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8383 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8384 (any_or:SWI (match_dup 1) (match_dup 2)))]
8385 "ix86_match_ccmode (insn, CCNOmode)
8386 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8387 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8388 [(set_attr "type" "alu")
8389 (set_attr "mode" "<MODE>")])
8391 (define_insn "kxnor<mode>"
8392 [(set (match_operand:SWI12 0 "register_operand" "=r,!Yk")
8395 (match_operand:SWI12 1 "register_operand" "0,Yk")
8396 (match_operand:SWI12 2 "register_operand" "r,Yk"))))
8397 (clobber (reg:CC FLAGS_REG))]
8401 kxnorw\t{%2, %1, %0|%0, %1, %2}"
8402 [(set_attr "type" "*,msklog")
8403 (set_attr "prefix" "*,vex")
8404 (set_attr "mode" "<MODE>")])
8407 [(set (match_operand:SWI12 0 "general_reg_operand")
8411 (match_operand:SWI12 1 "general_reg_operand"))))
8412 (clobber (reg:CC FLAGS_REG))]
8413 "TARGET_AVX512F && reload_completed"
8414 [(parallel [(set (match_dup 0)
8415 (xor:HI (match_dup 0)
8417 (clobber (reg:CC FLAGS_REG))])
8419 (not:HI (match_dup 0)))])
8421 (define_insn "kortestzhi"
8422 [(set (reg:CCZ FLAGS_REG)
8425 (match_operand:HI 0 "register_operand" "Yk")
8426 (match_operand:HI 1 "register_operand" "Yk"))
8428 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8429 "kortestw\t{%1, %0|%0, %1}"
8430 [(set_attr "mode" "HI")
8431 (set_attr "type" "msklog")
8432 (set_attr "prefix" "vex")])
8434 (define_insn "kortestchi"
8435 [(set (reg:CCC FLAGS_REG)
8438 (match_operand:HI 0 "register_operand" "Yk")
8439 (match_operand:HI 1 "register_operand" "Yk"))
8441 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8442 "kortestw\t{%1, %0|%0, %1}"
8443 [(set_attr "mode" "HI")
8444 (set_attr "type" "msklog")
8445 (set_attr "prefix" "vex")])
8447 (define_insn "kunpckhi"
8448 [(set (match_operand:HI 0 "register_operand" "=Yk")
8451 (match_operand:HI 1 "register_operand" "Yk")
8453 (zero_extend:HI (match_operand:QI 2 "register_operand" "Yk"))))]
8455 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8456 [(set_attr "mode" "HI")
8457 (set_attr "type" "msklog")
8458 (set_attr "prefix" "vex")])
8460 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8461 ;; ??? Special case for immediate operand is missing - it is tricky.
8462 (define_insn "*<code>si_2_zext"
8463 [(set (reg FLAGS_REG)
8464 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8465 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8467 (set (match_operand:DI 0 "register_operand" "=r")
8468 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8469 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8470 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8471 "<logic>{l}\t{%2, %k0|%k0, %2}"
8472 [(set_attr "type" "alu")
8473 (set_attr "mode" "SI")])
8475 (define_insn "*<code>si_2_zext_imm"
8476 [(set (reg FLAGS_REG)
8478 (match_operand:SI 1 "nonimmediate_operand" "%0")
8479 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8481 (set (match_operand:DI 0 "register_operand" "=r")
8482 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8483 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8484 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8485 "<logic>{l}\t{%2, %k0|%k0, %2}"
8486 [(set_attr "type" "alu")
8487 (set_attr "mode" "SI")])
8489 (define_insn "*<code>qi_2_slp"
8490 [(set (reg FLAGS_REG)
8491 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8492 (match_operand:QI 1 "general_operand" "qmn,qn"))
8494 (set (strict_low_part (match_dup 0))
8495 (any_or:QI (match_dup 0) (match_dup 1)))]
8496 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8497 && ix86_match_ccmode (insn, CCNOmode)
8498 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8499 "<logic>{b}\t{%1, %0|%0, %1}"
8500 [(set_attr "type" "alu1")
8501 (set_attr "mode" "QI")])
8503 (define_insn "*<code><mode>_3"
8504 [(set (reg FLAGS_REG)
8505 (compare (any_or:SWI
8506 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8507 (match_operand:SWI 2 "<general_operand>" "<g>"))
8509 (clobber (match_scratch:SWI 0 "=<r>"))]
8510 "ix86_match_ccmode (insn, CCNOmode)
8511 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8512 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8513 [(set_attr "type" "alu")
8514 (set_attr "mode" "<MODE>")])
8516 (define_insn "*<code>qi_ext_0"
8517 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8522 (match_operand 1 "ext_register_operand" "0")
8525 (match_operand 2 "const_int_operand" "n")))
8526 (clobber (reg:CC FLAGS_REG))]
8527 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8528 "<logic>{b}\t{%2, %h0|%h0, %2}"
8529 [(set_attr "type" "alu")
8530 (set_attr "length_immediate" "1")
8531 (set_attr "modrm" "1")
8532 (set_attr "mode" "QI")])
8534 (define_insn "*<code>qi_ext_1"
8535 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8540 (match_operand 1 "ext_register_operand" "0,0")
8544 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8545 (clobber (reg:CC FLAGS_REG))]
8546 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8547 "<logic>{b}\t{%2, %h0|%h0, %2}"
8548 [(set_attr "isa" "*,nox64")
8549 (set_attr "type" "alu")
8550 (set_attr "length_immediate" "0")
8551 (set_attr "mode" "QI")])
8553 (define_insn "*<code>qi_ext_2"
8554 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8558 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8561 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8564 (clobber (reg:CC FLAGS_REG))]
8565 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8566 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8567 [(set_attr "type" "alu")
8568 (set_attr "length_immediate" "0")
8569 (set_attr "mode" "QI")])
8572 [(set (match_operand 0 "register_operand")
8573 (any_or (match_operand 1 "register_operand")
8574 (match_operand 2 "const_int_operand")))
8575 (clobber (reg:CC FLAGS_REG))]
8577 && QI_REG_P (operands[0])
8578 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8579 && !(INTVAL (operands[2]) & ~(255 << 8))
8580 && GET_MODE (operands[0]) != QImode"
8581 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8582 (any_or:SI (zero_extract:SI (match_dup 1)
8583 (const_int 8) (const_int 8))
8585 (clobber (reg:CC FLAGS_REG))])]
8587 operands[0] = gen_lowpart (SImode, operands[0]);
8588 operands[1] = gen_lowpart (SImode, operands[1]);
8589 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8592 ;; Since OR can be encoded with sign extended immediate, this is only
8593 ;; profitable when 7th bit is set.
8595 [(set (match_operand 0 "register_operand")
8596 (any_or (match_operand 1 "general_operand")
8597 (match_operand 2 "const_int_operand")))
8598 (clobber (reg:CC FLAGS_REG))]
8600 && ANY_QI_REG_P (operands[0])
8601 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8602 && !(INTVAL (operands[2]) & ~255)
8603 && (INTVAL (operands[2]) & 128)
8604 && GET_MODE (operands[0]) != QImode"
8605 [(parallel [(set (strict_low_part (match_dup 0))
8606 (any_or:QI (match_dup 1)
8608 (clobber (reg:CC FLAGS_REG))])]
8610 operands[0] = gen_lowpart (QImode, operands[0]);
8611 operands[1] = gen_lowpart (QImode, operands[1]);
8612 operands[2] = gen_lowpart (QImode, operands[2]);
8615 (define_expand "xorqi_cc_ext_1"
8617 (set (reg:CCNO FLAGS_REG)
8621 (match_operand 1 "ext_register_operand")
8624 (match_operand:QI 2 "const_int_operand"))
8626 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8636 (define_insn "*xorqi_cc_ext_1"
8637 [(set (reg FLAGS_REG)
8641 (match_operand 1 "ext_register_operand" "0,0")
8644 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8646 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8655 "ix86_match_ccmode (insn, CCNOmode)"
8656 "xor{b}\t{%2, %h0|%h0, %2}"
8657 [(set_attr "isa" "*,nox64")
8658 (set_attr "type" "alu")
8659 (set_attr "modrm" "1")
8660 (set_attr "mode" "QI")])
8662 ;; Negation instructions
8664 (define_expand "neg<mode>2"
8665 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8666 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8668 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8670 (define_insn_and_split "*neg<dwi>2_doubleword"
8671 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8672 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8673 (clobber (reg:CC FLAGS_REG))]
8674 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8678 [(set (reg:CCZ FLAGS_REG)
8679 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8680 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8683 (plus:DWIH (match_dup 3)
8684 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8686 (clobber (reg:CC FLAGS_REG))])
8689 (neg:DWIH (match_dup 2)))
8690 (clobber (reg:CC FLAGS_REG))])]
8691 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8693 (define_insn "*neg<mode>2_1"
8694 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8695 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8696 (clobber (reg:CC FLAGS_REG))]
8697 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8698 "neg{<imodesuffix>}\t%0"
8699 [(set_attr "type" "negnot")
8700 (set_attr "mode" "<MODE>")])
8702 ;; Combine is quite creative about this pattern.
8703 (define_insn "*negsi2_1_zext"
8704 [(set (match_operand:DI 0 "register_operand" "=r")
8706 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8709 (clobber (reg:CC FLAGS_REG))]
8710 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8712 [(set_attr "type" "negnot")
8713 (set_attr "mode" "SI")])
8715 ;; The problem with neg is that it does not perform (compare x 0),
8716 ;; it really performs (compare 0 x), which leaves us with the zero
8717 ;; flag being the only useful item.
8719 (define_insn "*neg<mode>2_cmpz"
8720 [(set (reg:CCZ FLAGS_REG)
8722 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8724 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8725 (neg:SWI (match_dup 1)))]
8726 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8727 "neg{<imodesuffix>}\t%0"
8728 [(set_attr "type" "negnot")
8729 (set_attr "mode" "<MODE>")])
8731 (define_insn "*negsi2_cmpz_zext"
8732 [(set (reg:CCZ FLAGS_REG)
8736 (match_operand:DI 1 "register_operand" "0")
8740 (set (match_operand:DI 0 "register_operand" "=r")
8741 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8744 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8746 [(set_attr "type" "negnot")
8747 (set_attr "mode" "SI")])
8749 ;; Negate with jump on overflow.
8750 (define_expand "negv<mode>3"
8751 [(parallel [(set (reg:CCO FLAGS_REG)
8752 (ne:CCO (match_operand:SWI 1 "register_operand")
8754 (set (match_operand:SWI 0 "register_operand")
8755 (neg:SWI (match_dup 1)))])
8756 (set (pc) (if_then_else
8757 (eq (reg:CCO FLAGS_REG) (const_int 0))
8758 (label_ref (match_operand 2))
8763 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8767 (define_insn "*negv<mode>3"
8768 [(set (reg:CCO FLAGS_REG)
8769 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8770 (match_operand:SWI 2 "const_int_operand")))
8771 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8772 (neg:SWI (match_dup 1)))]
8773 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8774 && mode_signbit_p (<MODE>mode, operands[2])"
8775 "neg{<imodesuffix>}\t%0"
8776 [(set_attr "type" "negnot")
8777 (set_attr "mode" "<MODE>")])
8779 ;; Changing of sign for FP values is doable using integer unit too.
8781 (define_expand "<code><mode>2"
8782 [(set (match_operand:X87MODEF 0 "register_operand")
8783 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8784 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8785 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8787 (define_insn "*absneg<mode>2_mixed"
8788 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8789 (match_operator:MODEF 3 "absneg_operator"
8790 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8791 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8792 (clobber (reg:CC FLAGS_REG))]
8793 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8796 (define_insn "*absneg<mode>2_sse"
8797 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8798 (match_operator:MODEF 3 "absneg_operator"
8799 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8800 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8801 (clobber (reg:CC FLAGS_REG))]
8802 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8805 (define_insn "*absneg<mode>2_i387"
8806 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8807 (match_operator:X87MODEF 3 "absneg_operator"
8808 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8809 (use (match_operand 2))
8810 (clobber (reg:CC FLAGS_REG))]
8811 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8814 (define_expand "<code>tf2"
8815 [(set (match_operand:TF 0 "register_operand")
8816 (absneg:TF (match_operand:TF 1 "register_operand")))]
8818 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8820 (define_insn "*absnegtf2_sse"
8821 [(set (match_operand:TF 0 "register_operand" "=x,x")
8822 (match_operator:TF 3 "absneg_operator"
8823 [(match_operand:TF 1 "register_operand" "0,x")]))
8824 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8825 (clobber (reg:CC FLAGS_REG))]
8829 ;; Splitters for fp abs and neg.
8832 [(set (match_operand 0 "fp_register_operand")
8833 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8834 (use (match_operand 2))
8835 (clobber (reg:CC FLAGS_REG))]
8837 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8840 [(set (match_operand 0 "register_operand")
8841 (match_operator 3 "absneg_operator"
8842 [(match_operand 1 "register_operand")]))
8843 (use (match_operand 2 "nonimmediate_operand"))
8844 (clobber (reg:CC FLAGS_REG))]
8845 "reload_completed && SSE_REG_P (operands[0])"
8846 [(set (match_dup 0) (match_dup 3))]
8848 enum machine_mode mode = GET_MODE (operands[0]);
8849 enum machine_mode vmode = GET_MODE (operands[2]);
8852 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8853 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8854 if (operands_match_p (operands[0], operands[2]))
8857 operands[1] = operands[2];
8860 if (GET_CODE (operands[3]) == ABS)
8861 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8863 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8868 [(set (match_operand:SF 0 "register_operand")
8869 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8870 (use (match_operand:V4SF 2))
8871 (clobber (reg:CC FLAGS_REG))]
8873 [(parallel [(set (match_dup 0) (match_dup 1))
8874 (clobber (reg:CC FLAGS_REG))])]
8877 operands[0] = gen_lowpart (SImode, operands[0]);
8878 if (GET_CODE (operands[1]) == ABS)
8880 tmp = gen_int_mode (0x7fffffff, SImode);
8881 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8885 tmp = gen_int_mode (0x80000000, SImode);
8886 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8892 [(set (match_operand:DF 0 "register_operand")
8893 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8894 (use (match_operand 2))
8895 (clobber (reg:CC FLAGS_REG))]
8897 [(parallel [(set (match_dup 0) (match_dup 1))
8898 (clobber (reg:CC FLAGS_REG))])]
8903 tmp = gen_lowpart (DImode, operands[0]);
8904 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8907 if (GET_CODE (operands[1]) == ABS)
8910 tmp = gen_rtx_NOT (DImode, tmp);
8914 operands[0] = gen_highpart (SImode, operands[0]);
8915 if (GET_CODE (operands[1]) == ABS)
8917 tmp = gen_int_mode (0x7fffffff, SImode);
8918 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8922 tmp = gen_int_mode (0x80000000, SImode);
8923 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8930 [(set (match_operand:XF 0 "register_operand")
8931 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8932 (use (match_operand 2))
8933 (clobber (reg:CC FLAGS_REG))]
8935 [(parallel [(set (match_dup 0) (match_dup 1))
8936 (clobber (reg:CC FLAGS_REG))])]
8939 operands[0] = gen_rtx_REG (SImode,
8940 true_regnum (operands[0])
8941 + (TARGET_64BIT ? 1 : 2));
8942 if (GET_CODE (operands[1]) == ABS)
8944 tmp = GEN_INT (0x7fff);
8945 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8949 tmp = GEN_INT (0x8000);
8950 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8955 ;; Conditionalize these after reload. If they match before reload, we
8956 ;; lose the clobber and ability to use integer instructions.
8958 (define_insn "*<code><mode>2_1"
8959 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8960 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8962 && (reload_completed
8963 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8964 "f<absneg_mnemonic>"
8965 [(set_attr "type" "fsgn")
8966 (set_attr "mode" "<MODE>")])
8968 (define_insn "*<code>extendsfdf2"
8969 [(set (match_operand:DF 0 "register_operand" "=f")
8970 (absneg:DF (float_extend:DF
8971 (match_operand:SF 1 "register_operand" "0"))))]
8972 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8973 "f<absneg_mnemonic>"
8974 [(set_attr "type" "fsgn")
8975 (set_attr "mode" "DF")])
8977 (define_insn "*<code>extendsfxf2"
8978 [(set (match_operand:XF 0 "register_operand" "=f")
8979 (absneg:XF (float_extend:XF
8980 (match_operand:SF 1 "register_operand" "0"))))]
8982 "f<absneg_mnemonic>"
8983 [(set_attr "type" "fsgn")
8984 (set_attr "mode" "XF")])
8986 (define_insn "*<code>extenddfxf2"
8987 [(set (match_operand:XF 0 "register_operand" "=f")
8988 (absneg:XF (float_extend:XF
8989 (match_operand:DF 1 "register_operand" "0"))))]
8991 "f<absneg_mnemonic>"
8992 [(set_attr "type" "fsgn")
8993 (set_attr "mode" "XF")])
8995 ;; Copysign instructions
8997 (define_mode_iterator CSGNMODE [SF DF TF])
8998 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9000 (define_expand "copysign<mode>3"
9001 [(match_operand:CSGNMODE 0 "register_operand")
9002 (match_operand:CSGNMODE 1 "nonmemory_operand")
9003 (match_operand:CSGNMODE 2 "register_operand")]
9004 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9005 || (TARGET_SSE && (<MODE>mode == TFmode))"
9006 "ix86_expand_copysign (operands); DONE;")
9008 (define_insn_and_split "copysign<mode>3_const"
9009 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9011 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9012 (match_operand:CSGNMODE 2 "register_operand" "0")
9013 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9015 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9016 || (TARGET_SSE && (<MODE>mode == TFmode))"
9018 "&& reload_completed"
9020 "ix86_split_copysign_const (operands); DONE;")
9022 (define_insn "copysign<mode>3_var"
9023 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9025 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9026 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9027 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9028 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9030 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9031 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9032 || (TARGET_SSE && (<MODE>mode == TFmode))"
9036 [(set (match_operand:CSGNMODE 0 "register_operand")
9038 [(match_operand:CSGNMODE 2 "register_operand")
9039 (match_operand:CSGNMODE 3 "register_operand")
9040 (match_operand:<CSGNVMODE> 4)
9041 (match_operand:<CSGNVMODE> 5)]
9043 (clobber (match_scratch:<CSGNVMODE> 1))]
9044 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9045 || (TARGET_SSE && (<MODE>mode == TFmode)))
9046 && reload_completed"
9048 "ix86_split_copysign_var (operands); DONE;")
9050 ;; One complement instructions
9052 (define_expand "one_cmpl<mode>2"
9053 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9054 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9056 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9058 (define_insn "*one_cmpl<mode>2_1"
9059 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9060 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0")))]
9061 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9062 "not{<imodesuffix>}\t%0"
9063 [(set_attr "type" "negnot")
9064 (set_attr "mode" "<MODE>")])
9066 (define_insn "*one_cmplhi2_1"
9067 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!Yk")
9068 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,Yk")))]
9069 "ix86_unary_operator_ok (NOT, HImode, operands)"
9072 knotw\t{%1, %0|%0, %1}"
9073 [(set_attr "isa" "*,avx512f")
9074 (set_attr "type" "negnot,msklog")
9075 (set_attr "prefix" "*,vex")
9076 (set_attr "mode" "HI")])
9078 ;; %%% Potential partial reg stall on alternative 1. What to do?
9079 (define_insn "*one_cmplqi2_1"
9080 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!Yk")
9081 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,Yk")))]
9082 "ix86_unary_operator_ok (NOT, QImode, operands)"
9086 knotw\t{%1, %0|%0, %1}"
9087 [(set_attr "isa" "*,*,avx512f")
9088 (set_attr "type" "negnot,negnot,msklog")
9089 (set_attr "prefix" "*,*,vex")
9090 (set_attr "mode" "QI,SI,QI")])
9092 ;; ??? Currently never generated - xor is used instead.
9093 (define_insn "*one_cmplsi2_1_zext"
9094 [(set (match_operand:DI 0 "register_operand" "=r")
9096 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9097 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9099 [(set_attr "type" "negnot")
9100 (set_attr "mode" "SI")])
9102 (define_insn "*one_cmpl<mode>2_2"
9103 [(set (reg FLAGS_REG)
9104 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9106 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9107 (not:SWI (match_dup 1)))]
9108 "ix86_match_ccmode (insn, CCNOmode)
9109 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9111 [(set_attr "type" "alu1")
9112 (set_attr "mode" "<MODE>")])
9115 [(set (match_operand 0 "flags_reg_operand")
9116 (match_operator 2 "compare_operator"
9117 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9119 (set (match_operand:SWI 1 "nonimmediate_operand")
9120 (not:SWI (match_dup 3)))]
9121 "ix86_match_ccmode (insn, CCNOmode)"
9122 [(parallel [(set (match_dup 0)
9123 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9126 (xor:SWI (match_dup 3) (const_int -1)))])])
9128 ;; ??? Currently never generated - xor is used instead.
9129 (define_insn "*one_cmplsi2_2_zext"
9130 [(set (reg FLAGS_REG)
9131 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9133 (set (match_operand:DI 0 "register_operand" "=r")
9134 (zero_extend:DI (not:SI (match_dup 1))))]
9135 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9136 && ix86_unary_operator_ok (NOT, SImode, operands)"
9138 [(set_attr "type" "alu1")
9139 (set_attr "mode" "SI")])
9142 [(set (match_operand 0 "flags_reg_operand")
9143 (match_operator 2 "compare_operator"
9144 [(not:SI (match_operand:SI 3 "register_operand"))
9146 (set (match_operand:DI 1 "register_operand")
9147 (zero_extend:DI (not:SI (match_dup 3))))]
9148 "ix86_match_ccmode (insn, CCNOmode)"
9149 [(parallel [(set (match_dup 0)
9150 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9153 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9155 ;; Shift instructions
9157 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9158 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9159 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9160 ;; from the assembler input.
9162 ;; This instruction shifts the target reg/mem as usual, but instead of
9163 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9164 ;; is a left shift double, bits are taken from the high order bits of
9165 ;; reg, else if the insn is a shift right double, bits are taken from the
9166 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9167 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9169 ;; Since sh[lr]d does not change the `reg' operand, that is done
9170 ;; separately, making all shifts emit pairs of shift double and normal
9171 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9172 ;; support a 63 bit shift, each shift where the count is in a reg expands
9173 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9175 ;; If the shift count is a constant, we need never emit more than one
9176 ;; shift pair, instead using moves and sign extension for counts greater
9179 (define_expand "ashl<mode>3"
9180 [(set (match_operand:SDWIM 0 "<shift_operand>")
9181 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9182 (match_operand:QI 2 "nonmemory_operand")))]
9184 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9186 (define_insn "*ashl<mode>3_doubleword"
9187 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9188 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9189 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9190 (clobber (reg:CC FLAGS_REG))]
9193 [(set_attr "type" "multi")])
9196 [(set (match_operand:DWI 0 "register_operand")
9197 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9198 (match_operand:QI 2 "nonmemory_operand")))
9199 (clobber (reg:CC FLAGS_REG))]
9200 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9202 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9204 ;; By default we don't ask for a scratch register, because when DWImode
9205 ;; values are manipulated, registers are already at a premium. But if
9206 ;; we have one handy, we won't turn it away.
9209 [(match_scratch:DWIH 3 "r")
9210 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9212 (match_operand:<DWI> 1 "nonmemory_operand")
9213 (match_operand:QI 2 "nonmemory_operand")))
9214 (clobber (reg:CC FLAGS_REG))])
9218 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9220 (define_insn "x86_64_shld"
9221 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9222 (ior:DI (ashift:DI (match_dup 0)
9223 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9224 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9225 (minus:QI (const_int 64) (match_dup 2)))))
9226 (clobber (reg:CC FLAGS_REG))]
9228 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9229 [(set_attr "type" "ishift")
9230 (set_attr "prefix_0f" "1")
9231 (set_attr "mode" "DI")
9232 (set_attr "athlon_decode" "vector")
9233 (set_attr "amdfam10_decode" "vector")
9234 (set_attr "bdver1_decode" "vector")])
9236 (define_insn "x86_shld"
9237 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9238 (ior:SI (ashift:SI (match_dup 0)
9239 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9240 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9241 (minus:QI (const_int 32) (match_dup 2)))))
9242 (clobber (reg:CC FLAGS_REG))]
9244 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9245 [(set_attr "type" "ishift")
9246 (set_attr "prefix_0f" "1")
9247 (set_attr "mode" "SI")
9248 (set_attr "pent_pair" "np")
9249 (set_attr "athlon_decode" "vector")
9250 (set_attr "amdfam10_decode" "vector")
9251 (set_attr "bdver1_decode" "vector")])
9253 (define_expand "x86_shift<mode>_adj_1"
9254 [(set (reg:CCZ FLAGS_REG)
9255 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9258 (set (match_operand:SWI48 0 "register_operand")
9259 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9260 (match_operand:SWI48 1 "register_operand")
9263 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9264 (match_operand:SWI48 3 "register_operand")
9267 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9269 (define_expand "x86_shift<mode>_adj_2"
9270 [(use (match_operand:SWI48 0 "register_operand"))
9271 (use (match_operand:SWI48 1 "register_operand"))
9272 (use (match_operand:QI 2 "register_operand"))]
9275 rtx label = gen_label_rtx ();
9278 emit_insn (gen_testqi_ccz_1 (operands[2],
9279 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9281 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9282 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9283 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9284 gen_rtx_LABEL_REF (VOIDmode, label),
9286 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9287 JUMP_LABEL (tmp) = label;
9289 emit_move_insn (operands[0], operands[1]);
9290 ix86_expand_clear (operands[1]);
9293 LABEL_NUSES (label) = 1;
9298 ;; Avoid useless masking of count operand.
9299 (define_insn "*ashl<mode>3_mask"
9300 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9302 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9305 (match_operand:SI 2 "register_operand" "c")
9306 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9307 (clobber (reg:CC FLAGS_REG))]
9308 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9309 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9310 == GET_MODE_BITSIZE (<MODE>mode)-1"
9312 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9314 [(set_attr "type" "ishift")
9315 (set_attr "mode" "<MODE>")])
9317 (define_insn "*bmi2_ashl<mode>3_1"
9318 [(set (match_operand:SWI48 0 "register_operand" "=r")
9319 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9320 (match_operand:SWI48 2 "register_operand" "r")))]
9322 "shlx\t{%2, %1, %0|%0, %1, %2}"
9323 [(set_attr "type" "ishiftx")
9324 (set_attr "mode" "<MODE>")])
9326 (define_insn "*ashl<mode>3_1"
9327 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9328 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9329 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9330 (clobber (reg:CC FLAGS_REG))]
9331 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9333 switch (get_attr_type (insn))
9340 gcc_assert (operands[2] == const1_rtx);
9341 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9342 return "add{<imodesuffix>}\t%0, %0";
9345 if (operands[2] == const1_rtx
9346 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9347 return "sal{<imodesuffix>}\t%0";
9349 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9352 [(set_attr "isa" "*,*,bmi2")
9354 (cond [(eq_attr "alternative" "1")
9355 (const_string "lea")
9356 (eq_attr "alternative" "2")
9357 (const_string "ishiftx")
9358 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9359 (match_operand 0 "register_operand"))
9360 (match_operand 2 "const1_operand"))
9361 (const_string "alu")
9363 (const_string "ishift")))
9364 (set (attr "length_immediate")
9366 (ior (eq_attr "type" "alu")
9367 (and (eq_attr "type" "ishift")
9368 (and (match_operand 2 "const1_operand")
9369 (ior (match_test "TARGET_SHIFT1")
9370 (match_test "optimize_function_for_size_p (cfun)")))))
9372 (const_string "*")))
9373 (set_attr "mode" "<MODE>")])
9375 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9377 [(set (match_operand:SWI48 0 "register_operand")
9378 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9379 (match_operand:QI 2 "register_operand")))
9380 (clobber (reg:CC FLAGS_REG))]
9381 "TARGET_BMI2 && reload_completed"
9383 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9384 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9386 (define_insn "*bmi2_ashlsi3_1_zext"
9387 [(set (match_operand:DI 0 "register_operand" "=r")
9389 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9390 (match_operand:SI 2 "register_operand" "r"))))]
9391 "TARGET_64BIT && TARGET_BMI2"
9392 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9393 [(set_attr "type" "ishiftx")
9394 (set_attr "mode" "SI")])
9396 (define_insn "*ashlsi3_1_zext"
9397 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9399 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9400 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9401 (clobber (reg:CC FLAGS_REG))]
9402 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9404 switch (get_attr_type (insn))
9411 gcc_assert (operands[2] == const1_rtx);
9412 return "add{l}\t%k0, %k0";
9415 if (operands[2] == const1_rtx
9416 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9417 return "sal{l}\t%k0";
9419 return "sal{l}\t{%2, %k0|%k0, %2}";
9422 [(set_attr "isa" "*,*,bmi2")
9424 (cond [(eq_attr "alternative" "1")
9425 (const_string "lea")
9426 (eq_attr "alternative" "2")
9427 (const_string "ishiftx")
9428 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9429 (match_operand 2 "const1_operand"))
9430 (const_string "alu")
9432 (const_string "ishift")))
9433 (set (attr "length_immediate")
9435 (ior (eq_attr "type" "alu")
9436 (and (eq_attr "type" "ishift")
9437 (and (match_operand 2 "const1_operand")
9438 (ior (match_test "TARGET_SHIFT1")
9439 (match_test "optimize_function_for_size_p (cfun)")))))
9441 (const_string "*")))
9442 (set_attr "mode" "SI")])
9444 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9446 [(set (match_operand:DI 0 "register_operand")
9448 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9449 (match_operand:QI 2 "register_operand"))))
9450 (clobber (reg:CC FLAGS_REG))]
9451 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9453 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9454 "operands[2] = gen_lowpart (SImode, operands[2]);")
9456 (define_insn "*ashlhi3_1"
9457 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9458 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9459 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9460 (clobber (reg:CC FLAGS_REG))]
9461 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9463 switch (get_attr_type (insn))
9469 gcc_assert (operands[2] == const1_rtx);
9470 return "add{w}\t%0, %0";
9473 if (operands[2] == const1_rtx
9474 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9475 return "sal{w}\t%0";
9477 return "sal{w}\t{%2, %0|%0, %2}";
9481 (cond [(eq_attr "alternative" "1")
9482 (const_string "lea")
9483 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9484 (match_operand 0 "register_operand"))
9485 (match_operand 2 "const1_operand"))
9486 (const_string "alu")
9488 (const_string "ishift")))
9489 (set (attr "length_immediate")
9491 (ior (eq_attr "type" "alu")
9492 (and (eq_attr "type" "ishift")
9493 (and (match_operand 2 "const1_operand")
9494 (ior (match_test "TARGET_SHIFT1")
9495 (match_test "optimize_function_for_size_p (cfun)")))))
9497 (const_string "*")))
9498 (set_attr "mode" "HI,SI")])
9500 ;; %%% Potential partial reg stall on alternative 1. What to do?
9501 (define_insn "*ashlqi3_1"
9502 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9503 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9504 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9505 (clobber (reg:CC FLAGS_REG))]
9506 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9508 switch (get_attr_type (insn))
9514 gcc_assert (operands[2] == const1_rtx);
9515 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9516 return "add{l}\t%k0, %k0";
9518 return "add{b}\t%0, %0";
9521 if (operands[2] == const1_rtx
9522 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9524 if (get_attr_mode (insn) == MODE_SI)
9525 return "sal{l}\t%k0";
9527 return "sal{b}\t%0";
9531 if (get_attr_mode (insn) == MODE_SI)
9532 return "sal{l}\t{%2, %k0|%k0, %2}";
9534 return "sal{b}\t{%2, %0|%0, %2}";
9539 (cond [(eq_attr "alternative" "2")
9540 (const_string "lea")
9541 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9542 (match_operand 0 "register_operand"))
9543 (match_operand 2 "const1_operand"))
9544 (const_string "alu")
9546 (const_string "ishift")))
9547 (set (attr "length_immediate")
9549 (ior (eq_attr "type" "alu")
9550 (and (eq_attr "type" "ishift")
9551 (and (match_operand 2 "const1_operand")
9552 (ior (match_test "TARGET_SHIFT1")
9553 (match_test "optimize_function_for_size_p (cfun)")))))
9555 (const_string "*")))
9556 (set_attr "mode" "QI,SI,SI")])
9558 (define_insn "*ashlqi3_1_slp"
9559 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9560 (ashift:QI (match_dup 0)
9561 (match_operand:QI 1 "nonmemory_operand" "cI")))
9562 (clobber (reg:CC FLAGS_REG))]
9563 "(optimize_function_for_size_p (cfun)
9564 || !TARGET_PARTIAL_FLAG_REG_STALL
9565 || (operands[1] == const1_rtx
9567 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9569 switch (get_attr_type (insn))
9572 gcc_assert (operands[1] == const1_rtx);
9573 return "add{b}\t%0, %0";
9576 if (operands[1] == const1_rtx
9577 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9578 return "sal{b}\t%0";
9580 return "sal{b}\t{%1, %0|%0, %1}";
9584 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9585 (match_operand 0 "register_operand"))
9586 (match_operand 1 "const1_operand"))
9587 (const_string "alu")
9589 (const_string "ishift1")))
9590 (set (attr "length_immediate")
9592 (ior (eq_attr "type" "alu")
9593 (and (eq_attr "type" "ishift1")
9594 (and (match_operand 1 "const1_operand")
9595 (ior (match_test "TARGET_SHIFT1")
9596 (match_test "optimize_function_for_size_p (cfun)")))))
9598 (const_string "*")))
9599 (set_attr "mode" "QI")])
9601 ;; Convert ashift to the lea pattern to avoid flags dependency.
9603 [(set (match_operand 0 "register_operand")
9604 (ashift (match_operand 1 "index_register_operand")
9605 (match_operand:QI 2 "const_int_operand")))
9606 (clobber (reg:CC FLAGS_REG))]
9607 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9609 && true_regnum (operands[0]) != true_regnum (operands[1])"
9612 enum machine_mode mode = GET_MODE (operands[0]);
9615 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9618 operands[0] = gen_lowpart (mode, operands[0]);
9619 operands[1] = gen_lowpart (mode, operands[1]);
9622 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9624 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9626 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9630 ;; Convert ashift to the lea pattern to avoid flags dependency.
9632 [(set (match_operand:DI 0 "register_operand")
9634 (ashift:SI (match_operand:SI 1 "index_register_operand")
9635 (match_operand:QI 2 "const_int_operand"))))
9636 (clobber (reg:CC FLAGS_REG))]
9637 "TARGET_64BIT && reload_completed
9638 && true_regnum (operands[0]) != true_regnum (operands[1])"
9640 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9642 operands[1] = gen_lowpart (SImode, operands[1]);
9643 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9646 ;; This pattern can't accept a variable shift count, since shifts by
9647 ;; zero don't affect the flags. We assume that shifts by constant
9648 ;; zero are optimized away.
9649 (define_insn "*ashl<mode>3_cmp"
9650 [(set (reg FLAGS_REG)
9652 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9653 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9655 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9656 (ashift:SWI (match_dup 1) (match_dup 2)))]
9657 "(optimize_function_for_size_p (cfun)
9658 || !TARGET_PARTIAL_FLAG_REG_STALL
9659 || (operands[2] == const1_rtx
9661 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9662 && ix86_match_ccmode (insn, CCGOCmode)
9663 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9665 switch (get_attr_type (insn))
9668 gcc_assert (operands[2] == const1_rtx);
9669 return "add{<imodesuffix>}\t%0, %0";
9672 if (operands[2] == const1_rtx
9673 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9674 return "sal{<imodesuffix>}\t%0";
9676 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9680 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9681 (match_operand 0 "register_operand"))
9682 (match_operand 2 "const1_operand"))
9683 (const_string "alu")
9685 (const_string "ishift")))
9686 (set (attr "length_immediate")
9688 (ior (eq_attr "type" "alu")
9689 (and (eq_attr "type" "ishift")
9690 (and (match_operand 2 "const1_operand")
9691 (ior (match_test "TARGET_SHIFT1")
9692 (match_test "optimize_function_for_size_p (cfun)")))))
9694 (const_string "*")))
9695 (set_attr "mode" "<MODE>")])
9697 (define_insn "*ashlsi3_cmp_zext"
9698 [(set (reg FLAGS_REG)
9700 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9701 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9703 (set (match_operand:DI 0 "register_operand" "=r")
9704 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9706 && (optimize_function_for_size_p (cfun)
9707 || !TARGET_PARTIAL_FLAG_REG_STALL
9708 || (operands[2] == const1_rtx
9710 || TARGET_DOUBLE_WITH_ADD)))
9711 && ix86_match_ccmode (insn, CCGOCmode)
9712 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9714 switch (get_attr_type (insn))
9717 gcc_assert (operands[2] == const1_rtx);
9718 return "add{l}\t%k0, %k0";
9721 if (operands[2] == const1_rtx
9722 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9723 return "sal{l}\t%k0";
9725 return "sal{l}\t{%2, %k0|%k0, %2}";
9729 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9730 (match_operand 2 "const1_operand"))
9731 (const_string "alu")
9733 (const_string "ishift")))
9734 (set (attr "length_immediate")
9736 (ior (eq_attr "type" "alu")
9737 (and (eq_attr "type" "ishift")
9738 (and (match_operand 2 "const1_operand")
9739 (ior (match_test "TARGET_SHIFT1")
9740 (match_test "optimize_function_for_size_p (cfun)")))))
9742 (const_string "*")))
9743 (set_attr "mode" "SI")])
9745 (define_insn "*ashl<mode>3_cconly"
9746 [(set (reg FLAGS_REG)
9748 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9749 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9751 (clobber (match_scratch:SWI 0 "=<r>"))]
9752 "(optimize_function_for_size_p (cfun)
9753 || !TARGET_PARTIAL_FLAG_REG_STALL
9754 || (operands[2] == const1_rtx
9756 || TARGET_DOUBLE_WITH_ADD)))
9757 && ix86_match_ccmode (insn, CCGOCmode)"
9759 switch (get_attr_type (insn))
9762 gcc_assert (operands[2] == const1_rtx);
9763 return "add{<imodesuffix>}\t%0, %0";
9766 if (operands[2] == const1_rtx
9767 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9768 return "sal{<imodesuffix>}\t%0";
9770 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9774 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9775 (match_operand 0 "register_operand"))
9776 (match_operand 2 "const1_operand"))
9777 (const_string "alu")
9779 (const_string "ishift")))
9780 (set (attr "length_immediate")
9782 (ior (eq_attr "type" "alu")
9783 (and (eq_attr "type" "ishift")
9784 (and (match_operand 2 "const1_operand")
9785 (ior (match_test "TARGET_SHIFT1")
9786 (match_test "optimize_function_for_size_p (cfun)")))))
9788 (const_string "*")))
9789 (set_attr "mode" "<MODE>")])
9791 ;; See comment above `ashl<mode>3' about how this works.
9793 (define_expand "<shift_insn><mode>3"
9794 [(set (match_operand:SDWIM 0 "<shift_operand>")
9795 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9796 (match_operand:QI 2 "nonmemory_operand")))]
9798 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9800 ;; Avoid useless masking of count operand.
9801 (define_insn "*<shift_insn><mode>3_mask"
9802 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9804 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9807 (match_operand:SI 2 "register_operand" "c")
9808 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9809 (clobber (reg:CC FLAGS_REG))]
9810 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9811 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9812 == GET_MODE_BITSIZE (<MODE>mode)-1"
9814 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9816 [(set_attr "type" "ishift")
9817 (set_attr "mode" "<MODE>")])
9819 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9820 [(set (match_operand:DWI 0 "register_operand" "=r")
9821 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9822 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9823 (clobber (reg:CC FLAGS_REG))]
9826 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9828 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9829 [(set_attr "type" "multi")])
9831 ;; By default we don't ask for a scratch register, because when DWImode
9832 ;; values are manipulated, registers are already at a premium. But if
9833 ;; we have one handy, we won't turn it away.
9836 [(match_scratch:DWIH 3 "r")
9837 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9839 (match_operand:<DWI> 1 "register_operand")
9840 (match_operand:QI 2 "nonmemory_operand")))
9841 (clobber (reg:CC FLAGS_REG))])
9845 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9847 (define_insn "x86_64_shrd"
9848 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9849 (ior:DI (ashiftrt:DI (match_dup 0)
9850 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9851 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9852 (minus:QI (const_int 64) (match_dup 2)))))
9853 (clobber (reg:CC FLAGS_REG))]
9855 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9856 [(set_attr "type" "ishift")
9857 (set_attr "prefix_0f" "1")
9858 (set_attr "mode" "DI")
9859 (set_attr "athlon_decode" "vector")
9860 (set_attr "amdfam10_decode" "vector")
9861 (set_attr "bdver1_decode" "vector")])
9863 (define_insn "x86_shrd"
9864 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9865 (ior:SI (ashiftrt:SI (match_dup 0)
9866 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9867 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9868 (minus:QI (const_int 32) (match_dup 2)))))
9869 (clobber (reg:CC FLAGS_REG))]
9871 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9872 [(set_attr "type" "ishift")
9873 (set_attr "prefix_0f" "1")
9874 (set_attr "mode" "SI")
9875 (set_attr "pent_pair" "np")
9876 (set_attr "athlon_decode" "vector")
9877 (set_attr "amdfam10_decode" "vector")
9878 (set_attr "bdver1_decode" "vector")])
9880 (define_insn "ashrdi3_cvt"
9881 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9882 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9883 (match_operand:QI 2 "const_int_operand")))
9884 (clobber (reg:CC FLAGS_REG))]
9885 "TARGET_64BIT && INTVAL (operands[2]) == 63
9886 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9887 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9890 sar{q}\t{%2, %0|%0, %2}"
9891 [(set_attr "type" "imovx,ishift")
9892 (set_attr "prefix_0f" "0,*")
9893 (set_attr "length_immediate" "0,*")
9894 (set_attr "modrm" "0,1")
9895 (set_attr "mode" "DI")])
9897 (define_insn "ashrsi3_cvt"
9898 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9899 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9900 (match_operand:QI 2 "const_int_operand")))
9901 (clobber (reg:CC FLAGS_REG))]
9902 "INTVAL (operands[2]) == 31
9903 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9904 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9907 sar{l}\t{%2, %0|%0, %2}"
9908 [(set_attr "type" "imovx,ishift")
9909 (set_attr "prefix_0f" "0,*")
9910 (set_attr "length_immediate" "0,*")
9911 (set_attr "modrm" "0,1")
9912 (set_attr "mode" "SI")])
9914 (define_insn "*ashrsi3_cvt_zext"
9915 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9917 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9918 (match_operand:QI 2 "const_int_operand"))))
9919 (clobber (reg:CC FLAGS_REG))]
9920 "TARGET_64BIT && INTVAL (operands[2]) == 31
9921 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9922 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9925 sar{l}\t{%2, %k0|%k0, %2}"
9926 [(set_attr "type" "imovx,ishift")
9927 (set_attr "prefix_0f" "0,*")
9928 (set_attr "length_immediate" "0,*")
9929 (set_attr "modrm" "0,1")
9930 (set_attr "mode" "SI")])
9932 (define_expand "x86_shift<mode>_adj_3"
9933 [(use (match_operand:SWI48 0 "register_operand"))
9934 (use (match_operand:SWI48 1 "register_operand"))
9935 (use (match_operand:QI 2 "register_operand"))]
9938 rtx label = gen_label_rtx ();
9941 emit_insn (gen_testqi_ccz_1 (operands[2],
9942 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9944 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9945 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9946 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9947 gen_rtx_LABEL_REF (VOIDmode, label),
9949 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9950 JUMP_LABEL (tmp) = label;
9952 emit_move_insn (operands[0], operands[1]);
9953 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9954 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9956 LABEL_NUSES (label) = 1;
9961 (define_insn "*bmi2_<shift_insn><mode>3_1"
9962 [(set (match_operand:SWI48 0 "register_operand" "=r")
9963 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9964 (match_operand:SWI48 2 "register_operand" "r")))]
9966 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9967 [(set_attr "type" "ishiftx")
9968 (set_attr "mode" "<MODE>")])
9970 (define_insn "*<shift_insn><mode>3_1"
9971 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9973 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9974 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9975 (clobber (reg:CC FLAGS_REG))]
9976 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9978 switch (get_attr_type (insn))
9984 if (operands[2] == const1_rtx
9985 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9986 return "<shift>{<imodesuffix>}\t%0";
9988 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9991 [(set_attr "isa" "*,bmi2")
9992 (set_attr "type" "ishift,ishiftx")
9993 (set (attr "length_immediate")
9995 (and (match_operand 2 "const1_operand")
9996 (ior (match_test "TARGET_SHIFT1")
9997 (match_test "optimize_function_for_size_p (cfun)")))
9999 (const_string "*")))
10000 (set_attr "mode" "<MODE>")])
10002 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10004 [(set (match_operand:SWI48 0 "register_operand")
10005 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10006 (match_operand:QI 2 "register_operand")))
10007 (clobber (reg:CC FLAGS_REG))]
10008 "TARGET_BMI2 && reload_completed"
10009 [(set (match_dup 0)
10010 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10011 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10013 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10014 [(set (match_operand:DI 0 "register_operand" "=r")
10016 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10017 (match_operand:SI 2 "register_operand" "r"))))]
10018 "TARGET_64BIT && TARGET_BMI2"
10019 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10020 [(set_attr "type" "ishiftx")
10021 (set_attr "mode" "SI")])
10023 (define_insn "*<shift_insn>si3_1_zext"
10024 [(set (match_operand:DI 0 "register_operand" "=r,r")
10026 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10027 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10028 (clobber (reg:CC FLAGS_REG))]
10029 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10031 switch (get_attr_type (insn))
10037 if (operands[2] == const1_rtx
10038 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10039 return "<shift>{l}\t%k0";
10041 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10044 [(set_attr "isa" "*,bmi2")
10045 (set_attr "type" "ishift,ishiftx")
10046 (set (attr "length_immediate")
10048 (and (match_operand 2 "const1_operand")
10049 (ior (match_test "TARGET_SHIFT1")
10050 (match_test "optimize_function_for_size_p (cfun)")))
10052 (const_string "*")))
10053 (set_attr "mode" "SI")])
10055 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10057 [(set (match_operand:DI 0 "register_operand")
10059 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10060 (match_operand:QI 2 "register_operand"))))
10061 (clobber (reg:CC FLAGS_REG))]
10062 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10063 [(set (match_dup 0)
10064 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10065 "operands[2] = gen_lowpart (SImode, operands[2]);")
10067 (define_insn "*<shift_insn><mode>3_1"
10068 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10070 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10071 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10072 (clobber (reg:CC FLAGS_REG))]
10073 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10075 if (operands[2] == const1_rtx
10076 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10077 return "<shift>{<imodesuffix>}\t%0";
10079 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10081 [(set_attr "type" "ishift")
10082 (set (attr "length_immediate")
10084 (and (match_operand 2 "const1_operand")
10085 (ior (match_test "TARGET_SHIFT1")
10086 (match_test "optimize_function_for_size_p (cfun)")))
10088 (const_string "*")))
10089 (set_attr "mode" "<MODE>")])
10091 (define_insn "*<shift_insn>qi3_1_slp"
10092 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10093 (any_shiftrt:QI (match_dup 0)
10094 (match_operand:QI 1 "nonmemory_operand" "cI")))
10095 (clobber (reg:CC FLAGS_REG))]
10096 "(optimize_function_for_size_p (cfun)
10097 || !TARGET_PARTIAL_REG_STALL
10098 || (operands[1] == const1_rtx
10099 && TARGET_SHIFT1))"
10101 if (operands[1] == const1_rtx
10102 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10103 return "<shift>{b}\t%0";
10105 return "<shift>{b}\t{%1, %0|%0, %1}";
10107 [(set_attr "type" "ishift1")
10108 (set (attr "length_immediate")
10110 (and (match_operand 1 "const1_operand")
10111 (ior (match_test "TARGET_SHIFT1")
10112 (match_test "optimize_function_for_size_p (cfun)")))
10114 (const_string "*")))
10115 (set_attr "mode" "QI")])
10117 ;; This pattern can't accept a variable shift count, since shifts by
10118 ;; zero don't affect the flags. We assume that shifts by constant
10119 ;; zero are optimized away.
10120 (define_insn "*<shift_insn><mode>3_cmp"
10121 [(set (reg FLAGS_REG)
10124 (match_operand:SWI 1 "nonimmediate_operand" "0")
10125 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10127 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10128 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10129 "(optimize_function_for_size_p (cfun)
10130 || !TARGET_PARTIAL_FLAG_REG_STALL
10131 || (operands[2] == const1_rtx
10133 && ix86_match_ccmode (insn, CCGOCmode)
10134 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10136 if (operands[2] == const1_rtx
10137 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10138 return "<shift>{<imodesuffix>}\t%0";
10140 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10142 [(set_attr "type" "ishift")
10143 (set (attr "length_immediate")
10145 (and (match_operand 2 "const1_operand")
10146 (ior (match_test "TARGET_SHIFT1")
10147 (match_test "optimize_function_for_size_p (cfun)")))
10149 (const_string "*")))
10150 (set_attr "mode" "<MODE>")])
10152 (define_insn "*<shift_insn>si3_cmp_zext"
10153 [(set (reg FLAGS_REG)
10155 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10156 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10158 (set (match_operand:DI 0 "register_operand" "=r")
10159 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10161 && (optimize_function_for_size_p (cfun)
10162 || !TARGET_PARTIAL_FLAG_REG_STALL
10163 || (operands[2] == const1_rtx
10165 && ix86_match_ccmode (insn, CCGOCmode)
10166 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10168 if (operands[2] == const1_rtx
10169 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10170 return "<shift>{l}\t%k0";
10172 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10174 [(set_attr "type" "ishift")
10175 (set (attr "length_immediate")
10177 (and (match_operand 2 "const1_operand")
10178 (ior (match_test "TARGET_SHIFT1")
10179 (match_test "optimize_function_for_size_p (cfun)")))
10181 (const_string "*")))
10182 (set_attr "mode" "SI")])
10184 (define_insn "*<shift_insn><mode>3_cconly"
10185 [(set (reg FLAGS_REG)
10188 (match_operand:SWI 1 "register_operand" "0")
10189 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10191 (clobber (match_scratch:SWI 0 "=<r>"))]
10192 "(optimize_function_for_size_p (cfun)
10193 || !TARGET_PARTIAL_FLAG_REG_STALL
10194 || (operands[2] == const1_rtx
10196 && ix86_match_ccmode (insn, CCGOCmode)"
10198 if (operands[2] == const1_rtx
10199 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10200 return "<shift>{<imodesuffix>}\t%0";
10202 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10204 [(set_attr "type" "ishift")
10205 (set (attr "length_immediate")
10207 (and (match_operand 2 "const1_operand")
10208 (ior (match_test "TARGET_SHIFT1")
10209 (match_test "optimize_function_for_size_p (cfun)")))
10211 (const_string "*")))
10212 (set_attr "mode" "<MODE>")])
10214 ;; Rotate instructions
10216 (define_expand "<rotate_insn>ti3"
10217 [(set (match_operand:TI 0 "register_operand")
10218 (any_rotate:TI (match_operand:TI 1 "register_operand")
10219 (match_operand:QI 2 "nonmemory_operand")))]
10222 if (const_1_to_63_operand (operands[2], VOIDmode))
10223 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10224 (operands[0], operands[1], operands[2]));
10231 (define_expand "<rotate_insn>di3"
10232 [(set (match_operand:DI 0 "shiftdi_operand")
10233 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10234 (match_operand:QI 2 "nonmemory_operand")))]
10238 ix86_expand_binary_operator (<CODE>, DImode, operands);
10239 else if (const_1_to_31_operand (operands[2], VOIDmode))
10240 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10241 (operands[0], operands[1], operands[2]));
10248 (define_expand "<rotate_insn><mode>3"
10249 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10250 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10251 (match_operand:QI 2 "nonmemory_operand")))]
10253 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10255 ;; Avoid useless masking of count operand.
10256 (define_insn "*<rotate_insn><mode>3_mask"
10257 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10259 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10262 (match_operand:SI 2 "register_operand" "c")
10263 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10264 (clobber (reg:CC FLAGS_REG))]
10265 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10266 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10267 == GET_MODE_BITSIZE (<MODE>mode)-1"
10269 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10271 [(set_attr "type" "rotate")
10272 (set_attr "mode" "<MODE>")])
10274 ;; Implement rotation using two double-precision
10275 ;; shift instructions and a scratch register.
10277 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10278 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10279 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10280 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10281 (clobber (reg:CC FLAGS_REG))
10282 (clobber (match_scratch:DWIH 3 "=&r"))]
10286 [(set (match_dup 3) (match_dup 4))
10288 [(set (match_dup 4)
10289 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10290 (lshiftrt:DWIH (match_dup 5)
10291 (minus:QI (match_dup 6) (match_dup 2)))))
10292 (clobber (reg:CC FLAGS_REG))])
10294 [(set (match_dup 5)
10295 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10296 (lshiftrt:DWIH (match_dup 3)
10297 (minus:QI (match_dup 6) (match_dup 2)))))
10298 (clobber (reg:CC FLAGS_REG))])]
10300 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10302 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10305 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10306 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10307 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10308 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10309 (clobber (reg:CC FLAGS_REG))
10310 (clobber (match_scratch:DWIH 3 "=&r"))]
10314 [(set (match_dup 3) (match_dup 4))
10316 [(set (match_dup 4)
10317 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10318 (ashift:DWIH (match_dup 5)
10319 (minus:QI (match_dup 6) (match_dup 2)))))
10320 (clobber (reg:CC FLAGS_REG))])
10322 [(set (match_dup 5)
10323 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10324 (ashift:DWIH (match_dup 3)
10325 (minus:QI (match_dup 6) (match_dup 2)))))
10326 (clobber (reg:CC FLAGS_REG))])]
10328 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10330 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10333 (define_insn "*bmi2_rorx<mode>3_1"
10334 [(set (match_operand:SWI48 0 "register_operand" "=r")
10335 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10336 (match_operand:QI 2 "immediate_operand" "<S>")))]
10338 "rorx\t{%2, %1, %0|%0, %1, %2}"
10339 [(set_attr "type" "rotatex")
10340 (set_attr "mode" "<MODE>")])
10342 (define_insn "*<rotate_insn><mode>3_1"
10343 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10345 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10346 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10347 (clobber (reg:CC FLAGS_REG))]
10348 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10350 switch (get_attr_type (insn))
10356 if (operands[2] == const1_rtx
10357 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10358 return "<rotate>{<imodesuffix>}\t%0";
10360 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10363 [(set_attr "isa" "*,bmi2")
10364 (set_attr "type" "rotate,rotatex")
10365 (set (attr "length_immediate")
10367 (and (eq_attr "type" "rotate")
10368 (and (match_operand 2 "const1_operand")
10369 (ior (match_test "TARGET_SHIFT1")
10370 (match_test "optimize_function_for_size_p (cfun)"))))
10372 (const_string "*")))
10373 (set_attr "mode" "<MODE>")])
10375 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10377 [(set (match_operand:SWI48 0 "register_operand")
10378 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10379 (match_operand:QI 2 "immediate_operand")))
10380 (clobber (reg:CC FLAGS_REG))]
10381 "TARGET_BMI2 && reload_completed"
10382 [(set (match_dup 0)
10383 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10386 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10390 [(set (match_operand:SWI48 0 "register_operand")
10391 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10392 (match_operand:QI 2 "immediate_operand")))
10393 (clobber (reg:CC FLAGS_REG))]
10394 "TARGET_BMI2 && reload_completed"
10395 [(set (match_dup 0)
10396 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10398 (define_insn "*bmi2_rorxsi3_1_zext"
10399 [(set (match_operand:DI 0 "register_operand" "=r")
10401 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10402 (match_operand:QI 2 "immediate_operand" "I"))))]
10403 "TARGET_64BIT && TARGET_BMI2"
10404 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10405 [(set_attr "type" "rotatex")
10406 (set_attr "mode" "SI")])
10408 (define_insn "*<rotate_insn>si3_1_zext"
10409 [(set (match_operand:DI 0 "register_operand" "=r,r")
10411 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10412 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10413 (clobber (reg:CC FLAGS_REG))]
10414 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10416 switch (get_attr_type (insn))
10422 if (operands[2] == const1_rtx
10423 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10424 return "<rotate>{l}\t%k0";
10426 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10429 [(set_attr "isa" "*,bmi2")
10430 (set_attr "type" "rotate,rotatex")
10431 (set (attr "length_immediate")
10433 (and (eq_attr "type" "rotate")
10434 (and (match_operand 2 "const1_operand")
10435 (ior (match_test "TARGET_SHIFT1")
10436 (match_test "optimize_function_for_size_p (cfun)"))))
10438 (const_string "*")))
10439 (set_attr "mode" "SI")])
10441 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10443 [(set (match_operand:DI 0 "register_operand")
10445 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10446 (match_operand:QI 2 "immediate_operand"))))
10447 (clobber (reg:CC FLAGS_REG))]
10448 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10449 [(set (match_dup 0)
10450 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10453 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10457 [(set (match_operand:DI 0 "register_operand")
10459 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10460 (match_operand:QI 2 "immediate_operand"))))
10461 (clobber (reg:CC FLAGS_REG))]
10462 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10463 [(set (match_dup 0)
10464 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10466 (define_insn "*<rotate_insn><mode>3_1"
10467 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10468 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10469 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10470 (clobber (reg:CC FLAGS_REG))]
10471 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10473 if (operands[2] == const1_rtx
10474 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10475 return "<rotate>{<imodesuffix>}\t%0";
10477 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10479 [(set_attr "type" "rotate")
10480 (set (attr "length_immediate")
10482 (and (match_operand 2 "const1_operand")
10483 (ior (match_test "TARGET_SHIFT1")
10484 (match_test "optimize_function_for_size_p (cfun)")))
10486 (const_string "*")))
10487 (set_attr "mode" "<MODE>")])
10489 (define_insn "*<rotate_insn>qi3_1_slp"
10490 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10491 (any_rotate:QI (match_dup 0)
10492 (match_operand:QI 1 "nonmemory_operand" "cI")))
10493 (clobber (reg:CC FLAGS_REG))]
10494 "(optimize_function_for_size_p (cfun)
10495 || !TARGET_PARTIAL_REG_STALL
10496 || (operands[1] == const1_rtx
10497 && TARGET_SHIFT1))"
10499 if (operands[1] == const1_rtx
10500 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10501 return "<rotate>{b}\t%0";
10503 return "<rotate>{b}\t{%1, %0|%0, %1}";
10505 [(set_attr "type" "rotate1")
10506 (set (attr "length_immediate")
10508 (and (match_operand 1 "const1_operand")
10509 (ior (match_test "TARGET_SHIFT1")
10510 (match_test "optimize_function_for_size_p (cfun)")))
10512 (const_string "*")))
10513 (set_attr "mode" "QI")])
10516 [(set (match_operand:HI 0 "register_operand")
10517 (any_rotate:HI (match_dup 0) (const_int 8)))
10518 (clobber (reg:CC FLAGS_REG))]
10520 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10521 [(parallel [(set (strict_low_part (match_dup 0))
10522 (bswap:HI (match_dup 0)))
10523 (clobber (reg:CC FLAGS_REG))])])
10525 ;; Bit set / bit test instructions
10527 (define_expand "extv"
10528 [(set (match_operand:SI 0 "register_operand")
10529 (sign_extract:SI (match_operand:SI 1 "register_operand")
10530 (match_operand:SI 2 "const8_operand")
10531 (match_operand:SI 3 "const8_operand")))]
10534 /* Handle extractions from %ah et al. */
10535 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10538 /* From mips.md: extract_bit_field doesn't verify that our source
10539 matches the predicate, so check it again here. */
10540 if (! ext_register_operand (operands[1], VOIDmode))
10544 (define_expand "extzv"
10545 [(set (match_operand:SI 0 "register_operand")
10546 (zero_extract:SI (match_operand 1 "ext_register_operand")
10547 (match_operand:SI 2 "const8_operand")
10548 (match_operand:SI 3 "const8_operand")))]
10551 /* Handle extractions from %ah et al. */
10552 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10555 /* From mips.md: extract_bit_field doesn't verify that our source
10556 matches the predicate, so check it again here. */
10557 if (! ext_register_operand (operands[1], VOIDmode))
10561 (define_expand "insv"
10562 [(set (zero_extract (match_operand 0 "register_operand")
10563 (match_operand 1 "const_int_operand")
10564 (match_operand 2 "const_int_operand"))
10565 (match_operand 3 "register_operand"))]
10568 rtx (*gen_mov_insv_1) (rtx, rtx);
10570 if (ix86_expand_pinsr (operands))
10573 /* Handle insertions to %ah et al. */
10574 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10577 /* From mips.md: insert_bit_field doesn't verify that our source
10578 matches the predicate, so check it again here. */
10579 if (! ext_register_operand (operands[0], VOIDmode))
10582 gen_mov_insv_1 = (TARGET_64BIT
10583 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10585 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10589 ;; %%% bts, btr, btc, bt.
10590 ;; In general these instructions are *slow* when applied to memory,
10591 ;; since they enforce atomic operation. When applied to registers,
10592 ;; it depends on the cpu implementation. They're never faster than
10593 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10594 ;; no point. But in 64-bit, we can't hold the relevant immediates
10595 ;; within the instruction itself, so operating on bits in the high
10596 ;; 32-bits of a register becomes easier.
10598 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10599 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10600 ;; negdf respectively, so they can never be disabled entirely.
10602 (define_insn "*btsq"
10603 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10605 (match_operand:DI 1 "const_0_to_63_operand"))
10607 (clobber (reg:CC FLAGS_REG))]
10608 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10609 "bts{q}\t{%1, %0|%0, %1}"
10610 [(set_attr "type" "alu1")
10611 (set_attr "prefix_0f" "1")
10612 (set_attr "mode" "DI")])
10614 (define_insn "*btrq"
10615 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10617 (match_operand:DI 1 "const_0_to_63_operand"))
10619 (clobber (reg:CC FLAGS_REG))]
10620 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10621 "btr{q}\t{%1, %0|%0, %1}"
10622 [(set_attr "type" "alu1")
10623 (set_attr "prefix_0f" "1")
10624 (set_attr "mode" "DI")])
10626 (define_insn "*btcq"
10627 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10629 (match_operand:DI 1 "const_0_to_63_operand"))
10630 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10631 (clobber (reg:CC FLAGS_REG))]
10632 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10633 "btc{q}\t{%1, %0|%0, %1}"
10634 [(set_attr "type" "alu1")
10635 (set_attr "prefix_0f" "1")
10636 (set_attr "mode" "DI")])
10638 ;; Allow Nocona to avoid these instructions if a register is available.
10641 [(match_scratch:DI 2 "r")
10642 (parallel [(set (zero_extract:DI
10643 (match_operand:DI 0 "register_operand")
10645 (match_operand:DI 1 "const_0_to_63_operand"))
10647 (clobber (reg:CC FLAGS_REG))])]
10648 "TARGET_64BIT && !TARGET_USE_BT"
10651 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10654 if (HOST_BITS_PER_WIDE_INT >= 64)
10655 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10656 else if (i < HOST_BITS_PER_WIDE_INT)
10657 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10659 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10661 op1 = immed_double_const (lo, hi, DImode);
10664 emit_move_insn (operands[2], op1);
10668 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10673 [(match_scratch:DI 2 "r")
10674 (parallel [(set (zero_extract:DI
10675 (match_operand:DI 0 "register_operand")
10677 (match_operand:DI 1 "const_0_to_63_operand"))
10679 (clobber (reg:CC FLAGS_REG))])]
10680 "TARGET_64BIT && !TARGET_USE_BT"
10683 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10686 if (HOST_BITS_PER_WIDE_INT >= 64)
10687 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10688 else if (i < HOST_BITS_PER_WIDE_INT)
10689 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10691 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10693 op1 = immed_double_const (~lo, ~hi, DImode);
10696 emit_move_insn (operands[2], op1);
10700 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10705 [(match_scratch:DI 2 "r")
10706 (parallel [(set (zero_extract:DI
10707 (match_operand:DI 0 "register_operand")
10709 (match_operand:DI 1 "const_0_to_63_operand"))
10710 (not:DI (zero_extract:DI
10711 (match_dup 0) (const_int 1) (match_dup 1))))
10712 (clobber (reg:CC FLAGS_REG))])]
10713 "TARGET_64BIT && !TARGET_USE_BT"
10716 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10719 if (HOST_BITS_PER_WIDE_INT >= 64)
10720 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10721 else if (i < HOST_BITS_PER_WIDE_INT)
10722 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10724 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10726 op1 = immed_double_const (lo, hi, DImode);
10729 emit_move_insn (operands[2], op1);
10733 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10737 (define_insn "*bt<mode>"
10738 [(set (reg:CCC FLAGS_REG)
10740 (zero_extract:SWI48
10741 (match_operand:SWI48 0 "register_operand" "r")
10743 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10745 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10746 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10747 [(set_attr "type" "alu1")
10748 (set_attr "prefix_0f" "1")
10749 (set_attr "mode" "<MODE>")])
10751 ;; Store-flag instructions.
10753 ;; For all sCOND expanders, also expand the compare or test insn that
10754 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10756 (define_insn_and_split "*setcc_di_1"
10757 [(set (match_operand:DI 0 "register_operand" "=q")
10758 (match_operator:DI 1 "ix86_comparison_operator"
10759 [(reg FLAGS_REG) (const_int 0)]))]
10760 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10762 "&& reload_completed"
10763 [(set (match_dup 2) (match_dup 1))
10764 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10766 PUT_MODE (operands[1], QImode);
10767 operands[2] = gen_lowpart (QImode, operands[0]);
10770 (define_insn_and_split "*setcc_si_1_and"
10771 [(set (match_operand:SI 0 "register_operand" "=q")
10772 (match_operator:SI 1 "ix86_comparison_operator"
10773 [(reg FLAGS_REG) (const_int 0)]))
10774 (clobber (reg:CC FLAGS_REG))]
10775 "!TARGET_PARTIAL_REG_STALL
10776 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10778 "&& reload_completed"
10779 [(set (match_dup 2) (match_dup 1))
10780 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10781 (clobber (reg:CC FLAGS_REG))])]
10783 PUT_MODE (operands[1], QImode);
10784 operands[2] = gen_lowpart (QImode, operands[0]);
10787 (define_insn_and_split "*setcc_si_1_movzbl"
10788 [(set (match_operand:SI 0 "register_operand" "=q")
10789 (match_operator:SI 1 "ix86_comparison_operator"
10790 [(reg FLAGS_REG) (const_int 0)]))]
10791 "!TARGET_PARTIAL_REG_STALL
10792 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10794 "&& reload_completed"
10795 [(set (match_dup 2) (match_dup 1))
10796 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10798 PUT_MODE (operands[1], QImode);
10799 operands[2] = gen_lowpart (QImode, operands[0]);
10802 (define_insn "*setcc_qi"
10803 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10804 (match_operator:QI 1 "ix86_comparison_operator"
10805 [(reg FLAGS_REG) (const_int 0)]))]
10808 [(set_attr "type" "setcc")
10809 (set_attr "mode" "QI")])
10811 (define_insn "*setcc_qi_slp"
10812 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10813 (match_operator:QI 1 "ix86_comparison_operator"
10814 [(reg FLAGS_REG) (const_int 0)]))]
10817 [(set_attr "type" "setcc")
10818 (set_attr "mode" "QI")])
10820 ;; In general it is not safe to assume too much about CCmode registers,
10821 ;; so simplify-rtx stops when it sees a second one. Under certain
10822 ;; conditions this is safe on x86, so help combine not create
10829 [(set (match_operand:QI 0 "nonimmediate_operand")
10830 (ne:QI (match_operator 1 "ix86_comparison_operator"
10831 [(reg FLAGS_REG) (const_int 0)])
10834 [(set (match_dup 0) (match_dup 1))]
10835 "PUT_MODE (operands[1], QImode);")
10838 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10839 (ne:QI (match_operator 1 "ix86_comparison_operator"
10840 [(reg FLAGS_REG) (const_int 0)])
10843 [(set (match_dup 0) (match_dup 1))]
10844 "PUT_MODE (operands[1], QImode);")
10847 [(set (match_operand:QI 0 "nonimmediate_operand")
10848 (eq:QI (match_operator 1 "ix86_comparison_operator"
10849 [(reg FLAGS_REG) (const_int 0)])
10852 [(set (match_dup 0) (match_dup 1))]
10854 rtx new_op1 = copy_rtx (operands[1]);
10855 operands[1] = new_op1;
10856 PUT_MODE (new_op1, QImode);
10857 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10858 GET_MODE (XEXP (new_op1, 0))));
10860 /* Make sure that (a) the CCmode we have for the flags is strong
10861 enough for the reversed compare or (b) we have a valid FP compare. */
10862 if (! ix86_comparison_operator (new_op1, VOIDmode))
10867 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10868 (eq:QI (match_operator 1 "ix86_comparison_operator"
10869 [(reg FLAGS_REG) (const_int 0)])
10872 [(set (match_dup 0) (match_dup 1))]
10874 rtx new_op1 = copy_rtx (operands[1]);
10875 operands[1] = new_op1;
10876 PUT_MODE (new_op1, QImode);
10877 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10878 GET_MODE (XEXP (new_op1, 0))));
10880 /* Make sure that (a) the CCmode we have for the flags is strong
10881 enough for the reversed compare or (b) we have a valid FP compare. */
10882 if (! ix86_comparison_operator (new_op1, VOIDmode))
10886 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10887 ;; subsequent logical operations are used to imitate conditional moves.
10888 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10891 (define_insn "setcc_<mode>_sse"
10892 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10893 (match_operator:MODEF 3 "sse_comparison_operator"
10894 [(match_operand:MODEF 1 "register_operand" "0,x")
10895 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10896 "SSE_FLOAT_MODE_P (<MODE>mode)"
10898 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10899 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10900 [(set_attr "isa" "noavx,avx")
10901 (set_attr "type" "ssecmp")
10902 (set_attr "length_immediate" "1")
10903 (set_attr "prefix" "orig,vex")
10904 (set_attr "mode" "<MODE>")])
10906 ;; Basic conditional jump instructions.
10907 ;; We ignore the overflow flag for signed branch instructions.
10909 (define_insn "*jcc_1"
10911 (if_then_else (match_operator 1 "ix86_comparison_operator"
10912 [(reg FLAGS_REG) (const_int 0)])
10913 (label_ref (match_operand 0))
10917 [(set_attr "type" "ibr")
10918 (set_attr "modrm" "0")
10919 (set (attr "length")
10920 (if_then_else (and (ge (minus (match_dup 0) (pc))
10922 (lt (minus (match_dup 0) (pc))
10927 (define_insn "*jcc_2"
10929 (if_then_else (match_operator 1 "ix86_comparison_operator"
10930 [(reg FLAGS_REG) (const_int 0)])
10932 (label_ref (match_operand 0))))]
10935 [(set_attr "type" "ibr")
10936 (set_attr "modrm" "0")
10937 (set (attr "length")
10938 (if_then_else (and (ge (minus (match_dup 0) (pc))
10940 (lt (minus (match_dup 0) (pc))
10945 ;; In general it is not safe to assume too much about CCmode registers,
10946 ;; so simplify-rtx stops when it sees a second one. Under certain
10947 ;; conditions this is safe on x86, so help combine not create
10955 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10956 [(reg FLAGS_REG) (const_int 0)])
10958 (label_ref (match_operand 1))
10962 (if_then_else (match_dup 0)
10963 (label_ref (match_dup 1))
10965 "PUT_MODE (operands[0], VOIDmode);")
10969 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10970 [(reg FLAGS_REG) (const_int 0)])
10972 (label_ref (match_operand 1))
10976 (if_then_else (match_dup 0)
10977 (label_ref (match_dup 1))
10980 rtx new_op0 = copy_rtx (operands[0]);
10981 operands[0] = new_op0;
10982 PUT_MODE (new_op0, VOIDmode);
10983 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10984 GET_MODE (XEXP (new_op0, 0))));
10986 /* Make sure that (a) the CCmode we have for the flags is strong
10987 enough for the reversed compare or (b) we have a valid FP compare. */
10988 if (! ix86_comparison_operator (new_op0, VOIDmode))
10992 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10993 ;; pass generates from shift insn with QImode operand. Actually, the mode
10994 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10995 ;; appropriate modulo of the bit offset value.
10997 (define_insn_and_split "*jcc_bt<mode>"
10999 (if_then_else (match_operator 0 "bt_comparison_operator"
11000 [(zero_extract:SWI48
11001 (match_operand:SWI48 1 "register_operand" "r")
11004 (match_operand:QI 2 "register_operand" "r")))
11006 (label_ref (match_operand 3))
11008 (clobber (reg:CC FLAGS_REG))]
11009 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11012 [(set (reg:CCC FLAGS_REG)
11014 (zero_extract:SWI48
11020 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11021 (label_ref (match_dup 3))
11024 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11026 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11029 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
11030 ;; zero extended to SImode.
11031 (define_insn_and_split "*jcc_bt<mode>_1"
11033 (if_then_else (match_operator 0 "bt_comparison_operator"
11034 [(zero_extract:SWI48
11035 (match_operand:SWI48 1 "register_operand" "r")
11037 (match_operand:SI 2 "register_operand" "r"))
11039 (label_ref (match_operand 3))
11041 (clobber (reg:CC FLAGS_REG))]
11042 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11045 [(set (reg:CCC FLAGS_REG)
11047 (zero_extract:SWI48
11053 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11054 (label_ref (match_dup 3))
11057 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11059 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11062 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
11063 ;; also for DImode, this is what combine produces.
11064 (define_insn_and_split "*jcc_bt<mode>_mask"
11066 (if_then_else (match_operator 0 "bt_comparison_operator"
11067 [(zero_extract:SWI48
11068 (match_operand:SWI48 1 "register_operand" "r")
11071 (match_operand:SI 2 "register_operand" "r")
11072 (match_operand:SI 3 "const_int_operand" "n")))])
11073 (label_ref (match_operand 4))
11075 (clobber (reg:CC FLAGS_REG))]
11076 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11077 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11078 == GET_MODE_BITSIZE (<MODE>mode)-1"
11081 [(set (reg:CCC FLAGS_REG)
11083 (zero_extract:SWI48
11089 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11090 (label_ref (match_dup 4))
11093 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11095 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11098 (define_insn_and_split "*jcc_btsi_1"
11100 (if_then_else (match_operator 0 "bt_comparison_operator"
11103 (match_operand:SI 1 "register_operand" "r")
11104 (match_operand:QI 2 "register_operand" "r"))
11107 (label_ref (match_operand 3))
11109 (clobber (reg:CC FLAGS_REG))]
11110 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11113 [(set (reg:CCC FLAGS_REG)
11121 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11122 (label_ref (match_dup 3))
11125 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11127 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11130 ;; avoid useless masking of bit offset operand
11131 (define_insn_and_split "*jcc_btsi_mask_1"
11134 (match_operator 0 "bt_comparison_operator"
11137 (match_operand:SI 1 "register_operand" "r")
11140 (match_operand:SI 2 "register_operand" "r")
11141 (match_operand:SI 3 "const_int_operand" "n")) 0))
11144 (label_ref (match_operand 4))
11146 (clobber (reg:CC FLAGS_REG))]
11147 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11148 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11151 [(set (reg:CCC FLAGS_REG)
11159 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11160 (label_ref (match_dup 4))
11162 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11164 ;; Define combination compare-and-branch fp compare instructions to help
11167 (define_insn "*jcc<mode>_0_i387"
11169 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11170 [(match_operand:X87MODEF 1 "register_operand" "f")
11171 (match_operand:X87MODEF 2 "const0_operand")])
11172 (label_ref (match_operand 3))
11174 (clobber (reg:CCFP FPSR_REG))
11175 (clobber (reg:CCFP FLAGS_REG))
11176 (clobber (match_scratch:HI 4 "=a"))]
11177 "TARGET_80387 && !TARGET_CMOVE"
11180 (define_insn "*jcc<mode>_0_r_i387"
11182 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11183 [(match_operand:X87MODEF 1 "register_operand" "f")
11184 (match_operand:X87MODEF 2 "const0_operand")])
11186 (label_ref (match_operand 3))))
11187 (clobber (reg:CCFP FPSR_REG))
11188 (clobber (reg:CCFP FLAGS_REG))
11189 (clobber (match_scratch:HI 4 "=a"))]
11190 "TARGET_80387 && !TARGET_CMOVE"
11193 (define_insn "*jccxf_i387"
11195 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11196 [(match_operand:XF 1 "register_operand" "f")
11197 (match_operand:XF 2 "register_operand" "f")])
11198 (label_ref (match_operand 3))
11200 (clobber (reg:CCFP FPSR_REG))
11201 (clobber (reg:CCFP FLAGS_REG))
11202 (clobber (match_scratch:HI 4 "=a"))]
11203 "TARGET_80387 && !TARGET_CMOVE"
11206 (define_insn "*jccxf_r_i387"
11208 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11209 [(match_operand:XF 1 "register_operand" "f")
11210 (match_operand:XF 2 "register_operand" "f")])
11212 (label_ref (match_operand 3))))
11213 (clobber (reg:CCFP FPSR_REG))
11214 (clobber (reg:CCFP FLAGS_REG))
11215 (clobber (match_scratch:HI 4 "=a"))]
11216 "TARGET_80387 && !TARGET_CMOVE"
11219 (define_insn "*jcc<mode>_i387"
11221 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11222 [(match_operand:MODEF 1 "register_operand" "f")
11223 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11224 (label_ref (match_operand 3))
11226 (clobber (reg:CCFP FPSR_REG))
11227 (clobber (reg:CCFP FLAGS_REG))
11228 (clobber (match_scratch:HI 4 "=a"))]
11229 "TARGET_80387 && !TARGET_CMOVE"
11232 (define_insn "*jcc<mode>_r_i387"
11234 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11235 [(match_operand:MODEF 1 "register_operand" "f")
11236 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11238 (label_ref (match_operand 3))))
11239 (clobber (reg:CCFP FPSR_REG))
11240 (clobber (reg:CCFP FLAGS_REG))
11241 (clobber (match_scratch:HI 4 "=a"))]
11242 "TARGET_80387 && !TARGET_CMOVE"
11245 (define_insn "*jccu<mode>_i387"
11247 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11248 [(match_operand:X87MODEF 1 "register_operand" "f")
11249 (match_operand:X87MODEF 2 "register_operand" "f")])
11250 (label_ref (match_operand 3))
11252 (clobber (reg:CCFP FPSR_REG))
11253 (clobber (reg:CCFP FLAGS_REG))
11254 (clobber (match_scratch:HI 4 "=a"))]
11255 "TARGET_80387 && !TARGET_CMOVE"
11258 (define_insn "*jccu<mode>_r_i387"
11260 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11261 [(match_operand:X87MODEF 1 "register_operand" "f")
11262 (match_operand:X87MODEF 2 "register_operand" "f")])
11264 (label_ref (match_operand 3))))
11265 (clobber (reg:CCFP FPSR_REG))
11266 (clobber (reg:CCFP FLAGS_REG))
11267 (clobber (match_scratch:HI 4 "=a"))]
11268 "TARGET_80387 && !TARGET_CMOVE"
11273 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11274 [(match_operand:X87MODEF 1 "register_operand")
11275 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11277 (match_operand 4)))
11278 (clobber (reg:CCFP FPSR_REG))
11279 (clobber (reg:CCFP FLAGS_REG))]
11280 "TARGET_80387 && !TARGET_CMOVE
11281 && reload_completed"
11284 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11285 operands[3], operands[4], NULL_RTX, NULL_RTX);
11291 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11292 [(match_operand:X87MODEF 1 "register_operand")
11293 (match_operand:X87MODEF 2 "general_operand")])
11295 (match_operand 4)))
11296 (clobber (reg:CCFP FPSR_REG))
11297 (clobber (reg:CCFP FLAGS_REG))
11298 (clobber (match_scratch:HI 5))]
11299 "TARGET_80387 && !TARGET_CMOVE
11300 && reload_completed"
11303 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11304 operands[3], operands[4], operands[5], NULL_RTX);
11308 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11309 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11310 ;; with a precedence over other operators and is always put in the first
11311 ;; place. Swap condition and operands to match ficom instruction.
11313 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11316 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11317 [(match_operator:X87MODEF 1 "float_operator"
11318 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11319 (match_operand:X87MODEF 3 "register_operand" "f,f")])
11320 (label_ref (match_operand 4))
11322 (clobber (reg:CCFP FPSR_REG))
11323 (clobber (reg:CCFP FLAGS_REG))
11324 (clobber (match_scratch:HI 5 "=a,a"))]
11325 "TARGET_80387 && !TARGET_CMOVE
11326 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11327 || optimize_function_for_size_p (cfun))"
11330 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11333 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11334 [(match_operator:X87MODEF 1 "float_operator"
11335 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11336 (match_operand:X87MODEF 3 "register_operand" "f,f")])
11338 (label_ref (match_operand 4))))
11339 (clobber (reg:CCFP FPSR_REG))
11340 (clobber (reg:CCFP FLAGS_REG))
11341 (clobber (match_scratch:HI 5 "=a,a"))]
11342 "TARGET_80387 && !TARGET_CMOVE
11343 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11344 || optimize_function_for_size_p (cfun))"
11350 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11351 [(match_operator:X87MODEF 1 "float_operator"
11352 [(match_operand:SWI24 2 "memory_operand")])
11353 (match_operand:X87MODEF 3 "register_operand")])
11355 (match_operand 5)))
11356 (clobber (reg:CCFP FPSR_REG))
11357 (clobber (reg:CCFP FLAGS_REG))
11358 (clobber (match_scratch:HI 6))]
11359 "TARGET_80387 && !TARGET_CMOVE
11360 && reload_completed"
11363 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11364 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11365 operands[4], operands[5], operands[6], NULL_RTX);
11369 ;; %%% Kill this when reload knows how to do it.
11373 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11374 [(match_operator:X87MODEF 1 "float_operator"
11375 [(match_operand:SWI24 2 "register_operand")])
11376 (match_operand:X87MODEF 3 "register_operand")])
11378 (match_operand 5)))
11379 (clobber (reg:CCFP FPSR_REG))
11380 (clobber (reg:CCFP FLAGS_REG))
11381 (clobber (match_scratch:HI 6))]
11382 "TARGET_80387 && !TARGET_CMOVE
11383 && reload_completed"
11386 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11388 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11389 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
11390 operands[4], operands[5], operands[6], operands[2]);
11394 ;; Unconditional and other jump instructions
11396 (define_insn "jump"
11398 (label_ref (match_operand 0)))]
11401 [(set_attr "type" "ibr")
11402 (set (attr "length")
11403 (if_then_else (and (ge (minus (match_dup 0) (pc))
11405 (lt (minus (match_dup 0) (pc))
11409 (set_attr "modrm" "0")])
11411 (define_expand "indirect_jump"
11412 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11416 operands[0] = convert_memory_address (word_mode, operands[0]);
11419 (define_insn "*indirect_jump"
11420 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11423 [(set_attr "type" "ibr")
11424 (set_attr "length_immediate" "0")])
11426 (define_expand "tablejump"
11427 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11428 (use (label_ref (match_operand 1)))])]
11431 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11432 relative. Convert the relative address to an absolute address. */
11436 enum rtx_code code;
11438 /* We can't use @GOTOFF for text labels on VxWorks;
11439 see gotoff_operand. */
11440 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11444 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11446 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11450 op1 = pic_offset_table_rtx;
11455 op0 = pic_offset_table_rtx;
11459 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11464 operands[0] = convert_memory_address (word_mode, operands[0]);
11467 (define_insn "*tablejump_1"
11468 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11469 (use (label_ref (match_operand 1)))]
11472 [(set_attr "type" "ibr")
11473 (set_attr "length_immediate" "0")])
11475 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11478 [(set (reg FLAGS_REG) (match_operand 0))
11479 (set (match_operand:QI 1 "register_operand")
11480 (match_operator:QI 2 "ix86_comparison_operator"
11481 [(reg FLAGS_REG) (const_int 0)]))
11482 (set (match_operand 3 "q_regs_operand")
11483 (zero_extend (match_dup 1)))]
11484 "(peep2_reg_dead_p (3, operands[1])
11485 || operands_match_p (operands[1], operands[3]))
11486 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11487 [(set (match_dup 4) (match_dup 0))
11488 (set (strict_low_part (match_dup 5))
11491 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11492 operands[5] = gen_lowpart (QImode, operands[3]);
11493 ix86_expand_clear (operands[3]);
11497 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11498 (match_operand 4)])
11499 (set (match_operand:QI 1 "register_operand")
11500 (match_operator:QI 2 "ix86_comparison_operator"
11501 [(reg FLAGS_REG) (const_int 0)]))
11502 (set (match_operand 3 "q_regs_operand")
11503 (zero_extend (match_dup 1)))]
11504 "(peep2_reg_dead_p (3, operands[1])
11505 || operands_match_p (operands[1], operands[3]))
11506 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11507 [(parallel [(set (match_dup 5) (match_dup 0))
11509 (set (strict_low_part (match_dup 6))
11512 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11513 operands[6] = gen_lowpart (QImode, operands[3]);
11514 ix86_expand_clear (operands[3]);
11517 ;; Similar, but match zero extend with andsi3.
11520 [(set (reg FLAGS_REG) (match_operand 0))
11521 (set (match_operand:QI 1 "register_operand")
11522 (match_operator:QI 2 "ix86_comparison_operator"
11523 [(reg FLAGS_REG) (const_int 0)]))
11524 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11525 (and:SI (match_dup 3) (const_int 255)))
11526 (clobber (reg:CC FLAGS_REG))])]
11527 "REGNO (operands[1]) == REGNO (operands[3])
11528 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11529 [(set (match_dup 4) (match_dup 0))
11530 (set (strict_low_part (match_dup 5))
11533 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11534 operands[5] = gen_lowpart (QImode, operands[3]);
11535 ix86_expand_clear (operands[3]);
11539 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11540 (match_operand 4)])
11541 (set (match_operand:QI 1 "register_operand")
11542 (match_operator:QI 2 "ix86_comparison_operator"
11543 [(reg FLAGS_REG) (const_int 0)]))
11544 (parallel [(set (match_operand 3 "q_regs_operand")
11545 (zero_extend (match_dup 1)))
11546 (clobber (reg:CC FLAGS_REG))])]
11547 "(peep2_reg_dead_p (3, operands[1])
11548 || operands_match_p (operands[1], operands[3]))
11549 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11550 [(parallel [(set (match_dup 5) (match_dup 0))
11552 (set (strict_low_part (match_dup 6))
11555 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11556 operands[6] = gen_lowpart (QImode, operands[3]);
11557 ix86_expand_clear (operands[3]);
11560 ;; Call instructions.
11562 ;; The predicates normally associated with named expanders are not properly
11563 ;; checked for calls. This is a bug in the generic code, but it isn't that
11564 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11566 ;; P6 processors will jump to the address after the decrement when %esp
11567 ;; is used as a call operand, so they will execute return address as a code.
11568 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11570 ;; Register constraint for call instruction.
11571 (define_mode_attr c [(SI "l") (DI "r")])
11573 ;; Call subroutine returning no value.
11575 (define_expand "call"
11576 [(call (match_operand:QI 0)
11578 (use (match_operand 2))]
11581 ix86_expand_call (NULL, operands[0], operands[1],
11582 operands[2], NULL, false);
11586 (define_expand "sibcall"
11587 [(call (match_operand:QI 0)
11589 (use (match_operand 2))]
11592 ix86_expand_call (NULL, operands[0], operands[1],
11593 operands[2], NULL, true);
11597 (define_insn "*call"
11598 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11599 (match_operand 1))]
11600 "!SIBLING_CALL_P (insn)"
11601 "* return ix86_output_call_insn (insn, operands[0]);"
11602 [(set_attr "type" "call")])
11604 (define_insn "*call_rex64_ms_sysv"
11605 [(match_parallel 2 "call_rex64_ms_sysv_operation"
11606 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11608 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11609 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11610 "* return ix86_output_call_insn (insn, operands[0]);"
11611 [(set_attr "type" "call")])
11613 (define_insn "*sibcall"
11614 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11615 (match_operand 1))]
11616 "SIBLING_CALL_P (insn)"
11617 "* return ix86_output_call_insn (insn, operands[0]);"
11618 [(set_attr "type" "call")])
11620 (define_expand "call_pop"
11621 [(parallel [(call (match_operand:QI 0)
11622 (match_operand:SI 1))
11623 (set (reg:SI SP_REG)
11624 (plus:SI (reg:SI SP_REG)
11625 (match_operand:SI 3)))])]
11628 ix86_expand_call (NULL, operands[0], operands[1],
11629 operands[2], operands[3], false);
11633 (define_insn "*call_pop"
11634 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11636 (set (reg:SI SP_REG)
11637 (plus:SI (reg:SI SP_REG)
11638 (match_operand:SI 2 "immediate_operand" "i")))]
11639 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11640 "* return ix86_output_call_insn (insn, operands[0]);"
11641 [(set_attr "type" "call")])
11643 (define_insn "*sibcall_pop"
11644 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11646 (set (reg:SI SP_REG)
11647 (plus:SI (reg:SI SP_REG)
11648 (match_operand:SI 2 "immediate_operand" "i")))]
11649 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11650 "* return ix86_output_call_insn (insn, operands[0]);"
11651 [(set_attr "type" "call")])
11653 ;; Call subroutine, returning value in operand 0
11655 (define_expand "call_value"
11656 [(set (match_operand 0)
11657 (call (match_operand:QI 1)
11658 (match_operand 2)))
11659 (use (match_operand 3))]
11662 ix86_expand_call (operands[0], operands[1], operands[2],
11663 operands[3], NULL, false);
11667 (define_expand "sibcall_value"
11668 [(set (match_operand 0)
11669 (call (match_operand:QI 1)
11670 (match_operand 2)))
11671 (use (match_operand 3))]
11674 ix86_expand_call (operands[0], operands[1], operands[2],
11675 operands[3], NULL, true);
11679 (define_insn "*call_value"
11680 [(set (match_operand 0)
11681 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11682 (match_operand 2)))]
11683 "!SIBLING_CALL_P (insn)"
11684 "* return ix86_output_call_insn (insn, operands[1]);"
11685 [(set_attr "type" "callv")])
11687 (define_insn "*sibcall_value"
11688 [(set (match_operand 0)
11689 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11690 (match_operand 2)))]
11691 "SIBLING_CALL_P (insn)"
11692 "* return ix86_output_call_insn (insn, operands[1]);"
11693 [(set_attr "type" "callv")])
11695 (define_insn "*call_value_rex64_ms_sysv"
11696 [(match_parallel 3 "call_rex64_ms_sysv_operation"
11697 [(set (match_operand 0)
11698 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11699 (match_operand 2)))
11700 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11701 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11702 "* return ix86_output_call_insn (insn, operands[1]);"
11703 [(set_attr "type" "callv")])
11705 (define_expand "call_value_pop"
11706 [(parallel [(set (match_operand 0)
11707 (call (match_operand:QI 1)
11708 (match_operand:SI 2)))
11709 (set (reg:SI SP_REG)
11710 (plus:SI (reg:SI SP_REG)
11711 (match_operand:SI 4)))])]
11714 ix86_expand_call (operands[0], operands[1], operands[2],
11715 operands[3], operands[4], false);
11719 (define_insn "*call_value_pop"
11720 [(set (match_operand 0)
11721 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11722 (match_operand 2)))
11723 (set (reg:SI SP_REG)
11724 (plus:SI (reg:SI SP_REG)
11725 (match_operand:SI 3 "immediate_operand" "i")))]
11726 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11727 "* return ix86_output_call_insn (insn, operands[1]);"
11728 [(set_attr "type" "callv")])
11730 (define_insn "*sibcall_value_pop"
11731 [(set (match_operand 0)
11732 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11733 (match_operand 2)))
11734 (set (reg:SI SP_REG)
11735 (plus:SI (reg:SI SP_REG)
11736 (match_operand:SI 3 "immediate_operand" "i")))]
11737 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11738 "* return ix86_output_call_insn (insn, operands[1]);"
11739 [(set_attr "type" "callv")])
11741 ;; Call subroutine returning any type.
11743 (define_expand "untyped_call"
11744 [(parallel [(call (match_operand 0)
11747 (match_operand 2)])]
11752 /* In order to give reg-stack an easier job in validating two
11753 coprocessor registers as containing a possible return value,
11754 simply pretend the untyped call returns a complex long double
11757 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11758 and should have the default ABI. */
11760 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11761 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11762 operands[0], const0_rtx,
11763 GEN_INT ((TARGET_64BIT
11764 ? (ix86_abi == SYSV_ABI
11765 ? X86_64_SSE_REGPARM_MAX
11766 : X86_64_MS_SSE_REGPARM_MAX)
11767 : X86_32_SSE_REGPARM_MAX)
11771 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11773 rtx set = XVECEXP (operands[2], 0, i);
11774 emit_move_insn (SET_DEST (set), SET_SRC (set));
11777 /* The optimizer does not know that the call sets the function value
11778 registers we stored in the result block. We avoid problems by
11779 claiming that all hard registers are used and clobbered at this
11781 emit_insn (gen_blockage ());
11786 ;; Prologue and epilogue instructions
11788 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11789 ;; all of memory. This blocks insns from being moved across this point.
11791 (define_insn "blockage"
11792 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11795 [(set_attr "length" "0")])
11797 ;; Do not schedule instructions accessing memory across this point.
11799 (define_expand "memory_blockage"
11800 [(set (match_dup 0)
11801 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11804 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11805 MEM_VOLATILE_P (operands[0]) = 1;
11808 (define_insn "*memory_blockage"
11809 [(set (match_operand:BLK 0)
11810 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11813 [(set_attr "length" "0")])
11815 ;; As USE insns aren't meaningful after reload, this is used instead
11816 ;; to prevent deleting instructions setting registers for PIC code
11817 (define_insn "prologue_use"
11818 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11821 [(set_attr "length" "0")])
11823 ;; Insn emitted into the body of a function to return from a function.
11824 ;; This is only done if the function's epilogue is known to be simple.
11825 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11827 (define_expand "return"
11829 "ix86_can_use_return_insn_p ()"
11831 if (crtl->args.pops_args)
11833 rtx popc = GEN_INT (crtl->args.pops_args);
11834 emit_jump_insn (gen_simple_return_pop_internal (popc));
11839 ;; We need to disable this for TARGET_SEH, as otherwise
11840 ;; shrink-wrapped prologue gets enabled too. This might exceed
11841 ;; the maximum size of prologue in unwind information.
11843 (define_expand "simple_return"
11847 if (crtl->args.pops_args)
11849 rtx popc = GEN_INT (crtl->args.pops_args);
11850 emit_jump_insn (gen_simple_return_pop_internal (popc));
11855 (define_insn "simple_return_internal"
11859 [(set_attr "length" "1")
11860 (set_attr "atom_unit" "jeu")
11861 (set_attr "length_immediate" "0")
11862 (set_attr "modrm" "0")])
11864 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11865 ;; instruction Athlon and K8 have.
11867 (define_insn "simple_return_internal_long"
11869 (unspec [(const_int 0)] UNSPEC_REP)]
11872 [(set_attr "length" "2")
11873 (set_attr "atom_unit" "jeu")
11874 (set_attr "length_immediate" "0")
11875 (set_attr "prefix_rep" "1")
11876 (set_attr "modrm" "0")])
11878 (define_insn "simple_return_pop_internal"
11880 (use (match_operand:SI 0 "const_int_operand"))]
11883 [(set_attr "length" "3")
11884 (set_attr "atom_unit" "jeu")
11885 (set_attr "length_immediate" "2")
11886 (set_attr "modrm" "0")])
11888 (define_insn "simple_return_indirect_internal"
11890 (use (match_operand:SI 0 "register_operand" "r"))]
11893 [(set_attr "type" "ibr")
11894 (set_attr "length_immediate" "0")])
11900 [(set_attr "length" "1")
11901 (set_attr "length_immediate" "0")
11902 (set_attr "modrm" "0")])
11904 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11905 (define_insn "nops"
11906 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11910 int num = INTVAL (operands[0]);
11912 gcc_assert (IN_RANGE (num, 1, 8));
11915 fputs ("\tnop\n", asm_out_file);
11919 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11920 (set_attr "length_immediate" "0")
11921 (set_attr "modrm" "0")])
11923 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11924 ;; branch prediction penalty for the third jump in a 16-byte
11928 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11931 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11932 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11934 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11935 The align insn is used to avoid 3 jump instructions in the row to improve
11936 branch prediction and the benefits hardly outweigh the cost of extra 8
11937 nops on the average inserted by full alignment pseudo operation. */
11941 [(set_attr "length" "16")])
11943 (define_expand "prologue"
11946 "ix86_expand_prologue (); DONE;")
11948 (define_insn "set_got"
11949 [(set (match_operand:SI 0 "register_operand" "=r")
11950 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11951 (clobber (reg:CC FLAGS_REG))]
11953 "* return output_set_got (operands[0], NULL_RTX);"
11954 [(set_attr "type" "multi")
11955 (set_attr "length" "12")])
11957 (define_insn "set_got_labelled"
11958 [(set (match_operand:SI 0 "register_operand" "=r")
11959 (unspec:SI [(label_ref (match_operand 1))]
11961 (clobber (reg:CC FLAGS_REG))]
11963 "* return output_set_got (operands[0], operands[1]);"
11964 [(set_attr "type" "multi")
11965 (set_attr "length" "12")])
11967 (define_insn "set_got_rex64"
11968 [(set (match_operand:DI 0 "register_operand" "=r")
11969 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11971 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11972 [(set_attr "type" "lea")
11973 (set_attr "length_address" "4")
11974 (set_attr "mode" "DI")])
11976 (define_insn "set_rip_rex64"
11977 [(set (match_operand:DI 0 "register_operand" "=r")
11978 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11980 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11981 [(set_attr "type" "lea")
11982 (set_attr "length_address" "4")
11983 (set_attr "mode" "DI")])
11985 (define_insn "set_got_offset_rex64"
11986 [(set (match_operand:DI 0 "register_operand" "=r")
11988 [(label_ref (match_operand 1))]
11989 UNSPEC_SET_GOT_OFFSET))]
11991 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11992 [(set_attr "type" "imov")
11993 (set_attr "length_immediate" "0")
11994 (set_attr "length_address" "8")
11995 (set_attr "mode" "DI")])
11997 (define_expand "epilogue"
12000 "ix86_expand_epilogue (1); DONE;")
12002 (define_expand "sibcall_epilogue"
12005 "ix86_expand_epilogue (0); DONE;")
12007 (define_expand "eh_return"
12008 [(use (match_operand 0 "register_operand"))]
12011 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12013 /* Tricky bit: we write the address of the handler to which we will
12014 be returning into someone else's stack frame, one word below the
12015 stack address we wish to restore. */
12016 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12017 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12018 tmp = gen_rtx_MEM (Pmode, tmp);
12019 emit_move_insn (tmp, ra);
12021 emit_jump_insn (gen_eh_return_internal ());
12026 (define_insn_and_split "eh_return_internal"
12030 "epilogue_completed"
12032 "ix86_expand_epilogue (2); DONE;")
12034 (define_insn "leave"
12035 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12036 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12037 (clobber (mem:BLK (scratch)))]
12040 [(set_attr "type" "leave")])
12042 (define_insn "leave_rex64"
12043 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12044 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12045 (clobber (mem:BLK (scratch)))]
12048 [(set_attr "type" "leave")])
12050 ;; Handle -fsplit-stack.
12052 (define_expand "split_stack_prologue"
12056 ix86_expand_split_stack_prologue ();
12060 ;; In order to support the call/return predictor, we use a return
12061 ;; instruction which the middle-end doesn't see.
12062 (define_insn "split_stack_return"
12063 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12064 UNSPECV_SPLIT_STACK_RETURN)]
12067 if (operands[0] == const0_rtx)
12072 [(set_attr "atom_unit" "jeu")
12073 (set_attr "modrm" "0")
12074 (set (attr "length")
12075 (if_then_else (match_operand:SI 0 "const0_operand")
12078 (set (attr "length_immediate")
12079 (if_then_else (match_operand:SI 0 "const0_operand")
12083 ;; If there are operand 0 bytes available on the stack, jump to
12086 (define_expand "split_stack_space_check"
12087 [(set (pc) (if_then_else
12088 (ltu (minus (reg SP_REG)
12089 (match_operand 0 "register_operand"))
12090 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12091 (label_ref (match_operand 1))
12095 rtx reg, size, limit;
12097 reg = gen_reg_rtx (Pmode);
12098 size = force_reg (Pmode, operands[0]);
12099 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12100 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12101 UNSPEC_STACK_CHECK);
12102 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12103 ix86_expand_branch (GEU, reg, limit, operands[1]);
12108 ;; Bit manipulation instructions.
12110 (define_expand "ffs<mode>2"
12111 [(set (match_dup 2) (const_int -1))
12112 (parallel [(set (match_dup 3) (match_dup 4))
12113 (set (match_operand:SWI48 0 "register_operand")
12115 (match_operand:SWI48 1 "nonimmediate_operand")))])
12116 (set (match_dup 0) (if_then_else:SWI48
12117 (eq (match_dup 3) (const_int 0))
12120 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12121 (clobber (reg:CC FLAGS_REG))])]
12124 enum machine_mode flags_mode;
12126 if (<MODE>mode == SImode && !TARGET_CMOVE)
12128 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12132 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12134 operands[2] = gen_reg_rtx (<MODE>mode);
12135 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12136 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12139 (define_insn_and_split "ffssi2_no_cmove"
12140 [(set (match_operand:SI 0 "register_operand" "=r")
12141 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12142 (clobber (match_scratch:SI 2 "=&q"))
12143 (clobber (reg:CC FLAGS_REG))]
12146 "&& reload_completed"
12147 [(parallel [(set (match_dup 4) (match_dup 5))
12148 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12149 (set (strict_low_part (match_dup 3))
12150 (eq:QI (match_dup 4) (const_int 0)))
12151 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12152 (clobber (reg:CC FLAGS_REG))])
12153 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12154 (clobber (reg:CC FLAGS_REG))])
12155 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12156 (clobber (reg:CC FLAGS_REG))])]
12158 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12160 operands[3] = gen_lowpart (QImode, operands[2]);
12161 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12162 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12164 ix86_expand_clear (operands[2]);
12167 (define_insn "*tzcnt<mode>_1"
12168 [(set (reg:CCC FLAGS_REG)
12169 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12171 (set (match_operand:SWI48 0 "register_operand" "=r")
12172 (ctz:SWI48 (match_dup 1)))]
12174 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12175 [(set_attr "type" "alu1")
12176 (set_attr "prefix_0f" "1")
12177 (set_attr "prefix_rep" "1")
12178 (set_attr "btver2_decode" "double")
12179 (set_attr "mode" "<MODE>")])
12181 (define_insn "*bsf<mode>_1"
12182 [(set (reg:CCZ FLAGS_REG)
12183 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12185 (set (match_operand:SWI48 0 "register_operand" "=r")
12186 (ctz:SWI48 (match_dup 1)))]
12188 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12189 [(set_attr "type" "alu1")
12190 (set_attr "prefix_0f" "1")
12191 (set_attr "btver2_decode" "double")
12192 (set_attr "mode" "<MODE>")])
12194 (define_insn "ctz<mode>2"
12195 [(set (match_operand:SWI248 0 "register_operand" "=r")
12196 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12197 (clobber (reg:CC FLAGS_REG))]
12201 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12202 else if (optimize_function_for_size_p (cfun))
12204 else if (TARGET_GENERIC)
12205 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12206 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12208 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12210 [(set_attr "type" "alu1")
12211 (set_attr "prefix_0f" "1")
12212 (set (attr "prefix_rep")
12214 (ior (match_test "TARGET_BMI")
12215 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12216 (match_test "TARGET_GENERIC")))
12218 (const_string "0")))
12219 (set_attr "mode" "<MODE>")])
12221 (define_expand "clz<mode>2"
12223 [(set (match_operand:SWI248 0 "register_operand")
12226 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12227 (clobber (reg:CC FLAGS_REG))])
12229 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12230 (clobber (reg:CC FLAGS_REG))])]
12235 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12238 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12241 (define_insn "clz<mode>2_lzcnt"
12242 [(set (match_operand:SWI248 0 "register_operand" "=r")
12243 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12244 (clobber (reg:CC FLAGS_REG))]
12246 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12247 [(set_attr "prefix_rep" "1")
12248 (set_attr "type" "bitmanip")
12249 (set_attr "mode" "<MODE>")])
12251 ;; BMI instructions.
12252 (define_insn "*bmi_andn_<mode>"
12253 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12256 (match_operand:SWI48 1 "register_operand" "r,r"))
12257 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12258 (clobber (reg:CC FLAGS_REG))]
12260 "andn\t{%2, %1, %0|%0, %1, %2}"
12261 [(set_attr "type" "bitmanip")
12262 (set_attr "btver2_decode" "direct, double")
12263 (set_attr "mode" "<MODE>")])
12265 (define_insn "bmi_bextr_<mode>"
12266 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12267 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12268 (match_operand:SWI48 2 "register_operand" "r,r")]
12270 (clobber (reg:CC FLAGS_REG))]
12272 "bextr\t{%2, %1, %0|%0, %1, %2}"
12273 [(set_attr "type" "bitmanip")
12274 (set_attr "btver2_decode" "direct, double")
12275 (set_attr "mode" "<MODE>")])
12277 (define_insn "*bmi_blsi_<mode>"
12278 [(set (match_operand:SWI48 0 "register_operand" "=r")
12281 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12283 (clobber (reg:CC FLAGS_REG))]
12285 "blsi\t{%1, %0|%0, %1}"
12286 [(set_attr "type" "bitmanip")
12287 (set_attr "btver2_decode" "double")
12288 (set_attr "mode" "<MODE>")])
12290 (define_insn "*bmi_blsmsk_<mode>"
12291 [(set (match_operand:SWI48 0 "register_operand" "=r")
12294 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12297 (clobber (reg:CC FLAGS_REG))]
12299 "blsmsk\t{%1, %0|%0, %1}"
12300 [(set_attr "type" "bitmanip")
12301 (set_attr "btver2_decode" "double")
12302 (set_attr "mode" "<MODE>")])
12304 (define_insn "*bmi_blsr_<mode>"
12305 [(set (match_operand:SWI48 0 "register_operand" "=r")
12308 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12311 (clobber (reg:CC FLAGS_REG))]
12313 "blsr\t{%1, %0|%0, %1}"
12314 [(set_attr "type" "bitmanip")
12315 (set_attr "btver2_decode" "double")
12316 (set_attr "mode" "<MODE>")])
12318 ;; BMI2 instructions.
12319 (define_insn "bmi2_bzhi_<mode>3"
12320 [(set (match_operand:SWI48 0 "register_operand" "=r")
12321 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12322 (match_operand:SWI48 2 "register_operand" "r"))
12323 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12324 (clobber (reg:CC FLAGS_REG))]
12326 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12327 [(set_attr "type" "bitmanip")
12328 (set_attr "prefix" "vex")
12329 (set_attr "mode" "<MODE>")])
12331 (define_insn "bmi2_pdep_<mode>3"
12332 [(set (match_operand:SWI48 0 "register_operand" "=r")
12333 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12334 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12337 "pdep\t{%2, %1, %0|%0, %1, %2}"
12338 [(set_attr "type" "bitmanip")
12339 (set_attr "prefix" "vex")
12340 (set_attr "mode" "<MODE>")])
12342 (define_insn "bmi2_pext_<mode>3"
12343 [(set (match_operand:SWI48 0 "register_operand" "=r")
12344 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12345 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12348 "pext\t{%2, %1, %0|%0, %1, %2}"
12349 [(set_attr "type" "bitmanip")
12350 (set_attr "prefix" "vex")
12351 (set_attr "mode" "<MODE>")])
12353 ;; TBM instructions.
12354 (define_insn "tbm_bextri_<mode>"
12355 [(set (match_operand:SWI48 0 "register_operand" "=r")
12356 (zero_extract:SWI48
12357 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12358 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12359 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12360 (clobber (reg:CC FLAGS_REG))]
12363 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12364 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12366 [(set_attr "type" "bitmanip")
12367 (set_attr "mode" "<MODE>")])
12369 (define_insn "*tbm_blcfill_<mode>"
12370 [(set (match_operand:SWI48 0 "register_operand" "=r")
12373 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12376 (clobber (reg:CC FLAGS_REG))]
12378 "blcfill\t{%1, %0|%0, %1}"
12379 [(set_attr "type" "bitmanip")
12380 (set_attr "mode" "<MODE>")])
12382 (define_insn "*tbm_blci_<mode>"
12383 [(set (match_operand:SWI48 0 "register_operand" "=r")
12387 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12390 (clobber (reg:CC FLAGS_REG))]
12392 "blci\t{%1, %0|%0, %1}"
12393 [(set_attr "type" "bitmanip")
12394 (set_attr "mode" "<MODE>")])
12396 (define_insn "*tbm_blcic_<mode>"
12397 [(set (match_operand:SWI48 0 "register_operand" "=r")
12400 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12404 (clobber (reg:CC FLAGS_REG))]
12406 "blcic\t{%1, %0|%0, %1}"
12407 [(set_attr "type" "bitmanip")
12408 (set_attr "mode" "<MODE>")])
12410 (define_insn "*tbm_blcmsk_<mode>"
12411 [(set (match_operand:SWI48 0 "register_operand" "=r")
12414 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12417 (clobber (reg:CC FLAGS_REG))]
12419 "blcmsk\t{%1, %0|%0, %1}"
12420 [(set_attr "type" "bitmanip")
12421 (set_attr "mode" "<MODE>")])
12423 (define_insn "*tbm_blcs_<mode>"
12424 [(set (match_operand:SWI48 0 "register_operand" "=r")
12427 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12430 (clobber (reg:CC FLAGS_REG))]
12432 "blcs\t{%1, %0|%0, %1}"
12433 [(set_attr "type" "bitmanip")
12434 (set_attr "mode" "<MODE>")])
12436 (define_insn "*tbm_blsfill_<mode>"
12437 [(set (match_operand:SWI48 0 "register_operand" "=r")
12440 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12443 (clobber (reg:CC FLAGS_REG))]
12445 "blsfill\t{%1, %0|%0, %1}"
12446 [(set_attr "type" "bitmanip")
12447 (set_attr "mode" "<MODE>")])
12449 (define_insn "*tbm_blsic_<mode>"
12450 [(set (match_operand:SWI48 0 "register_operand" "=r")
12453 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12457 (clobber (reg:CC FLAGS_REG))]
12459 "blsic\t{%1, %0|%0, %1}"
12460 [(set_attr "type" "bitmanip")
12461 (set_attr "mode" "<MODE>")])
12463 (define_insn "*tbm_t1mskc_<mode>"
12464 [(set (match_operand:SWI48 0 "register_operand" "=r")
12467 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12471 (clobber (reg:CC FLAGS_REG))]
12473 "t1mskc\t{%1, %0|%0, %1}"
12474 [(set_attr "type" "bitmanip")
12475 (set_attr "mode" "<MODE>")])
12477 (define_insn "*tbm_tzmsk_<mode>"
12478 [(set (match_operand:SWI48 0 "register_operand" "=r")
12481 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12485 (clobber (reg:CC FLAGS_REG))]
12487 "tzmsk\t{%1, %0|%0, %1}"
12488 [(set_attr "type" "bitmanip")
12489 (set_attr "mode" "<MODE>")])
12491 (define_insn "bsr_rex64"
12492 [(set (match_operand:DI 0 "register_operand" "=r")
12493 (minus:DI (const_int 63)
12494 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12495 (clobber (reg:CC FLAGS_REG))]
12497 "bsr{q}\t{%1, %0|%0, %1}"
12498 [(set_attr "type" "alu1")
12499 (set_attr "prefix_0f" "1")
12500 (set_attr "mode" "DI")])
12503 [(set (match_operand:SI 0 "register_operand" "=r")
12504 (minus:SI (const_int 31)
12505 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12506 (clobber (reg:CC FLAGS_REG))]
12508 "bsr{l}\t{%1, %0|%0, %1}"
12509 [(set_attr "type" "alu1")
12510 (set_attr "prefix_0f" "1")
12511 (set_attr "mode" "SI")])
12513 (define_insn "*bsrhi"
12514 [(set (match_operand:HI 0 "register_operand" "=r")
12515 (minus:HI (const_int 15)
12516 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12517 (clobber (reg:CC FLAGS_REG))]
12519 "bsr{w}\t{%1, %0|%0, %1}"
12520 [(set_attr "type" "alu1")
12521 (set_attr "prefix_0f" "1")
12522 (set_attr "mode" "HI")])
12524 (define_insn "popcount<mode>2"
12525 [(set (match_operand:SWI248 0 "register_operand" "=r")
12527 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12528 (clobber (reg:CC FLAGS_REG))]
12532 return "popcnt\t{%1, %0|%0, %1}";
12534 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12537 [(set_attr "prefix_rep" "1")
12538 (set_attr "type" "bitmanip")
12539 (set_attr "mode" "<MODE>")])
12541 (define_insn "*popcount<mode>2_cmp"
12542 [(set (reg FLAGS_REG)
12545 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12547 (set (match_operand:SWI248 0 "register_operand" "=r")
12548 (popcount:SWI248 (match_dup 1)))]
12549 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12552 return "popcnt\t{%1, %0|%0, %1}";
12554 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12557 [(set_attr "prefix_rep" "1")
12558 (set_attr "type" "bitmanip")
12559 (set_attr "mode" "<MODE>")])
12561 (define_insn "*popcountsi2_cmp_zext"
12562 [(set (reg FLAGS_REG)
12564 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12566 (set (match_operand:DI 0 "register_operand" "=r")
12567 (zero_extend:DI(popcount:SI (match_dup 1))))]
12568 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12571 return "popcnt\t{%1, %0|%0, %1}";
12573 return "popcnt{l}\t{%1, %0|%0, %1}";
12576 [(set_attr "prefix_rep" "1")
12577 (set_attr "type" "bitmanip")
12578 (set_attr "mode" "SI")])
12580 (define_expand "bswapdi2"
12581 [(set (match_operand:DI 0 "register_operand")
12582 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12586 operands[1] = force_reg (DImode, operands[1]);
12589 (define_expand "bswapsi2"
12590 [(set (match_operand:SI 0 "register_operand")
12591 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12596 else if (TARGET_BSWAP)
12597 operands[1] = force_reg (SImode, operands[1]);
12600 rtx x = operands[0];
12602 emit_move_insn (x, operands[1]);
12603 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12604 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12605 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12610 (define_insn "*bswap<mode>2_movbe"
12611 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12612 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12614 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12617 movbe\t{%1, %0|%0, %1}
12618 movbe\t{%1, %0|%0, %1}"
12619 [(set_attr "type" "bitmanip,imov,imov")
12620 (set_attr "modrm" "0,1,1")
12621 (set_attr "prefix_0f" "*,1,1")
12622 (set_attr "prefix_extra" "*,1,1")
12623 (set_attr "mode" "<MODE>")])
12625 (define_insn "*bswap<mode>2"
12626 [(set (match_operand:SWI48 0 "register_operand" "=r")
12627 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12630 [(set_attr "type" "bitmanip")
12631 (set_attr "modrm" "0")
12632 (set_attr "mode" "<MODE>")])
12634 (define_insn "*bswaphi_lowpart_1"
12635 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12636 (bswap:HI (match_dup 0)))
12637 (clobber (reg:CC FLAGS_REG))]
12638 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12640 xchg{b}\t{%h0, %b0|%b0, %h0}
12641 rol{w}\t{$8, %0|%0, 8}"
12642 [(set_attr "length" "2,4")
12643 (set_attr "mode" "QI,HI")])
12645 (define_insn "bswaphi_lowpart"
12646 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12647 (bswap:HI (match_dup 0)))
12648 (clobber (reg:CC FLAGS_REG))]
12650 "rol{w}\t{$8, %0|%0, 8}"
12651 [(set_attr "length" "4")
12652 (set_attr "mode" "HI")])
12654 (define_expand "paritydi2"
12655 [(set (match_operand:DI 0 "register_operand")
12656 (parity:DI (match_operand:DI 1 "register_operand")))]
12659 rtx scratch = gen_reg_rtx (QImode);
12662 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12663 NULL_RTX, operands[1]));
12665 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12666 gen_rtx_REG (CCmode, FLAGS_REG),
12668 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12671 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12674 rtx tmp = gen_reg_rtx (SImode);
12676 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12677 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12682 (define_expand "paritysi2"
12683 [(set (match_operand:SI 0 "register_operand")
12684 (parity:SI (match_operand:SI 1 "register_operand")))]
12687 rtx scratch = gen_reg_rtx (QImode);
12690 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12692 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12693 gen_rtx_REG (CCmode, FLAGS_REG),
12695 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12697 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12701 (define_insn_and_split "paritydi2_cmp"
12702 [(set (reg:CC FLAGS_REG)
12703 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12705 (clobber (match_scratch:DI 0 "=r"))
12706 (clobber (match_scratch:SI 1 "=&r"))
12707 (clobber (match_scratch:HI 2 "=Q"))]
12710 "&& reload_completed"
12712 [(set (match_dup 1)
12713 (xor:SI (match_dup 1) (match_dup 4)))
12714 (clobber (reg:CC FLAGS_REG))])
12716 [(set (reg:CC FLAGS_REG)
12717 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12718 (clobber (match_dup 1))
12719 (clobber (match_dup 2))])]
12721 operands[4] = gen_lowpart (SImode, operands[3]);
12725 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12726 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12729 operands[1] = gen_highpart (SImode, operands[3]);
12732 (define_insn_and_split "paritysi2_cmp"
12733 [(set (reg:CC FLAGS_REG)
12734 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12736 (clobber (match_scratch:SI 0 "=r"))
12737 (clobber (match_scratch:HI 1 "=&Q"))]
12740 "&& reload_completed"
12742 [(set (match_dup 1)
12743 (xor:HI (match_dup 1) (match_dup 3)))
12744 (clobber (reg:CC FLAGS_REG))])
12746 [(set (reg:CC FLAGS_REG)
12747 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12748 (clobber (match_dup 1))])]
12750 operands[3] = gen_lowpart (HImode, operands[2]);
12752 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12753 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12756 (define_insn "*parityhi2_cmp"
12757 [(set (reg:CC FLAGS_REG)
12758 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12760 (clobber (match_scratch:HI 0 "=Q"))]
12762 "xor{b}\t{%h0, %b0|%b0, %h0}"
12763 [(set_attr "length" "2")
12764 (set_attr "mode" "HI")])
12767 ;; Thread-local storage patterns for ELF.
12769 ;; Note that these code sequences must appear exactly as shown
12770 ;; in order to allow linker relaxation.
12772 (define_insn "*tls_global_dynamic_32_gnu"
12773 [(set (match_operand:SI 0 "register_operand" "=a")
12775 [(match_operand:SI 1 "register_operand" "b")
12776 (match_operand 2 "tls_symbolic_operand")
12777 (match_operand 3 "constant_call_address_operand" "z")]
12779 (clobber (match_scratch:SI 4 "=d"))
12780 (clobber (match_scratch:SI 5 "=c"))
12781 (clobber (reg:CC FLAGS_REG))]
12782 "!TARGET_64BIT && TARGET_GNU_TLS"
12785 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12786 if (TARGET_SUN_TLS)
12787 #ifdef HAVE_AS_IX86_TLSGDPLT
12788 return "call\t%a2@tlsgdplt";
12790 return "call\t%p3@plt";
12792 return "call\t%P3";
12794 [(set_attr "type" "multi")
12795 (set_attr "length" "12")])
12797 (define_expand "tls_global_dynamic_32"
12799 [(set (match_operand:SI 0 "register_operand")
12800 (unspec:SI [(match_operand:SI 2 "register_operand")
12801 (match_operand 1 "tls_symbolic_operand")
12802 (match_operand 3 "constant_call_address_operand")]
12804 (clobber (match_scratch:SI 4))
12805 (clobber (match_scratch:SI 5))
12806 (clobber (reg:CC FLAGS_REG))])])
12808 (define_insn "*tls_global_dynamic_64_<mode>"
12809 [(set (match_operand:P 0 "register_operand" "=a")
12811 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12812 (match_operand 3)))
12813 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12818 fputs (ASM_BYTE "0x66\n", asm_out_file);
12820 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12821 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12822 fputs ("\trex64\n", asm_out_file);
12823 if (TARGET_SUN_TLS)
12824 return "call\t%p2@plt";
12825 return "call\t%P2";
12827 [(set_attr "type" "multi")
12828 (set (attr "length")
12829 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12831 (define_insn "*tls_global_dynamic_64_largepic"
12832 [(set (match_operand:DI 0 "register_operand" "=a")
12834 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12835 (match_operand:DI 3 "immediate_operand" "i")))
12836 (match_operand 4)))
12837 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12839 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12840 && GET_CODE (operands[3]) == CONST
12841 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
12842 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
12845 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12846 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
12847 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
12848 return "call\t{*%%rax|rax}";
12850 [(set_attr "type" "multi")
12851 (set_attr "length" "22")])
12853 (define_expand "tls_global_dynamic_64_<mode>"
12855 [(set (match_operand:P 0 "register_operand")
12857 (mem:QI (match_operand 2))
12859 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12863 (define_insn "*tls_local_dynamic_base_32_gnu"
12864 [(set (match_operand:SI 0 "register_operand" "=a")
12866 [(match_operand:SI 1 "register_operand" "b")
12867 (match_operand 2 "constant_call_address_operand" "z")]
12868 UNSPEC_TLS_LD_BASE))
12869 (clobber (match_scratch:SI 3 "=d"))
12870 (clobber (match_scratch:SI 4 "=c"))
12871 (clobber (reg:CC FLAGS_REG))]
12872 "!TARGET_64BIT && TARGET_GNU_TLS"
12875 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12876 if (TARGET_SUN_TLS)
12877 #ifdef HAVE_AS_IX86_TLSLDMPLT
12878 return "call\t%&@tlsldmplt";
12880 return "call\t%p2@plt";
12882 return "call\t%P2";
12884 [(set_attr "type" "multi")
12885 (set_attr "length" "11")])
12887 (define_expand "tls_local_dynamic_base_32"
12889 [(set (match_operand:SI 0 "register_operand")
12891 [(match_operand:SI 1 "register_operand")
12892 (match_operand 2 "constant_call_address_operand")]
12893 UNSPEC_TLS_LD_BASE))
12894 (clobber (match_scratch:SI 3))
12895 (clobber (match_scratch:SI 4))
12896 (clobber (reg:CC FLAGS_REG))])])
12898 (define_insn "*tls_local_dynamic_base_64_<mode>"
12899 [(set (match_operand:P 0 "register_operand" "=a")
12901 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12902 (match_operand 2)))
12903 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12907 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12908 if (TARGET_SUN_TLS)
12909 return "call\t%p1@plt";
12910 return "call\t%P1";
12912 [(set_attr "type" "multi")
12913 (set_attr "length" "12")])
12915 (define_insn "*tls_local_dynamic_base_64_largepic"
12916 [(set (match_operand:DI 0 "register_operand" "=a")
12918 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
12919 (match_operand:DI 2 "immediate_operand" "i")))
12920 (match_operand 3)))
12921 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12922 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12923 && GET_CODE (operands[2]) == CONST
12924 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
12925 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
12928 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12929 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
12930 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
12931 return "call\t{*%%rax|rax}";
12933 [(set_attr "type" "multi")
12934 (set_attr "length" "22")])
12936 (define_expand "tls_local_dynamic_base_64_<mode>"
12938 [(set (match_operand:P 0 "register_operand")
12940 (mem:QI (match_operand 1))
12942 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12945 ;; Local dynamic of a single variable is a lose. Show combine how
12946 ;; to convert that back to global dynamic.
12948 (define_insn_and_split "*tls_local_dynamic_32_once"
12949 [(set (match_operand:SI 0 "register_operand" "=a")
12951 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12952 (match_operand 2 "constant_call_address_operand" "z")]
12953 UNSPEC_TLS_LD_BASE)
12954 (const:SI (unspec:SI
12955 [(match_operand 3 "tls_symbolic_operand")]
12957 (clobber (match_scratch:SI 4 "=d"))
12958 (clobber (match_scratch:SI 5 "=c"))
12959 (clobber (reg:CC FLAGS_REG))]
12964 [(set (match_dup 0)
12965 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12967 (clobber (match_dup 4))
12968 (clobber (match_dup 5))
12969 (clobber (reg:CC FLAGS_REG))])])
12971 ;; Segment register for the thread base ptr load
12972 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12974 ;; Load and add the thread base pointer from %<tp_seg>:0.
12975 (define_insn "*load_tp_x32"
12976 [(set (match_operand:SI 0 "register_operand" "=r")
12977 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12979 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12980 [(set_attr "type" "imov")
12981 (set_attr "modrm" "0")
12982 (set_attr "length" "7")
12983 (set_attr "memory" "load")
12984 (set_attr "imm_disp" "false")])
12986 (define_insn "*load_tp_x32_zext"
12987 [(set (match_operand:DI 0 "register_operand" "=r")
12988 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12990 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12991 [(set_attr "type" "imov")
12992 (set_attr "modrm" "0")
12993 (set_attr "length" "7")
12994 (set_attr "memory" "load")
12995 (set_attr "imm_disp" "false")])
12997 (define_insn "*load_tp_<mode>"
12998 [(set (match_operand:P 0 "register_operand" "=r")
12999 (unspec:P [(const_int 0)] UNSPEC_TP))]
13001 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13002 [(set_attr "type" "imov")
13003 (set_attr "modrm" "0")
13004 (set_attr "length" "7")
13005 (set_attr "memory" "load")
13006 (set_attr "imm_disp" "false")])
13008 (define_insn "*add_tp_x32"
13009 [(set (match_operand:SI 0 "register_operand" "=r")
13010 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13011 (match_operand:SI 1 "register_operand" "0")))
13012 (clobber (reg:CC FLAGS_REG))]
13014 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13015 [(set_attr "type" "alu")
13016 (set_attr "modrm" "0")
13017 (set_attr "length" "7")
13018 (set_attr "memory" "load")
13019 (set_attr "imm_disp" "false")])
13021 (define_insn "*add_tp_x32_zext"
13022 [(set (match_operand:DI 0 "register_operand" "=r")
13024 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13025 (match_operand:SI 1 "register_operand" "0"))))
13026 (clobber (reg:CC FLAGS_REG))]
13028 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13029 [(set_attr "type" "alu")
13030 (set_attr "modrm" "0")
13031 (set_attr "length" "7")
13032 (set_attr "memory" "load")
13033 (set_attr "imm_disp" "false")])
13035 (define_insn "*add_tp_<mode>"
13036 [(set (match_operand:P 0 "register_operand" "=r")
13037 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13038 (match_operand:P 1 "register_operand" "0")))
13039 (clobber (reg:CC FLAGS_REG))]
13041 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13042 [(set_attr "type" "alu")
13043 (set_attr "modrm" "0")
13044 (set_attr "length" "7")
13045 (set_attr "memory" "load")
13046 (set_attr "imm_disp" "false")])
13048 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13049 ;; %rax as destination of the initial executable code sequence.
13050 (define_insn "tls_initial_exec_64_sun"
13051 [(set (match_operand:DI 0 "register_operand" "=a")
13053 [(match_operand 1 "tls_symbolic_operand")]
13054 UNSPEC_TLS_IE_SUN))
13055 (clobber (reg:CC FLAGS_REG))]
13056 "TARGET_64BIT && TARGET_SUN_TLS"
13059 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13060 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13062 [(set_attr "type" "multi")])
13064 ;; GNU2 TLS patterns can be split.
13066 (define_expand "tls_dynamic_gnu2_32"
13067 [(set (match_dup 3)
13068 (plus:SI (match_operand:SI 2 "register_operand")
13070 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13073 [(set (match_operand:SI 0 "register_operand")
13074 (unspec:SI [(match_dup 1) (match_dup 3)
13075 (match_dup 2) (reg:SI SP_REG)]
13077 (clobber (reg:CC FLAGS_REG))])]
13078 "!TARGET_64BIT && TARGET_GNU2_TLS"
13080 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13081 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13084 (define_insn "*tls_dynamic_gnu2_lea_32"
13085 [(set (match_operand:SI 0 "register_operand" "=r")
13086 (plus:SI (match_operand:SI 1 "register_operand" "b")
13088 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13089 UNSPEC_TLSDESC))))]
13090 "!TARGET_64BIT && TARGET_GNU2_TLS"
13091 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13092 [(set_attr "type" "lea")
13093 (set_attr "mode" "SI")
13094 (set_attr "length" "6")
13095 (set_attr "length_address" "4")])
13097 (define_insn "*tls_dynamic_gnu2_call_32"
13098 [(set (match_operand:SI 0 "register_operand" "=a")
13099 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13100 (match_operand:SI 2 "register_operand" "0")
13101 ;; we have to make sure %ebx still points to the GOT
13102 (match_operand:SI 3 "register_operand" "b")
13105 (clobber (reg:CC FLAGS_REG))]
13106 "!TARGET_64BIT && TARGET_GNU2_TLS"
13107 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13108 [(set_attr "type" "call")
13109 (set_attr "length" "2")
13110 (set_attr "length_address" "0")])
13112 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13113 [(set (match_operand:SI 0 "register_operand" "=&a")
13115 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13116 (match_operand:SI 4)
13117 (match_operand:SI 2 "register_operand" "b")
13120 (const:SI (unspec:SI
13121 [(match_operand 1 "tls_symbolic_operand")]
13123 (clobber (reg:CC FLAGS_REG))]
13124 "!TARGET_64BIT && TARGET_GNU2_TLS"
13127 [(set (match_dup 0) (match_dup 5))]
13129 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13130 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13133 (define_expand "tls_dynamic_gnu2_64"
13134 [(set (match_dup 2)
13135 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13138 [(set (match_operand:DI 0 "register_operand")
13139 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13141 (clobber (reg:CC FLAGS_REG))])]
13142 "TARGET_64BIT && TARGET_GNU2_TLS"
13144 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13145 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13148 (define_insn "*tls_dynamic_gnu2_lea_64"
13149 [(set (match_operand:DI 0 "register_operand" "=r")
13150 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13152 "TARGET_64BIT && TARGET_GNU2_TLS"
13153 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13154 [(set_attr "type" "lea")
13155 (set_attr "mode" "DI")
13156 (set_attr "length" "7")
13157 (set_attr "length_address" "4")])
13159 (define_insn "*tls_dynamic_gnu2_call_64"
13160 [(set (match_operand:DI 0 "register_operand" "=a")
13161 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13162 (match_operand:DI 2 "register_operand" "0")
13165 (clobber (reg:CC FLAGS_REG))]
13166 "TARGET_64BIT && TARGET_GNU2_TLS"
13167 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13168 [(set_attr "type" "call")
13169 (set_attr "length" "2")
13170 (set_attr "length_address" "0")])
13172 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13173 [(set (match_operand:DI 0 "register_operand" "=&a")
13175 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13176 (match_operand:DI 3)
13179 (const:DI (unspec:DI
13180 [(match_operand 1 "tls_symbolic_operand")]
13182 (clobber (reg:CC FLAGS_REG))]
13183 "TARGET_64BIT && TARGET_GNU2_TLS"
13186 [(set (match_dup 0) (match_dup 4))]
13188 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13189 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13192 ;; These patterns match the binary 387 instructions for addM3, subM3,
13193 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13194 ;; SFmode. The first is the normal insn, the second the same insn but
13195 ;; with one operand a conversion, and the third the same insn but with
13196 ;; the other operand a conversion. The conversion may be SFmode or
13197 ;; SImode if the target mode DFmode, but only SImode if the target mode
13200 ;; Gcc is slightly more smart about handling normal two address instructions
13201 ;; so use special patterns for add and mull.
13203 (define_insn "*fop_<mode>_comm_mixed"
13204 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13205 (match_operator:MODEF 3 "binary_fp_operator"
13206 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13207 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13208 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13209 && COMMUTATIVE_ARITH_P (operands[3])
13210 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13211 "* return output_387_binary_op (insn, operands);"
13212 [(set (attr "type")
13213 (if_then_else (eq_attr "alternative" "1,2")
13214 (if_then_else (match_operand:MODEF 3 "mult_operator")
13215 (const_string "ssemul")
13216 (const_string "sseadd"))
13217 (if_then_else (match_operand:MODEF 3 "mult_operator")
13218 (const_string "fmul")
13219 (const_string "fop"))))
13220 (set_attr "isa" "*,noavx,avx")
13221 (set_attr "prefix" "orig,orig,vex")
13222 (set_attr "mode" "<MODE>")])
13224 (define_insn "*fop_<mode>_comm_sse"
13225 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13226 (match_operator:MODEF 3 "binary_fp_operator"
13227 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13228 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13229 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13230 && COMMUTATIVE_ARITH_P (operands[3])
13231 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13232 "* return output_387_binary_op (insn, operands);"
13233 [(set (attr "type")
13234 (if_then_else (match_operand:MODEF 3 "mult_operator")
13235 (const_string "ssemul")
13236 (const_string "sseadd")))
13237 (set_attr "isa" "noavx,avx")
13238 (set_attr "prefix" "orig,vex")
13239 (set_attr "mode" "<MODE>")])
13241 (define_insn "*fop_<mode>_comm_i387"
13242 [(set (match_operand:MODEF 0 "register_operand" "=f")
13243 (match_operator:MODEF 3 "binary_fp_operator"
13244 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13245 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13246 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13247 && COMMUTATIVE_ARITH_P (operands[3])
13248 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13249 "* return output_387_binary_op (insn, operands);"
13250 [(set (attr "type")
13251 (if_then_else (match_operand:MODEF 3 "mult_operator")
13252 (const_string "fmul")
13253 (const_string "fop")))
13254 (set_attr "mode" "<MODE>")])
13256 (define_insn "*fop_<mode>_1_mixed"
13257 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13258 (match_operator:MODEF 3 "binary_fp_operator"
13259 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13260 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13261 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13262 && !COMMUTATIVE_ARITH_P (operands[3])
13263 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13264 "* return output_387_binary_op (insn, operands);"
13265 [(set (attr "type")
13266 (cond [(and (eq_attr "alternative" "2,3")
13267 (match_operand:MODEF 3 "mult_operator"))
13268 (const_string "ssemul")
13269 (and (eq_attr "alternative" "2,3")
13270 (match_operand:MODEF 3 "div_operator"))
13271 (const_string "ssediv")
13272 (eq_attr "alternative" "2,3")
13273 (const_string "sseadd")
13274 (match_operand:MODEF 3 "mult_operator")
13275 (const_string "fmul")
13276 (match_operand:MODEF 3 "div_operator")
13277 (const_string "fdiv")
13279 (const_string "fop")))
13280 (set_attr "isa" "*,*,noavx,avx")
13281 (set_attr "prefix" "orig,orig,orig,vex")
13282 (set_attr "mode" "<MODE>")])
13284 (define_insn "*rcpsf2_sse"
13285 [(set (match_operand:SF 0 "register_operand" "=x")
13286 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13289 "%vrcpss\t{%1, %d0|%d0, %1}"
13290 [(set_attr "type" "sse")
13291 (set_attr "atom_sse_attr" "rcp")
13292 (set_attr "btver2_sse_attr" "rcp")
13293 (set_attr "prefix" "maybe_vex")
13294 (set_attr "mode" "SF")])
13296 (define_insn "*fop_<mode>_1_sse"
13297 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13298 (match_operator:MODEF 3 "binary_fp_operator"
13299 [(match_operand:MODEF 1 "register_operand" "0,x")
13300 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13301 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13302 && !COMMUTATIVE_ARITH_P (operands[3])"
13303 "* return output_387_binary_op (insn, operands);"
13304 [(set (attr "type")
13305 (cond [(match_operand:MODEF 3 "mult_operator")
13306 (const_string "ssemul")
13307 (match_operand:MODEF 3 "div_operator")
13308 (const_string "ssediv")
13310 (const_string "sseadd")))
13311 (set_attr "isa" "noavx,avx")
13312 (set_attr "prefix" "orig,vex")
13313 (set_attr "mode" "<MODE>")])
13315 ;; This pattern is not fully shadowed by the pattern above.
13316 (define_insn "*fop_<mode>_1_i387"
13317 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13318 (match_operator:MODEF 3 "binary_fp_operator"
13319 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13320 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13321 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13322 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13323 && !COMMUTATIVE_ARITH_P (operands[3])
13324 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13325 "* return output_387_binary_op (insn, operands);"
13326 [(set (attr "type")
13327 (cond [(match_operand:MODEF 3 "mult_operator")
13328 (const_string "fmul")
13329 (match_operand:MODEF 3 "div_operator")
13330 (const_string "fdiv")
13332 (const_string "fop")))
13333 (set_attr "mode" "<MODE>")])
13335 ;; ??? Add SSE splitters for these!
13336 (define_insn "*fop_<MODEF:mode>_2_i387"
13337 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13338 (match_operator:MODEF 3 "binary_fp_operator"
13340 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13341 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13342 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13343 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13344 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13345 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13346 [(set (attr "type")
13347 (cond [(match_operand:MODEF 3 "mult_operator")
13348 (const_string "fmul")
13349 (match_operand:MODEF 3 "div_operator")
13350 (const_string "fdiv")
13352 (const_string "fop")))
13353 (set_attr "fp_int_src" "true")
13354 (set_attr "mode" "<SWI24:MODE>")])
13356 (define_insn "*fop_<MODEF:mode>_3_i387"
13357 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13358 (match_operator:MODEF 3 "binary_fp_operator"
13359 [(match_operand:MODEF 1 "register_operand" "0,0")
13361 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13362 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13363 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13364 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13365 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13366 [(set (attr "type")
13367 (cond [(match_operand:MODEF 3 "mult_operator")
13368 (const_string "fmul")
13369 (match_operand:MODEF 3 "div_operator")
13370 (const_string "fdiv")
13372 (const_string "fop")))
13373 (set_attr "fp_int_src" "true")
13374 (set_attr "mode" "<MODE>")])
13376 (define_insn "*fop_df_4_i387"
13377 [(set (match_operand:DF 0 "register_operand" "=f,f")
13378 (match_operator:DF 3 "binary_fp_operator"
13380 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13381 (match_operand:DF 2 "register_operand" "0,f")]))]
13382 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13383 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13384 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13385 "* return output_387_binary_op (insn, operands);"
13386 [(set (attr "type")
13387 (cond [(match_operand:DF 3 "mult_operator")
13388 (const_string "fmul")
13389 (match_operand:DF 3 "div_operator")
13390 (const_string "fdiv")
13392 (const_string "fop")))
13393 (set_attr "mode" "SF")])
13395 (define_insn "*fop_df_5_i387"
13396 [(set (match_operand:DF 0 "register_operand" "=f,f")
13397 (match_operator:DF 3 "binary_fp_operator"
13398 [(match_operand:DF 1 "register_operand" "0,f")
13400 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13401 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13402 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13403 "* return output_387_binary_op (insn, operands);"
13404 [(set (attr "type")
13405 (cond [(match_operand:DF 3 "mult_operator")
13406 (const_string "fmul")
13407 (match_operand:DF 3 "div_operator")
13408 (const_string "fdiv")
13410 (const_string "fop")))
13411 (set_attr "mode" "SF")])
13413 (define_insn "*fop_df_6_i387"
13414 [(set (match_operand:DF 0 "register_operand" "=f,f")
13415 (match_operator:DF 3 "binary_fp_operator"
13417 (match_operand:SF 1 "register_operand" "0,f"))
13419 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13420 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13421 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13422 "* return output_387_binary_op (insn, operands);"
13423 [(set (attr "type")
13424 (cond [(match_operand:DF 3 "mult_operator")
13425 (const_string "fmul")
13426 (match_operand:DF 3 "div_operator")
13427 (const_string "fdiv")
13429 (const_string "fop")))
13430 (set_attr "mode" "SF")])
13432 (define_insn "*fop_xf_comm_i387"
13433 [(set (match_operand:XF 0 "register_operand" "=f")
13434 (match_operator:XF 3 "binary_fp_operator"
13435 [(match_operand:XF 1 "register_operand" "%0")
13436 (match_operand:XF 2 "register_operand" "f")]))]
13438 && COMMUTATIVE_ARITH_P (operands[3])"
13439 "* return output_387_binary_op (insn, operands);"
13440 [(set (attr "type")
13441 (if_then_else (match_operand:XF 3 "mult_operator")
13442 (const_string "fmul")
13443 (const_string "fop")))
13444 (set_attr "mode" "XF")])
13446 (define_insn "*fop_xf_1_i387"
13447 [(set (match_operand:XF 0 "register_operand" "=f,f")
13448 (match_operator:XF 3 "binary_fp_operator"
13449 [(match_operand:XF 1 "register_operand" "0,f")
13450 (match_operand:XF 2 "register_operand" "f,0")]))]
13452 && !COMMUTATIVE_ARITH_P (operands[3])"
13453 "* return output_387_binary_op (insn, operands);"
13454 [(set (attr "type")
13455 (cond [(match_operand:XF 3 "mult_operator")
13456 (const_string "fmul")
13457 (match_operand:XF 3 "div_operator")
13458 (const_string "fdiv")
13460 (const_string "fop")))
13461 (set_attr "mode" "XF")])
13463 (define_insn "*fop_xf_2_i387"
13464 [(set (match_operand:XF 0 "register_operand" "=f,f")
13465 (match_operator:XF 3 "binary_fp_operator"
13467 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13468 (match_operand:XF 2 "register_operand" "0,0")]))]
13469 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13470 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13471 [(set (attr "type")
13472 (cond [(match_operand:XF 3 "mult_operator")
13473 (const_string "fmul")
13474 (match_operand:XF 3 "div_operator")
13475 (const_string "fdiv")
13477 (const_string "fop")))
13478 (set_attr "fp_int_src" "true")
13479 (set_attr "mode" "<MODE>")])
13481 (define_insn "*fop_xf_3_i387"
13482 [(set (match_operand:XF 0 "register_operand" "=f,f")
13483 (match_operator:XF 3 "binary_fp_operator"
13484 [(match_operand:XF 1 "register_operand" "0,0")
13486 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13487 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13488 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13489 [(set (attr "type")
13490 (cond [(match_operand:XF 3 "mult_operator")
13491 (const_string "fmul")
13492 (match_operand:XF 3 "div_operator")
13493 (const_string "fdiv")
13495 (const_string "fop")))
13496 (set_attr "fp_int_src" "true")
13497 (set_attr "mode" "<MODE>")])
13499 (define_insn "*fop_xf_4_i387"
13500 [(set (match_operand:XF 0 "register_operand" "=f,f")
13501 (match_operator:XF 3 "binary_fp_operator"
13503 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13504 (match_operand:XF 2 "register_operand" "0,f")]))]
13506 "* return output_387_binary_op (insn, operands);"
13507 [(set (attr "type")
13508 (cond [(match_operand:XF 3 "mult_operator")
13509 (const_string "fmul")
13510 (match_operand:XF 3 "div_operator")
13511 (const_string "fdiv")
13513 (const_string "fop")))
13514 (set_attr "mode" "<MODE>")])
13516 (define_insn "*fop_xf_5_i387"
13517 [(set (match_operand:XF 0 "register_operand" "=f,f")
13518 (match_operator:XF 3 "binary_fp_operator"
13519 [(match_operand:XF 1 "register_operand" "0,f")
13521 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13523 "* return output_387_binary_op (insn, operands);"
13524 [(set (attr "type")
13525 (cond [(match_operand:XF 3 "mult_operator")
13526 (const_string "fmul")
13527 (match_operand:XF 3 "div_operator")
13528 (const_string "fdiv")
13530 (const_string "fop")))
13531 (set_attr "mode" "<MODE>")])
13533 (define_insn "*fop_xf_6_i387"
13534 [(set (match_operand:XF 0 "register_operand" "=f,f")
13535 (match_operator:XF 3 "binary_fp_operator"
13537 (match_operand:MODEF 1 "register_operand" "0,f"))
13539 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13541 "* return output_387_binary_op (insn, operands);"
13542 [(set (attr "type")
13543 (cond [(match_operand:XF 3 "mult_operator")
13544 (const_string "fmul")
13545 (match_operand:XF 3 "div_operator")
13546 (const_string "fdiv")
13548 (const_string "fop")))
13549 (set_attr "mode" "<MODE>")])
13552 [(set (match_operand 0 "register_operand")
13553 (match_operator 3 "binary_fp_operator"
13554 [(float (match_operand:SWI24 1 "register_operand"))
13555 (match_operand 2 "register_operand")]))]
13557 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13558 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13561 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13562 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13563 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13564 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13565 GET_MODE (operands[3]),
13568 ix86_free_from_memory (GET_MODE (operands[1]));
13573 [(set (match_operand 0 "register_operand")
13574 (match_operator 3 "binary_fp_operator"
13575 [(match_operand 1 "register_operand")
13576 (float (match_operand:SWI24 2 "register_operand"))]))]
13578 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13579 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13582 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13583 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13584 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13585 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13586 GET_MODE (operands[3]),
13589 ix86_free_from_memory (GET_MODE (operands[2]));
13593 ;; FPU special functions.
13595 ;; This pattern implements a no-op XFmode truncation for
13596 ;; all fancy i386 XFmode math functions.
13598 (define_insn "truncxf<mode>2_i387_noop_unspec"
13599 [(set (match_operand:MODEF 0 "register_operand" "=f")
13600 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13601 UNSPEC_TRUNC_NOOP))]
13602 "TARGET_USE_FANCY_MATH_387"
13603 "* return output_387_reg_move (insn, operands);"
13604 [(set_attr "type" "fmov")
13605 (set_attr "mode" "<MODE>")])
13607 (define_insn "sqrtxf2"
13608 [(set (match_operand:XF 0 "register_operand" "=f")
13609 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13610 "TARGET_USE_FANCY_MATH_387"
13612 [(set_attr "type" "fpspc")
13613 (set_attr "mode" "XF")
13614 (set_attr "athlon_decode" "direct")
13615 (set_attr "amdfam10_decode" "direct")
13616 (set_attr "bdver1_decode" "direct")])
13618 (define_insn "sqrt_extend<mode>xf2_i387"
13619 [(set (match_operand:XF 0 "register_operand" "=f")
13622 (match_operand:MODEF 1 "register_operand" "0"))))]
13623 "TARGET_USE_FANCY_MATH_387"
13625 [(set_attr "type" "fpspc")
13626 (set_attr "mode" "XF")
13627 (set_attr "athlon_decode" "direct")
13628 (set_attr "amdfam10_decode" "direct")
13629 (set_attr "bdver1_decode" "direct")])
13631 (define_insn "*rsqrtsf2_sse"
13632 [(set (match_operand:SF 0 "register_operand" "=x")
13633 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13636 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13637 [(set_attr "type" "sse")
13638 (set_attr "atom_sse_attr" "rcp")
13639 (set_attr "btver2_sse_attr" "rcp")
13640 (set_attr "prefix" "maybe_vex")
13641 (set_attr "mode" "SF")])
13643 (define_expand "rsqrtsf2"
13644 [(set (match_operand:SF 0 "register_operand")
13645 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13649 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13653 (define_insn "*sqrt<mode>2_sse"
13654 [(set (match_operand:MODEF 0 "register_operand" "=x")
13656 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13657 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13658 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13659 [(set_attr "type" "sse")
13660 (set_attr "atom_sse_attr" "sqrt")
13661 (set_attr "btver2_sse_attr" "sqrt")
13662 (set_attr "prefix" "maybe_vex")
13663 (set_attr "mode" "<MODE>")
13664 (set_attr "athlon_decode" "*")
13665 (set_attr "amdfam10_decode" "*")
13666 (set_attr "bdver1_decode" "*")])
13668 (define_expand "sqrt<mode>2"
13669 [(set (match_operand:MODEF 0 "register_operand")
13671 (match_operand:MODEF 1 "nonimmediate_operand")))]
13672 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13673 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13675 if (<MODE>mode == SFmode
13677 && TARGET_RECIP_SQRT
13678 && !optimize_function_for_size_p (cfun)
13679 && flag_finite_math_only && !flag_trapping_math
13680 && flag_unsafe_math_optimizations)
13682 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13686 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13688 rtx op0 = gen_reg_rtx (XFmode);
13689 rtx op1 = force_reg (<MODE>mode, operands[1]);
13691 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13692 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13697 (define_insn "fpremxf4_i387"
13698 [(set (match_operand:XF 0 "register_operand" "=f")
13699 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13700 (match_operand:XF 3 "register_operand" "1")]
13702 (set (match_operand:XF 1 "register_operand" "=u")
13703 (unspec:XF [(match_dup 2) (match_dup 3)]
13705 (set (reg:CCFP FPSR_REG)
13706 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13708 "TARGET_USE_FANCY_MATH_387"
13710 [(set_attr "type" "fpspc")
13711 (set_attr "mode" "XF")])
13713 (define_expand "fmodxf3"
13714 [(use (match_operand:XF 0 "register_operand"))
13715 (use (match_operand:XF 1 "general_operand"))
13716 (use (match_operand:XF 2 "general_operand"))]
13717 "TARGET_USE_FANCY_MATH_387"
13719 rtx label = gen_label_rtx ();
13721 rtx op1 = gen_reg_rtx (XFmode);
13722 rtx op2 = gen_reg_rtx (XFmode);
13724 emit_move_insn (op2, operands[2]);
13725 emit_move_insn (op1, operands[1]);
13727 emit_label (label);
13728 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13729 ix86_emit_fp_unordered_jump (label);
13730 LABEL_NUSES (label) = 1;
13732 emit_move_insn (operands[0], op1);
13736 (define_expand "fmod<mode>3"
13737 [(use (match_operand:MODEF 0 "register_operand"))
13738 (use (match_operand:MODEF 1 "general_operand"))
13739 (use (match_operand:MODEF 2 "general_operand"))]
13740 "TARGET_USE_FANCY_MATH_387"
13742 rtx (*gen_truncxf) (rtx, rtx);
13744 rtx label = gen_label_rtx ();
13746 rtx op1 = gen_reg_rtx (XFmode);
13747 rtx op2 = gen_reg_rtx (XFmode);
13749 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13750 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13752 emit_label (label);
13753 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13754 ix86_emit_fp_unordered_jump (label);
13755 LABEL_NUSES (label) = 1;
13757 /* Truncate the result properly for strict SSE math. */
13758 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13759 && !TARGET_MIX_SSE_I387)
13760 gen_truncxf = gen_truncxf<mode>2;
13762 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13764 emit_insn (gen_truncxf (operands[0], op1));
13768 (define_insn "fprem1xf4_i387"
13769 [(set (match_operand:XF 0 "register_operand" "=f")
13770 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13771 (match_operand:XF 3 "register_operand" "1")]
13773 (set (match_operand:XF 1 "register_operand" "=u")
13774 (unspec:XF [(match_dup 2) (match_dup 3)]
13776 (set (reg:CCFP FPSR_REG)
13777 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13779 "TARGET_USE_FANCY_MATH_387"
13781 [(set_attr "type" "fpspc")
13782 (set_attr "mode" "XF")])
13784 (define_expand "remainderxf3"
13785 [(use (match_operand:XF 0 "register_operand"))
13786 (use (match_operand:XF 1 "general_operand"))
13787 (use (match_operand:XF 2 "general_operand"))]
13788 "TARGET_USE_FANCY_MATH_387"
13790 rtx label = gen_label_rtx ();
13792 rtx op1 = gen_reg_rtx (XFmode);
13793 rtx op2 = gen_reg_rtx (XFmode);
13795 emit_move_insn (op2, operands[2]);
13796 emit_move_insn (op1, operands[1]);
13798 emit_label (label);
13799 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13800 ix86_emit_fp_unordered_jump (label);
13801 LABEL_NUSES (label) = 1;
13803 emit_move_insn (operands[0], op1);
13807 (define_expand "remainder<mode>3"
13808 [(use (match_operand:MODEF 0 "register_operand"))
13809 (use (match_operand:MODEF 1 "general_operand"))
13810 (use (match_operand:MODEF 2 "general_operand"))]
13811 "TARGET_USE_FANCY_MATH_387"
13813 rtx (*gen_truncxf) (rtx, rtx);
13815 rtx label = gen_label_rtx ();
13817 rtx op1 = gen_reg_rtx (XFmode);
13818 rtx op2 = gen_reg_rtx (XFmode);
13820 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13821 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13823 emit_label (label);
13825 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13826 ix86_emit_fp_unordered_jump (label);
13827 LABEL_NUSES (label) = 1;
13829 /* Truncate the result properly for strict SSE math. */
13830 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13831 && !TARGET_MIX_SSE_I387)
13832 gen_truncxf = gen_truncxf<mode>2;
13834 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13836 emit_insn (gen_truncxf (operands[0], op1));
13840 (define_int_iterator SINCOS
13844 (define_int_attr sincos
13845 [(UNSPEC_SIN "sin")
13846 (UNSPEC_COS "cos")])
13848 (define_insn "*<sincos>xf2_i387"
13849 [(set (match_operand:XF 0 "register_operand" "=f")
13850 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13852 "TARGET_USE_FANCY_MATH_387
13853 && flag_unsafe_math_optimizations"
13855 [(set_attr "type" "fpspc")
13856 (set_attr "mode" "XF")])
13858 (define_insn "*<sincos>_extend<mode>xf2_i387"
13859 [(set (match_operand:XF 0 "register_operand" "=f")
13860 (unspec:XF [(float_extend:XF
13861 (match_operand:MODEF 1 "register_operand" "0"))]
13863 "TARGET_USE_FANCY_MATH_387
13864 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13865 || TARGET_MIX_SSE_I387)
13866 && flag_unsafe_math_optimizations"
13868 [(set_attr "type" "fpspc")
13869 (set_attr "mode" "XF")])
13871 ;; When sincos pattern is defined, sin and cos builtin functions will be
13872 ;; expanded to sincos pattern with one of its outputs left unused.
13873 ;; CSE pass will figure out if two sincos patterns can be combined,
13874 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13875 ;; depending on the unused output.
13877 (define_insn "sincosxf3"
13878 [(set (match_operand:XF 0 "register_operand" "=f")
13879 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13880 UNSPEC_SINCOS_COS))
13881 (set (match_operand:XF 1 "register_operand" "=u")
13882 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13883 "TARGET_USE_FANCY_MATH_387
13884 && flag_unsafe_math_optimizations"
13886 [(set_attr "type" "fpspc")
13887 (set_attr "mode" "XF")])
13890 [(set (match_operand:XF 0 "register_operand")
13891 (unspec:XF [(match_operand:XF 2 "register_operand")]
13892 UNSPEC_SINCOS_COS))
13893 (set (match_operand:XF 1 "register_operand")
13894 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13895 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13896 && can_create_pseudo_p ()"
13897 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13900 [(set (match_operand:XF 0 "register_operand")
13901 (unspec:XF [(match_operand:XF 2 "register_operand")]
13902 UNSPEC_SINCOS_COS))
13903 (set (match_operand:XF 1 "register_operand")
13904 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13905 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13906 && can_create_pseudo_p ()"
13907 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13909 (define_insn "sincos_extend<mode>xf3_i387"
13910 [(set (match_operand:XF 0 "register_operand" "=f")
13911 (unspec:XF [(float_extend:XF
13912 (match_operand:MODEF 2 "register_operand" "0"))]
13913 UNSPEC_SINCOS_COS))
13914 (set (match_operand:XF 1 "register_operand" "=u")
13915 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13916 "TARGET_USE_FANCY_MATH_387
13917 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13918 || TARGET_MIX_SSE_I387)
13919 && flag_unsafe_math_optimizations"
13921 [(set_attr "type" "fpspc")
13922 (set_attr "mode" "XF")])
13925 [(set (match_operand:XF 0 "register_operand")
13926 (unspec:XF [(float_extend:XF
13927 (match_operand:MODEF 2 "register_operand"))]
13928 UNSPEC_SINCOS_COS))
13929 (set (match_operand:XF 1 "register_operand")
13930 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13931 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13932 && can_create_pseudo_p ()"
13933 [(set (match_dup 1)
13934 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13937 [(set (match_operand:XF 0 "register_operand")
13938 (unspec:XF [(float_extend:XF
13939 (match_operand:MODEF 2 "register_operand"))]
13940 UNSPEC_SINCOS_COS))
13941 (set (match_operand:XF 1 "register_operand")
13942 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13943 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13944 && can_create_pseudo_p ()"
13945 [(set (match_dup 0)
13946 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13948 (define_expand "sincos<mode>3"
13949 [(use (match_operand:MODEF 0 "register_operand"))
13950 (use (match_operand:MODEF 1 "register_operand"))
13951 (use (match_operand:MODEF 2 "register_operand"))]
13952 "TARGET_USE_FANCY_MATH_387
13953 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13954 || TARGET_MIX_SSE_I387)
13955 && flag_unsafe_math_optimizations"
13957 rtx op0 = gen_reg_rtx (XFmode);
13958 rtx op1 = gen_reg_rtx (XFmode);
13960 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13961 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13962 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13966 (define_insn "fptanxf4_i387"
13967 [(set (match_operand:XF 0 "register_operand" "=f")
13968 (match_operand:XF 3 "const_double_operand" "F"))
13969 (set (match_operand:XF 1 "register_operand" "=u")
13970 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13972 "TARGET_USE_FANCY_MATH_387
13973 && flag_unsafe_math_optimizations
13974 && standard_80387_constant_p (operands[3]) == 2"
13976 [(set_attr "type" "fpspc")
13977 (set_attr "mode" "XF")])
13979 (define_insn "fptan_extend<mode>xf4_i387"
13980 [(set (match_operand:MODEF 0 "register_operand" "=f")
13981 (match_operand:MODEF 3 "const_double_operand" "F"))
13982 (set (match_operand:XF 1 "register_operand" "=u")
13983 (unspec:XF [(float_extend:XF
13984 (match_operand:MODEF 2 "register_operand" "0"))]
13986 "TARGET_USE_FANCY_MATH_387
13987 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13988 || TARGET_MIX_SSE_I387)
13989 && flag_unsafe_math_optimizations
13990 && standard_80387_constant_p (operands[3]) == 2"
13992 [(set_attr "type" "fpspc")
13993 (set_attr "mode" "XF")])
13995 (define_expand "tanxf2"
13996 [(use (match_operand:XF 0 "register_operand"))
13997 (use (match_operand:XF 1 "register_operand"))]
13998 "TARGET_USE_FANCY_MATH_387
13999 && flag_unsafe_math_optimizations"
14001 rtx one = gen_reg_rtx (XFmode);
14002 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14004 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14008 (define_expand "tan<mode>2"
14009 [(use (match_operand:MODEF 0 "register_operand"))
14010 (use (match_operand:MODEF 1 "register_operand"))]
14011 "TARGET_USE_FANCY_MATH_387
14012 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14013 || TARGET_MIX_SSE_I387)
14014 && flag_unsafe_math_optimizations"
14016 rtx op0 = gen_reg_rtx (XFmode);
14018 rtx one = gen_reg_rtx (<MODE>mode);
14019 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14021 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14022 operands[1], op2));
14023 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14027 (define_insn "*fpatanxf3_i387"
14028 [(set (match_operand:XF 0 "register_operand" "=f")
14029 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14030 (match_operand:XF 2 "register_operand" "u")]
14032 (clobber (match_scratch:XF 3 "=2"))]
14033 "TARGET_USE_FANCY_MATH_387
14034 && flag_unsafe_math_optimizations"
14036 [(set_attr "type" "fpspc")
14037 (set_attr "mode" "XF")])
14039 (define_insn "fpatan_extend<mode>xf3_i387"
14040 [(set (match_operand:XF 0 "register_operand" "=f")
14041 (unspec:XF [(float_extend:XF
14042 (match_operand:MODEF 1 "register_operand" "0"))
14044 (match_operand:MODEF 2 "register_operand" "u"))]
14046 (clobber (match_scratch:XF 3 "=2"))]
14047 "TARGET_USE_FANCY_MATH_387
14048 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14049 || TARGET_MIX_SSE_I387)
14050 && flag_unsafe_math_optimizations"
14052 [(set_attr "type" "fpspc")
14053 (set_attr "mode" "XF")])
14055 (define_expand "atan2xf3"
14056 [(parallel [(set (match_operand:XF 0 "register_operand")
14057 (unspec:XF [(match_operand:XF 2 "register_operand")
14058 (match_operand:XF 1 "register_operand")]
14060 (clobber (match_scratch:XF 3))])]
14061 "TARGET_USE_FANCY_MATH_387
14062 && flag_unsafe_math_optimizations")
14064 (define_expand "atan2<mode>3"
14065 [(use (match_operand:MODEF 0 "register_operand"))
14066 (use (match_operand:MODEF 1 "register_operand"))
14067 (use (match_operand:MODEF 2 "register_operand"))]
14068 "TARGET_USE_FANCY_MATH_387
14069 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14070 || TARGET_MIX_SSE_I387)
14071 && flag_unsafe_math_optimizations"
14073 rtx op0 = gen_reg_rtx (XFmode);
14075 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14076 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14080 (define_expand "atanxf2"
14081 [(parallel [(set (match_operand:XF 0 "register_operand")
14082 (unspec:XF [(match_dup 2)
14083 (match_operand:XF 1 "register_operand")]
14085 (clobber (match_scratch:XF 3))])]
14086 "TARGET_USE_FANCY_MATH_387
14087 && flag_unsafe_math_optimizations"
14089 operands[2] = gen_reg_rtx (XFmode);
14090 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14093 (define_expand "atan<mode>2"
14094 [(use (match_operand:MODEF 0 "register_operand"))
14095 (use (match_operand:MODEF 1 "register_operand"))]
14096 "TARGET_USE_FANCY_MATH_387
14097 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14098 || TARGET_MIX_SSE_I387)
14099 && flag_unsafe_math_optimizations"
14101 rtx op0 = gen_reg_rtx (XFmode);
14103 rtx op2 = gen_reg_rtx (<MODE>mode);
14104 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14106 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14107 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14111 (define_expand "asinxf2"
14112 [(set (match_dup 2)
14113 (mult:XF (match_operand:XF 1 "register_operand")
14115 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14116 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14117 (parallel [(set (match_operand:XF 0 "register_operand")
14118 (unspec:XF [(match_dup 5) (match_dup 1)]
14120 (clobber (match_scratch:XF 6))])]
14121 "TARGET_USE_FANCY_MATH_387
14122 && flag_unsafe_math_optimizations"
14126 if (optimize_insn_for_size_p ())
14129 for (i = 2; i < 6; i++)
14130 operands[i] = gen_reg_rtx (XFmode);
14132 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14135 (define_expand "asin<mode>2"
14136 [(use (match_operand:MODEF 0 "register_operand"))
14137 (use (match_operand:MODEF 1 "general_operand"))]
14138 "TARGET_USE_FANCY_MATH_387
14139 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14140 || TARGET_MIX_SSE_I387)
14141 && flag_unsafe_math_optimizations"
14143 rtx op0 = gen_reg_rtx (XFmode);
14144 rtx op1 = gen_reg_rtx (XFmode);
14146 if (optimize_insn_for_size_p ())
14149 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14150 emit_insn (gen_asinxf2 (op0, op1));
14151 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14155 (define_expand "acosxf2"
14156 [(set (match_dup 2)
14157 (mult:XF (match_operand:XF 1 "register_operand")
14159 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14160 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14161 (parallel [(set (match_operand:XF 0 "register_operand")
14162 (unspec:XF [(match_dup 1) (match_dup 5)]
14164 (clobber (match_scratch:XF 6))])]
14165 "TARGET_USE_FANCY_MATH_387
14166 && flag_unsafe_math_optimizations"
14170 if (optimize_insn_for_size_p ())
14173 for (i = 2; i < 6; i++)
14174 operands[i] = gen_reg_rtx (XFmode);
14176 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14179 (define_expand "acos<mode>2"
14180 [(use (match_operand:MODEF 0 "register_operand"))
14181 (use (match_operand:MODEF 1 "general_operand"))]
14182 "TARGET_USE_FANCY_MATH_387
14183 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14184 || TARGET_MIX_SSE_I387)
14185 && flag_unsafe_math_optimizations"
14187 rtx op0 = gen_reg_rtx (XFmode);
14188 rtx op1 = gen_reg_rtx (XFmode);
14190 if (optimize_insn_for_size_p ())
14193 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14194 emit_insn (gen_acosxf2 (op0, op1));
14195 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14199 (define_insn "fyl2xxf3_i387"
14200 [(set (match_operand:XF 0 "register_operand" "=f")
14201 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14202 (match_operand:XF 2 "register_operand" "u")]
14204 (clobber (match_scratch:XF 3 "=2"))]
14205 "TARGET_USE_FANCY_MATH_387
14206 && flag_unsafe_math_optimizations"
14208 [(set_attr "type" "fpspc")
14209 (set_attr "mode" "XF")])
14211 (define_insn "fyl2x_extend<mode>xf3_i387"
14212 [(set (match_operand:XF 0 "register_operand" "=f")
14213 (unspec:XF [(float_extend:XF
14214 (match_operand:MODEF 1 "register_operand" "0"))
14215 (match_operand:XF 2 "register_operand" "u")]
14217 (clobber (match_scratch:XF 3 "=2"))]
14218 "TARGET_USE_FANCY_MATH_387
14219 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14220 || TARGET_MIX_SSE_I387)
14221 && flag_unsafe_math_optimizations"
14223 [(set_attr "type" "fpspc")
14224 (set_attr "mode" "XF")])
14226 (define_expand "logxf2"
14227 [(parallel [(set (match_operand:XF 0 "register_operand")
14228 (unspec:XF [(match_operand:XF 1 "register_operand")
14229 (match_dup 2)] UNSPEC_FYL2X))
14230 (clobber (match_scratch:XF 3))])]
14231 "TARGET_USE_FANCY_MATH_387
14232 && flag_unsafe_math_optimizations"
14234 operands[2] = gen_reg_rtx (XFmode);
14235 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14238 (define_expand "log<mode>2"
14239 [(use (match_operand:MODEF 0 "register_operand"))
14240 (use (match_operand:MODEF 1 "register_operand"))]
14241 "TARGET_USE_FANCY_MATH_387
14242 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14243 || TARGET_MIX_SSE_I387)
14244 && flag_unsafe_math_optimizations"
14246 rtx op0 = gen_reg_rtx (XFmode);
14248 rtx op2 = gen_reg_rtx (XFmode);
14249 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14251 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14252 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14256 (define_expand "log10xf2"
14257 [(parallel [(set (match_operand:XF 0 "register_operand")
14258 (unspec:XF [(match_operand:XF 1 "register_operand")
14259 (match_dup 2)] UNSPEC_FYL2X))
14260 (clobber (match_scratch:XF 3))])]
14261 "TARGET_USE_FANCY_MATH_387
14262 && flag_unsafe_math_optimizations"
14264 operands[2] = gen_reg_rtx (XFmode);
14265 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14268 (define_expand "log10<mode>2"
14269 [(use (match_operand:MODEF 0 "register_operand"))
14270 (use (match_operand:MODEF 1 "register_operand"))]
14271 "TARGET_USE_FANCY_MATH_387
14272 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14273 || TARGET_MIX_SSE_I387)
14274 && flag_unsafe_math_optimizations"
14276 rtx op0 = gen_reg_rtx (XFmode);
14278 rtx op2 = gen_reg_rtx (XFmode);
14279 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14281 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14282 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14286 (define_expand "log2xf2"
14287 [(parallel [(set (match_operand:XF 0 "register_operand")
14288 (unspec:XF [(match_operand:XF 1 "register_operand")
14289 (match_dup 2)] UNSPEC_FYL2X))
14290 (clobber (match_scratch:XF 3))])]
14291 "TARGET_USE_FANCY_MATH_387
14292 && flag_unsafe_math_optimizations"
14294 operands[2] = gen_reg_rtx (XFmode);
14295 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14298 (define_expand "log2<mode>2"
14299 [(use (match_operand:MODEF 0 "register_operand"))
14300 (use (match_operand:MODEF 1 "register_operand"))]
14301 "TARGET_USE_FANCY_MATH_387
14302 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14303 || TARGET_MIX_SSE_I387)
14304 && flag_unsafe_math_optimizations"
14306 rtx op0 = gen_reg_rtx (XFmode);
14308 rtx op2 = gen_reg_rtx (XFmode);
14309 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14311 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14312 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14316 (define_insn "fyl2xp1xf3_i387"
14317 [(set (match_operand:XF 0 "register_operand" "=f")
14318 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14319 (match_operand:XF 2 "register_operand" "u")]
14321 (clobber (match_scratch:XF 3 "=2"))]
14322 "TARGET_USE_FANCY_MATH_387
14323 && flag_unsafe_math_optimizations"
14325 [(set_attr "type" "fpspc")
14326 (set_attr "mode" "XF")])
14328 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14329 [(set (match_operand:XF 0 "register_operand" "=f")
14330 (unspec:XF [(float_extend:XF
14331 (match_operand:MODEF 1 "register_operand" "0"))
14332 (match_operand:XF 2 "register_operand" "u")]
14334 (clobber (match_scratch:XF 3 "=2"))]
14335 "TARGET_USE_FANCY_MATH_387
14336 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14337 || TARGET_MIX_SSE_I387)
14338 && flag_unsafe_math_optimizations"
14340 [(set_attr "type" "fpspc")
14341 (set_attr "mode" "XF")])
14343 (define_expand "log1pxf2"
14344 [(use (match_operand:XF 0 "register_operand"))
14345 (use (match_operand:XF 1 "register_operand"))]
14346 "TARGET_USE_FANCY_MATH_387
14347 && flag_unsafe_math_optimizations"
14349 if (optimize_insn_for_size_p ())
14352 ix86_emit_i387_log1p (operands[0], operands[1]);
14356 (define_expand "log1p<mode>2"
14357 [(use (match_operand:MODEF 0 "register_operand"))
14358 (use (match_operand:MODEF 1 "register_operand"))]
14359 "TARGET_USE_FANCY_MATH_387
14360 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14361 || TARGET_MIX_SSE_I387)
14362 && flag_unsafe_math_optimizations"
14366 if (optimize_insn_for_size_p ())
14369 op0 = gen_reg_rtx (XFmode);
14371 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14373 ix86_emit_i387_log1p (op0, operands[1]);
14374 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14378 (define_insn "fxtractxf3_i387"
14379 [(set (match_operand:XF 0 "register_operand" "=f")
14380 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14381 UNSPEC_XTRACT_FRACT))
14382 (set (match_operand:XF 1 "register_operand" "=u")
14383 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14384 "TARGET_USE_FANCY_MATH_387
14385 && flag_unsafe_math_optimizations"
14387 [(set_attr "type" "fpspc")
14388 (set_attr "mode" "XF")])
14390 (define_insn "fxtract_extend<mode>xf3_i387"
14391 [(set (match_operand:XF 0 "register_operand" "=f")
14392 (unspec:XF [(float_extend:XF
14393 (match_operand:MODEF 2 "register_operand" "0"))]
14394 UNSPEC_XTRACT_FRACT))
14395 (set (match_operand:XF 1 "register_operand" "=u")
14396 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14397 "TARGET_USE_FANCY_MATH_387
14398 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14399 || TARGET_MIX_SSE_I387)
14400 && flag_unsafe_math_optimizations"
14402 [(set_attr "type" "fpspc")
14403 (set_attr "mode" "XF")])
14405 (define_expand "logbxf2"
14406 [(parallel [(set (match_dup 2)
14407 (unspec:XF [(match_operand:XF 1 "register_operand")]
14408 UNSPEC_XTRACT_FRACT))
14409 (set (match_operand:XF 0 "register_operand")
14410 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14411 "TARGET_USE_FANCY_MATH_387
14412 && flag_unsafe_math_optimizations"
14413 "operands[2] = gen_reg_rtx (XFmode);")
14415 (define_expand "logb<mode>2"
14416 [(use (match_operand:MODEF 0 "register_operand"))
14417 (use (match_operand:MODEF 1 "register_operand"))]
14418 "TARGET_USE_FANCY_MATH_387
14419 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14420 || TARGET_MIX_SSE_I387)
14421 && flag_unsafe_math_optimizations"
14423 rtx op0 = gen_reg_rtx (XFmode);
14424 rtx op1 = gen_reg_rtx (XFmode);
14426 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14427 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14431 (define_expand "ilogbxf2"
14432 [(use (match_operand:SI 0 "register_operand"))
14433 (use (match_operand:XF 1 "register_operand"))]
14434 "TARGET_USE_FANCY_MATH_387
14435 && flag_unsafe_math_optimizations"
14439 if (optimize_insn_for_size_p ())
14442 op0 = gen_reg_rtx (XFmode);
14443 op1 = gen_reg_rtx (XFmode);
14445 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14446 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14450 (define_expand "ilogb<mode>2"
14451 [(use (match_operand:SI 0 "register_operand"))
14452 (use (match_operand:MODEF 1 "register_operand"))]
14453 "TARGET_USE_FANCY_MATH_387
14454 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14455 || TARGET_MIX_SSE_I387)
14456 && flag_unsafe_math_optimizations"
14460 if (optimize_insn_for_size_p ())
14463 op0 = gen_reg_rtx (XFmode);
14464 op1 = gen_reg_rtx (XFmode);
14466 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14467 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14471 (define_insn "*f2xm1xf2_i387"
14472 [(set (match_operand:XF 0 "register_operand" "=f")
14473 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14475 "TARGET_USE_FANCY_MATH_387
14476 && flag_unsafe_math_optimizations"
14478 [(set_attr "type" "fpspc")
14479 (set_attr "mode" "XF")])
14481 (define_insn "*fscalexf4_i387"
14482 [(set (match_operand:XF 0 "register_operand" "=f")
14483 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14484 (match_operand:XF 3 "register_operand" "1")]
14485 UNSPEC_FSCALE_FRACT))
14486 (set (match_operand:XF 1 "register_operand" "=u")
14487 (unspec:XF [(match_dup 2) (match_dup 3)]
14488 UNSPEC_FSCALE_EXP))]
14489 "TARGET_USE_FANCY_MATH_387
14490 && flag_unsafe_math_optimizations"
14492 [(set_attr "type" "fpspc")
14493 (set_attr "mode" "XF")])
14495 (define_expand "expNcorexf3"
14496 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14497 (match_operand:XF 2 "register_operand")))
14498 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14499 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14500 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14501 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14502 (parallel [(set (match_operand:XF 0 "register_operand")
14503 (unspec:XF [(match_dup 8) (match_dup 4)]
14504 UNSPEC_FSCALE_FRACT))
14506 (unspec:XF [(match_dup 8) (match_dup 4)]
14507 UNSPEC_FSCALE_EXP))])]
14508 "TARGET_USE_FANCY_MATH_387
14509 && flag_unsafe_math_optimizations"
14513 if (optimize_insn_for_size_p ())
14516 for (i = 3; i < 10; i++)
14517 operands[i] = gen_reg_rtx (XFmode);
14519 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14522 (define_expand "expxf2"
14523 [(use (match_operand:XF 0 "register_operand"))
14524 (use (match_operand:XF 1 "register_operand"))]
14525 "TARGET_USE_FANCY_MATH_387
14526 && flag_unsafe_math_optimizations"
14530 if (optimize_insn_for_size_p ())
14533 op2 = gen_reg_rtx (XFmode);
14534 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14536 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14540 (define_expand "exp<mode>2"
14541 [(use (match_operand:MODEF 0 "register_operand"))
14542 (use (match_operand:MODEF 1 "general_operand"))]
14543 "TARGET_USE_FANCY_MATH_387
14544 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14545 || TARGET_MIX_SSE_I387)
14546 && flag_unsafe_math_optimizations"
14550 if (optimize_insn_for_size_p ())
14553 op0 = gen_reg_rtx (XFmode);
14554 op1 = gen_reg_rtx (XFmode);
14556 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14557 emit_insn (gen_expxf2 (op0, op1));
14558 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14562 (define_expand "exp10xf2"
14563 [(use (match_operand:XF 0 "register_operand"))
14564 (use (match_operand:XF 1 "register_operand"))]
14565 "TARGET_USE_FANCY_MATH_387
14566 && flag_unsafe_math_optimizations"
14570 if (optimize_insn_for_size_p ())
14573 op2 = gen_reg_rtx (XFmode);
14574 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14576 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14580 (define_expand "exp10<mode>2"
14581 [(use (match_operand:MODEF 0 "register_operand"))
14582 (use (match_operand:MODEF 1 "general_operand"))]
14583 "TARGET_USE_FANCY_MATH_387
14584 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14585 || TARGET_MIX_SSE_I387)
14586 && flag_unsafe_math_optimizations"
14590 if (optimize_insn_for_size_p ())
14593 op0 = gen_reg_rtx (XFmode);
14594 op1 = gen_reg_rtx (XFmode);
14596 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14597 emit_insn (gen_exp10xf2 (op0, op1));
14598 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14602 (define_expand "exp2xf2"
14603 [(use (match_operand:XF 0 "register_operand"))
14604 (use (match_operand:XF 1 "register_operand"))]
14605 "TARGET_USE_FANCY_MATH_387
14606 && flag_unsafe_math_optimizations"
14610 if (optimize_insn_for_size_p ())
14613 op2 = gen_reg_rtx (XFmode);
14614 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14616 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14620 (define_expand "exp2<mode>2"
14621 [(use (match_operand:MODEF 0 "register_operand"))
14622 (use (match_operand:MODEF 1 "general_operand"))]
14623 "TARGET_USE_FANCY_MATH_387
14624 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14625 || TARGET_MIX_SSE_I387)
14626 && flag_unsafe_math_optimizations"
14630 if (optimize_insn_for_size_p ())
14633 op0 = gen_reg_rtx (XFmode);
14634 op1 = gen_reg_rtx (XFmode);
14636 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14637 emit_insn (gen_exp2xf2 (op0, op1));
14638 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14642 (define_expand "expm1xf2"
14643 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14645 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14646 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14647 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14648 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14649 (parallel [(set (match_dup 7)
14650 (unspec:XF [(match_dup 6) (match_dup 4)]
14651 UNSPEC_FSCALE_FRACT))
14653 (unspec:XF [(match_dup 6) (match_dup 4)]
14654 UNSPEC_FSCALE_EXP))])
14655 (parallel [(set (match_dup 10)
14656 (unspec:XF [(match_dup 9) (match_dup 8)]
14657 UNSPEC_FSCALE_FRACT))
14658 (set (match_dup 11)
14659 (unspec:XF [(match_dup 9) (match_dup 8)]
14660 UNSPEC_FSCALE_EXP))])
14661 (set (match_dup 12) (minus:XF (match_dup 10)
14662 (float_extend:XF (match_dup 13))))
14663 (set (match_operand:XF 0 "register_operand")
14664 (plus:XF (match_dup 12) (match_dup 7)))]
14665 "TARGET_USE_FANCY_MATH_387
14666 && flag_unsafe_math_optimizations"
14670 if (optimize_insn_for_size_p ())
14673 for (i = 2; i < 13; i++)
14674 operands[i] = gen_reg_rtx (XFmode);
14677 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14679 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14682 (define_expand "expm1<mode>2"
14683 [(use (match_operand:MODEF 0 "register_operand"))
14684 (use (match_operand:MODEF 1 "general_operand"))]
14685 "TARGET_USE_FANCY_MATH_387
14686 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14687 || TARGET_MIX_SSE_I387)
14688 && flag_unsafe_math_optimizations"
14692 if (optimize_insn_for_size_p ())
14695 op0 = gen_reg_rtx (XFmode);
14696 op1 = gen_reg_rtx (XFmode);
14698 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14699 emit_insn (gen_expm1xf2 (op0, op1));
14700 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14704 (define_expand "ldexpxf3"
14705 [(set (match_dup 3)
14706 (float:XF (match_operand:SI 2 "register_operand")))
14707 (parallel [(set (match_operand:XF 0 " register_operand")
14708 (unspec:XF [(match_operand:XF 1 "register_operand")
14710 UNSPEC_FSCALE_FRACT))
14712 (unspec:XF [(match_dup 1) (match_dup 3)]
14713 UNSPEC_FSCALE_EXP))])]
14714 "TARGET_USE_FANCY_MATH_387
14715 && flag_unsafe_math_optimizations"
14717 if (optimize_insn_for_size_p ())
14720 operands[3] = gen_reg_rtx (XFmode);
14721 operands[4] = gen_reg_rtx (XFmode);
14724 (define_expand "ldexp<mode>3"
14725 [(use (match_operand:MODEF 0 "register_operand"))
14726 (use (match_operand:MODEF 1 "general_operand"))
14727 (use (match_operand:SI 2 "register_operand"))]
14728 "TARGET_USE_FANCY_MATH_387
14729 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14730 || TARGET_MIX_SSE_I387)
14731 && flag_unsafe_math_optimizations"
14735 if (optimize_insn_for_size_p ())
14738 op0 = gen_reg_rtx (XFmode);
14739 op1 = gen_reg_rtx (XFmode);
14741 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14742 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14743 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14747 (define_expand "scalbxf3"
14748 [(parallel [(set (match_operand:XF 0 " register_operand")
14749 (unspec:XF [(match_operand:XF 1 "register_operand")
14750 (match_operand:XF 2 "register_operand")]
14751 UNSPEC_FSCALE_FRACT))
14753 (unspec:XF [(match_dup 1) (match_dup 2)]
14754 UNSPEC_FSCALE_EXP))])]
14755 "TARGET_USE_FANCY_MATH_387
14756 && flag_unsafe_math_optimizations"
14758 if (optimize_insn_for_size_p ())
14761 operands[3] = gen_reg_rtx (XFmode);
14764 (define_expand "scalb<mode>3"
14765 [(use (match_operand:MODEF 0 "register_operand"))
14766 (use (match_operand:MODEF 1 "general_operand"))
14767 (use (match_operand:MODEF 2 "general_operand"))]
14768 "TARGET_USE_FANCY_MATH_387
14769 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14770 || TARGET_MIX_SSE_I387)
14771 && flag_unsafe_math_optimizations"
14775 if (optimize_insn_for_size_p ())
14778 op0 = gen_reg_rtx (XFmode);
14779 op1 = gen_reg_rtx (XFmode);
14780 op2 = gen_reg_rtx (XFmode);
14782 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14783 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14784 emit_insn (gen_scalbxf3 (op0, op1, op2));
14785 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14789 (define_expand "significandxf2"
14790 [(parallel [(set (match_operand:XF 0 "register_operand")
14791 (unspec:XF [(match_operand:XF 1 "register_operand")]
14792 UNSPEC_XTRACT_FRACT))
14794 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14795 "TARGET_USE_FANCY_MATH_387
14796 && flag_unsafe_math_optimizations"
14797 "operands[2] = gen_reg_rtx (XFmode);")
14799 (define_expand "significand<mode>2"
14800 [(use (match_operand:MODEF 0 "register_operand"))
14801 (use (match_operand:MODEF 1 "register_operand"))]
14802 "TARGET_USE_FANCY_MATH_387
14803 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14804 || TARGET_MIX_SSE_I387)
14805 && flag_unsafe_math_optimizations"
14807 rtx op0 = gen_reg_rtx (XFmode);
14808 rtx op1 = gen_reg_rtx (XFmode);
14810 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14811 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14816 (define_insn "sse4_1_round<mode>2"
14817 [(set (match_operand:MODEF 0 "register_operand" "=x")
14818 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14819 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14822 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14823 [(set_attr "type" "ssecvt")
14824 (set_attr "prefix_extra" "1")
14825 (set_attr "prefix" "maybe_vex")
14826 (set_attr "mode" "<MODE>")])
14828 (define_insn "rintxf2"
14829 [(set (match_operand:XF 0 "register_operand" "=f")
14830 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14832 "TARGET_USE_FANCY_MATH_387
14833 && flag_unsafe_math_optimizations"
14835 [(set_attr "type" "fpspc")
14836 (set_attr "mode" "XF")])
14838 (define_expand "rint<mode>2"
14839 [(use (match_operand:MODEF 0 "register_operand"))
14840 (use (match_operand:MODEF 1 "register_operand"))]
14841 "(TARGET_USE_FANCY_MATH_387
14842 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14843 || TARGET_MIX_SSE_I387)
14844 && flag_unsafe_math_optimizations)
14845 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14846 && !flag_trapping_math)"
14848 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14849 && !flag_trapping_math)
14852 emit_insn (gen_sse4_1_round<mode>2
14853 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14854 else if (optimize_insn_for_size_p ())
14857 ix86_expand_rint (operands[0], operands[1]);
14861 rtx op0 = gen_reg_rtx (XFmode);
14862 rtx op1 = gen_reg_rtx (XFmode);
14864 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14865 emit_insn (gen_rintxf2 (op0, op1));
14867 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14872 (define_expand "round<mode>2"
14873 [(match_operand:X87MODEF 0 "register_operand")
14874 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14875 "(TARGET_USE_FANCY_MATH_387
14876 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14877 || TARGET_MIX_SSE_I387)
14878 && flag_unsafe_math_optimizations)
14879 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14880 && !flag_trapping_math && !flag_rounding_math)"
14882 if (optimize_insn_for_size_p ())
14885 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14886 && !flag_trapping_math && !flag_rounding_math)
14890 operands[1] = force_reg (<MODE>mode, operands[1]);
14891 ix86_expand_round_sse4 (operands[0], operands[1]);
14893 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14894 ix86_expand_round (operands[0], operands[1]);
14896 ix86_expand_rounddf_32 (operands[0], operands[1]);
14900 operands[1] = force_reg (<MODE>mode, operands[1]);
14901 ix86_emit_i387_round (operands[0], operands[1]);
14906 (define_insn_and_split "*fistdi2_1"
14907 [(set (match_operand:DI 0 "nonimmediate_operand")
14908 (unspec:DI [(match_operand:XF 1 "register_operand")]
14910 "TARGET_USE_FANCY_MATH_387
14911 && can_create_pseudo_p ()"
14916 if (memory_operand (operands[0], VOIDmode))
14917 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14920 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14921 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14926 [(set_attr "type" "fpspc")
14927 (set_attr "mode" "DI")])
14929 (define_insn "fistdi2"
14930 [(set (match_operand:DI 0 "memory_operand" "=m")
14931 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14933 (clobber (match_scratch:XF 2 "=&1f"))]
14934 "TARGET_USE_FANCY_MATH_387"
14935 "* return output_fix_trunc (insn, operands, false);"
14936 [(set_attr "type" "fpspc")
14937 (set_attr "mode" "DI")])
14939 (define_insn "fistdi2_with_temp"
14940 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14941 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14943 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14944 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14945 "TARGET_USE_FANCY_MATH_387"
14947 [(set_attr "type" "fpspc")
14948 (set_attr "mode" "DI")])
14951 [(set (match_operand:DI 0 "register_operand")
14952 (unspec:DI [(match_operand:XF 1 "register_operand")]
14954 (clobber (match_operand:DI 2 "memory_operand"))
14955 (clobber (match_scratch 3))]
14957 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14958 (clobber (match_dup 3))])
14959 (set (match_dup 0) (match_dup 2))])
14962 [(set (match_operand:DI 0 "memory_operand")
14963 (unspec:DI [(match_operand:XF 1 "register_operand")]
14965 (clobber (match_operand:DI 2 "memory_operand"))
14966 (clobber (match_scratch 3))]
14968 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14969 (clobber (match_dup 3))])])
14971 (define_insn_and_split "*fist<mode>2_1"
14972 [(set (match_operand:SWI24 0 "register_operand")
14973 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14975 "TARGET_USE_FANCY_MATH_387
14976 && can_create_pseudo_p ()"
14981 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14982 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14986 [(set_attr "type" "fpspc")
14987 (set_attr "mode" "<MODE>")])
14989 (define_insn "fist<mode>2"
14990 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14991 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14993 "TARGET_USE_FANCY_MATH_387"
14994 "* return output_fix_trunc (insn, operands, false);"
14995 [(set_attr "type" "fpspc")
14996 (set_attr "mode" "<MODE>")])
14998 (define_insn "fist<mode>2_with_temp"
14999 [(set (match_operand:SWI24 0 "register_operand" "=r")
15000 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15002 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15003 "TARGET_USE_FANCY_MATH_387"
15005 [(set_attr "type" "fpspc")
15006 (set_attr "mode" "<MODE>")])
15009 [(set (match_operand:SWI24 0 "register_operand")
15010 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15012 (clobber (match_operand:SWI24 2 "memory_operand"))]
15014 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15015 (set (match_dup 0) (match_dup 2))])
15018 [(set (match_operand:SWI24 0 "memory_operand")
15019 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15021 (clobber (match_operand:SWI24 2 "memory_operand"))]
15023 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15025 (define_expand "lrintxf<mode>2"
15026 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15027 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15029 "TARGET_USE_FANCY_MATH_387")
15031 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15032 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15033 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15034 UNSPEC_FIX_NOTRUNC))]
15035 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15037 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15038 [(match_operand:SWI248x 0 "nonimmediate_operand")
15039 (match_operand:X87MODEF 1 "register_operand")]
15040 "(TARGET_USE_FANCY_MATH_387
15041 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15042 || TARGET_MIX_SSE_I387)
15043 && flag_unsafe_math_optimizations)
15044 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15045 && <SWI248x:MODE>mode != HImode
15046 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15047 && !flag_trapping_math && !flag_rounding_math)"
15049 if (optimize_insn_for_size_p ())
15052 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15053 && <SWI248x:MODE>mode != HImode
15054 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15055 && !flag_trapping_math && !flag_rounding_math)
15056 ix86_expand_lround (operands[0], operands[1]);
15058 ix86_emit_i387_round (operands[0], operands[1]);
15062 (define_int_iterator FRNDINT_ROUNDING
15063 [UNSPEC_FRNDINT_FLOOR
15064 UNSPEC_FRNDINT_CEIL
15065 UNSPEC_FRNDINT_TRUNC])
15067 (define_int_iterator FIST_ROUNDING
15071 ;; Base name for define_insn
15072 (define_int_attr rounding_insn
15073 [(UNSPEC_FRNDINT_FLOOR "floor")
15074 (UNSPEC_FRNDINT_CEIL "ceil")
15075 (UNSPEC_FRNDINT_TRUNC "btrunc")
15076 (UNSPEC_FIST_FLOOR "floor")
15077 (UNSPEC_FIST_CEIL "ceil")])
15079 (define_int_attr rounding
15080 [(UNSPEC_FRNDINT_FLOOR "floor")
15081 (UNSPEC_FRNDINT_CEIL "ceil")
15082 (UNSPEC_FRNDINT_TRUNC "trunc")
15083 (UNSPEC_FIST_FLOOR "floor")
15084 (UNSPEC_FIST_CEIL "ceil")])
15086 (define_int_attr ROUNDING
15087 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15088 (UNSPEC_FRNDINT_CEIL "CEIL")
15089 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15090 (UNSPEC_FIST_FLOOR "FLOOR")
15091 (UNSPEC_FIST_CEIL "CEIL")])
15093 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15094 (define_insn_and_split "frndintxf2_<rounding>"
15095 [(set (match_operand:XF 0 "register_operand")
15096 (unspec:XF [(match_operand:XF 1 "register_operand")]
15098 (clobber (reg:CC FLAGS_REG))]
15099 "TARGET_USE_FANCY_MATH_387
15100 && flag_unsafe_math_optimizations
15101 && can_create_pseudo_p ()"
15106 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15108 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15109 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15111 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15112 operands[2], operands[3]));
15115 [(set_attr "type" "frndint")
15116 (set_attr "i387_cw" "<rounding>")
15117 (set_attr "mode" "XF")])
15119 (define_insn "frndintxf2_<rounding>_i387"
15120 [(set (match_operand:XF 0 "register_operand" "=f")
15121 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15123 (use (match_operand:HI 2 "memory_operand" "m"))
15124 (use (match_operand:HI 3 "memory_operand" "m"))]
15125 "TARGET_USE_FANCY_MATH_387
15126 && flag_unsafe_math_optimizations"
15127 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15128 [(set_attr "type" "frndint")
15129 (set_attr "i387_cw" "<rounding>")
15130 (set_attr "mode" "XF")])
15132 (define_expand "<rounding_insn>xf2"
15133 [(parallel [(set (match_operand:XF 0 "register_operand")
15134 (unspec:XF [(match_operand:XF 1 "register_operand")]
15136 (clobber (reg:CC FLAGS_REG))])]
15137 "TARGET_USE_FANCY_MATH_387
15138 && flag_unsafe_math_optimizations
15139 && !optimize_insn_for_size_p ()")
15141 (define_expand "<rounding_insn><mode>2"
15142 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15143 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15145 (clobber (reg:CC FLAGS_REG))])]
15146 "(TARGET_USE_FANCY_MATH_387
15147 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15148 || TARGET_MIX_SSE_I387)
15149 && flag_unsafe_math_optimizations)
15150 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15151 && !flag_trapping_math)"
15153 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15154 && !flag_trapping_math)
15157 emit_insn (gen_sse4_1_round<mode>2
15158 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15159 else if (optimize_insn_for_size_p ())
15161 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15163 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15164 ix86_expand_floorceil (operands[0], operands[1], true);
15165 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15166 ix86_expand_floorceil (operands[0], operands[1], false);
15167 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15168 ix86_expand_trunc (operands[0], operands[1]);
15170 gcc_unreachable ();
15174 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15175 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15176 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15177 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15178 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15179 ix86_expand_truncdf_32 (operands[0], operands[1]);
15181 gcc_unreachable ();
15188 if (optimize_insn_for_size_p ())
15191 op0 = gen_reg_rtx (XFmode);
15192 op1 = gen_reg_rtx (XFmode);
15193 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15194 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15196 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15201 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15202 (define_insn_and_split "frndintxf2_mask_pm"
15203 [(set (match_operand:XF 0 "register_operand")
15204 (unspec:XF [(match_operand:XF 1 "register_operand")]
15205 UNSPEC_FRNDINT_MASK_PM))
15206 (clobber (reg:CC FLAGS_REG))]
15207 "TARGET_USE_FANCY_MATH_387
15208 && flag_unsafe_math_optimizations
15209 && can_create_pseudo_p ()"
15214 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15216 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15217 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15219 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15220 operands[2], operands[3]));
15223 [(set_attr "type" "frndint")
15224 (set_attr "i387_cw" "mask_pm")
15225 (set_attr "mode" "XF")])
15227 (define_insn "frndintxf2_mask_pm_i387"
15228 [(set (match_operand:XF 0 "register_operand" "=f")
15229 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15230 UNSPEC_FRNDINT_MASK_PM))
15231 (use (match_operand:HI 2 "memory_operand" "m"))
15232 (use (match_operand:HI 3 "memory_operand" "m"))]
15233 "TARGET_USE_FANCY_MATH_387
15234 && flag_unsafe_math_optimizations"
15235 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15236 [(set_attr "type" "frndint")
15237 (set_attr "i387_cw" "mask_pm")
15238 (set_attr "mode" "XF")])
15240 (define_expand "nearbyintxf2"
15241 [(parallel [(set (match_operand:XF 0 "register_operand")
15242 (unspec:XF [(match_operand:XF 1 "register_operand")]
15243 UNSPEC_FRNDINT_MASK_PM))
15244 (clobber (reg:CC FLAGS_REG))])]
15245 "TARGET_USE_FANCY_MATH_387
15246 && flag_unsafe_math_optimizations")
15248 (define_expand "nearbyint<mode>2"
15249 [(use (match_operand:MODEF 0 "register_operand"))
15250 (use (match_operand:MODEF 1 "register_operand"))]
15251 "TARGET_USE_FANCY_MATH_387
15252 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15253 || TARGET_MIX_SSE_I387)
15254 && flag_unsafe_math_optimizations"
15256 rtx op0 = gen_reg_rtx (XFmode);
15257 rtx op1 = gen_reg_rtx (XFmode);
15259 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15260 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15262 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15266 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15267 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15268 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15269 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15271 (clobber (reg:CC FLAGS_REG))]
15272 "TARGET_USE_FANCY_MATH_387
15273 && flag_unsafe_math_optimizations
15274 && can_create_pseudo_p ()"
15279 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15281 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15282 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15283 if (memory_operand (operands[0], VOIDmode))
15284 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15285 operands[2], operands[3]));
15288 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15289 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15290 (operands[0], operands[1], operands[2],
15291 operands[3], operands[4]));
15295 [(set_attr "type" "fistp")
15296 (set_attr "i387_cw" "<rounding>")
15297 (set_attr "mode" "<MODE>")])
15299 (define_insn "fistdi2_<rounding>"
15300 [(set (match_operand:DI 0 "memory_operand" "=m")
15301 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15303 (use (match_operand:HI 2 "memory_operand" "m"))
15304 (use (match_operand:HI 3 "memory_operand" "m"))
15305 (clobber (match_scratch:XF 4 "=&1f"))]
15306 "TARGET_USE_FANCY_MATH_387
15307 && flag_unsafe_math_optimizations"
15308 "* return output_fix_trunc (insn, operands, false);"
15309 [(set_attr "type" "fistp")
15310 (set_attr "i387_cw" "<rounding>")
15311 (set_attr "mode" "DI")])
15313 (define_insn "fistdi2_<rounding>_with_temp"
15314 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15315 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15317 (use (match_operand:HI 2 "memory_operand" "m,m"))
15318 (use (match_operand:HI 3 "memory_operand" "m,m"))
15319 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15320 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15321 "TARGET_USE_FANCY_MATH_387
15322 && flag_unsafe_math_optimizations"
15324 [(set_attr "type" "fistp")
15325 (set_attr "i387_cw" "<rounding>")
15326 (set_attr "mode" "DI")])
15329 [(set (match_operand:DI 0 "register_operand")
15330 (unspec:DI [(match_operand:XF 1 "register_operand")]
15332 (use (match_operand:HI 2 "memory_operand"))
15333 (use (match_operand:HI 3 "memory_operand"))
15334 (clobber (match_operand:DI 4 "memory_operand"))
15335 (clobber (match_scratch 5))]
15337 [(parallel [(set (match_dup 4)
15338 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15339 (use (match_dup 2))
15340 (use (match_dup 3))
15341 (clobber (match_dup 5))])
15342 (set (match_dup 0) (match_dup 4))])
15345 [(set (match_operand:DI 0 "memory_operand")
15346 (unspec:DI [(match_operand:XF 1 "register_operand")]
15348 (use (match_operand:HI 2 "memory_operand"))
15349 (use (match_operand:HI 3 "memory_operand"))
15350 (clobber (match_operand:DI 4 "memory_operand"))
15351 (clobber (match_scratch 5))]
15353 [(parallel [(set (match_dup 0)
15354 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15355 (use (match_dup 2))
15356 (use (match_dup 3))
15357 (clobber (match_dup 5))])])
15359 (define_insn "fist<mode>2_<rounding>"
15360 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15361 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15363 (use (match_operand:HI 2 "memory_operand" "m"))
15364 (use (match_operand:HI 3 "memory_operand" "m"))]
15365 "TARGET_USE_FANCY_MATH_387
15366 && flag_unsafe_math_optimizations"
15367 "* return output_fix_trunc (insn, operands, false);"
15368 [(set_attr "type" "fistp")
15369 (set_attr "i387_cw" "<rounding>")
15370 (set_attr "mode" "<MODE>")])
15372 (define_insn "fist<mode>2_<rounding>_with_temp"
15373 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15374 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15376 (use (match_operand:HI 2 "memory_operand" "m,m"))
15377 (use (match_operand:HI 3 "memory_operand" "m,m"))
15378 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15379 "TARGET_USE_FANCY_MATH_387
15380 && flag_unsafe_math_optimizations"
15382 [(set_attr "type" "fistp")
15383 (set_attr "i387_cw" "<rounding>")
15384 (set_attr "mode" "<MODE>")])
15387 [(set (match_operand:SWI24 0 "register_operand")
15388 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15390 (use (match_operand:HI 2 "memory_operand"))
15391 (use (match_operand:HI 3 "memory_operand"))
15392 (clobber (match_operand:SWI24 4 "memory_operand"))]
15394 [(parallel [(set (match_dup 4)
15395 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15396 (use (match_dup 2))
15397 (use (match_dup 3))])
15398 (set (match_dup 0) (match_dup 4))])
15401 [(set (match_operand:SWI24 0 "memory_operand")
15402 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15404 (use (match_operand:HI 2 "memory_operand"))
15405 (use (match_operand:HI 3 "memory_operand"))
15406 (clobber (match_operand:SWI24 4 "memory_operand"))]
15408 [(parallel [(set (match_dup 0)
15409 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15410 (use (match_dup 2))
15411 (use (match_dup 3))])])
15413 (define_expand "l<rounding_insn>xf<mode>2"
15414 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15415 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15417 (clobber (reg:CC FLAGS_REG))])]
15418 "TARGET_USE_FANCY_MATH_387
15419 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15420 && flag_unsafe_math_optimizations")
15422 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15423 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15424 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15426 (clobber (reg:CC FLAGS_REG))])]
15427 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15428 && !flag_trapping_math"
15430 if (TARGET_64BIT && optimize_insn_for_size_p ())
15433 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15434 ix86_expand_lfloorceil (operands[0], operands[1], true);
15435 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15436 ix86_expand_lfloorceil (operands[0], operands[1], false);
15438 gcc_unreachable ();
15443 (define_insn "fxam<mode>2_i387"
15444 [(set (match_operand:HI 0 "register_operand" "=a")
15446 [(match_operand:X87MODEF 1 "register_operand" "f")]
15448 "TARGET_USE_FANCY_MATH_387"
15449 "fxam\n\tfnstsw\t%0"
15450 [(set_attr "type" "multi")
15451 (set_attr "length" "4")
15452 (set_attr "unit" "i387")
15453 (set_attr "mode" "<MODE>")])
15455 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15456 [(set (match_operand:HI 0 "register_operand")
15458 [(match_operand:MODEF 1 "memory_operand")]
15460 "TARGET_USE_FANCY_MATH_387
15461 && can_create_pseudo_p ()"
15464 [(set (match_dup 2)(match_dup 1))
15466 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15468 operands[2] = gen_reg_rtx (<MODE>mode);
15470 MEM_VOLATILE_P (operands[1]) = 1;
15472 [(set_attr "type" "multi")
15473 (set_attr "unit" "i387")
15474 (set_attr "mode" "<MODE>")])
15476 (define_expand "isinfxf2"
15477 [(use (match_operand:SI 0 "register_operand"))
15478 (use (match_operand:XF 1 "register_operand"))]
15479 "TARGET_USE_FANCY_MATH_387
15480 && ix86_libc_has_function (function_c99_misc)"
15482 rtx mask = GEN_INT (0x45);
15483 rtx val = GEN_INT (0x05);
15487 rtx scratch = gen_reg_rtx (HImode);
15488 rtx res = gen_reg_rtx (QImode);
15490 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15492 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15493 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15494 cond = gen_rtx_fmt_ee (EQ, QImode,
15495 gen_rtx_REG (CCmode, FLAGS_REG),
15497 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15498 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15502 (define_expand "isinf<mode>2"
15503 [(use (match_operand:SI 0 "register_operand"))
15504 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15505 "TARGET_USE_FANCY_MATH_387
15506 && ix86_libc_has_function (function_c99_misc)
15507 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15509 rtx mask = GEN_INT (0x45);
15510 rtx val = GEN_INT (0x05);
15514 rtx scratch = gen_reg_rtx (HImode);
15515 rtx res = gen_reg_rtx (QImode);
15517 /* Remove excess precision by forcing value through memory. */
15518 if (memory_operand (operands[1], VOIDmode))
15519 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15522 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15524 emit_move_insn (temp, operands[1]);
15525 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15528 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15529 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15530 cond = gen_rtx_fmt_ee (EQ, QImode,
15531 gen_rtx_REG (CCmode, FLAGS_REG),
15533 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15534 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15538 (define_expand "signbitxf2"
15539 [(use (match_operand:SI 0 "register_operand"))
15540 (use (match_operand:XF 1 "register_operand"))]
15541 "TARGET_USE_FANCY_MATH_387"
15543 rtx scratch = gen_reg_rtx (HImode);
15545 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15546 emit_insn (gen_andsi3 (operands[0],
15547 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15551 (define_insn "movmsk_df"
15552 [(set (match_operand:SI 0 "register_operand" "=r")
15554 [(match_operand:DF 1 "register_operand" "x")]
15556 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15557 "%vmovmskpd\t{%1, %0|%0, %1}"
15558 [(set_attr "type" "ssemov")
15559 (set_attr "prefix" "maybe_vex")
15560 (set_attr "mode" "DF")])
15562 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15563 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15564 (define_expand "signbitdf2"
15565 [(use (match_operand:SI 0 "register_operand"))
15566 (use (match_operand:DF 1 "register_operand"))]
15567 "TARGET_USE_FANCY_MATH_387
15568 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15570 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15572 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15573 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15577 rtx scratch = gen_reg_rtx (HImode);
15579 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15580 emit_insn (gen_andsi3 (operands[0],
15581 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15586 (define_expand "signbitsf2"
15587 [(use (match_operand:SI 0 "register_operand"))
15588 (use (match_operand:SF 1 "register_operand"))]
15589 "TARGET_USE_FANCY_MATH_387
15590 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15592 rtx scratch = gen_reg_rtx (HImode);
15594 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15595 emit_insn (gen_andsi3 (operands[0],
15596 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15600 ;; Block operation instructions
15603 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15606 [(set_attr "length" "1")
15607 (set_attr "length_immediate" "0")
15608 (set_attr "modrm" "0")])
15610 (define_expand "movmem<mode>"
15611 [(use (match_operand:BLK 0 "memory_operand"))
15612 (use (match_operand:BLK 1 "memory_operand"))
15613 (use (match_operand:SWI48 2 "nonmemory_operand"))
15614 (use (match_operand:SWI48 3 "const_int_operand"))
15615 (use (match_operand:SI 4 "const_int_operand"))
15616 (use (match_operand:SI 5 "const_int_operand"))
15617 (use (match_operand:SI 6 ""))
15618 (use (match_operand:SI 7 ""))
15619 (use (match_operand:SI 8 ""))]
15622 if (ix86_expand_set_or_movmem (operands[0], operands[1],
15623 operands[2], NULL, operands[3],
15624 operands[4], operands[5],
15625 operands[6], operands[7],
15626 operands[8], false))
15632 ;; Most CPUs don't like single string operations
15633 ;; Handle this case here to simplify previous expander.
15635 (define_expand "strmov"
15636 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15637 (set (match_operand 1 "memory_operand") (match_dup 4))
15638 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15639 (clobber (reg:CC FLAGS_REG))])
15640 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15641 (clobber (reg:CC FLAGS_REG))])]
15644 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15646 /* If .md ever supports :P for Pmode, these can be directly
15647 in the pattern above. */
15648 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15649 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15651 /* Can't use this if the user has appropriated esi or edi. */
15652 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15653 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15655 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15656 operands[2], operands[3],
15657 operands[5], operands[6]));
15661 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15664 (define_expand "strmov_singleop"
15665 [(parallel [(set (match_operand 1 "memory_operand")
15666 (match_operand 3 "memory_operand"))
15667 (set (match_operand 0 "register_operand")
15669 (set (match_operand 2 "register_operand")
15670 (match_operand 5))])]
15672 "ix86_current_function_needs_cld = 1;")
15674 (define_insn "*strmovdi_rex_1"
15675 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15676 (mem:DI (match_operand:P 3 "register_operand" "1")))
15677 (set (match_operand:P 0 "register_operand" "=D")
15678 (plus:P (match_dup 2)
15680 (set (match_operand:P 1 "register_operand" "=S")
15681 (plus:P (match_dup 3)
15684 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15686 [(set_attr "type" "str")
15687 (set_attr "memory" "both")
15688 (set_attr "mode" "DI")])
15690 (define_insn "*strmovsi_1"
15691 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15692 (mem:SI (match_operand:P 3 "register_operand" "1")))
15693 (set (match_operand:P 0 "register_operand" "=D")
15694 (plus:P (match_dup 2)
15696 (set (match_operand:P 1 "register_operand" "=S")
15697 (plus:P (match_dup 3)
15699 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15701 [(set_attr "type" "str")
15702 (set_attr "memory" "both")
15703 (set_attr "mode" "SI")])
15705 (define_insn "*strmovhi_1"
15706 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15707 (mem:HI (match_operand:P 3 "register_operand" "1")))
15708 (set (match_operand:P 0 "register_operand" "=D")
15709 (plus:P (match_dup 2)
15711 (set (match_operand:P 1 "register_operand" "=S")
15712 (plus:P (match_dup 3)
15714 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15716 [(set_attr "type" "str")
15717 (set_attr "memory" "both")
15718 (set_attr "mode" "HI")])
15720 (define_insn "*strmovqi_1"
15721 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15722 (mem:QI (match_operand:P 3 "register_operand" "1")))
15723 (set (match_operand:P 0 "register_operand" "=D")
15724 (plus:P (match_dup 2)
15726 (set (match_operand:P 1 "register_operand" "=S")
15727 (plus:P (match_dup 3)
15729 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15731 [(set_attr "type" "str")
15732 (set_attr "memory" "both")
15733 (set (attr "prefix_rex")
15735 (match_test "<P:MODE>mode == DImode")
15737 (const_string "*")))
15738 (set_attr "mode" "QI")])
15740 (define_expand "rep_mov"
15741 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15742 (set (match_operand 0 "register_operand")
15744 (set (match_operand 2 "register_operand")
15746 (set (match_operand 1 "memory_operand")
15747 (match_operand 3 "memory_operand"))
15748 (use (match_dup 4))])]
15750 "ix86_current_function_needs_cld = 1;")
15752 (define_insn "*rep_movdi_rex64"
15753 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15754 (set (match_operand:P 0 "register_operand" "=D")
15755 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15757 (match_operand:P 3 "register_operand" "0")))
15758 (set (match_operand:P 1 "register_operand" "=S")
15759 (plus:P (ashift:P (match_dup 5) (const_int 3))
15760 (match_operand:P 4 "register_operand" "1")))
15761 (set (mem:BLK (match_dup 3))
15762 (mem:BLK (match_dup 4)))
15763 (use (match_dup 5))]
15765 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15767 [(set_attr "type" "str")
15768 (set_attr "prefix_rep" "1")
15769 (set_attr "memory" "both")
15770 (set_attr "mode" "DI")])
15772 (define_insn "*rep_movsi"
15773 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15774 (set (match_operand:P 0 "register_operand" "=D")
15775 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15777 (match_operand:P 3 "register_operand" "0")))
15778 (set (match_operand:P 1 "register_operand" "=S")
15779 (plus:P (ashift:P (match_dup 5) (const_int 2))
15780 (match_operand:P 4 "register_operand" "1")))
15781 (set (mem:BLK (match_dup 3))
15782 (mem:BLK (match_dup 4)))
15783 (use (match_dup 5))]
15784 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15785 "%^rep{%;} movs{l|d}"
15786 [(set_attr "type" "str")
15787 (set_attr "prefix_rep" "1")
15788 (set_attr "memory" "both")
15789 (set_attr "mode" "SI")])
15791 (define_insn "*rep_movqi"
15792 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15793 (set (match_operand:P 0 "register_operand" "=D")
15794 (plus:P (match_operand:P 3 "register_operand" "0")
15795 (match_operand:P 5 "register_operand" "2")))
15796 (set (match_operand:P 1 "register_operand" "=S")
15797 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15798 (set (mem:BLK (match_dup 3))
15799 (mem:BLK (match_dup 4)))
15800 (use (match_dup 5))]
15801 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15803 [(set_attr "type" "str")
15804 (set_attr "prefix_rep" "1")
15805 (set_attr "memory" "both")
15806 (set_attr "mode" "QI")])
15808 (define_expand "setmem<mode>"
15809 [(use (match_operand:BLK 0 "memory_operand"))
15810 (use (match_operand:SWI48 1 "nonmemory_operand"))
15811 (use (match_operand:QI 2 "nonmemory_operand"))
15812 (use (match_operand 3 "const_int_operand"))
15813 (use (match_operand:SI 4 "const_int_operand"))
15814 (use (match_operand:SI 5 "const_int_operand"))
15815 (use (match_operand:SI 6 ""))
15816 (use (match_operand:SI 7 ""))
15817 (use (match_operand:SI 8 ""))]
15820 if (ix86_expand_set_or_movmem (operands[0], NULL,
15821 operands[1], operands[2],
15822 operands[3], operands[4],
15823 operands[5], operands[6],
15824 operands[7], operands[8], true))
15830 ;; Most CPUs don't like single string operations
15831 ;; Handle this case here to simplify previous expander.
15833 (define_expand "strset"
15834 [(set (match_operand 1 "memory_operand")
15835 (match_operand 2 "register_operand"))
15836 (parallel [(set (match_operand 0 "register_operand")
15838 (clobber (reg:CC FLAGS_REG))])]
15841 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15842 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15844 /* If .md ever supports :P for Pmode, this can be directly
15845 in the pattern above. */
15846 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15847 GEN_INT (GET_MODE_SIZE (GET_MODE
15849 /* Can't use this if the user has appropriated eax or edi. */
15850 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15851 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15853 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15859 (define_expand "strset_singleop"
15860 [(parallel [(set (match_operand 1 "memory_operand")
15861 (match_operand 2 "register_operand"))
15862 (set (match_operand 0 "register_operand")
15864 (unspec [(const_int 0)] UNSPEC_STOS)])]
15866 "ix86_current_function_needs_cld = 1;")
15868 (define_insn "*strsetdi_rex_1"
15869 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15870 (match_operand:DI 2 "register_operand" "a"))
15871 (set (match_operand:P 0 "register_operand" "=D")
15872 (plus:P (match_dup 1)
15874 (unspec [(const_int 0)] UNSPEC_STOS)]
15876 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15878 [(set_attr "type" "str")
15879 (set_attr "memory" "store")
15880 (set_attr "mode" "DI")])
15882 (define_insn "*strsetsi_1"
15883 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15884 (match_operand:SI 2 "register_operand" "a"))
15885 (set (match_operand:P 0 "register_operand" "=D")
15886 (plus:P (match_dup 1)
15888 (unspec [(const_int 0)] UNSPEC_STOS)]
15889 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15891 [(set_attr "type" "str")
15892 (set_attr "memory" "store")
15893 (set_attr "mode" "SI")])
15895 (define_insn "*strsethi_1"
15896 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15897 (match_operand:HI 2 "register_operand" "a"))
15898 (set (match_operand:P 0 "register_operand" "=D")
15899 (plus:P (match_dup 1)
15901 (unspec [(const_int 0)] UNSPEC_STOS)]
15902 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15904 [(set_attr "type" "str")
15905 (set_attr "memory" "store")
15906 (set_attr "mode" "HI")])
15908 (define_insn "*strsetqi_1"
15909 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15910 (match_operand:QI 2 "register_operand" "a"))
15911 (set (match_operand:P 0 "register_operand" "=D")
15912 (plus:P (match_dup 1)
15914 (unspec [(const_int 0)] UNSPEC_STOS)]
15915 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15917 [(set_attr "type" "str")
15918 (set_attr "memory" "store")
15919 (set (attr "prefix_rex")
15921 (match_test "<P:MODE>mode == DImode")
15923 (const_string "*")))
15924 (set_attr "mode" "QI")])
15926 (define_expand "rep_stos"
15927 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15928 (set (match_operand 0 "register_operand")
15930 (set (match_operand 2 "memory_operand") (const_int 0))
15931 (use (match_operand 3 "register_operand"))
15932 (use (match_dup 1))])]
15934 "ix86_current_function_needs_cld = 1;")
15936 (define_insn "*rep_stosdi_rex64"
15937 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15938 (set (match_operand:P 0 "register_operand" "=D")
15939 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15941 (match_operand:P 3 "register_operand" "0")))
15942 (set (mem:BLK (match_dup 3))
15944 (use (match_operand:DI 2 "register_operand" "a"))
15945 (use (match_dup 4))]
15947 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15949 [(set_attr "type" "str")
15950 (set_attr "prefix_rep" "1")
15951 (set_attr "memory" "store")
15952 (set_attr "mode" "DI")])
15954 (define_insn "*rep_stossi"
15955 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15956 (set (match_operand:P 0 "register_operand" "=D")
15957 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15959 (match_operand:P 3 "register_operand" "0")))
15960 (set (mem:BLK (match_dup 3))
15962 (use (match_operand:SI 2 "register_operand" "a"))
15963 (use (match_dup 4))]
15964 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15965 "%^rep{%;} stos{l|d}"
15966 [(set_attr "type" "str")
15967 (set_attr "prefix_rep" "1")
15968 (set_attr "memory" "store")
15969 (set_attr "mode" "SI")])
15971 (define_insn "*rep_stosqi"
15972 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15973 (set (match_operand:P 0 "register_operand" "=D")
15974 (plus:P (match_operand:P 3 "register_operand" "0")
15975 (match_operand:P 4 "register_operand" "1")))
15976 (set (mem:BLK (match_dup 3))
15978 (use (match_operand:QI 2 "register_operand" "a"))
15979 (use (match_dup 4))]
15980 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15982 [(set_attr "type" "str")
15983 (set_attr "prefix_rep" "1")
15984 (set_attr "memory" "store")
15985 (set (attr "prefix_rex")
15987 (match_test "<P:MODE>mode == DImode")
15989 (const_string "*")))
15990 (set_attr "mode" "QI")])
15992 (define_expand "cmpstrnsi"
15993 [(set (match_operand:SI 0 "register_operand")
15994 (compare:SI (match_operand:BLK 1 "general_operand")
15995 (match_operand:BLK 2 "general_operand")))
15996 (use (match_operand 3 "general_operand"))
15997 (use (match_operand 4 "immediate_operand"))]
16000 rtx addr1, addr2, out, outlow, count, countreg, align;
16002 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16005 /* Can't use this if the user has appropriated ecx, esi or edi. */
16006 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16011 out = gen_reg_rtx (SImode);
16013 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16014 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16015 if (addr1 != XEXP (operands[1], 0))
16016 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16017 if (addr2 != XEXP (operands[2], 0))
16018 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16020 count = operands[3];
16021 countreg = ix86_zero_extend_to_Pmode (count);
16023 /* %%% Iff we are testing strict equality, we can use known alignment
16024 to good advantage. This may be possible with combine, particularly
16025 once cc0 is dead. */
16026 align = operands[4];
16028 if (CONST_INT_P (count))
16030 if (INTVAL (count) == 0)
16032 emit_move_insn (operands[0], const0_rtx);
16035 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16036 operands[1], operands[2]));
16040 rtx (*gen_cmp) (rtx, rtx);
16042 gen_cmp = (TARGET_64BIT
16043 ? gen_cmpdi_1 : gen_cmpsi_1);
16045 emit_insn (gen_cmp (countreg, countreg));
16046 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16047 operands[1], operands[2]));
16050 outlow = gen_lowpart (QImode, out);
16051 emit_insn (gen_cmpintqi (outlow));
16052 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16054 if (operands[0] != out)
16055 emit_move_insn (operands[0], out);
16060 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16062 (define_expand "cmpintqi"
16063 [(set (match_dup 1)
16064 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16066 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16067 (parallel [(set (match_operand:QI 0 "register_operand")
16068 (minus:QI (match_dup 1)
16070 (clobber (reg:CC FLAGS_REG))])]
16073 operands[1] = gen_reg_rtx (QImode);
16074 operands[2] = gen_reg_rtx (QImode);
16077 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16078 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16080 (define_expand "cmpstrnqi_nz_1"
16081 [(parallel [(set (reg:CC FLAGS_REG)
16082 (compare:CC (match_operand 4 "memory_operand")
16083 (match_operand 5 "memory_operand")))
16084 (use (match_operand 2 "register_operand"))
16085 (use (match_operand:SI 3 "immediate_operand"))
16086 (clobber (match_operand 0 "register_operand"))
16087 (clobber (match_operand 1 "register_operand"))
16088 (clobber (match_dup 2))])]
16090 "ix86_current_function_needs_cld = 1;")
16092 (define_insn "*cmpstrnqi_nz_1"
16093 [(set (reg:CC FLAGS_REG)
16094 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16095 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16096 (use (match_operand:P 6 "register_operand" "2"))
16097 (use (match_operand:SI 3 "immediate_operand" "i"))
16098 (clobber (match_operand:P 0 "register_operand" "=S"))
16099 (clobber (match_operand:P 1 "register_operand" "=D"))
16100 (clobber (match_operand:P 2 "register_operand" "=c"))]
16101 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16103 [(set_attr "type" "str")
16104 (set_attr "mode" "QI")
16105 (set (attr "prefix_rex")
16107 (match_test "<P:MODE>mode == DImode")
16109 (const_string "*")))
16110 (set_attr "prefix_rep" "1")])
16112 ;; The same, but the count is not known to not be zero.
16114 (define_expand "cmpstrnqi_1"
16115 [(parallel [(set (reg:CC FLAGS_REG)
16116 (if_then_else:CC (ne (match_operand 2 "register_operand")
16118 (compare:CC (match_operand 4 "memory_operand")
16119 (match_operand 5 "memory_operand"))
16121 (use (match_operand:SI 3 "immediate_operand"))
16122 (use (reg:CC FLAGS_REG))
16123 (clobber (match_operand 0 "register_operand"))
16124 (clobber (match_operand 1 "register_operand"))
16125 (clobber (match_dup 2))])]
16127 "ix86_current_function_needs_cld = 1;")
16129 (define_insn "*cmpstrnqi_1"
16130 [(set (reg:CC FLAGS_REG)
16131 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16133 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16134 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16136 (use (match_operand:SI 3 "immediate_operand" "i"))
16137 (use (reg:CC FLAGS_REG))
16138 (clobber (match_operand:P 0 "register_operand" "=S"))
16139 (clobber (match_operand:P 1 "register_operand" "=D"))
16140 (clobber (match_operand:P 2 "register_operand" "=c"))]
16141 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16143 [(set_attr "type" "str")
16144 (set_attr "mode" "QI")
16145 (set (attr "prefix_rex")
16147 (match_test "<P:MODE>mode == DImode")
16149 (const_string "*")))
16150 (set_attr "prefix_rep" "1")])
16152 (define_expand "strlen<mode>"
16153 [(set (match_operand:P 0 "register_operand")
16154 (unspec:P [(match_operand:BLK 1 "general_operand")
16155 (match_operand:QI 2 "immediate_operand")
16156 (match_operand 3 "immediate_operand")]
16160 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16166 (define_expand "strlenqi_1"
16167 [(parallel [(set (match_operand 0 "register_operand")
16169 (clobber (match_operand 1 "register_operand"))
16170 (clobber (reg:CC FLAGS_REG))])]
16172 "ix86_current_function_needs_cld = 1;")
16174 (define_insn "*strlenqi_1"
16175 [(set (match_operand:P 0 "register_operand" "=&c")
16176 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16177 (match_operand:QI 2 "register_operand" "a")
16178 (match_operand:P 3 "immediate_operand" "i")
16179 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16180 (clobber (match_operand:P 1 "register_operand" "=D"))
16181 (clobber (reg:CC FLAGS_REG))]
16182 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16183 "%^repnz{%;} scasb"
16184 [(set_attr "type" "str")
16185 (set_attr "mode" "QI")
16186 (set (attr "prefix_rex")
16188 (match_test "<P:MODE>mode == DImode")
16190 (const_string "*")))
16191 (set_attr "prefix_rep" "1")])
16193 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16194 ;; handled in combine, but it is not currently up to the task.
16195 ;; When used for their truth value, the cmpstrn* expanders generate
16204 ;; The intermediate three instructions are unnecessary.
16206 ;; This one handles cmpstrn*_nz_1...
16209 (set (reg:CC FLAGS_REG)
16210 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16211 (mem:BLK (match_operand 5 "register_operand"))))
16212 (use (match_operand 6 "register_operand"))
16213 (use (match_operand:SI 3 "immediate_operand"))
16214 (clobber (match_operand 0 "register_operand"))
16215 (clobber (match_operand 1 "register_operand"))
16216 (clobber (match_operand 2 "register_operand"))])
16217 (set (match_operand:QI 7 "register_operand")
16218 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16219 (set (match_operand:QI 8 "register_operand")
16220 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16221 (set (reg FLAGS_REG)
16222 (compare (match_dup 7) (match_dup 8)))
16224 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16226 (set (reg:CC FLAGS_REG)
16227 (compare:CC (mem:BLK (match_dup 4))
16228 (mem:BLK (match_dup 5))))
16229 (use (match_dup 6))
16230 (use (match_dup 3))
16231 (clobber (match_dup 0))
16232 (clobber (match_dup 1))
16233 (clobber (match_dup 2))])])
16235 ;; ...and this one handles cmpstrn*_1.
16238 (set (reg:CC FLAGS_REG)
16239 (if_then_else:CC (ne (match_operand 6 "register_operand")
16241 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16242 (mem:BLK (match_operand 5 "register_operand")))
16244 (use (match_operand:SI 3 "immediate_operand"))
16245 (use (reg:CC FLAGS_REG))
16246 (clobber (match_operand 0 "register_operand"))
16247 (clobber (match_operand 1 "register_operand"))
16248 (clobber (match_operand 2 "register_operand"))])
16249 (set (match_operand:QI 7 "register_operand")
16250 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16251 (set (match_operand:QI 8 "register_operand")
16252 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16253 (set (reg FLAGS_REG)
16254 (compare (match_dup 7) (match_dup 8)))
16256 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16258 (set (reg:CC FLAGS_REG)
16259 (if_then_else:CC (ne (match_dup 6)
16261 (compare:CC (mem:BLK (match_dup 4))
16262 (mem:BLK (match_dup 5)))
16264 (use (match_dup 3))
16265 (use (reg:CC FLAGS_REG))
16266 (clobber (match_dup 0))
16267 (clobber (match_dup 1))
16268 (clobber (match_dup 2))])])
16270 ;; Conditional move instructions.
16272 (define_expand "mov<mode>cc"
16273 [(set (match_operand:SWIM 0 "register_operand")
16274 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16275 (match_operand:SWIM 2 "<general_operand>")
16276 (match_operand:SWIM 3 "<general_operand>")))]
16278 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16280 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16281 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16282 ;; So just document what we're doing explicitly.
16284 (define_expand "x86_mov<mode>cc_0_m1"
16286 [(set (match_operand:SWI48 0 "register_operand")
16287 (if_then_else:SWI48
16288 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16289 [(match_operand 1 "flags_reg_operand")
16293 (clobber (reg:CC FLAGS_REG))])])
16295 (define_insn "*x86_mov<mode>cc_0_m1"
16296 [(set (match_operand:SWI48 0 "register_operand" "=r")
16297 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16298 [(reg FLAGS_REG) (const_int 0)])
16301 (clobber (reg:CC FLAGS_REG))]
16303 "sbb{<imodesuffix>}\t%0, %0"
16304 ; Since we don't have the proper number of operands for an alu insn,
16305 ; fill in all the blanks.
16306 [(set_attr "type" "alu")
16307 (set_attr "use_carry" "1")
16308 (set_attr "pent_pair" "pu")
16309 (set_attr "memory" "none")
16310 (set_attr "imm_disp" "false")
16311 (set_attr "mode" "<MODE>")
16312 (set_attr "length_immediate" "0")])
16314 (define_insn "*x86_mov<mode>cc_0_m1_se"
16315 [(set (match_operand:SWI48 0 "register_operand" "=r")
16316 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16317 [(reg FLAGS_REG) (const_int 0)])
16320 (clobber (reg:CC FLAGS_REG))]
16322 "sbb{<imodesuffix>}\t%0, %0"
16323 [(set_attr "type" "alu")
16324 (set_attr "use_carry" "1")
16325 (set_attr "pent_pair" "pu")
16326 (set_attr "memory" "none")
16327 (set_attr "imm_disp" "false")
16328 (set_attr "mode" "<MODE>")
16329 (set_attr "length_immediate" "0")])
16331 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16332 [(set (match_operand:SWI48 0 "register_operand" "=r")
16333 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16334 [(reg FLAGS_REG) (const_int 0)])))
16335 (clobber (reg:CC FLAGS_REG))]
16337 "sbb{<imodesuffix>}\t%0, %0"
16338 [(set_attr "type" "alu")
16339 (set_attr "use_carry" "1")
16340 (set_attr "pent_pair" "pu")
16341 (set_attr "memory" "none")
16342 (set_attr "imm_disp" "false")
16343 (set_attr "mode" "<MODE>")
16344 (set_attr "length_immediate" "0")])
16346 (define_insn "*mov<mode>cc_noc"
16347 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16348 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16349 [(reg FLAGS_REG) (const_int 0)])
16350 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16351 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16352 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16354 cmov%O2%C1\t{%2, %0|%0, %2}
16355 cmov%O2%c1\t{%3, %0|%0, %3}"
16356 [(set_attr "type" "icmov")
16357 (set_attr "mode" "<MODE>")])
16359 ;; Don't do conditional moves with memory inputs. This splitter helps
16360 ;; register starved x86_32 by forcing inputs into registers before reload.
16362 [(set (match_operand:SWI248 0 "register_operand")
16363 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16364 [(reg FLAGS_REG) (const_int 0)])
16365 (match_operand:SWI248 2 "nonimmediate_operand")
16366 (match_operand:SWI248 3 "nonimmediate_operand")))]
16367 "!TARGET_64BIT && TARGET_CMOVE
16368 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16369 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16370 && can_create_pseudo_p ()
16371 && optimize_insn_for_speed_p ()"
16372 [(set (match_dup 0)
16373 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16375 if (MEM_P (operands[2]))
16376 operands[2] = force_reg (<MODE>mode, operands[2]);
16377 if (MEM_P (operands[3]))
16378 operands[3] = force_reg (<MODE>mode, operands[3]);
16381 (define_insn "*movqicc_noc"
16382 [(set (match_operand:QI 0 "register_operand" "=r,r")
16383 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16384 [(reg FLAGS_REG) (const_int 0)])
16385 (match_operand:QI 2 "register_operand" "r,0")
16386 (match_operand:QI 3 "register_operand" "0,r")))]
16387 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16389 [(set_attr "type" "icmov")
16390 (set_attr "mode" "QI")])
16393 [(set (match_operand:SWI12 0 "register_operand")
16394 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16395 [(reg FLAGS_REG) (const_int 0)])
16396 (match_operand:SWI12 2 "register_operand")
16397 (match_operand:SWI12 3 "register_operand")))]
16398 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16399 && reload_completed"
16400 [(set (match_dup 0)
16401 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16403 operands[0] = gen_lowpart (SImode, operands[0]);
16404 operands[2] = gen_lowpart (SImode, operands[2]);
16405 operands[3] = gen_lowpart (SImode, operands[3]);
16408 ;; Don't do conditional moves with memory inputs
16410 [(match_scratch:SWI248 2 "r")
16411 (set (match_operand:SWI248 0 "register_operand")
16412 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16413 [(reg FLAGS_REG) (const_int 0)])
16415 (match_operand:SWI248 3 "memory_operand")))]
16416 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16417 && optimize_insn_for_speed_p ()"
16418 [(set (match_dup 2) (match_dup 3))
16420 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16423 [(match_scratch:SWI248 2 "r")
16424 (set (match_operand:SWI248 0 "register_operand")
16425 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16426 [(reg FLAGS_REG) (const_int 0)])
16427 (match_operand:SWI248 3 "memory_operand")
16429 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16430 && optimize_insn_for_speed_p ()"
16431 [(set (match_dup 2) (match_dup 3))
16433 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16435 (define_expand "mov<mode>cc"
16436 [(set (match_operand:X87MODEF 0 "register_operand")
16437 (if_then_else:X87MODEF
16438 (match_operand 1 "comparison_operator")
16439 (match_operand:X87MODEF 2 "register_operand")
16440 (match_operand:X87MODEF 3 "register_operand")))]
16441 "(TARGET_80387 && TARGET_CMOVE)
16442 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16443 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16445 (define_insn "*movxfcc_1"
16446 [(set (match_operand:XF 0 "register_operand" "=f,f")
16447 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16448 [(reg FLAGS_REG) (const_int 0)])
16449 (match_operand:XF 2 "register_operand" "f,0")
16450 (match_operand:XF 3 "register_operand" "0,f")))]
16451 "TARGET_80387 && TARGET_CMOVE"
16453 fcmov%F1\t{%2, %0|%0, %2}
16454 fcmov%f1\t{%3, %0|%0, %3}"
16455 [(set_attr "type" "fcmov")
16456 (set_attr "mode" "XF")])
16458 (define_insn "*movdfcc_1"
16459 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16460 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16461 [(reg FLAGS_REG) (const_int 0)])
16462 (match_operand:DF 2 "nonimmediate_operand"
16464 (match_operand:DF 3 "nonimmediate_operand"
16465 "0 ,f,0 ,rm,0, rm")))]
16466 "TARGET_80387 && TARGET_CMOVE
16467 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16469 fcmov%F1\t{%2, %0|%0, %2}
16470 fcmov%f1\t{%3, %0|%0, %3}
16473 cmov%O2%C1\t{%2, %0|%0, %2}
16474 cmov%O2%c1\t{%3, %0|%0, %3}"
16475 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16476 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16477 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16480 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16481 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16482 [(reg FLAGS_REG) (const_int 0)])
16483 (match_operand:DF 2 "nonimmediate_operand")
16484 (match_operand:DF 3 "nonimmediate_operand")))]
16485 "!TARGET_64BIT && reload_completed"
16486 [(set (match_dup 2)
16487 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16489 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16491 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16492 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16495 (define_insn "*movsfcc_1_387"
16496 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16497 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16498 [(reg FLAGS_REG) (const_int 0)])
16499 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16500 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16501 "TARGET_80387 && TARGET_CMOVE
16502 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16504 fcmov%F1\t{%2, %0|%0, %2}
16505 fcmov%f1\t{%3, %0|%0, %3}
16506 cmov%O2%C1\t{%2, %0|%0, %2}
16507 cmov%O2%c1\t{%3, %0|%0, %3}"
16508 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16509 (set_attr "mode" "SF,SF,SI,SI")])
16511 ;; Don't do conditional moves with memory inputs. This splitter helps
16512 ;; register starved x86_32 by forcing inputs into registers before reload.
16514 [(set (match_operand:MODEF 0 "register_operand")
16515 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16516 [(reg FLAGS_REG) (const_int 0)])
16517 (match_operand:MODEF 2 "nonimmediate_operand")
16518 (match_operand:MODEF 3 "nonimmediate_operand")))]
16519 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16520 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16521 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16522 && can_create_pseudo_p ()
16523 && optimize_insn_for_speed_p ()"
16524 [(set (match_dup 0)
16525 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16527 if (MEM_P (operands[2]))
16528 operands[2] = force_reg (<MODE>mode, operands[2]);
16529 if (MEM_P (operands[3]))
16530 operands[3] = force_reg (<MODE>mode, operands[3]);
16533 ;; Don't do conditional moves with memory inputs
16535 [(match_scratch:MODEF 2 "r")
16536 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16537 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16538 [(reg FLAGS_REG) (const_int 0)])
16540 (match_operand:MODEF 3 "memory_operand")))]
16541 "(<MODE>mode != DFmode || TARGET_64BIT)
16542 && TARGET_80387 && TARGET_CMOVE
16543 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16544 && optimize_insn_for_speed_p ()"
16545 [(set (match_dup 2) (match_dup 3))
16547 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16550 [(match_scratch:MODEF 2 "r")
16551 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16552 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16553 [(reg FLAGS_REG) (const_int 0)])
16554 (match_operand:MODEF 3 "memory_operand")
16556 "(<MODE>mode != DFmode || TARGET_64BIT)
16557 && TARGET_80387 && TARGET_CMOVE
16558 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16559 && optimize_insn_for_speed_p ()"
16560 [(set (match_dup 2) (match_dup 3))
16562 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16564 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16565 ;; the scalar versions to have only XMM registers as operands.
16567 ;; XOP conditional move
16568 (define_insn "*xop_pcmov_<mode>"
16569 [(set (match_operand:MODEF 0 "register_operand" "=x")
16570 (if_then_else:MODEF
16571 (match_operand:MODEF 1 "register_operand" "x")
16572 (match_operand:MODEF 2 "register_operand" "x")
16573 (match_operand:MODEF 3 "register_operand" "x")))]
16575 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16576 [(set_attr "type" "sse4arg")])
16578 ;; These versions of the min/max patterns are intentionally ignorant of
16579 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16580 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16581 ;; are undefined in this condition, we're certain this is correct.
16583 (define_insn "<code><mode>3"
16584 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16586 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16587 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16588 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16590 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16591 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16592 [(set_attr "isa" "noavx,avx")
16593 (set_attr "prefix" "orig,vex")
16594 (set_attr "type" "sseadd")
16595 (set_attr "mode" "<MODE>")])
16597 ;; These versions of the min/max patterns implement exactly the operations
16598 ;; min = (op1 < op2 ? op1 : op2)
16599 ;; max = (!(op1 < op2) ? op1 : op2)
16600 ;; Their operands are not commutative, and thus they may be used in the
16601 ;; presence of -0.0 and NaN.
16603 (define_int_iterator IEEE_MAXMIN
16607 (define_int_attr ieee_maxmin
16608 [(UNSPEC_IEEE_MAX "max")
16609 (UNSPEC_IEEE_MIN "min")])
16611 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16612 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16614 [(match_operand:MODEF 1 "register_operand" "0,x")
16615 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16617 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16619 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16620 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16621 [(set_attr "isa" "noavx,avx")
16622 (set_attr "prefix" "orig,vex")
16623 (set_attr "type" "sseadd")
16624 (set_attr "mode" "<MODE>")])
16626 ;; Make two stack loads independent:
16628 ;; fld %st(0) -> fld bb
16629 ;; fmul bb fmul %st(1), %st
16631 ;; Actually we only match the last two instructions for simplicity.
16633 [(set (match_operand 0 "fp_register_operand")
16634 (match_operand 1 "fp_register_operand"))
16636 (match_operator 2 "binary_fp_operator"
16638 (match_operand 3 "memory_operand")]))]
16639 "REGNO (operands[0]) != REGNO (operands[1])"
16640 [(set (match_dup 0) (match_dup 3))
16641 (set (match_dup 0) (match_dup 4))]
16643 ;; The % modifier is not operational anymore in peephole2's, so we have to
16644 ;; swap the operands manually in the case of addition and multiplication.
16648 if (COMMUTATIVE_ARITH_P (operands[2]))
16649 op0 = operands[0], op1 = operands[1];
16651 op0 = operands[1], op1 = operands[0];
16653 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16654 GET_MODE (operands[2]),
16658 ;; Conditional addition patterns
16659 (define_expand "add<mode>cc"
16660 [(match_operand:SWI 0 "register_operand")
16661 (match_operand 1 "ordered_comparison_operator")
16662 (match_operand:SWI 2 "register_operand")
16663 (match_operand:SWI 3 "const_int_operand")]
16665 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16667 ;; Misc patterns (?)
16669 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16670 ;; Otherwise there will be nothing to keep
16672 ;; [(set (reg ebp) (reg esp))]
16673 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16674 ;; (clobber (eflags)]
16675 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16677 ;; in proper program order.
16679 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16680 [(set (match_operand:P 0 "register_operand" "=r,r")
16681 (plus:P (match_operand:P 1 "register_operand" "0,r")
16682 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16683 (clobber (reg:CC FLAGS_REG))
16684 (clobber (mem:BLK (scratch)))]
16687 switch (get_attr_type (insn))
16690 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16693 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16694 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16695 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16697 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16700 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16701 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16704 [(set (attr "type")
16705 (cond [(and (eq_attr "alternative" "0")
16706 (not (match_test "TARGET_OPT_AGU")))
16707 (const_string "alu")
16708 (match_operand:<MODE> 2 "const0_operand")
16709 (const_string "imov")
16711 (const_string "lea")))
16712 (set (attr "length_immediate")
16713 (cond [(eq_attr "type" "imov")
16715 (and (eq_attr "type" "alu")
16716 (match_operand 2 "const128_operand"))
16719 (const_string "*")))
16720 (set_attr "mode" "<MODE>")])
16722 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16723 [(set (match_operand:P 0 "register_operand" "=r")
16724 (minus:P (match_operand:P 1 "register_operand" "0")
16725 (match_operand:P 2 "register_operand" "r")))
16726 (clobber (reg:CC FLAGS_REG))
16727 (clobber (mem:BLK (scratch)))]
16729 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16730 [(set_attr "type" "alu")
16731 (set_attr "mode" "<MODE>")])
16733 (define_insn "allocate_stack_worker_probe_<mode>"
16734 [(set (match_operand:P 0 "register_operand" "=a")
16735 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16736 UNSPECV_STACK_PROBE))
16737 (clobber (reg:CC FLAGS_REG))]
16738 "ix86_target_stack_probe ()"
16739 "call\t___chkstk_ms"
16740 [(set_attr "type" "multi")
16741 (set_attr "length" "5")])
16743 (define_expand "allocate_stack"
16744 [(match_operand 0 "register_operand")
16745 (match_operand 1 "general_operand")]
16746 "ix86_target_stack_probe ()"
16750 #ifndef CHECK_STACK_LIMIT
16751 #define CHECK_STACK_LIMIT 0
16754 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16755 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16759 rtx (*insn) (rtx, rtx);
16761 x = copy_to_mode_reg (Pmode, operands[1]);
16763 insn = (TARGET_64BIT
16764 ? gen_allocate_stack_worker_probe_di
16765 : gen_allocate_stack_worker_probe_si);
16767 emit_insn (insn (x, x));
16770 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16771 stack_pointer_rtx, 0, OPTAB_DIRECT);
16773 if (x != stack_pointer_rtx)
16774 emit_move_insn (stack_pointer_rtx, x);
16776 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16780 ;; Use IOR for stack probes, this is shorter.
16781 (define_expand "probe_stack"
16782 [(match_operand 0 "memory_operand")]
16785 rtx (*gen_ior3) (rtx, rtx, rtx);
16787 gen_ior3 = (GET_MODE (operands[0]) == DImode
16788 ? gen_iordi3 : gen_iorsi3);
16790 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16794 (define_insn "adjust_stack_and_probe<mode>"
16795 [(set (match_operand:P 0 "register_operand" "=r")
16796 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16797 UNSPECV_PROBE_STACK_RANGE))
16798 (set (reg:P SP_REG)
16799 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16800 (clobber (reg:CC FLAGS_REG))
16801 (clobber (mem:BLK (scratch)))]
16803 "* return output_adjust_stack_and_probe (operands[0]);"
16804 [(set_attr "type" "multi")])
16806 (define_insn "probe_stack_range<mode>"
16807 [(set (match_operand:P 0 "register_operand" "=r")
16808 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16809 (match_operand:P 2 "const_int_operand" "n")]
16810 UNSPECV_PROBE_STACK_RANGE))
16811 (clobber (reg:CC FLAGS_REG))]
16813 "* return output_probe_stack_range (operands[0], operands[2]);"
16814 [(set_attr "type" "multi")])
16816 (define_expand "builtin_setjmp_receiver"
16817 [(label_ref (match_operand 0))]
16818 "!TARGET_64BIT && flag_pic"
16824 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16825 rtx label_rtx = gen_label_rtx ();
16826 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16827 xops[0] = xops[1] = picreg;
16828 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16829 ix86_expand_binary_operator (MINUS, SImode, xops);
16833 emit_insn (gen_set_got (pic_offset_table_rtx));
16837 (define_insn_and_split "nonlocal_goto_receiver"
16838 [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16839 "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16841 "&& reload_completed"
16844 if (crtl->uses_pic_offset_table)
16847 rtx label_rtx = gen_label_rtx ();
16850 /* Get a new pic base. */
16851 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16852 /* Correct this with the offset from the new to the old. */
16853 xops[0] = xops[1] = pic_offset_table_rtx;
16854 label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16855 tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16856 UNSPEC_MACHOPIC_OFFSET);
16857 xops[2] = gen_rtx_CONST (Pmode, tmp);
16858 ix86_expand_binary_operator (MINUS, SImode, xops);
16861 /* No pic reg restore needed. */
16862 emit_note (NOTE_INSN_DELETED);
16867 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16868 ;; Do not split instructions with mask registers.
16870 [(set (match_operand 0 "general_reg_operand")
16871 (match_operator 3 "promotable_binary_operator"
16872 [(match_operand 1 "general_reg_operand")
16873 (match_operand 2 "aligned_operand")]))
16874 (clobber (reg:CC FLAGS_REG))]
16875 "! TARGET_PARTIAL_REG_STALL && reload_completed
16876 && ((GET_MODE (operands[0]) == HImode
16877 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16878 /* ??? next two lines just !satisfies_constraint_K (...) */
16879 || !CONST_INT_P (operands[2])
16880 || satisfies_constraint_K (operands[2])))
16881 || (GET_MODE (operands[0]) == QImode
16882 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16883 [(parallel [(set (match_dup 0)
16884 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16885 (clobber (reg:CC FLAGS_REG))])]
16887 operands[0] = gen_lowpart (SImode, operands[0]);
16888 operands[1] = gen_lowpart (SImode, operands[1]);
16889 if (GET_CODE (operands[3]) != ASHIFT)
16890 operands[2] = gen_lowpart (SImode, operands[2]);
16891 PUT_MODE (operands[3], SImode);
16894 ; Promote the QImode tests, as i386 has encoding of the AND
16895 ; instruction with 32-bit sign-extended immediate and thus the
16896 ; instruction size is unchanged, except in the %eax case for
16897 ; which it is increased by one byte, hence the ! optimize_size.
16899 [(set (match_operand 0 "flags_reg_operand")
16900 (match_operator 2 "compare_operator"
16901 [(and (match_operand 3 "aligned_operand")
16902 (match_operand 4 "const_int_operand"))
16904 (set (match_operand 1 "register_operand")
16905 (and (match_dup 3) (match_dup 4)))]
16906 "! TARGET_PARTIAL_REG_STALL && reload_completed
16907 && optimize_insn_for_speed_p ()
16908 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16909 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16910 /* Ensure that the operand will remain sign-extended immediate. */
16911 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16912 [(parallel [(set (match_dup 0)
16913 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16916 (and:SI (match_dup 3) (match_dup 4)))])]
16919 = gen_int_mode (INTVAL (operands[4])
16920 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16921 operands[1] = gen_lowpart (SImode, operands[1]);
16922 operands[3] = gen_lowpart (SImode, operands[3]);
16925 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16926 ; the TEST instruction with 32-bit sign-extended immediate and thus
16927 ; the instruction size would at least double, which is not what we
16928 ; want even with ! optimize_size.
16930 [(set (match_operand 0 "flags_reg_operand")
16931 (match_operator 1 "compare_operator"
16932 [(and (match_operand:HI 2 "aligned_operand")
16933 (match_operand:HI 3 "const_int_operand"))
16935 "! TARGET_PARTIAL_REG_STALL && reload_completed
16936 && ! TARGET_FAST_PREFIX
16937 && optimize_insn_for_speed_p ()
16938 /* Ensure that the operand will remain sign-extended immediate. */
16939 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16940 [(set (match_dup 0)
16941 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16945 = gen_int_mode (INTVAL (operands[3])
16946 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16947 operands[2] = gen_lowpart (SImode, operands[2]);
16951 [(set (match_operand 0 "register_operand")
16952 (neg (match_operand 1 "register_operand")))
16953 (clobber (reg:CC FLAGS_REG))]
16954 "! TARGET_PARTIAL_REG_STALL && reload_completed
16955 && (GET_MODE (operands[0]) == HImode
16956 || (GET_MODE (operands[0]) == QImode
16957 && (TARGET_PROMOTE_QImode
16958 || optimize_insn_for_size_p ())))"
16959 [(parallel [(set (match_dup 0)
16960 (neg:SI (match_dup 1)))
16961 (clobber (reg:CC FLAGS_REG))])]
16963 operands[0] = gen_lowpart (SImode, operands[0]);
16964 operands[1] = gen_lowpart (SImode, operands[1]);
16967 ;; Do not split instructions with mask regs.
16969 [(set (match_operand 0 "general_reg_operand")
16970 (not (match_operand 1 "general_reg_operand")))]
16971 "! TARGET_PARTIAL_REG_STALL && reload_completed
16972 && (GET_MODE (operands[0]) == HImode
16973 || (GET_MODE (operands[0]) == QImode
16974 && (TARGET_PROMOTE_QImode
16975 || optimize_insn_for_size_p ())))"
16976 [(set (match_dup 0)
16977 (not:SI (match_dup 1)))]
16979 operands[0] = gen_lowpart (SImode, operands[0]);
16980 operands[1] = gen_lowpart (SImode, operands[1]);
16983 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16984 ;; transform a complex memory operation into two memory to register operations.
16986 ;; Don't push memory operands
16988 [(set (match_operand:SWI 0 "push_operand")
16989 (match_operand:SWI 1 "memory_operand"))
16990 (match_scratch:SWI 2 "<r>")]
16991 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16992 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16993 [(set (match_dup 2) (match_dup 1))
16994 (set (match_dup 0) (match_dup 2))])
16996 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16999 [(set (match_operand:SF 0 "push_operand")
17000 (match_operand:SF 1 "memory_operand"))
17001 (match_scratch:SF 2 "r")]
17002 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17003 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17004 [(set (match_dup 2) (match_dup 1))
17005 (set (match_dup 0) (match_dup 2))])
17007 ;; Don't move an immediate directly to memory when the instruction
17008 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17010 [(match_scratch:SWI124 1 "<r>")
17011 (set (match_operand:SWI124 0 "memory_operand")
17013 "optimize_insn_for_speed_p ()
17014 && ((<MODE>mode == HImode
17015 && TARGET_LCP_STALL)
17016 || (!TARGET_USE_MOV0
17017 && TARGET_SPLIT_LONG_MOVES
17018 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17019 && peep2_regno_dead_p (0, FLAGS_REG)"
17020 [(parallel [(set (match_dup 2) (const_int 0))
17021 (clobber (reg:CC FLAGS_REG))])
17022 (set (match_dup 0) (match_dup 1))]
17023 "operands[2] = gen_lowpart (SImode, operands[1]);")
17026 [(match_scratch:SWI124 2 "<r>")
17027 (set (match_operand:SWI124 0 "memory_operand")
17028 (match_operand:SWI124 1 "immediate_operand"))]
17029 "optimize_insn_for_speed_p ()
17030 && ((<MODE>mode == HImode
17031 && TARGET_LCP_STALL)
17032 || (TARGET_SPLIT_LONG_MOVES
17033 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17034 [(set (match_dup 2) (match_dup 1))
17035 (set (match_dup 0) (match_dup 2))])
17037 ;; Don't compare memory with zero, load and use a test instead.
17039 [(set (match_operand 0 "flags_reg_operand")
17040 (match_operator 1 "compare_operator"
17041 [(match_operand:SI 2 "memory_operand")
17043 (match_scratch:SI 3 "r")]
17044 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17045 [(set (match_dup 3) (match_dup 2))
17046 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17048 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17049 ;; Don't split NOTs with a displacement operand, because resulting XOR
17050 ;; will not be pairable anyway.
17052 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17053 ;; represented using a modRM byte. The XOR replacement is long decoded,
17054 ;; so this split helps here as well.
17056 ;; Note: Can't do this as a regular split because we can't get proper
17057 ;; lifetime information then.
17060 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17061 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17062 "optimize_insn_for_speed_p ()
17063 && ((TARGET_NOT_UNPAIRABLE
17064 && (!MEM_P (operands[0])
17065 || !memory_displacement_operand (operands[0], <MODE>mode)))
17066 || (TARGET_NOT_VECTORMODE
17067 && long_memory_operand (operands[0], <MODE>mode)))
17068 && peep2_regno_dead_p (0, FLAGS_REG)"
17069 [(parallel [(set (match_dup 0)
17070 (xor:SWI124 (match_dup 1) (const_int -1)))
17071 (clobber (reg:CC FLAGS_REG))])])
17073 ;; Non pairable "test imm, reg" instructions can be translated to
17074 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17075 ;; byte opcode instead of two, have a short form for byte operands),
17076 ;; so do it for other CPUs as well. Given that the value was dead,
17077 ;; this should not create any new dependencies. Pass on the sub-word
17078 ;; versions if we're concerned about partial register stalls.
17081 [(set (match_operand 0 "flags_reg_operand")
17082 (match_operator 1 "compare_operator"
17083 [(and:SI (match_operand:SI 2 "register_operand")
17084 (match_operand:SI 3 "immediate_operand"))
17086 "ix86_match_ccmode (insn, CCNOmode)
17087 && (true_regnum (operands[2]) != AX_REG
17088 || satisfies_constraint_K (operands[3]))
17089 && peep2_reg_dead_p (1, operands[2])"
17091 [(set (match_dup 0)
17092 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17095 (and:SI (match_dup 2) (match_dup 3)))])])
17097 ;; We don't need to handle HImode case, because it will be promoted to SImode
17098 ;; on ! TARGET_PARTIAL_REG_STALL
17101 [(set (match_operand 0 "flags_reg_operand")
17102 (match_operator 1 "compare_operator"
17103 [(and:QI (match_operand:QI 2 "register_operand")
17104 (match_operand:QI 3 "immediate_operand"))
17106 "! TARGET_PARTIAL_REG_STALL
17107 && ix86_match_ccmode (insn, CCNOmode)
17108 && true_regnum (operands[2]) != AX_REG
17109 && peep2_reg_dead_p (1, operands[2])"
17111 [(set (match_dup 0)
17112 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17115 (and:QI (match_dup 2) (match_dup 3)))])])
17118 [(set (match_operand 0 "flags_reg_operand")
17119 (match_operator 1 "compare_operator"
17122 (match_operand 2 "ext_register_operand")
17125 (match_operand 3 "const_int_operand"))
17127 "! TARGET_PARTIAL_REG_STALL
17128 && ix86_match_ccmode (insn, CCNOmode)
17129 && true_regnum (operands[2]) != AX_REG
17130 && peep2_reg_dead_p (1, operands[2])"
17131 [(parallel [(set (match_dup 0)
17140 (set (zero_extract:SI (match_dup 2)
17148 (match_dup 3)))])])
17150 ;; Don't do logical operations with memory inputs.
17152 [(match_scratch:SI 2 "r")
17153 (parallel [(set (match_operand:SI 0 "register_operand")
17154 (match_operator:SI 3 "arith_or_logical_operator"
17156 (match_operand:SI 1 "memory_operand")]))
17157 (clobber (reg:CC FLAGS_REG))])]
17158 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17159 [(set (match_dup 2) (match_dup 1))
17160 (parallel [(set (match_dup 0)
17161 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17162 (clobber (reg:CC FLAGS_REG))])])
17165 [(match_scratch:SI 2 "r")
17166 (parallel [(set (match_operand:SI 0 "register_operand")
17167 (match_operator:SI 3 "arith_or_logical_operator"
17168 [(match_operand:SI 1 "memory_operand")
17170 (clobber (reg:CC FLAGS_REG))])]
17171 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17172 [(set (match_dup 2) (match_dup 1))
17173 (parallel [(set (match_dup 0)
17174 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17175 (clobber (reg:CC FLAGS_REG))])])
17177 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17178 ;; refers to the destination of the load!
17181 [(set (match_operand:SI 0 "register_operand")
17182 (match_operand:SI 1 "register_operand"))
17183 (parallel [(set (match_dup 0)
17184 (match_operator:SI 3 "commutative_operator"
17186 (match_operand:SI 2 "memory_operand")]))
17187 (clobber (reg:CC FLAGS_REG))])]
17188 "REGNO (operands[0]) != REGNO (operands[1])
17189 && GENERAL_REGNO_P (REGNO (operands[0]))
17190 && GENERAL_REGNO_P (REGNO (operands[1]))"
17191 [(set (match_dup 0) (match_dup 4))
17192 (parallel [(set (match_dup 0)
17193 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17194 (clobber (reg:CC FLAGS_REG))])]
17195 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17198 [(set (match_operand 0 "register_operand")
17199 (match_operand 1 "register_operand"))
17201 (match_operator 3 "commutative_operator"
17203 (match_operand 2 "memory_operand")]))]
17204 "REGNO (operands[0]) != REGNO (operands[1])
17205 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17206 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17207 [(set (match_dup 0) (match_dup 2))
17209 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17211 ; Don't do logical operations with memory outputs
17213 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17214 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17215 ; the same decoder scheduling characteristics as the original.
17218 [(match_scratch:SI 2 "r")
17219 (parallel [(set (match_operand:SI 0 "memory_operand")
17220 (match_operator:SI 3 "arith_or_logical_operator"
17222 (match_operand:SI 1 "nonmemory_operand")]))
17223 (clobber (reg:CC FLAGS_REG))])]
17224 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17225 /* Do not split stack checking probes. */
17226 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17227 [(set (match_dup 2) (match_dup 0))
17228 (parallel [(set (match_dup 2)
17229 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17230 (clobber (reg:CC FLAGS_REG))])
17231 (set (match_dup 0) (match_dup 2))])
17234 [(match_scratch:SI 2 "r")
17235 (parallel [(set (match_operand:SI 0 "memory_operand")
17236 (match_operator:SI 3 "arith_or_logical_operator"
17237 [(match_operand:SI 1 "nonmemory_operand")
17239 (clobber (reg:CC FLAGS_REG))])]
17240 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17241 /* Do not split stack checking probes. */
17242 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17243 [(set (match_dup 2) (match_dup 0))
17244 (parallel [(set (match_dup 2)
17245 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17246 (clobber (reg:CC FLAGS_REG))])
17247 (set (match_dup 0) (match_dup 2))])
17249 ;; Attempt to use arith or logical operations with memory outputs with
17250 ;; setting of flags.
17252 [(set (match_operand:SWI 0 "register_operand")
17253 (match_operand:SWI 1 "memory_operand"))
17254 (parallel [(set (match_dup 0)
17255 (match_operator:SWI 3 "plusminuslogic_operator"
17257 (match_operand:SWI 2 "<nonmemory_operand>")]))
17258 (clobber (reg:CC FLAGS_REG))])
17259 (set (match_dup 1) (match_dup 0))
17260 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17261 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17262 && peep2_reg_dead_p (4, operands[0])
17263 && !reg_overlap_mentioned_p (operands[0], operands[1])
17264 && !reg_overlap_mentioned_p (operands[0], operands[2])
17265 && (<MODE>mode != QImode
17266 || immediate_operand (operands[2], QImode)
17267 || q_regs_operand (operands[2], QImode))
17268 && ix86_match_ccmode (peep2_next_insn (3),
17269 (GET_CODE (operands[3]) == PLUS
17270 || GET_CODE (operands[3]) == MINUS)
17271 ? CCGOCmode : CCNOmode)"
17272 [(parallel [(set (match_dup 4) (match_dup 5))
17273 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17274 (match_dup 2)]))])]
17276 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17277 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17278 copy_rtx (operands[1]),
17279 copy_rtx (operands[2]));
17280 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17281 operands[5], const0_rtx);
17285 [(parallel [(set (match_operand:SWI 0 "register_operand")
17286 (match_operator:SWI 2 "plusminuslogic_operator"
17288 (match_operand:SWI 1 "memory_operand")]))
17289 (clobber (reg:CC FLAGS_REG))])
17290 (set (match_dup 1) (match_dup 0))
17291 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17292 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17293 && GET_CODE (operands[2]) != MINUS
17294 && peep2_reg_dead_p (3, operands[0])
17295 && !reg_overlap_mentioned_p (operands[0], operands[1])
17296 && ix86_match_ccmode (peep2_next_insn (2),
17297 GET_CODE (operands[2]) == PLUS
17298 ? CCGOCmode : CCNOmode)"
17299 [(parallel [(set (match_dup 3) (match_dup 4))
17300 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17301 (match_dup 0)]))])]
17303 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17304 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17305 copy_rtx (operands[1]),
17306 copy_rtx (operands[0]));
17307 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17308 operands[4], const0_rtx);
17312 [(set (match_operand:SWI12 0 "register_operand")
17313 (match_operand:SWI12 1 "memory_operand"))
17314 (parallel [(set (match_operand:SI 4 "register_operand")
17315 (match_operator:SI 3 "plusminuslogic_operator"
17317 (match_operand:SI 2 "nonmemory_operand")]))
17318 (clobber (reg:CC FLAGS_REG))])
17319 (set (match_dup 1) (match_dup 0))
17320 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17321 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17322 && REG_P (operands[0]) && REG_P (operands[4])
17323 && REGNO (operands[0]) == REGNO (operands[4])
17324 && peep2_reg_dead_p (4, operands[0])
17325 && (<MODE>mode != QImode
17326 || immediate_operand (operands[2], SImode)
17327 || q_regs_operand (operands[2], SImode))
17328 && !reg_overlap_mentioned_p (operands[0], operands[1])
17329 && !reg_overlap_mentioned_p (operands[0], operands[2])
17330 && ix86_match_ccmode (peep2_next_insn (3),
17331 (GET_CODE (operands[3]) == PLUS
17332 || GET_CODE (operands[3]) == MINUS)
17333 ? CCGOCmode : CCNOmode)"
17334 [(parallel [(set (match_dup 4) (match_dup 5))
17335 (set (match_dup 1) (match_dup 6))])]
17337 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17338 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17339 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17340 copy_rtx (operands[1]), operands[2]);
17341 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17342 operands[5], const0_rtx);
17343 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17344 copy_rtx (operands[1]),
17345 copy_rtx (operands[2]));
17348 ;; Attempt to always use XOR for zeroing registers.
17350 [(set (match_operand 0 "register_operand")
17351 (match_operand 1 "const0_operand"))]
17352 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17353 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17354 && GENERAL_REG_P (operands[0])
17355 && peep2_regno_dead_p (0, FLAGS_REG)"
17356 [(parallel [(set (match_dup 0) (const_int 0))
17357 (clobber (reg:CC FLAGS_REG))])]
17358 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17361 [(set (strict_low_part (match_operand 0 "register_operand"))
17363 "(GET_MODE (operands[0]) == QImode
17364 || GET_MODE (operands[0]) == HImode)
17365 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17366 && peep2_regno_dead_p (0, FLAGS_REG)"
17367 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17368 (clobber (reg:CC FLAGS_REG))])])
17370 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17372 [(set (match_operand:SWI248 0 "register_operand")
17374 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17375 && peep2_regno_dead_p (0, FLAGS_REG)"
17376 [(parallel [(set (match_dup 0) (const_int -1))
17377 (clobber (reg:CC FLAGS_REG))])]
17379 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17380 operands[0] = gen_lowpart (SImode, operands[0]);
17383 ;; Attempt to convert simple lea to add/shift.
17384 ;; These can be created by move expanders.
17385 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17386 ;; relevant lea instructions were already split.
17389 [(set (match_operand:SWI48 0 "register_operand")
17390 (plus:SWI48 (match_dup 0)
17391 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17393 && peep2_regno_dead_p (0, FLAGS_REG)"
17394 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17395 (clobber (reg:CC FLAGS_REG))])])
17398 [(set (match_operand:SWI48 0 "register_operand")
17399 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17402 && peep2_regno_dead_p (0, FLAGS_REG)"
17403 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17404 (clobber (reg:CC FLAGS_REG))])])
17407 [(set (match_operand:DI 0 "register_operand")
17409 (plus:SI (match_operand:SI 1 "register_operand")
17410 (match_operand:SI 2 "nonmemory_operand"))))]
17411 "TARGET_64BIT && !TARGET_OPT_AGU
17412 && REGNO (operands[0]) == REGNO (operands[1])
17413 && peep2_regno_dead_p (0, FLAGS_REG)"
17414 [(parallel [(set (match_dup 0)
17415 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17416 (clobber (reg:CC FLAGS_REG))])])
17419 [(set (match_operand:DI 0 "register_operand")
17421 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17422 (match_operand:SI 2 "register_operand"))))]
17423 "TARGET_64BIT && !TARGET_OPT_AGU
17424 && REGNO (operands[0]) == REGNO (operands[2])
17425 && peep2_regno_dead_p (0, FLAGS_REG)"
17426 [(parallel [(set (match_dup 0)
17427 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17428 (clobber (reg:CC FLAGS_REG))])])
17431 [(set (match_operand:SWI48 0 "register_operand")
17432 (mult:SWI48 (match_dup 0)
17433 (match_operand:SWI48 1 "const_int_operand")))]
17434 "exact_log2 (INTVAL (operands[1])) >= 0
17435 && peep2_regno_dead_p (0, FLAGS_REG)"
17436 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17437 (clobber (reg:CC FLAGS_REG))])]
17438 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17441 [(set (match_operand:DI 0 "register_operand")
17443 (mult:SI (match_operand:SI 1 "register_operand")
17444 (match_operand:SI 2 "const_int_operand"))))]
17446 && exact_log2 (INTVAL (operands[2])) >= 0
17447 && REGNO (operands[0]) == REGNO (operands[1])
17448 && peep2_regno_dead_p (0, FLAGS_REG)"
17449 [(parallel [(set (match_dup 0)
17450 (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
17451 (clobber (reg:CC FLAGS_REG))])]
17452 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17454 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17455 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17456 ;; On many CPUs it is also faster, since special hardware to avoid esp
17457 ;; dependencies is present.
17459 ;; While some of these conversions may be done using splitters, we use
17460 ;; peepholes in order to allow combine_stack_adjustments pass to see
17461 ;; nonobfuscated RTL.
17463 ;; Convert prologue esp subtractions to push.
17464 ;; We need register to push. In order to keep verify_flow_info happy we have
17466 ;; - use scratch and clobber it in order to avoid dependencies
17467 ;; - use already live register
17468 ;; We can't use the second way right now, since there is no reliable way how to
17469 ;; verify that given register is live. First choice will also most likely in
17470 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17471 ;; call clobbered registers are dead. We may want to use base pointer as an
17472 ;; alternative when no register is available later.
17475 [(match_scratch:W 1 "r")
17476 (parallel [(set (reg:P SP_REG)
17477 (plus:P (reg:P SP_REG)
17478 (match_operand:P 0 "const_int_operand")))
17479 (clobber (reg:CC FLAGS_REG))
17480 (clobber (mem:BLK (scratch)))])]
17481 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17482 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17483 [(clobber (match_dup 1))
17484 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17485 (clobber (mem:BLK (scratch)))])])
17488 [(match_scratch:W 1 "r")
17489 (parallel [(set (reg:P SP_REG)
17490 (plus:P (reg:P SP_REG)
17491 (match_operand:P 0 "const_int_operand")))
17492 (clobber (reg:CC FLAGS_REG))
17493 (clobber (mem:BLK (scratch)))])]
17494 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17495 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17496 [(clobber (match_dup 1))
17497 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17498 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17499 (clobber (mem:BLK (scratch)))])])
17501 ;; Convert esp subtractions to push.
17503 [(match_scratch:W 1 "r")
17504 (parallel [(set (reg:P SP_REG)
17505 (plus:P (reg:P SP_REG)
17506 (match_operand:P 0 "const_int_operand")))
17507 (clobber (reg:CC FLAGS_REG))])]
17508 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17509 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17510 [(clobber (match_dup 1))
17511 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17514 [(match_scratch:W 1 "r")
17515 (parallel [(set (reg:P SP_REG)
17516 (plus:P (reg:P SP_REG)
17517 (match_operand:P 0 "const_int_operand")))
17518 (clobber (reg:CC FLAGS_REG))])]
17519 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17520 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17521 [(clobber (match_dup 1))
17522 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17523 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17525 ;; Convert epilogue deallocator to pop.
17527 [(match_scratch:W 1 "r")
17528 (parallel [(set (reg:P SP_REG)
17529 (plus:P (reg:P SP_REG)
17530 (match_operand:P 0 "const_int_operand")))
17531 (clobber (reg:CC FLAGS_REG))
17532 (clobber (mem:BLK (scratch)))])]
17533 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17534 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17535 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17536 (clobber (mem:BLK (scratch)))])])
17538 ;; Two pops case is tricky, since pop causes dependency
17539 ;; on destination register. We use two registers if available.
17541 [(match_scratch:W 1 "r")
17542 (match_scratch:W 2 "r")
17543 (parallel [(set (reg:P SP_REG)
17544 (plus:P (reg:P SP_REG)
17545 (match_operand:P 0 "const_int_operand")))
17546 (clobber (reg:CC FLAGS_REG))
17547 (clobber (mem:BLK (scratch)))])]
17548 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17549 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17550 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17551 (clobber (mem:BLK (scratch)))])
17552 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17555 [(match_scratch:W 1 "r")
17556 (parallel [(set (reg:P SP_REG)
17557 (plus:P (reg:P SP_REG)
17558 (match_operand:P 0 "const_int_operand")))
17559 (clobber (reg:CC FLAGS_REG))
17560 (clobber (mem:BLK (scratch)))])]
17561 "optimize_insn_for_size_p ()
17562 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17563 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17564 (clobber (mem:BLK (scratch)))])
17565 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17567 ;; Convert esp additions to pop.
17569 [(match_scratch:W 1 "r")
17570 (parallel [(set (reg:P SP_REG)
17571 (plus:P (reg:P SP_REG)
17572 (match_operand:P 0 "const_int_operand")))
17573 (clobber (reg:CC FLAGS_REG))])]
17574 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17575 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17577 ;; Two pops case is tricky, since pop causes dependency
17578 ;; on destination register. We use two registers if available.
17580 [(match_scratch:W 1 "r")
17581 (match_scratch:W 2 "r")
17582 (parallel [(set (reg:P SP_REG)
17583 (plus:P (reg:P SP_REG)
17584 (match_operand:P 0 "const_int_operand")))
17585 (clobber (reg:CC FLAGS_REG))])]
17586 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17587 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17588 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17591 [(match_scratch:W 1 "r")
17592 (parallel [(set (reg:P SP_REG)
17593 (plus:P (reg:P SP_REG)
17594 (match_operand:P 0 "const_int_operand")))
17595 (clobber (reg:CC FLAGS_REG))])]
17596 "optimize_insn_for_size_p ()
17597 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17598 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17599 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17601 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17602 ;; required and register dies. Similarly for 128 to -128.
17604 [(set (match_operand 0 "flags_reg_operand")
17605 (match_operator 1 "compare_operator"
17606 [(match_operand 2 "register_operand")
17607 (match_operand 3 "const_int_operand")]))]
17608 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17609 && incdec_operand (operands[3], GET_MODE (operands[3])))
17610 || (!TARGET_FUSE_CMP_AND_BRANCH
17611 && INTVAL (operands[3]) == 128))
17612 && ix86_match_ccmode (insn, CCGCmode)
17613 && peep2_reg_dead_p (1, operands[2])"
17614 [(parallel [(set (match_dup 0)
17615 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17616 (clobber (match_dup 2))])])
17618 ;; Convert imul by three, five and nine into lea
17621 [(set (match_operand:SWI48 0 "register_operand")
17622 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17623 (match_operand:SWI48 2 "const359_operand")))
17624 (clobber (reg:CC FLAGS_REG))])]
17625 "!TARGET_PARTIAL_REG_STALL
17626 || <MODE>mode == SImode
17627 || optimize_function_for_size_p (cfun)"
17628 [(set (match_dup 0)
17629 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17631 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17635 [(set (match_operand:SWI48 0 "register_operand")
17636 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17637 (match_operand:SWI48 2 "const359_operand")))
17638 (clobber (reg:CC FLAGS_REG))])]
17639 "optimize_insn_for_speed_p ()
17640 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17641 [(set (match_dup 0) (match_dup 1))
17643 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17645 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17647 ;; imul $32bit_imm, mem, reg is vector decoded, while
17648 ;; imul $32bit_imm, reg, reg is direct decoded.
17650 [(match_scratch:SWI48 3 "r")
17651 (parallel [(set (match_operand:SWI48 0 "register_operand")
17652 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17653 (match_operand:SWI48 2 "immediate_operand")))
17654 (clobber (reg:CC FLAGS_REG))])]
17655 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17656 && !satisfies_constraint_K (operands[2])"
17657 [(set (match_dup 3) (match_dup 1))
17658 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17659 (clobber (reg:CC FLAGS_REG))])])
17662 [(match_scratch:SI 3 "r")
17663 (parallel [(set (match_operand:DI 0 "register_operand")
17665 (mult:SI (match_operand:SI 1 "memory_operand")
17666 (match_operand:SI 2 "immediate_operand"))))
17667 (clobber (reg:CC FLAGS_REG))])]
17669 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17670 && !satisfies_constraint_K (operands[2])"
17671 [(set (match_dup 3) (match_dup 1))
17672 (parallel [(set (match_dup 0)
17673 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17674 (clobber (reg:CC FLAGS_REG))])])
17676 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17677 ;; Convert it into imul reg, reg
17678 ;; It would be better to force assembler to encode instruction using long
17679 ;; immediate, but there is apparently no way to do so.
17681 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17683 (match_operand:SWI248 1 "nonimmediate_operand")
17684 (match_operand:SWI248 2 "const_int_operand")))
17685 (clobber (reg:CC FLAGS_REG))])
17686 (match_scratch:SWI248 3 "r")]
17687 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17688 && satisfies_constraint_K (operands[2])"
17689 [(set (match_dup 3) (match_dup 2))
17690 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17691 (clobber (reg:CC FLAGS_REG))])]
17693 if (!rtx_equal_p (operands[0], operands[1]))
17694 emit_move_insn (operands[0], operands[1]);
17697 ;; After splitting up read-modify operations, array accesses with memory
17698 ;; operands might end up in form:
17700 ;; movl 4(%esp), %edx
17702 ;; instead of pre-splitting:
17704 ;; addl 4(%esp), %eax
17706 ;; movl 4(%esp), %edx
17707 ;; leal (%edx,%eax,4), %eax
17710 [(match_scratch:W 5 "r")
17711 (parallel [(set (match_operand 0 "register_operand")
17712 (ashift (match_operand 1 "register_operand")
17713 (match_operand 2 "const_int_operand")))
17714 (clobber (reg:CC FLAGS_REG))])
17715 (parallel [(set (match_operand 3 "register_operand")
17716 (plus (match_dup 0)
17717 (match_operand 4 "x86_64_general_operand")))
17718 (clobber (reg:CC FLAGS_REG))])]
17719 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17720 /* Validate MODE for lea. */
17721 && ((!TARGET_PARTIAL_REG_STALL
17722 && (GET_MODE (operands[0]) == QImode
17723 || GET_MODE (operands[0]) == HImode))
17724 || GET_MODE (operands[0]) == SImode
17725 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17726 && (rtx_equal_p (operands[0], operands[3])
17727 || peep2_reg_dead_p (2, operands[0]))
17728 /* We reorder load and the shift. */
17729 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17730 [(set (match_dup 5) (match_dup 4))
17731 (set (match_dup 0) (match_dup 1))]
17733 enum machine_mode op1mode = GET_MODE (operands[1]);
17734 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17735 int scale = 1 << INTVAL (operands[2]);
17736 rtx index = gen_lowpart (word_mode, operands[1]);
17737 rtx base = gen_lowpart (word_mode, operands[5]);
17738 rtx dest = gen_lowpart (mode, operands[3]);
17740 operands[1] = gen_rtx_PLUS (word_mode, base,
17741 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17742 operands[5] = base;
17743 if (mode != word_mode)
17744 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17745 if (op1mode != word_mode)
17746 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17747 operands[0] = dest;
17750 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17751 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17752 ;; caught for use by garbage collectors and the like. Using an insn that
17753 ;; maps to SIGILL makes it more likely the program will rightfully die.
17754 ;; Keeping with tradition, "6" is in honor of #UD.
17755 (define_insn "trap"
17756 [(trap_if (const_int 1) (const_int 6))]
17758 { return ASM_SHORT "0x0b0f"; }
17759 [(set_attr "length" "2")])
17761 (define_expand "prefetch"
17762 [(prefetch (match_operand 0 "address_operand")
17763 (match_operand:SI 1 "const_int_operand")
17764 (match_operand:SI 2 "const_int_operand"))]
17765 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_AVX512PF"
17767 bool write = INTVAL (operands[1]) != 0;
17768 int locality = INTVAL (operands[2]);
17770 gcc_assert (IN_RANGE (locality, 0, 3));
17772 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17773 supported by SSE counterpart or the SSE prefetch is not available
17774 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17776 if (TARGET_AVX512PF && write)
17777 operands[2] = const1_rtx;
17778 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17779 operands[2] = GEN_INT (3);
17781 operands[1] = const0_rtx;
17784 (define_insn "*prefetch_sse"
17785 [(prefetch (match_operand 0 "address_operand" "p")
17787 (match_operand:SI 1 "const_int_operand"))]
17788 "TARGET_PREFETCH_SSE"
17790 static const char * const patterns[4] = {
17791 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17794 int locality = INTVAL (operands[1]);
17795 gcc_assert (IN_RANGE (locality, 0, 3));
17797 return patterns[locality];
17799 [(set_attr "type" "sse")
17800 (set_attr "atom_sse_attr" "prefetch")
17801 (set (attr "length_address")
17802 (symbol_ref "memory_address_length (operands[0], false)"))
17803 (set_attr "memory" "none")])
17805 (define_insn "*prefetch_3dnow"
17806 [(prefetch (match_operand 0 "address_operand" "p")
17807 (match_operand:SI 1 "const_int_operand" "n")
17811 if (INTVAL (operands[1]) == 0)
17812 return "prefetch\t%a0";
17814 return "prefetchw\t%a0";
17816 [(set_attr "type" "mmx")
17817 (set (attr "length_address")
17818 (symbol_ref "memory_address_length (operands[0], false)"))
17819 (set_attr "memory" "none")])
17821 (define_insn "*prefetch_avx512pf_<mode>"
17822 [(prefetch (match_operand:P 0 "address_operand" "p")
17826 "prefetchwt1\t%a0";
17827 [(set_attr "type" "sse")
17828 (set_attr "prefix" "evex")
17829 (set (attr "length_address")
17830 (symbol_ref "memory_address_length (operands[0], false)"))
17831 (set_attr "memory" "none")])
17833 (define_expand "stack_protect_set"
17834 [(match_operand 0 "memory_operand")
17835 (match_operand 1 "memory_operand")]
17836 "TARGET_SSP_TLS_GUARD"
17838 rtx (*insn)(rtx, rtx);
17840 #ifdef TARGET_THREAD_SSP_OFFSET
17841 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17842 insn = (TARGET_LP64
17843 ? gen_stack_tls_protect_set_di
17844 : gen_stack_tls_protect_set_si);
17846 insn = (TARGET_LP64
17847 ? gen_stack_protect_set_di
17848 : gen_stack_protect_set_si);
17851 emit_insn (insn (operands[0], operands[1]));
17855 (define_insn "stack_protect_set_<mode>"
17856 [(set (match_operand:PTR 0 "memory_operand" "=m")
17857 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17859 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17860 (clobber (reg:CC FLAGS_REG))]
17861 "TARGET_SSP_TLS_GUARD"
17862 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17863 [(set_attr "type" "multi")])
17865 (define_insn "stack_tls_protect_set_<mode>"
17866 [(set (match_operand:PTR 0 "memory_operand" "=m")
17867 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17868 UNSPEC_SP_TLS_SET))
17869 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17870 (clobber (reg:CC FLAGS_REG))]
17872 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17873 [(set_attr "type" "multi")])
17875 (define_expand "stack_protect_test"
17876 [(match_operand 0 "memory_operand")
17877 (match_operand 1 "memory_operand")
17879 "TARGET_SSP_TLS_GUARD"
17881 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17883 rtx (*insn)(rtx, rtx, rtx);
17885 #ifdef TARGET_THREAD_SSP_OFFSET
17886 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17887 insn = (TARGET_LP64
17888 ? gen_stack_tls_protect_test_di
17889 : gen_stack_tls_protect_test_si);
17891 insn = (TARGET_LP64
17892 ? gen_stack_protect_test_di
17893 : gen_stack_protect_test_si);
17896 emit_insn (insn (flags, operands[0], operands[1]));
17898 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17899 flags, const0_rtx, operands[2]));
17903 (define_insn "stack_protect_test_<mode>"
17904 [(set (match_operand:CCZ 0 "flags_reg_operand")
17905 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17906 (match_operand:PTR 2 "memory_operand" "m")]
17908 (clobber (match_scratch:PTR 3 "=&r"))]
17909 "TARGET_SSP_TLS_GUARD"
17910 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17911 [(set_attr "type" "multi")])
17913 (define_insn "stack_tls_protect_test_<mode>"
17914 [(set (match_operand:CCZ 0 "flags_reg_operand")
17915 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17916 (match_operand:PTR 2 "const_int_operand" "i")]
17917 UNSPEC_SP_TLS_TEST))
17918 (clobber (match_scratch:PTR 3 "=r"))]
17920 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17921 [(set_attr "type" "multi")])
17923 (define_insn "sse4_2_crc32<mode>"
17924 [(set (match_operand:SI 0 "register_operand" "=r")
17926 [(match_operand:SI 1 "register_operand" "0")
17927 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17929 "TARGET_SSE4_2 || TARGET_CRC32"
17930 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17931 [(set_attr "type" "sselog1")
17932 (set_attr "prefix_rep" "1")
17933 (set_attr "prefix_extra" "1")
17934 (set (attr "prefix_data16")
17935 (if_then_else (match_operand:HI 2)
17937 (const_string "*")))
17938 (set (attr "prefix_rex")
17939 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17941 (const_string "*")))
17942 (set_attr "mode" "SI")])
17944 (define_insn "sse4_2_crc32di"
17945 [(set (match_operand:DI 0 "register_operand" "=r")
17947 [(match_operand:DI 1 "register_operand" "0")
17948 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17950 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17951 "crc32{q}\t{%2, %0|%0, %2}"
17952 [(set_attr "type" "sselog1")
17953 (set_attr "prefix_rep" "1")
17954 (set_attr "prefix_extra" "1")
17955 (set_attr "mode" "DI")])
17957 (define_insn "rdpmc"
17958 [(set (match_operand:DI 0 "register_operand" "=A")
17959 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17963 [(set_attr "type" "other")
17964 (set_attr "length" "2")])
17966 (define_insn "rdpmc_rex64"
17967 [(set (match_operand:DI 0 "register_operand" "=a")
17968 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17970 (set (match_operand:DI 1 "register_operand" "=d")
17971 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17974 [(set_attr "type" "other")
17975 (set_attr "length" "2")])
17977 (define_insn "rdtsc"
17978 [(set (match_operand:DI 0 "register_operand" "=A")
17979 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17982 [(set_attr "type" "other")
17983 (set_attr "length" "2")])
17985 (define_insn "rdtsc_rex64"
17986 [(set (match_operand:DI 0 "register_operand" "=a")
17987 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17988 (set (match_operand:DI 1 "register_operand" "=d")
17989 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17992 [(set_attr "type" "other")
17993 (set_attr "length" "2")])
17995 (define_insn "rdtscp"
17996 [(set (match_operand:DI 0 "register_operand" "=A")
17997 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17998 (set (match_operand:SI 1 "register_operand" "=c")
17999 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18002 [(set_attr "type" "other")
18003 (set_attr "length" "3")])
18005 (define_insn "rdtscp_rex64"
18006 [(set (match_operand:DI 0 "register_operand" "=a")
18007 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18008 (set (match_operand:DI 1 "register_operand" "=d")
18009 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18010 (set (match_operand:SI 2 "register_operand" "=c")
18011 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18014 [(set_attr "type" "other")
18015 (set_attr "length" "3")])
18017 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18019 ;; FXSR, XSAVE and XSAVEOPT instructions
18021 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18023 (define_insn "fxsave"
18024 [(set (match_operand:BLK 0 "memory_operand" "=m")
18025 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18028 [(set_attr "type" "other")
18029 (set_attr "memory" "store")
18030 (set (attr "length")
18031 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18033 (define_insn "fxsave64"
18034 [(set (match_operand:BLK 0 "memory_operand" "=m")
18035 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18036 "TARGET_64BIT && TARGET_FXSR"
18038 [(set_attr "type" "other")
18039 (set_attr "memory" "store")
18040 (set (attr "length")
18041 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18043 (define_insn "fxrstor"
18044 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18048 [(set_attr "type" "other")
18049 (set_attr "memory" "load")
18050 (set (attr "length")
18051 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18053 (define_insn "fxrstor64"
18054 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18055 UNSPECV_FXRSTOR64)]
18056 "TARGET_64BIT && TARGET_FXSR"
18058 [(set_attr "type" "other")
18059 (set_attr "memory" "load")
18060 (set (attr "length")
18061 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18063 (define_int_iterator ANY_XSAVE
18065 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
18067 (define_int_iterator ANY_XSAVE64
18069 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
18071 (define_int_attr xsave
18072 [(UNSPECV_XSAVE "xsave")
18073 (UNSPECV_XSAVE64 "xsave64")
18074 (UNSPECV_XSAVEOPT "xsaveopt")
18075 (UNSPECV_XSAVEOPT64 "xsaveopt64")])
18077 (define_insn "<xsave>"
18078 [(set (match_operand:BLK 0 "memory_operand" "=m")
18079 (unspec_volatile:BLK
18080 [(match_operand:DI 1 "register_operand" "A")]
18082 "!TARGET_64BIT && TARGET_XSAVE"
18084 [(set_attr "type" "other")
18085 (set_attr "memory" "store")
18086 (set (attr "length")
18087 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18089 (define_insn "<xsave>_rex64"
18090 [(set (match_operand:BLK 0 "memory_operand" "=m")
18091 (unspec_volatile:BLK
18092 [(match_operand:SI 1 "register_operand" "a")
18093 (match_operand:SI 2 "register_operand" "d")]
18095 "TARGET_64BIT && TARGET_XSAVE"
18097 [(set_attr "type" "other")
18098 (set_attr "memory" "store")
18099 (set (attr "length")
18100 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18102 (define_insn "<xsave>"
18103 [(set (match_operand:BLK 0 "memory_operand" "=m")
18104 (unspec_volatile:BLK
18105 [(match_operand:SI 1 "register_operand" "a")
18106 (match_operand:SI 2 "register_operand" "d")]
18108 "TARGET_64BIT && TARGET_XSAVE"
18110 [(set_attr "type" "other")
18111 (set_attr "memory" "store")
18112 (set (attr "length")
18113 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18115 (define_insn "xrstor"
18116 [(unspec_volatile:BLK
18117 [(match_operand:BLK 0 "memory_operand" "m")
18118 (match_operand:DI 1 "register_operand" "A")]
18120 "!TARGET_64BIT && TARGET_XSAVE"
18122 [(set_attr "type" "other")
18123 (set_attr "memory" "load")
18124 (set (attr "length")
18125 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18127 (define_insn "xrstor_rex64"
18128 [(unspec_volatile:BLK
18129 [(match_operand:BLK 0 "memory_operand" "m")
18130 (match_operand:SI 1 "register_operand" "a")
18131 (match_operand:SI 2 "register_operand" "d")]
18133 "TARGET_64BIT && TARGET_XSAVE"
18135 [(set_attr "type" "other")
18136 (set_attr "memory" "load")
18137 (set (attr "length")
18138 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18140 (define_insn "xrstor64"
18141 [(unspec_volatile:BLK
18142 [(match_operand:BLK 0 "memory_operand" "m")
18143 (match_operand:SI 1 "register_operand" "a")
18144 (match_operand:SI 2 "register_operand" "d")]
18146 "TARGET_64BIT && TARGET_XSAVE"
18148 [(set_attr "type" "other")
18149 (set_attr "memory" "load")
18150 (set (attr "length")
18151 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18153 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18155 ;; Floating-point instructions for atomic compound assignments
18157 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18159 ; Clobber all floating-point registers on environment save and restore
18160 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18161 (define_insn "fnstenv"
18162 [(set (match_operand:BLK 0 "memory_operand" "=m")
18163 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18164 (clobber (reg:HI FPCR_REG))
18165 (clobber (reg:XF ST0_REG))
18166 (clobber (reg:XF ST1_REG))
18167 (clobber (reg:XF ST2_REG))
18168 (clobber (reg:XF ST3_REG))
18169 (clobber (reg:XF ST4_REG))
18170 (clobber (reg:XF ST5_REG))
18171 (clobber (reg:XF ST6_REG))
18172 (clobber (reg:XF ST7_REG))]
18175 [(set_attr "type" "other")
18176 (set_attr "memory" "store")
18177 (set (attr "length")
18178 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18180 (define_insn "fldenv"
18181 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18183 (clobber (reg:CCFP FPSR_REG))
18184 (clobber (reg:HI FPCR_REG))
18185 (clobber (reg:XF ST0_REG))
18186 (clobber (reg:XF ST1_REG))
18187 (clobber (reg:XF ST2_REG))
18188 (clobber (reg:XF ST3_REG))
18189 (clobber (reg:XF ST4_REG))
18190 (clobber (reg:XF ST5_REG))
18191 (clobber (reg:XF ST6_REG))
18192 (clobber (reg:XF ST7_REG))]
18195 [(set_attr "type" "other")
18196 (set_attr "memory" "load")
18197 (set (attr "length")
18198 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18200 (define_insn "fnstsw"
18201 [(set (match_operand:HI 0 "memory_operand" "=m")
18202 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18205 [(set_attr "type" "other")
18206 (set_attr "memory" "store")
18207 (set (attr "length")
18208 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18210 (define_insn "fnclex"
18211 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18214 [(set_attr "type" "other")
18215 (set_attr "memory" "none")
18216 (set_attr "length" "2")])
18218 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18220 ;; LWP instructions
18222 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18224 (define_expand "lwp_llwpcb"
18225 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18226 UNSPECV_LLWP_INTRINSIC)]
18229 (define_insn "*lwp_llwpcb<mode>1"
18230 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18231 UNSPECV_LLWP_INTRINSIC)]
18234 [(set_attr "type" "lwp")
18235 (set_attr "mode" "<MODE>")
18236 (set_attr "length" "5")])
18238 (define_expand "lwp_slwpcb"
18239 [(set (match_operand 0 "register_operand" "=r")
18240 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18245 insn = (Pmode == DImode
18247 : gen_lwp_slwpcbsi);
18249 emit_insn (insn (operands[0]));
18253 (define_insn "lwp_slwpcb<mode>"
18254 [(set (match_operand:P 0 "register_operand" "=r")
18255 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18258 [(set_attr "type" "lwp")
18259 (set_attr "mode" "<MODE>")
18260 (set_attr "length" "5")])
18262 (define_expand "lwp_lwpval<mode>3"
18263 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18264 (match_operand:SI 2 "nonimmediate_operand" "rm")
18265 (match_operand:SI 3 "const_int_operand" "i")]
18266 UNSPECV_LWPVAL_INTRINSIC)]
18268 ;; Avoid unused variable warning.
18269 "(void) operands[0];")
18271 (define_insn "*lwp_lwpval<mode>3_1"
18272 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18273 (match_operand:SI 1 "nonimmediate_operand" "rm")
18274 (match_operand:SI 2 "const_int_operand" "i")]
18275 UNSPECV_LWPVAL_INTRINSIC)]
18277 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18278 [(set_attr "type" "lwp")
18279 (set_attr "mode" "<MODE>")
18280 (set (attr "length")
18281 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18283 (define_expand "lwp_lwpins<mode>3"
18284 [(set (reg:CCC FLAGS_REG)
18285 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18286 (match_operand:SI 2 "nonimmediate_operand" "rm")
18287 (match_operand:SI 3 "const_int_operand" "i")]
18288 UNSPECV_LWPINS_INTRINSIC))
18289 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18290 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18293 (define_insn "*lwp_lwpins<mode>3_1"
18294 [(set (reg:CCC FLAGS_REG)
18295 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18296 (match_operand:SI 1 "nonimmediate_operand" "rm")
18297 (match_operand:SI 2 "const_int_operand" "i")]
18298 UNSPECV_LWPINS_INTRINSIC))]
18300 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18301 [(set_attr "type" "lwp")
18302 (set_attr "mode" "<MODE>")
18303 (set (attr "length")
18304 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18306 (define_int_iterator RDFSGSBASE
18310 (define_int_iterator WRFSGSBASE
18314 (define_int_attr fsgs
18315 [(UNSPECV_RDFSBASE "fs")
18316 (UNSPECV_RDGSBASE "gs")
18317 (UNSPECV_WRFSBASE "fs")
18318 (UNSPECV_WRGSBASE "gs")])
18320 (define_insn "rd<fsgs>base<mode>"
18321 [(set (match_operand:SWI48 0 "register_operand" "=r")
18322 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18323 "TARGET_64BIT && TARGET_FSGSBASE"
18325 [(set_attr "type" "other")
18326 (set_attr "prefix_extra" "2")])
18328 (define_insn "wr<fsgs>base<mode>"
18329 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18331 "TARGET_64BIT && TARGET_FSGSBASE"
18333 [(set_attr "type" "other")
18334 (set_attr "prefix_extra" "2")])
18336 (define_insn "rdrand<mode>_1"
18337 [(set (match_operand:SWI248 0 "register_operand" "=r")
18338 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18339 (set (reg:CCC FLAGS_REG)
18340 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18343 [(set_attr "type" "other")
18344 (set_attr "prefix_extra" "1")])
18346 (define_insn "rdseed<mode>_1"
18347 [(set (match_operand:SWI248 0 "register_operand" "=r")
18348 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18349 (set (reg:CCC FLAGS_REG)
18350 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18353 [(set_attr "type" "other")
18354 (set_attr "prefix_extra" "1")])
18356 (define_expand "pause"
18357 [(set (match_dup 0)
18358 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18361 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18362 MEM_VOLATILE_P (operands[0]) = 1;
18365 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18366 ;; They have the same encoding.
18367 (define_insn "*pause"
18368 [(set (match_operand:BLK 0)
18369 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18372 [(set_attr "length" "2")
18373 (set_attr "memory" "unknown")])
18375 (define_expand "xbegin"
18376 [(set (match_operand:SI 0 "register_operand")
18377 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18380 rtx label = gen_label_rtx ();
18382 /* xbegin is emitted as jump_insn, so reload won't be able
18383 to reload its operand. Force the value into AX hard register. */
18384 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18385 emit_move_insn (ax_reg, constm1_rtx);
18387 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18389 emit_label (label);
18390 LABEL_NUSES (label) = 1;
18392 emit_move_insn (operands[0], ax_reg);
18397 (define_insn "xbegin_1"
18399 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18401 (label_ref (match_operand 1))
18403 (set (match_operand:SI 0 "register_operand" "+a")
18404 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18407 [(set_attr "type" "other")
18408 (set_attr "length" "6")])
18410 (define_insn "xend"
18411 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18414 [(set_attr "type" "other")
18415 (set_attr "length" "3")])
18417 (define_insn "xabort"
18418 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18422 [(set_attr "type" "other")
18423 (set_attr "length" "3")])
18425 (define_expand "xtest"
18426 [(set (match_operand:QI 0 "register_operand")
18427 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18430 emit_insn (gen_xtest_1 ());
18432 ix86_expand_setcc (operands[0], NE,
18433 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18437 (define_insn "xtest_1"
18438 [(set (reg:CCZ FLAGS_REG)
18439 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18442 [(set_attr "type" "other")
18443 (set_attr "length" "3")])
18447 (include "sync.md")