1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
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 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
65 (define_c_enum "unspec" [
66 ;; Relocation specifiers
77 UNSPEC_MACHOPIC_OFFSET
86 UNSPEC_MEMORY_BLOCKAGE
94 ;; Other random patterns
103 UNSPEC_LD_MPIC ; load_macho_picbase
106 ;; For SSE/MMX support:
124 UNSPEC_MS_TO_SYSV_CALL
126 ;; Generic math support
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
131 ;; x87 Floating point
147 UNSPEC_FRNDINT_MASK_PM
151 ;; x87 Double output FP
183 ;; For SSE4.1 support
193 ;; For SSE4.2 support
199 UNSPEC_FMA4_INTRINSIC
202 UNSPEC_XOP_UNSIGNED_CMP
213 UNSPEC_AESKEYGENASSIST
215 ;; For PCLMUL support
231 (define_c_enum "unspecv" [
234 UNSPECV_PROBE_STACK_RANGE
254 UNSPECV_LLWP_INTRINSIC
255 UNSPECV_SLWP_INTRINSIC
256 UNSPECV_LWPVAL_INTRINSIC
257 UNSPECV_LWPINS_INTRINSIC
265 ;; Constants to represent pcomtrue/pcomfalse variants
275 ;; Constants used in the XOP pperm instruction
277 [(PPERM_SRC 0x00) /* copy source */
278 (PPERM_INVERT 0x20) /* invert source */
279 (PPERM_REVERSE 0x40) /* bit reverse source */
280 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
281 (PPERM_ZERO 0x80) /* all 0's */
282 (PPERM_ONES 0xa0) /* all 1's */
283 (PPERM_SIGN 0xc0) /* propagate sign bit */
284 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
285 (PPERM_SRC1 0x00) /* use first source byte */
286 (PPERM_SRC2 0x10) /* use second source byte */
289 ;; Registers by name.
342 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
345 ;; In C guard expressions, put expressions which may be compile-time
346 ;; constants first. This allows for better optimization. For
347 ;; example, write "TARGET_64BIT && reload_completed", not
348 ;; "reload_completed && TARGET_64BIT".
352 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
353 generic64,amdfam10,bdver1"
354 (const (symbol_ref "ix86_schedule")))
356 ;; A basic instruction type. Refinements due to arguments to be
357 ;; provided in other attributes.
360 alu,alu1,negnot,imov,imovx,lea,
361 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
362 icmp,test,ibr,setcc,icmov,
363 push,pop,call,callv,leave,
365 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
366 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
367 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
368 ssemuladd,sse4arg,lwp,
369 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
370 (const_string "other"))
372 ;; Main data type used by the insn
374 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
375 (const_string "unknown"))
377 ;; The CPU unit operations uses.
378 (define_attr "unit" "integer,i387,sse,mmx,unknown"
379 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
380 (const_string "i387")
381 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
382 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
383 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
385 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
387 (eq_attr "type" "other")
388 (const_string "unknown")]
389 (const_string "integer")))
391 ;; The (bounding maximum) length of an instruction immediate.
392 (define_attr "length_immediate" ""
393 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
396 (eq_attr "unit" "i387,sse,mmx")
398 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
400 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
401 (eq_attr "type" "imov,test")
402 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
403 (eq_attr "type" "call")
404 (if_then_else (match_operand 0 "constant_call_address_operand" "")
407 (eq_attr "type" "callv")
408 (if_then_else (match_operand 1 "constant_call_address_operand" "")
411 ;; We don't know the size before shorten_branches. Expect
412 ;; the instruction to fit for better scheduling.
413 (eq_attr "type" "ibr")
416 (symbol_ref "/* Update immediate_length and other attributes! */
417 gcc_unreachable (),1")))
419 ;; The (bounding maximum) length of an instruction address.
420 (define_attr "length_address" ""
421 (cond [(eq_attr "type" "str,other,multi,fxch")
423 (and (eq_attr "type" "call")
424 (match_operand 0 "constant_call_address_operand" ""))
426 (and (eq_attr "type" "callv")
427 (match_operand 1 "constant_call_address_operand" ""))
430 (symbol_ref "ix86_attr_length_address_default (insn)")))
432 ;; Set when length prefix is used.
433 (define_attr "prefix_data16" ""
434 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
436 (eq_attr "mode" "HI")
438 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
443 ;; Set when string REP prefix is used.
444 (define_attr "prefix_rep" ""
445 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
447 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
452 ;; Set when 0f opcode prefix is used.
453 (define_attr "prefix_0f" ""
455 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
456 (eq_attr "unit" "sse,mmx"))
460 ;; Set when REX opcode prefix is used.
461 (define_attr "prefix_rex" ""
462 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
464 (and (eq_attr "mode" "DI")
465 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
466 (eq_attr "unit" "!mmx")))
468 (and (eq_attr "mode" "QI")
469 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
472 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
475 (and (eq_attr "type" "imovx")
476 (match_operand:QI 1 "ext_QIreg_operand" ""))
481 ;; There are also additional prefixes in 3DNOW, SSSE3.
482 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
483 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
484 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
485 (define_attr "prefix_extra" ""
486 (cond [(eq_attr "type" "ssemuladd,sse4arg")
488 (eq_attr "type" "sseiadd1,ssecvt1")
493 ;; Prefix used: original, VEX or maybe VEX.
494 (define_attr "prefix" "orig,vex,maybe_vex"
495 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
497 (const_string "orig")))
499 ;; VEX W bit is used.
500 (define_attr "prefix_vex_w" "" (const_int 0))
502 ;; The length of VEX prefix
503 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
504 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
505 ;; still prefix_0f 1, with prefix_extra 1.
506 (define_attr "length_vex" ""
507 (if_then_else (and (eq_attr "prefix_0f" "1")
508 (eq_attr "prefix_extra" "0"))
509 (if_then_else (eq_attr "prefix_vex_w" "1")
510 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
511 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
512 (if_then_else (eq_attr "prefix_vex_w" "1")
513 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
514 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
516 ;; Set when modrm byte is used.
517 (define_attr "modrm" ""
518 (cond [(eq_attr "type" "str,leave")
520 (eq_attr "unit" "i387")
522 (and (eq_attr "type" "incdec")
523 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
524 (ior (match_operand:SI 1 "register_operand" "")
525 (match_operand:HI 1 "register_operand" ""))))
527 (and (eq_attr "type" "push")
528 (not (match_operand 1 "memory_operand" "")))
530 (and (eq_attr "type" "pop")
531 (not (match_operand 0 "memory_operand" "")))
533 (and (eq_attr "type" "imov")
534 (and (not (eq_attr "mode" "DI"))
535 (ior (and (match_operand 0 "register_operand" "")
536 (match_operand 1 "immediate_operand" ""))
537 (ior (and (match_operand 0 "ax_reg_operand" "")
538 (match_operand 1 "memory_displacement_only_operand" ""))
539 (and (match_operand 0 "memory_displacement_only_operand" "")
540 (match_operand 1 "ax_reg_operand" ""))))))
542 (and (eq_attr "type" "call")
543 (match_operand 0 "constant_call_address_operand" ""))
545 (and (eq_attr "type" "callv")
546 (match_operand 1 "constant_call_address_operand" ""))
548 (and (eq_attr "type" "alu,alu1,icmp,test")
549 (match_operand 0 "ax_reg_operand" ""))
550 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
554 ;; The (bounding maximum) length of an instruction in bytes.
555 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
556 ;; Later we may want to split them and compute proper length as for
558 (define_attr "length" ""
559 (cond [(eq_attr "type" "other,multi,fistp,frndint")
561 (eq_attr "type" "fcmp")
563 (eq_attr "unit" "i387")
565 (plus (attr "prefix_data16")
566 (attr "length_address")))
567 (ior (eq_attr "prefix" "vex")
568 (and (eq_attr "prefix" "maybe_vex")
569 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
570 (plus (attr "length_vex")
571 (plus (attr "length_immediate")
573 (attr "length_address"))))]
574 (plus (plus (attr "modrm")
575 (plus (attr "prefix_0f")
576 (plus (attr "prefix_rex")
577 (plus (attr "prefix_extra")
579 (plus (attr "prefix_rep")
580 (plus (attr "prefix_data16")
581 (plus (attr "length_immediate")
582 (attr "length_address")))))))
584 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
585 ;; `store' if there is a simple memory reference therein, or `unknown'
586 ;; if the instruction is complex.
588 (define_attr "memory" "none,load,store,both,unknown"
589 (cond [(eq_attr "type" "other,multi,str,lwp")
590 (const_string "unknown")
591 (eq_attr "type" "lea,fcmov,fpspc")
592 (const_string "none")
593 (eq_attr "type" "fistp,leave")
594 (const_string "both")
595 (eq_attr "type" "frndint")
596 (const_string "load")
597 (eq_attr "type" "push")
598 (if_then_else (match_operand 1 "memory_operand" "")
599 (const_string "both")
600 (const_string "store"))
601 (eq_attr "type" "pop")
602 (if_then_else (match_operand 0 "memory_operand" "")
603 (const_string "both")
604 (const_string "load"))
605 (eq_attr "type" "setcc")
606 (if_then_else (match_operand 0 "memory_operand" "")
607 (const_string "store")
608 (const_string "none"))
609 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
610 (if_then_else (ior (match_operand 0 "memory_operand" "")
611 (match_operand 1 "memory_operand" ""))
612 (const_string "load")
613 (const_string "none"))
614 (eq_attr "type" "ibr")
615 (if_then_else (match_operand 0 "memory_operand" "")
616 (const_string "load")
617 (const_string "none"))
618 (eq_attr "type" "call")
619 (if_then_else (match_operand 0 "constant_call_address_operand" "")
620 (const_string "none")
621 (const_string "load"))
622 (eq_attr "type" "callv")
623 (if_then_else (match_operand 1 "constant_call_address_operand" "")
624 (const_string "none")
625 (const_string "load"))
626 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
627 (match_operand 1 "memory_operand" ""))
628 (const_string "both")
629 (and (match_operand 0 "memory_operand" "")
630 (match_operand 1 "memory_operand" ""))
631 (const_string "both")
632 (match_operand 0 "memory_operand" "")
633 (const_string "store")
634 (match_operand 1 "memory_operand" "")
635 (const_string "load")
637 "!alu1,negnot,ishift1,
638 imov,imovx,icmp,test,bitmanip,
640 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
641 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
642 (match_operand 2 "memory_operand" ""))
643 (const_string "load")
644 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
645 (match_operand 3 "memory_operand" ""))
646 (const_string "load")
648 (const_string "none")))
650 ;; Indicates if an instruction has both an immediate and a displacement.
652 (define_attr "imm_disp" "false,true,unknown"
653 (cond [(eq_attr "type" "other,multi")
654 (const_string "unknown")
655 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
656 (and (match_operand 0 "memory_displacement_operand" "")
657 (match_operand 1 "immediate_operand" "")))
658 (const_string "true")
659 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
660 (and (match_operand 0 "memory_displacement_operand" "")
661 (match_operand 2 "immediate_operand" "")))
662 (const_string "true")
664 (const_string "false")))
666 ;; Indicates if an FP operation has an integer source.
668 (define_attr "fp_int_src" "false,true"
669 (const_string "false"))
671 ;; Defines rounding mode of an FP operation.
673 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
674 (const_string "any"))
676 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
677 (define_attr "use_carry" "0,1" (const_string "0"))
679 ;; Define attribute to indicate unaligned ssemov insns
680 (define_attr "movu" "0,1" (const_string "0"))
682 ;; Describe a user's asm statement.
683 (define_asm_attributes
684 [(set_attr "length" "128")
685 (set_attr "type" "multi")])
687 ;; All integer comparison codes.
688 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
690 ;; All floating-point comparison codes.
691 (define_code_iterator fp_cond [unordered ordered
692 uneq unge ungt unle unlt ltgt])
694 (define_code_iterator plusminus [plus minus])
696 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
698 ;; Base name for define_insn
699 (define_code_attr plusminus_insn
700 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
701 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
703 ;; Base name for insn mnemonic.
704 (define_code_attr plusminus_mnemonic
705 [(plus "add") (ss_plus "adds") (us_plus "addus")
706 (minus "sub") (ss_minus "subs") (us_minus "subus")])
707 (define_code_attr plusminus_carry_mnemonic
708 [(plus "adc") (minus "sbb")])
710 ;; Mark commutative operators as such in constraints.
711 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
712 (minus "") (ss_minus "") (us_minus "")])
714 ;; Mapping of signed max and min
715 (define_code_iterator smaxmin [smax smin])
717 ;; Mapping of unsigned max and min
718 (define_code_iterator umaxmin [umax umin])
720 ;; Mapping of signed/unsigned max and min
721 (define_code_iterator maxmin [smax smin umax umin])
723 ;; Base name for integer and FP insn mnemonic
724 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
725 (umax "maxu") (umin "minu")])
726 (define_code_attr maxmin_float [(smax "max") (smin "min")])
728 ;; Mapping of logic operators
729 (define_code_iterator any_logic [and ior xor])
730 (define_code_iterator any_or [ior xor])
732 ;; Base name for insn mnemonic.
733 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
735 ;; Mapping of shift-right operators
736 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
738 ;; Base name for define_insn
739 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
741 ;; Base name for insn mnemonic.
742 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
744 ;; Mapping of rotate operators
745 (define_code_iterator any_rotate [rotate rotatert])
747 ;; Base name for define_insn
748 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
750 ;; Base name for insn mnemonic.
751 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
753 ;; Mapping of abs neg operators
754 (define_code_iterator absneg [abs neg])
756 ;; Base name for x87 insn mnemonic.
757 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
759 ;; Used in signed and unsigned widening multiplications.
760 (define_code_iterator any_extend [sign_extend zero_extend])
762 ;; Various insn prefixes for signed and unsigned operations.
763 (define_code_attr u [(sign_extend "") (zero_extend "u")
764 (div "") (udiv "u")])
765 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
767 ;; Used in signed and unsigned divisions.
768 (define_code_iterator any_div [div udiv])
770 ;; Instruction prefix for signed and unsigned operations.
771 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
772 (div "i") (udiv "")])
774 ;; 64bit single word integer modes.
775 (define_mode_iterator SWI1248x [QI HI SI DI])
777 ;; 64bit single word integer modes without QImode and HImode.
778 (define_mode_iterator SWI48x [SI DI])
780 ;; Single word integer modes.
781 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
783 ;; Single word integer modes without SImode and DImode.
784 (define_mode_iterator SWI12 [QI HI])
786 ;; Single word integer modes without DImode.
787 (define_mode_iterator SWI124 [QI HI SI])
789 ;; Single word integer modes without QImode and DImode.
790 (define_mode_iterator SWI24 [HI SI])
792 ;; Single word integer modes without QImode.
793 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
795 ;; Single word integer modes without QImode and HImode.
796 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
798 ;; All math-dependant single and double word integer modes.
799 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
800 (HI "TARGET_HIMODE_MATH")
801 SI DI (TI "TARGET_64BIT")])
803 ;; Math-dependant single word integer modes.
804 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
805 (HI "TARGET_HIMODE_MATH")
806 SI (DI "TARGET_64BIT")])
808 ;; Math-dependant single word integer modes without DImode.
809 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
810 (HI "TARGET_HIMODE_MATH")
813 ;; Math-dependant single word integer modes without QImode.
814 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
815 SI (DI "TARGET_64BIT")])
817 ;; Double word integer modes.
818 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
819 (TI "TARGET_64BIT")])
821 ;; Double word integer modes as mode attribute.
822 (define_mode_attr DWI [(SI "DI") (DI "TI")])
823 (define_mode_attr dwi [(SI "di") (DI "ti")])
825 ;; Half mode for double word integer modes.
826 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
827 (DI "TARGET_64BIT")])
829 ;; Instruction suffix for integer modes.
830 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
832 ;; Register class for integer modes.
833 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
835 ;; Immediate operand constraint for integer modes.
836 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
838 ;; General operand constraint for word modes.
839 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
841 ;; Immediate operand constraint for double integer modes.
842 (define_mode_attr di [(SI "iF") (DI "e")])
844 ;; Immediate operand constraint for shifts.
845 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
847 ;; General operand predicate for integer modes.
848 (define_mode_attr general_operand
849 [(QI "general_operand")
850 (HI "general_operand")
851 (SI "general_operand")
852 (DI "x86_64_general_operand")
853 (TI "x86_64_general_operand")])
855 ;; General sign/zero extend operand predicate for integer modes.
856 (define_mode_attr general_szext_operand
857 [(QI "general_operand")
858 (HI "general_operand")
859 (SI "general_operand")
860 (DI "x86_64_szext_general_operand")])
862 ;; Immediate operand predicate for integer modes.
863 (define_mode_attr immediate_operand
864 [(QI "immediate_operand")
865 (HI "immediate_operand")
866 (SI "immediate_operand")
867 (DI "x86_64_immediate_operand")])
869 ;; Operand predicate for shifts.
870 (define_mode_attr shift_operand
871 [(QI "nonimmediate_operand")
872 (HI "nonimmediate_operand")
873 (SI "nonimmediate_operand")
874 (DI "shiftdi_operand")
875 (TI "register_operand")])
877 ;; Operand predicate for shift argument.
878 (define_mode_attr shift_immediate_operand
879 [(QI "const_1_to_31_operand")
880 (HI "const_1_to_31_operand")
881 (SI "const_1_to_31_operand")
882 (DI "const_1_to_63_operand")])
884 ;; Input operand predicate for arithmetic left shifts.
885 (define_mode_attr ashl_input_operand
886 [(QI "nonimmediate_operand")
887 (HI "nonimmediate_operand")
888 (SI "nonimmediate_operand")
889 (DI "ashldi_input_operand")
890 (TI "reg_or_pm1_operand")])
892 ;; SSE and x87 SFmode and DFmode floating point modes
893 (define_mode_iterator MODEF [SF DF])
895 ;; All x87 floating point modes
896 (define_mode_iterator X87MODEF [SF DF XF])
898 ;; All integer modes handled by x87 fisttp operator.
899 (define_mode_iterator X87MODEI [HI SI DI])
901 ;; All integer modes handled by integer x87 operators.
902 (define_mode_iterator X87MODEI12 [HI SI])
904 ;; All integer modes handled by SSE cvtts?2si* operators.
905 (define_mode_iterator SSEMODEI24 [SI DI])
907 ;; SSE asm suffix for floating point modes
908 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
910 ;; SSE vector mode corresponding to a scalar mode
911 (define_mode_attr ssevecmode
912 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
914 ;; Instruction suffix for REX 64bit operators.
915 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
917 ;; This mode iterator allows :P to be used for patterns that operate on
918 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
919 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
921 ;; Scheduling descriptions
923 (include "pentium.md")
926 (include "athlon.md")
931 ;; Operand and operator predicates and constraints
933 (include "predicates.md")
934 (include "constraints.md")
937 ;; Compare and branch/compare and store instructions.
939 (define_expand "cbranch<mode>4"
940 [(set (reg:CC FLAGS_REG)
941 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
942 (match_operand:SDWIM 2 "<general_operand>" "")))
943 (set (pc) (if_then_else
944 (match_operator 0 "comparison_operator"
945 [(reg:CC FLAGS_REG) (const_int 0)])
946 (label_ref (match_operand 3 "" ""))
950 if (MEM_P (operands[1]) && MEM_P (operands[2]))
951 operands[1] = force_reg (<MODE>mode, operands[1]);
952 ix86_compare_op0 = operands[1];
953 ix86_compare_op1 = operands[2];
954 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
958 (define_expand "cstore<mode>4"
959 [(set (reg:CC FLAGS_REG)
960 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
961 (match_operand:SWIM 3 "<general_operand>" "")))
962 (set (match_operand:QI 0 "register_operand" "")
963 (match_operator 1 "comparison_operator"
964 [(reg:CC FLAGS_REG) (const_int 0)]))]
967 if (MEM_P (operands[2]) && MEM_P (operands[3]))
968 operands[2] = force_reg (<MODE>mode, operands[2]);
969 ix86_compare_op0 = operands[2];
970 ix86_compare_op1 = operands[3];
971 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
975 (define_expand "cmp<mode>_1"
976 [(set (reg:CC FLAGS_REG)
977 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
978 (match_operand:SWI48 1 "<general_operand>" "")))]
982 (define_insn "*cmp<mode>_ccno_1"
983 [(set (reg FLAGS_REG)
984 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
985 (match_operand:SWI 1 "const0_operand" "")))]
986 "ix86_match_ccmode (insn, CCNOmode)"
988 test{<imodesuffix>}\t%0, %0
989 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
990 [(set_attr "type" "test,icmp")
991 (set_attr "length_immediate" "0,1")
992 (set_attr "mode" "<MODE>")])
994 (define_insn "*cmp<mode>_1"
995 [(set (reg FLAGS_REG)
996 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
997 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
998 "ix86_match_ccmode (insn, CCmode)"
999 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1000 [(set_attr "type" "icmp")
1001 (set_attr "mode" "<MODE>")])
1003 (define_insn "*cmp<mode>_minus_1"
1004 [(set (reg FLAGS_REG)
1006 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1007 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1009 "ix86_match_ccmode (insn, CCGOCmode)"
1010 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1011 [(set_attr "type" "icmp")
1012 (set_attr "mode" "<MODE>")])
1014 (define_insn "*cmpqi_ext_1"
1015 [(set (reg FLAGS_REG)
1017 (match_operand:QI 0 "general_operand" "Qm")
1020 (match_operand 1 "ext_register_operand" "Q")
1022 (const_int 8)) 0)))]
1023 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1024 "cmp{b}\t{%h1, %0|%0, %h1}"
1025 [(set_attr "type" "icmp")
1026 (set_attr "mode" "QI")])
1028 (define_insn "*cmpqi_ext_1_rex64"
1029 [(set (reg FLAGS_REG)
1031 (match_operand:QI 0 "register_operand" "Q")
1034 (match_operand 1 "ext_register_operand" "Q")
1036 (const_int 8)) 0)))]
1037 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1038 "cmp{b}\t{%h1, %0|%0, %h1}"
1039 [(set_attr "type" "icmp")
1040 (set_attr "mode" "QI")])
1042 (define_insn "*cmpqi_ext_2"
1043 [(set (reg FLAGS_REG)
1047 (match_operand 0 "ext_register_operand" "Q")
1050 (match_operand:QI 1 "const0_operand" "")))]
1051 "ix86_match_ccmode (insn, CCNOmode)"
1053 [(set_attr "type" "test")
1054 (set_attr "length_immediate" "0")
1055 (set_attr "mode" "QI")])
1057 (define_expand "cmpqi_ext_3"
1058 [(set (reg:CC FLAGS_REG)
1062 (match_operand 0 "ext_register_operand" "")
1065 (match_operand:QI 1 "immediate_operand" "")))]
1069 (define_insn "*cmpqi_ext_3_insn"
1070 [(set (reg FLAGS_REG)
1074 (match_operand 0 "ext_register_operand" "Q")
1077 (match_operand:QI 1 "general_operand" "Qmn")))]
1078 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1079 "cmp{b}\t{%1, %h0|%h0, %1}"
1080 [(set_attr "type" "icmp")
1081 (set_attr "modrm" "1")
1082 (set_attr "mode" "QI")])
1084 (define_insn "*cmpqi_ext_3_insn_rex64"
1085 [(set (reg FLAGS_REG)
1089 (match_operand 0 "ext_register_operand" "Q")
1092 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1093 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1094 "cmp{b}\t{%1, %h0|%h0, %1}"
1095 [(set_attr "type" "icmp")
1096 (set_attr "modrm" "1")
1097 (set_attr "mode" "QI")])
1099 (define_insn "*cmpqi_ext_4"
1100 [(set (reg FLAGS_REG)
1104 (match_operand 0 "ext_register_operand" "Q")
1109 (match_operand 1 "ext_register_operand" "Q")
1111 (const_int 8)) 0)))]
1112 "ix86_match_ccmode (insn, CCmode)"
1113 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1114 [(set_attr "type" "icmp")
1115 (set_attr "mode" "QI")])
1117 ;; These implement float point compares.
1118 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1119 ;; which would allow mix and match FP modes on the compares. Which is what
1120 ;; the old patterns did, but with many more of them.
1122 (define_expand "cbranchxf4"
1123 [(set (reg:CC FLAGS_REG)
1124 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1125 (match_operand:XF 2 "nonmemory_operand" "")))
1126 (set (pc) (if_then_else
1127 (match_operator 0 "ix86_fp_comparison_operator"
1130 (label_ref (match_operand 3 "" ""))
1134 ix86_compare_op0 = operands[1];
1135 ix86_compare_op1 = operands[2];
1136 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1140 (define_expand "cstorexf4"
1141 [(set (reg:CC FLAGS_REG)
1142 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1143 (match_operand:XF 3 "nonmemory_operand" "")))
1144 (set (match_operand:QI 0 "register_operand" "")
1145 (match_operator 1 "ix86_fp_comparison_operator"
1150 ix86_compare_op0 = operands[2];
1151 ix86_compare_op1 = operands[3];
1152 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1156 (define_expand "cbranch<mode>4"
1157 [(set (reg:CC FLAGS_REG)
1158 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1159 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1160 (set (pc) (if_then_else
1161 (match_operator 0 "ix86_fp_comparison_operator"
1164 (label_ref (match_operand 3 "" ""))
1166 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1168 ix86_compare_op0 = operands[1];
1169 ix86_compare_op1 = operands[2];
1170 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1174 (define_expand "cstore<mode>4"
1175 [(set (reg:CC FLAGS_REG)
1176 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1177 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1178 (set (match_operand:QI 0 "register_operand" "")
1179 (match_operator 1 "ix86_fp_comparison_operator"
1182 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1184 ix86_compare_op0 = operands[2];
1185 ix86_compare_op1 = operands[3];
1186 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1190 (define_expand "cbranchcc4"
1191 [(set (pc) (if_then_else
1192 (match_operator 0 "comparison_operator"
1193 [(match_operand 1 "flags_reg_operand" "")
1194 (match_operand 2 "const0_operand" "")])
1195 (label_ref (match_operand 3 "" ""))
1199 ix86_compare_op0 = operands[1];
1200 ix86_compare_op1 = operands[2];
1201 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1205 (define_expand "cstorecc4"
1206 [(set (match_operand:QI 0 "register_operand" "")
1207 (match_operator 1 "comparison_operator"
1208 [(match_operand 2 "flags_reg_operand" "")
1209 (match_operand 3 "const0_operand" "")]))]
1212 ix86_compare_op0 = operands[2];
1213 ix86_compare_op1 = operands[3];
1214 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1219 ;; FP compares, step 1:
1220 ;; Set the FP condition codes.
1222 ;; CCFPmode compare with exceptions
1223 ;; CCFPUmode compare with no exceptions
1225 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1226 ;; used to manage the reg stack popping would not be preserved.
1228 (define_insn "*cmpfp_0"
1229 [(set (match_operand:HI 0 "register_operand" "=a")
1232 (match_operand 1 "register_operand" "f")
1233 (match_operand 2 "const0_operand" ""))]
1235 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1236 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1237 "* return output_fp_compare (insn, operands, 0, 0);"
1238 [(set_attr "type" "multi")
1239 (set_attr "unit" "i387")
1241 (cond [(match_operand:SF 1 "" "")
1243 (match_operand:DF 1 "" "")
1246 (const_string "XF")))])
1248 (define_insn_and_split "*cmpfp_0_cc"
1249 [(set (reg:CCFP FLAGS_REG)
1251 (match_operand 1 "register_operand" "f")
1252 (match_operand 2 "const0_operand" "")))
1253 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1254 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1255 && TARGET_SAHF && !TARGET_CMOVE
1256 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1258 "&& reload_completed"
1261 [(compare:CCFP (match_dup 1)(match_dup 2))]
1263 (set (reg:CC FLAGS_REG)
1264 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1266 [(set_attr "type" "multi")
1267 (set_attr "unit" "i387")
1269 (cond [(match_operand:SF 1 "" "")
1271 (match_operand:DF 1 "" "")
1274 (const_string "XF")))])
1276 (define_insn "*cmpfp_xf"
1277 [(set (match_operand:HI 0 "register_operand" "=a")
1280 (match_operand:XF 1 "register_operand" "f")
1281 (match_operand:XF 2 "register_operand" "f"))]
1284 "* return output_fp_compare (insn, operands, 0, 0);"
1285 [(set_attr "type" "multi")
1286 (set_attr "unit" "i387")
1287 (set_attr "mode" "XF")])
1289 (define_insn_and_split "*cmpfp_xf_cc"
1290 [(set (reg:CCFP FLAGS_REG)
1292 (match_operand:XF 1 "register_operand" "f")
1293 (match_operand:XF 2 "register_operand" "f")))
1294 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1296 && TARGET_SAHF && !TARGET_CMOVE"
1298 "&& reload_completed"
1301 [(compare:CCFP (match_dup 1)(match_dup 2))]
1303 (set (reg:CC FLAGS_REG)
1304 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1306 [(set_attr "type" "multi")
1307 (set_attr "unit" "i387")
1308 (set_attr "mode" "XF")])
1310 (define_insn "*cmpfp_<mode>"
1311 [(set (match_operand:HI 0 "register_operand" "=a")
1314 (match_operand:MODEF 1 "register_operand" "f")
1315 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1318 "* return output_fp_compare (insn, operands, 0, 0);"
1319 [(set_attr "type" "multi")
1320 (set_attr "unit" "i387")
1321 (set_attr "mode" "<MODE>")])
1323 (define_insn_and_split "*cmpfp_<mode>_cc"
1324 [(set (reg:CCFP FLAGS_REG)
1326 (match_operand:MODEF 1 "register_operand" "f")
1327 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1328 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1330 && TARGET_SAHF && !TARGET_CMOVE"
1332 "&& reload_completed"
1335 [(compare:CCFP (match_dup 1)(match_dup 2))]
1337 (set (reg:CC FLAGS_REG)
1338 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1340 [(set_attr "type" "multi")
1341 (set_attr "unit" "i387")
1342 (set_attr "mode" "<MODE>")])
1344 (define_insn "*cmpfp_u"
1345 [(set (match_operand:HI 0 "register_operand" "=a")
1348 (match_operand 1 "register_operand" "f")
1349 (match_operand 2 "register_operand" "f"))]
1351 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1352 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1353 "* return output_fp_compare (insn, operands, 0, 1);"
1354 [(set_attr "type" "multi")
1355 (set_attr "unit" "i387")
1357 (cond [(match_operand:SF 1 "" "")
1359 (match_operand:DF 1 "" "")
1362 (const_string "XF")))])
1364 (define_insn_and_split "*cmpfp_u_cc"
1365 [(set (reg:CCFPU FLAGS_REG)
1367 (match_operand 1 "register_operand" "f")
1368 (match_operand 2 "register_operand" "f")))
1369 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1370 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1371 && TARGET_SAHF && !TARGET_CMOVE
1372 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1374 "&& reload_completed"
1377 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1379 (set (reg:CC FLAGS_REG)
1380 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1382 [(set_attr "type" "multi")
1383 (set_attr "unit" "i387")
1385 (cond [(match_operand:SF 1 "" "")
1387 (match_operand:DF 1 "" "")
1390 (const_string "XF")))])
1392 (define_insn "*cmpfp_<mode>"
1393 [(set (match_operand:HI 0 "register_operand" "=a")
1396 (match_operand 1 "register_operand" "f")
1397 (match_operator 3 "float_operator"
1398 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1400 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1401 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1402 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1403 "* return output_fp_compare (insn, operands, 0, 0);"
1404 [(set_attr "type" "multi")
1405 (set_attr "unit" "i387")
1406 (set_attr "fp_int_src" "true")
1407 (set_attr "mode" "<MODE>")])
1409 (define_insn_and_split "*cmpfp_<mode>_cc"
1410 [(set (reg:CCFP FLAGS_REG)
1412 (match_operand 1 "register_operand" "f")
1413 (match_operator 3 "float_operator"
1414 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1415 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1416 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1417 && TARGET_SAHF && !TARGET_CMOVE
1418 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1419 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1421 "&& reload_completed"
1426 (match_op_dup 3 [(match_dup 2)]))]
1428 (set (reg:CC FLAGS_REG)
1429 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1431 [(set_attr "type" "multi")
1432 (set_attr "unit" "i387")
1433 (set_attr "fp_int_src" "true")
1434 (set_attr "mode" "<MODE>")])
1436 ;; FP compares, step 2
1437 ;; Move the fpsw to ax.
1439 (define_insn "x86_fnstsw_1"
1440 [(set (match_operand:HI 0 "register_operand" "=a")
1441 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1444 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1445 (set_attr "mode" "SI")
1446 (set_attr "unit" "i387")])
1448 ;; FP compares, step 3
1449 ;; Get ax into flags, general case.
1451 (define_insn "x86_sahf_1"
1452 [(set (reg:CC FLAGS_REG)
1453 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1457 #ifndef HAVE_AS_IX86_SAHF
1459 return ASM_BYTE "0x9e";
1464 [(set_attr "length" "1")
1465 (set_attr "athlon_decode" "vector")
1466 (set_attr "amdfam10_decode" "direct")
1467 (set_attr "mode" "SI")])
1469 ;; Pentium Pro can do steps 1 through 3 in one go.
1470 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1471 (define_insn "*cmpfp_i_mixed"
1472 [(set (reg:CCFP FLAGS_REG)
1473 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1474 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1475 "TARGET_MIX_SSE_I387
1476 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1477 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1478 "* return output_fp_compare (insn, operands, 1, 0);"
1479 [(set_attr "type" "fcmp,ssecomi")
1480 (set_attr "prefix" "orig,maybe_vex")
1482 (if_then_else (match_operand:SF 1 "" "")
1484 (const_string "DF")))
1485 (set (attr "prefix_rep")
1486 (if_then_else (eq_attr "type" "ssecomi")
1488 (const_string "*")))
1489 (set (attr "prefix_data16")
1490 (cond [(eq_attr "type" "fcmp")
1492 (eq_attr "mode" "DF")
1495 (const_string "0")))
1496 (set_attr "athlon_decode" "vector")
1497 (set_attr "amdfam10_decode" "direct")])
1499 (define_insn "*cmpfp_i_sse"
1500 [(set (reg:CCFP FLAGS_REG)
1501 (compare:CCFP (match_operand 0 "register_operand" "x")
1502 (match_operand 1 "nonimmediate_operand" "xm")))]
1504 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1505 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1506 "* return output_fp_compare (insn, operands, 1, 0);"
1507 [(set_attr "type" "ssecomi")
1508 (set_attr "prefix" "maybe_vex")
1510 (if_then_else (match_operand:SF 1 "" "")
1512 (const_string "DF")))
1513 (set_attr "prefix_rep" "0")
1514 (set (attr "prefix_data16")
1515 (if_then_else (eq_attr "mode" "DF")
1517 (const_string "0")))
1518 (set_attr "athlon_decode" "vector")
1519 (set_attr "amdfam10_decode" "direct")])
1521 (define_insn "*cmpfp_i_i387"
1522 [(set (reg:CCFP FLAGS_REG)
1523 (compare:CCFP (match_operand 0 "register_operand" "f")
1524 (match_operand 1 "register_operand" "f")))]
1525 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1527 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1528 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1529 "* return output_fp_compare (insn, operands, 1, 0);"
1530 [(set_attr "type" "fcmp")
1532 (cond [(match_operand:SF 1 "" "")
1534 (match_operand:DF 1 "" "")
1537 (const_string "XF")))
1538 (set_attr "athlon_decode" "vector")
1539 (set_attr "amdfam10_decode" "direct")])
1541 (define_insn "*cmpfp_iu_mixed"
1542 [(set (reg:CCFPU FLAGS_REG)
1543 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1544 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1545 "TARGET_MIX_SSE_I387
1546 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1547 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1548 "* return output_fp_compare (insn, operands, 1, 1);"
1549 [(set_attr "type" "fcmp,ssecomi")
1550 (set_attr "prefix" "orig,maybe_vex")
1552 (if_then_else (match_operand:SF 1 "" "")
1554 (const_string "DF")))
1555 (set (attr "prefix_rep")
1556 (if_then_else (eq_attr "type" "ssecomi")
1558 (const_string "*")))
1559 (set (attr "prefix_data16")
1560 (cond [(eq_attr "type" "fcmp")
1562 (eq_attr "mode" "DF")
1565 (const_string "0")))
1566 (set_attr "athlon_decode" "vector")
1567 (set_attr "amdfam10_decode" "direct")])
1569 (define_insn "*cmpfp_iu_sse"
1570 [(set (reg:CCFPU FLAGS_REG)
1571 (compare:CCFPU (match_operand 0 "register_operand" "x")
1572 (match_operand 1 "nonimmediate_operand" "xm")))]
1574 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1575 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1576 "* return output_fp_compare (insn, operands, 1, 1);"
1577 [(set_attr "type" "ssecomi")
1578 (set_attr "prefix" "maybe_vex")
1580 (if_then_else (match_operand:SF 1 "" "")
1582 (const_string "DF")))
1583 (set_attr "prefix_rep" "0")
1584 (set (attr "prefix_data16")
1585 (if_then_else (eq_attr "mode" "DF")
1587 (const_string "0")))
1588 (set_attr "athlon_decode" "vector")
1589 (set_attr "amdfam10_decode" "direct")])
1591 (define_insn "*cmpfp_iu_387"
1592 [(set (reg:CCFPU FLAGS_REG)
1593 (compare:CCFPU (match_operand 0 "register_operand" "f")
1594 (match_operand 1 "register_operand" "f")))]
1595 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1597 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1598 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1599 "* return output_fp_compare (insn, operands, 1, 1);"
1600 [(set_attr "type" "fcmp")
1602 (cond [(match_operand:SF 1 "" "")
1604 (match_operand:DF 1 "" "")
1607 (const_string "XF")))
1608 (set_attr "athlon_decode" "vector")
1609 (set_attr "amdfam10_decode" "direct")])
1611 ;; Move instructions.
1613 (define_expand "movoi"
1614 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1615 (match_operand:OI 1 "general_operand" ""))]
1617 "ix86_expand_move (OImode, operands); DONE;")
1619 (define_expand "movti"
1620 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1621 (match_operand:TI 1 "nonimmediate_operand" ""))]
1622 "TARGET_64BIT || TARGET_SSE"
1625 ix86_expand_move (TImode, operands);
1626 else if (push_operand (operands[0], TImode))
1627 ix86_expand_push (TImode, operands[1]);
1629 ix86_expand_vector_move (TImode, operands);
1633 ;; This expands to what emit_move_complex would generate if we didn't
1634 ;; have a movti pattern. Having this avoids problems with reload on
1635 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1636 ;; to have around all the time.
1637 (define_expand "movcdi"
1638 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1639 (match_operand:CDI 1 "general_operand" ""))]
1642 if (push_operand (operands[0], CDImode))
1643 emit_move_complex_push (CDImode, operands[0], operands[1]);
1645 emit_move_complex_parts (operands[0], operands[1]);
1649 (define_expand "mov<mode>"
1650 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1651 (match_operand:SWI1248x 1 "general_operand" ""))]
1653 "ix86_expand_move (<MODE>mode, operands); DONE;")
1655 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1658 ;; %%% We don't use a post-inc memory reference because x86 is not a
1659 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1660 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1661 ;; targets without our curiosities, and it is just as easy to represent
1662 ;; this differently.
1664 (define_insn "*pushdi2_rex64"
1665 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1666 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1671 [(set_attr "type" "push,multi")
1672 (set_attr "mode" "DI")])
1674 ;; Convert impossible pushes of immediate to existing instructions.
1675 ;; First try to get scratch register and go through it. In case this
1676 ;; fails, push sign extended lower part first and then overwrite
1677 ;; upper part by 32bit move.
1679 [(match_scratch:DI 2 "r")
1680 (set (match_operand:DI 0 "push_operand" "")
1681 (match_operand:DI 1 "immediate_operand" ""))]
1682 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1683 && !x86_64_immediate_operand (operands[1], DImode)"
1684 [(set (match_dup 2) (match_dup 1))
1685 (set (match_dup 0) (match_dup 2))]
1688 ;; We need to define this as both peepholer and splitter for case
1689 ;; peephole2 pass is not run.
1690 ;; "&& 1" is needed to keep it from matching the previous pattern.
1692 [(set (match_operand:DI 0 "push_operand" "")
1693 (match_operand:DI 1 "immediate_operand" ""))]
1694 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1695 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1696 [(set (match_dup 0) (match_dup 1))
1697 (set (match_dup 2) (match_dup 3))]
1699 split_di (&operands[1], 1, &operands[2], &operands[3]);
1701 operands[1] = gen_lowpart (DImode, operands[2]);
1702 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1707 [(set (match_operand:DI 0 "push_operand" "")
1708 (match_operand:DI 1 "immediate_operand" ""))]
1709 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1710 ? epilogue_completed : reload_completed)
1711 && !symbolic_operand (operands[1], DImode)
1712 && !x86_64_immediate_operand (operands[1], DImode)"
1713 [(set (match_dup 0) (match_dup 1))
1714 (set (match_dup 2) (match_dup 3))]
1716 split_di (&operands[1], 1, &operands[2], &operands[3]);
1718 operands[1] = gen_lowpart (DImode, operands[2]);
1719 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1723 (define_insn "*pushdi2"
1724 [(set (match_operand:DI 0 "push_operand" "=<")
1725 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1730 [(set (match_operand:DI 0 "push_operand" "")
1731 (match_operand:DI 1 "general_operand" ""))]
1732 "!TARGET_64BIT && reload_completed
1733 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1735 "ix86_split_long_move (operands); DONE;")
1737 (define_insn "*pushsi2"
1738 [(set (match_operand:SI 0 "push_operand" "=<")
1739 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1742 [(set_attr "type" "push")
1743 (set_attr "mode" "SI")])
1745 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1746 ;; "push a byte/word". But actually we use pushl, which has the effect
1747 ;; of rounding the amount pushed up to a word.
1749 ;; For 64BIT abi we always round up to 8 bytes.
1750 (define_insn "*push<mode>2_rex64"
1751 [(set (match_operand:SWI124 0 "push_operand" "=X")
1752 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1755 [(set_attr "type" "push")
1756 (set_attr "mode" "DI")])
1758 (define_insn "*push<mode>2"
1759 [(set (match_operand:SWI12 0 "push_operand" "=X")
1760 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1763 [(set_attr "type" "push")
1764 (set_attr "mode" "SI")])
1766 (define_insn "*push<mode>2_prologue"
1767 [(set (match_operand:P 0 "push_operand" "=<")
1768 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1769 (clobber (mem:BLK (scratch)))]
1771 "push{<imodesuffix>}\t%1"
1772 [(set_attr "type" "push")
1773 (set_attr "mode" "<MODE>")])
1775 (define_insn "popdi1"
1776 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1777 (mem:DI (reg:DI SP_REG)))
1778 (set (reg:DI SP_REG)
1779 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1782 [(set_attr "type" "pop")
1783 (set_attr "mode" "DI")])
1785 (define_insn "popsi1"
1786 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1787 (mem:SI (reg:SI SP_REG)))
1788 (set (reg:SI SP_REG)
1789 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1792 [(set_attr "type" "pop")
1793 (set_attr "mode" "SI")])
1795 (define_insn "*popdi1_epilogue"
1796 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1797 (mem:DI (reg:DI SP_REG)))
1798 (set (reg:DI SP_REG)
1799 (plus:DI (reg:DI SP_REG) (const_int 8)))
1800 (clobber (mem:BLK (scratch)))]
1803 [(set_attr "type" "pop")
1804 (set_attr "mode" "DI")])
1806 (define_insn "*popsi1_epilogue"
1807 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1808 (mem:SI (reg:SI SP_REG)))
1809 (set (reg:SI SP_REG)
1810 (plus:SI (reg:SI SP_REG) (const_int 4)))
1811 (clobber (mem:BLK (scratch)))]
1814 [(set_attr "type" "pop")
1815 (set_attr "mode" "SI")])
1817 (define_insn "*mov<mode>_xor"
1818 [(set (match_operand:SWI48 0 "register_operand" "=r")
1819 (match_operand:SWI48 1 "const0_operand" ""))
1820 (clobber (reg:CC FLAGS_REG))]
1823 [(set_attr "type" "alu1")
1824 (set_attr "mode" "SI")
1825 (set_attr "length_immediate" "0")])
1827 (define_insn "*mov<mode>_or"
1828 [(set (match_operand:SWI48 0 "register_operand" "=r")
1829 (match_operand:SWI48 1 "const_int_operand" ""))
1830 (clobber (reg:CC FLAGS_REG))]
1832 && operands[1] == constm1_rtx"
1833 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1834 [(set_attr "type" "alu1")
1835 (set_attr "mode" "<MODE>")
1836 (set_attr "length_immediate" "1")])
1838 (define_insn "*movoi_internal_avx"
1839 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1840 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1841 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1843 switch (which_alternative)
1846 return "vxorps\t%0, %0, %0";
1849 if (misaligned_operand (operands[0], OImode)
1850 || misaligned_operand (operands[1], OImode))
1851 return "vmovdqu\t{%1, %0|%0, %1}";
1853 return "vmovdqa\t{%1, %0|%0, %1}";
1858 [(set_attr "type" "sselog1,ssemov,ssemov")
1859 (set_attr "prefix" "vex")
1860 (set_attr "mode" "OI")])
1862 (define_insn "*movti_internal_rex64"
1863 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1864 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1865 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1867 switch (which_alternative)
1873 if (get_attr_mode (insn) == MODE_V4SF)
1874 return "%vxorps\t%0, %d0";
1876 return "%vpxor\t%0, %d0";
1879 /* TDmode values are passed as TImode on the stack. Moving them
1880 to stack may result in unaligned memory access. */
1881 if (misaligned_operand (operands[0], TImode)
1882 || misaligned_operand (operands[1], TImode))
1884 if (get_attr_mode (insn) == MODE_V4SF)
1885 return "%vmovups\t{%1, %0|%0, %1}";
1887 return "%vmovdqu\t{%1, %0|%0, %1}";
1891 if (get_attr_mode (insn) == MODE_V4SF)
1892 return "%vmovaps\t{%1, %0|%0, %1}";
1894 return "%vmovdqa\t{%1, %0|%0, %1}";
1900 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1901 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1903 (cond [(eq_attr "alternative" "2,3")
1905 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1907 (const_string "V4SF")
1908 (const_string "TI"))
1909 (eq_attr "alternative" "4")
1911 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1913 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1915 (const_string "V4SF")
1916 (const_string "TI"))]
1917 (const_string "DI")))])
1920 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1921 (match_operand:TI 1 "general_operand" ""))]
1923 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1925 "ix86_split_long_move (operands); DONE;")
1927 (define_insn "*movti_internal_sse"
1928 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1929 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1930 "TARGET_SSE && !TARGET_64BIT
1931 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1933 switch (which_alternative)
1936 if (get_attr_mode (insn) == MODE_V4SF)
1937 return "%vxorps\t%0, %d0";
1939 return "%vpxor\t%0, %d0";
1942 /* TDmode values are passed as TImode on the stack. Moving them
1943 to stack may result in unaligned memory access. */
1944 if (misaligned_operand (operands[0], TImode)
1945 || misaligned_operand (operands[1], TImode))
1947 if (get_attr_mode (insn) == MODE_V4SF)
1948 return "%vmovups\t{%1, %0|%0, %1}";
1950 return "%vmovdqu\t{%1, %0|%0, %1}";
1954 if (get_attr_mode (insn) == MODE_V4SF)
1955 return "%vmovaps\t{%1, %0|%0, %1}";
1957 return "%vmovdqa\t{%1, %0|%0, %1}";
1963 [(set_attr "type" "sselog1,ssemov,ssemov")
1964 (set_attr "prefix" "maybe_vex")
1966 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1967 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1969 (const_string "V4SF")
1970 (and (eq_attr "alternative" "2")
1971 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1973 (const_string "V4SF")]
1974 (const_string "TI")))])
1976 (define_insn "*movdi_internal_rex64"
1977 [(set (match_operand:DI 0 "nonimmediate_operand"
1978 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1979 (match_operand:DI 1 "general_operand"
1980 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1981 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1983 switch (get_attr_type (insn))
1986 if (SSE_REG_P (operands[0]))
1987 return "movq2dq\t{%1, %0|%0, %1}";
1989 return "movdq2q\t{%1, %0|%0, %1}";
1994 if (get_attr_mode (insn) == MODE_TI)
1995 return "vmovdqa\t{%1, %0|%0, %1}";
1997 return "vmovq\t{%1, %0|%0, %1}";
2000 if (get_attr_mode (insn) == MODE_TI)
2001 return "movdqa\t{%1, %0|%0, %1}";
2005 /* Moves from and into integer register is done using movd
2006 opcode with REX prefix. */
2007 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2008 return "movd\t{%1, %0|%0, %1}";
2009 return "movq\t{%1, %0|%0, %1}";
2012 return "%vpxor\t%0, %d0";
2015 return "pxor\t%0, %0";
2021 return "lea{q}\t{%a1, %0|%0, %a1}";
2024 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2025 if (get_attr_mode (insn) == MODE_SI)
2026 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2027 else if (which_alternative == 2)
2028 return "movabs{q}\t{%1, %0|%0, %1}";
2030 return "mov{q}\t{%1, %0|%0, %1}";
2034 (cond [(eq_attr "alternative" "5")
2035 (const_string "mmx")
2036 (eq_attr "alternative" "6,7,8,9,10")
2037 (const_string "mmxmov")
2038 (eq_attr "alternative" "11")
2039 (const_string "sselog1")
2040 (eq_attr "alternative" "12,13,14,15,16")
2041 (const_string "ssemov")
2042 (eq_attr "alternative" "17,18")
2043 (const_string "ssecvt")
2044 (eq_attr "alternative" "4")
2045 (const_string "multi")
2046 (match_operand:DI 1 "pic_32bit_operand" "")
2047 (const_string "lea")
2049 (const_string "imov")))
2052 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2054 (const_string "*")))
2055 (set (attr "length_immediate")
2057 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2059 (const_string "*")))
2060 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2061 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2062 (set (attr "prefix")
2063 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2064 (const_string "maybe_vex")
2065 (const_string "orig")))
2066 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2068 ;; Convert impossible stores of immediate to existing instructions.
2069 ;; First try to get scratch register and go through it. In case this
2070 ;; fails, move by 32bit parts.
2072 [(match_scratch:DI 2 "r")
2073 (set (match_operand:DI 0 "memory_operand" "")
2074 (match_operand:DI 1 "immediate_operand" ""))]
2075 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2076 && !x86_64_immediate_operand (operands[1], DImode)"
2077 [(set (match_dup 2) (match_dup 1))
2078 (set (match_dup 0) (match_dup 2))]
2081 ;; We need to define this as both peepholer and splitter for case
2082 ;; peephole2 pass is not run.
2083 ;; "&& 1" is needed to keep it from matching the previous pattern.
2085 [(set (match_operand:DI 0 "memory_operand" "")
2086 (match_operand:DI 1 "immediate_operand" ""))]
2087 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2088 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2089 [(set (match_dup 2) (match_dup 3))
2090 (set (match_dup 4) (match_dup 5))]
2091 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2094 [(set (match_operand:DI 0 "memory_operand" "")
2095 (match_operand:DI 1 "immediate_operand" ""))]
2096 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2097 ? epilogue_completed : reload_completed)
2098 && !symbolic_operand (operands[1], DImode)
2099 && !x86_64_immediate_operand (operands[1], DImode)"
2100 [(set (match_dup 2) (match_dup 3))
2101 (set (match_dup 4) (match_dup 5))]
2102 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2104 (define_insn "*movdi_internal"
2105 [(set (match_operand:DI 0 "nonimmediate_operand"
2106 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2107 (match_operand:DI 1 "general_operand"
2108 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2109 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2114 movq\t{%1, %0|%0, %1}
2115 movq\t{%1, %0|%0, %1}
2117 %vmovq\t{%1, %0|%0, %1}
2118 %vmovdqa\t{%1, %0|%0, %1}
2119 %vmovq\t{%1, %0|%0, %1}
2121 movlps\t{%1, %0|%0, %1}
2122 movaps\t{%1, %0|%0, %1}
2123 movlps\t{%1, %0|%0, %1}"
2124 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2125 (set (attr "prefix")
2126 (if_then_else (eq_attr "alternative" "5,6,7,8")
2127 (const_string "vex")
2128 (const_string "orig")))
2129 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2132 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2133 (match_operand:DI 1 "general_operand" ""))]
2134 "!TARGET_64BIT && reload_completed
2135 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2136 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2138 "ix86_split_long_move (operands); DONE;")
2140 (define_insn "*movsi_internal"
2141 [(set (match_operand:SI 0 "nonimmediate_operand"
2142 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2143 (match_operand:SI 1 "general_operand"
2144 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2145 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2147 switch (get_attr_type (insn))
2150 if (get_attr_mode (insn) == MODE_TI)
2151 return "%vpxor\t%0, %d0";
2152 return "%vxorps\t%0, %d0";
2155 switch (get_attr_mode (insn))
2158 return "%vmovdqa\t{%1, %0|%0, %1}";
2160 return "%vmovaps\t{%1, %0|%0, %1}";
2162 return "%vmovd\t{%1, %0|%0, %1}";
2164 return "%vmovss\t{%1, %0|%0, %1}";
2170 return "pxor\t%0, %0";
2173 if (get_attr_mode (insn) == MODE_DI)
2174 return "movq\t{%1, %0|%0, %1}";
2175 return "movd\t{%1, %0|%0, %1}";
2178 return "lea{l}\t{%a1, %0|%0, %a1}";
2181 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2182 return "mov{l}\t{%1, %0|%0, %1}";
2186 (cond [(eq_attr "alternative" "2")
2187 (const_string "mmx")
2188 (eq_attr "alternative" "3,4,5")
2189 (const_string "mmxmov")
2190 (eq_attr "alternative" "6")
2191 (const_string "sselog1")
2192 (eq_attr "alternative" "7,8,9,10,11")
2193 (const_string "ssemov")
2194 (match_operand:DI 1 "pic_32bit_operand" "")
2195 (const_string "lea")
2197 (const_string "imov")))
2198 (set (attr "prefix")
2199 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2200 (const_string "orig")
2201 (const_string "maybe_vex")))
2202 (set (attr "prefix_data16")
2203 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2205 (const_string "*")))
2207 (cond [(eq_attr "alternative" "2,3")
2209 (eq_attr "alternative" "6,7")
2211 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2212 (const_string "V4SF")
2213 (const_string "TI"))
2214 (and (eq_attr "alternative" "8,9,10,11")
2215 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2218 (const_string "SI")))])
2220 (define_insn "*movhi_internal"
2221 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2222 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2223 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2225 switch (get_attr_type (insn))
2228 /* movzwl is faster than movw on p2 due to partial word stalls,
2229 though not as fast as an aligned movl. */
2230 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2232 if (get_attr_mode (insn) == MODE_SI)
2233 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2235 return "mov{w}\t{%1, %0|%0, %1}";
2239 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2241 (const_string "imov")
2242 (and (eq_attr "alternative" "0")
2243 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2245 (eq (symbol_ref "TARGET_HIMODE_MATH")
2247 (const_string "imov")
2248 (and (eq_attr "alternative" "1,2")
2249 (match_operand:HI 1 "aligned_operand" ""))
2250 (const_string "imov")
2251 (and (ne (symbol_ref "TARGET_MOVX")
2253 (eq_attr "alternative" "0,2"))
2254 (const_string "imovx")
2256 (const_string "imov")))
2258 (cond [(eq_attr "type" "imovx")
2260 (and (eq_attr "alternative" "1,2")
2261 (match_operand:HI 1 "aligned_operand" ""))
2263 (and (eq_attr "alternative" "0")
2264 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2266 (eq (symbol_ref "TARGET_HIMODE_MATH")
2270 (const_string "HI")))])
2272 ;; Situation is quite tricky about when to choose full sized (SImode) move
2273 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2274 ;; partial register dependency machines (such as AMD Athlon), where QImode
2275 ;; moves issue extra dependency and for partial register stalls machines
2276 ;; that don't use QImode patterns (and QImode move cause stall on the next
2279 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2280 ;; register stall machines with, where we use QImode instructions, since
2281 ;; partial register stall can be caused there. Then we use movzx.
2282 (define_insn "*movqi_internal"
2283 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2284 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2285 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2287 switch (get_attr_type (insn))
2290 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2291 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2293 if (get_attr_mode (insn) == MODE_SI)
2294 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2296 return "mov{b}\t{%1, %0|%0, %1}";
2300 (cond [(and (eq_attr "alternative" "5")
2301 (not (match_operand:QI 1 "aligned_operand" "")))
2302 (const_string "imovx")
2303 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2305 (const_string "imov")
2306 (and (eq_attr "alternative" "3")
2307 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2309 (eq (symbol_ref "TARGET_QIMODE_MATH")
2311 (const_string "imov")
2312 (eq_attr "alternative" "3,5")
2313 (const_string "imovx")
2314 (and (ne (symbol_ref "TARGET_MOVX")
2316 (eq_attr "alternative" "2"))
2317 (const_string "imovx")
2319 (const_string "imov")))
2321 (cond [(eq_attr "alternative" "3,4,5")
2323 (eq_attr "alternative" "6")
2325 (eq_attr "type" "imovx")
2327 (and (eq_attr "type" "imov")
2328 (and (eq_attr "alternative" "0,1")
2329 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2331 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2333 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2336 ;; Avoid partial register stalls when not using QImode arithmetic
2337 (and (eq_attr "type" "imov")
2338 (and (eq_attr "alternative" "0,1")
2339 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2341 (eq (symbol_ref "TARGET_QIMODE_MATH")
2345 (const_string "QI")))])
2347 ;; Stores and loads of ax to arbitrary constant address.
2348 ;; We fake an second form of instruction to force reload to load address
2349 ;; into register when rax is not available
2350 (define_insn "*movabs<mode>_1"
2351 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2352 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2353 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2355 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2356 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2357 [(set_attr "type" "imov")
2358 (set_attr "modrm" "0,*")
2359 (set_attr "length_address" "8,0")
2360 (set_attr "length_immediate" "0,*")
2361 (set_attr "memory" "store")
2362 (set_attr "mode" "<MODE>")])
2364 (define_insn "*movabs<mode>_2"
2365 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2366 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2367 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2369 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2370 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2371 [(set_attr "type" "imov")
2372 (set_attr "modrm" "0,*")
2373 (set_attr "length_address" "8,0")
2374 (set_attr "length_immediate" "0")
2375 (set_attr "memory" "load")
2376 (set_attr "mode" "<MODE>")])
2378 (define_insn "*swap<mode>"
2379 [(set (match_operand:SWI48 0 "register_operand" "+r")
2380 (match_operand:SWI48 1 "register_operand" "+r"))
2384 "xchg{<imodesuffix>}\t%1, %0"
2385 [(set_attr "type" "imov")
2386 (set_attr "mode" "<MODE>")
2387 (set_attr "pent_pair" "np")
2388 (set_attr "athlon_decode" "vector")
2389 (set_attr "amdfam10_decode" "double")])
2391 (define_insn "*swap<mode>_1"
2392 [(set (match_operand:SWI12 0 "register_operand" "+r")
2393 (match_operand:SWI12 1 "register_operand" "+r"))
2396 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2398 [(set_attr "type" "imov")
2399 (set_attr "mode" "SI")
2400 (set_attr "pent_pair" "np")
2401 (set_attr "athlon_decode" "vector")
2402 (set_attr "amdfam10_decode" "double")])
2404 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2405 ;; is disabled for AMDFAM10
2406 (define_insn "*swap<mode>_2"
2407 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2408 (match_operand:SWI12 1 "register_operand" "+<r>"))
2411 "TARGET_PARTIAL_REG_STALL"
2412 "xchg{<imodesuffix>}\t%1, %0"
2413 [(set_attr "type" "imov")
2414 (set_attr "mode" "<MODE>")
2415 (set_attr "pent_pair" "np")
2416 (set_attr "athlon_decode" "vector")])
2418 (define_expand "movstrict<mode>"
2419 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2420 (match_operand:SWI12 1 "general_operand" ""))]
2423 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2425 /* Don't generate memory->memory moves, go through a register */
2426 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2427 operands[1] = force_reg (<MODE>mode, operands[1]);
2430 (define_insn "*movstrict<mode>_1"
2431 [(set (strict_low_part
2432 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2433 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2434 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2435 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2436 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2437 [(set_attr "type" "imov")
2438 (set_attr "mode" "<MODE>")])
2440 (define_insn "*movstrict<mode>_xor"
2441 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2442 (match_operand:SWI12 1 "const0_operand" ""))
2443 (clobber (reg:CC FLAGS_REG))]
2445 "xor{<imodesuffix>}\t%0, %0"
2446 [(set_attr "type" "alu1")
2447 (set_attr "mode" "<MODE>")
2448 (set_attr "length_immediate" "0")])
2450 (define_insn "*mov<mode>_extv_1"
2451 [(set (match_operand:SWI24 0 "register_operand" "=R")
2452 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2456 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2457 [(set_attr "type" "imovx")
2458 (set_attr "mode" "SI")])
2460 (define_insn "*movqi_extv_1_rex64"
2461 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2462 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2467 switch (get_attr_type (insn))
2470 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2472 return "mov{b}\t{%h1, %0|%0, %h1}";
2476 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2477 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2478 (ne (symbol_ref "TARGET_MOVX")
2480 (const_string "imovx")
2481 (const_string "imov")))
2483 (if_then_else (eq_attr "type" "imovx")
2485 (const_string "QI")))])
2487 (define_insn "*movqi_extv_1"
2488 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2489 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2494 switch (get_attr_type (insn))
2497 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2499 return "mov{b}\t{%h1, %0|%0, %h1}";
2503 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2504 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2505 (ne (symbol_ref "TARGET_MOVX")
2507 (const_string "imovx")
2508 (const_string "imov")))
2510 (if_then_else (eq_attr "type" "imovx")
2512 (const_string "QI")))])
2514 (define_insn "*mov<mode>_extzv_1"
2515 [(set (match_operand:SWI48 0 "register_operand" "=R")
2516 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2520 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2521 [(set_attr "type" "imovx")
2522 (set_attr "mode" "SI")])
2524 (define_insn "*movqi_extzv_2_rex64"
2525 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2527 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2532 switch (get_attr_type (insn))
2535 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2537 return "mov{b}\t{%h1, %0|%0, %h1}";
2541 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2542 (ne (symbol_ref "TARGET_MOVX")
2544 (const_string "imovx")
2545 (const_string "imov")))
2547 (if_then_else (eq_attr "type" "imovx")
2549 (const_string "QI")))])
2551 (define_insn "*movqi_extzv_2"
2552 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2554 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2559 switch (get_attr_type (insn))
2562 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2564 return "mov{b}\t{%h1, %0|%0, %h1}";
2568 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2569 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2570 (ne (symbol_ref "TARGET_MOVX")
2572 (const_string "imovx")
2573 (const_string "imov")))
2575 (if_then_else (eq_attr "type" "imovx")
2577 (const_string "QI")))])
2579 (define_expand "mov<mode>_insv_1"
2580 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2583 (match_operand:SWI48 1 "nonmemory_operand" ""))]
2587 (define_insn "*mov<mode>_insv_1_rex64"
2588 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2591 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2593 "mov{b}\t{%b1, %h0|%h0, %b1}"
2594 [(set_attr "type" "imov")
2595 (set_attr "mode" "QI")])
2597 (define_insn "*movsi_insv_1"
2598 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2601 (match_operand:SI 1 "general_operand" "Qmn"))]
2603 "mov{b}\t{%b1, %h0|%h0, %b1}"
2604 [(set_attr "type" "imov")
2605 (set_attr "mode" "QI")])
2607 (define_insn "*movqi_insv_2"
2608 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2611 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2614 "mov{b}\t{%h1, %h0|%h0, %h1}"
2615 [(set_attr "type" "imov")
2616 (set_attr "mode" "QI")])
2618 ;; Floating point move instructions.
2620 (define_expand "movtf"
2621 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2622 (match_operand:TF 1 "nonimmediate_operand" ""))]
2625 ix86_expand_move (TFmode, operands);
2629 (define_expand "mov<mode>"
2630 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2631 (match_operand:X87MODEF 1 "general_operand" ""))]
2633 "ix86_expand_move (<MODE>mode, operands); DONE;")
2635 (define_insn "*pushtf"
2636 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2637 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2640 /* This insn should be already split before reg-stack. */
2643 [(set_attr "type" "multi")
2644 (set_attr "unit" "sse,*,*")
2645 (set_attr "mode" "TF,SI,SI")])
2648 [(set (match_operand:TF 0 "push_operand" "")
2649 (match_operand:TF 1 "general_operand" ""))]
2650 "TARGET_SSE2 && reload_completed
2651 && !SSE_REG_P (operands[1])"
2653 "ix86_split_long_move (operands); DONE;")
2656 [(set (match_operand:TF 0 "push_operand" "")
2657 (match_operand:TF 1 "any_fp_register_operand" ""))]
2659 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2660 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
2663 (define_insn "*pushxf"
2664 [(set (match_operand:XF 0 "push_operand" "=<,<")
2665 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2666 "optimize_function_for_speed_p (cfun)"
2668 /* This insn should be already split before reg-stack. */
2671 [(set_attr "type" "multi")
2672 (set_attr "unit" "i387,*")
2673 (set_attr "mode" "XF,SI")])
2675 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2676 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2677 ;; Pushing using integer instructions is longer except for constants
2678 ;; and direct memory references (assuming that any given constant is pushed
2679 ;; only once, but this ought to be handled elsewhere).
2681 (define_insn "*pushxf_nointeger"
2682 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2683 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2684 "optimize_function_for_size_p (cfun)"
2686 /* This insn should be already split before reg-stack. */
2689 [(set_attr "type" "multi")
2690 (set_attr "unit" "i387,*,*")
2691 (set_attr "mode" "XF,SI,SI")])
2694 [(set (match_operand:XF 0 "push_operand" "")
2695 (match_operand:XF 1 "any_fp_register_operand" ""))]
2697 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2698 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2699 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2702 [(set (match_operand:XF 0 "push_operand" "")
2703 (match_operand:XF 1 "general_operand" ""))]
2705 && !ANY_FP_REG_P (operands[1])"
2707 "ix86_split_long_move (operands); DONE;")
2709 (define_insn "*pushdf"
2710 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2711 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2712 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2714 /* This insn should be already split before reg-stack. */
2717 [(set_attr "type" "multi")
2718 (set_attr "unit" "i387,*,*")
2719 (set_attr "mode" "DF,SI,DF")])
2721 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2722 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2723 ;; On the average, pushdf using integers can be still shorter. Allow this
2724 ;; pattern for optimize_size too.
2726 (define_insn "*pushdf_nointeger"
2727 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2728 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2729 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2731 /* This insn should be already split before reg-stack. */
2734 [(set_attr "type" "multi")
2735 (set_attr "unit" "i387,*,*,*")
2736 (set_attr "mode" "DF,SI,SI,DF")])
2738 ;; %%% Kill this when call knows how to work this out.
2740 [(set (match_operand:DF 0 "push_operand" "")
2741 (match_operand:DF 1 "any_fp_register_operand" ""))]
2743 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2744 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2748 [(set (match_operand:DF 0 "push_operand" "")
2749 (match_operand:DF 1 "general_operand" ""))]
2751 && !ANY_FP_REG_P (operands[1])"
2753 "ix86_split_long_move (operands); DONE;")
2755 (define_insn "*pushsf_rex64"
2756 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2757 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2760 /* Anything else should be already split before reg-stack. */
2761 gcc_assert (which_alternative == 1);
2762 return "push{q}\t%q1";
2764 [(set_attr "type" "multi,push,multi")
2765 (set_attr "unit" "i387,*,*")
2766 (set_attr "mode" "SF,DI,SF")])
2768 (define_insn "*pushsf"
2769 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2770 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2773 /* Anything else should be already split before reg-stack. */
2774 gcc_assert (which_alternative == 1);
2775 return "push{l}\t%1";
2777 [(set_attr "type" "multi,push,multi")
2778 (set_attr "unit" "i387,*,*")
2779 (set_attr "mode" "SF,SI,SF")])
2782 [(set (match_operand:SF 0 "push_operand" "")
2783 (match_operand:SF 1 "memory_operand" ""))]
2785 && MEM_P (operands[1])
2786 && (operands[2] = find_constant_src (insn))"
2790 ;; %%% Kill this when call knows how to work this out.
2792 [(set (match_operand:SF 0 "push_operand" "")
2793 (match_operand:SF 1 "any_fp_register_operand" ""))]
2795 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2796 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2797 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2799 (define_insn "*movtf_internal"
2800 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2801 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2803 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2805 switch (which_alternative)
2809 if (get_attr_mode (insn) == MODE_V4SF)
2810 return "%vmovaps\t{%1, %0|%0, %1}";
2812 return "%vmovdqa\t{%1, %0|%0, %1}";
2814 if (get_attr_mode (insn) == MODE_V4SF)
2815 return "%vxorps\t%0, %d0";
2817 return "%vpxor\t%0, %d0";
2825 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2826 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2828 (cond [(eq_attr "alternative" "0,2")
2830 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2832 (const_string "V4SF")
2833 (const_string "TI"))
2834 (eq_attr "alternative" "1")
2836 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2838 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2840 (const_string "V4SF")
2841 (const_string "TI"))]
2842 (const_string "DI")))])
2845 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2846 (match_operand:TF 1 "general_operand" ""))]
2848 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2850 "ix86_split_long_move (operands); DONE;")
2852 (define_insn "*movxf_internal"
2853 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2854 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2855 "optimize_function_for_speed_p (cfun)
2856 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2857 && (reload_in_progress || reload_completed
2858 || GET_CODE (operands[1]) != CONST_DOUBLE
2859 || memory_operand (operands[0], XFmode))"
2861 switch (which_alternative)
2865 return output_387_reg_move (insn, operands);
2868 return standard_80387_constant_opcode (operands[1]);
2877 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2878 (set_attr "mode" "XF,XF,XF,SI,SI")])
2880 ;; Do not use integer registers when optimizing for size
2881 (define_insn "*movxf_internal_nointeger"
2882 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2883 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2884 "optimize_function_for_size_p (cfun)
2885 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2886 && (reload_in_progress || reload_completed
2887 || standard_80387_constant_p (operands[1])
2888 || GET_CODE (operands[1]) != CONST_DOUBLE
2889 || memory_operand (operands[0], XFmode))"
2891 switch (which_alternative)
2895 return output_387_reg_move (insn, operands);
2898 return standard_80387_constant_opcode (operands[1]);
2906 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2907 (set_attr "mode" "XF,XF,XF,SI,SI")])
2910 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2911 (match_operand:XF 1 "general_operand" ""))]
2913 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2914 && ! (ANY_FP_REG_P (operands[0]) ||
2915 (GET_CODE (operands[0]) == SUBREG
2916 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2917 && ! (ANY_FP_REG_P (operands[1]) ||
2918 (GET_CODE (operands[1]) == SUBREG
2919 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2921 "ix86_split_long_move (operands); DONE;")
2923 (define_insn "*movdf_internal_rex64"
2924 [(set (match_operand:DF 0 "nonimmediate_operand"
2925 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2926 (match_operand:DF 1 "general_operand"
2927 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2928 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2929 && (reload_in_progress || reload_completed
2930 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2931 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2932 && optimize_function_for_size_p (cfun)
2933 && standard_80387_constant_p (operands[1]))
2934 || GET_CODE (operands[1]) != CONST_DOUBLE
2935 || memory_operand (operands[0], DFmode))"
2937 switch (which_alternative)
2941 return output_387_reg_move (insn, operands);
2944 return standard_80387_constant_opcode (operands[1]);
2951 switch (get_attr_mode (insn))
2954 return "%vxorps\t%0, %d0";
2956 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2957 return "%vxorps\t%0, %d0";
2959 return "%vxorpd\t%0, %d0";
2961 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2962 return "%vxorps\t%0, %d0";
2964 return "%vpxor\t%0, %d0";
2971 switch (get_attr_mode (insn))
2974 return "%vmovaps\t{%1, %0|%0, %1}";
2976 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2977 return "%vmovaps\t{%1, %0|%0, %1}";
2979 return "%vmovapd\t{%1, %0|%0, %1}";
2981 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2982 return "%vmovaps\t{%1, %0|%0, %1}";
2984 return "%vmovdqa\t{%1, %0|%0, %1}";
2986 return "%vmovq\t{%1, %0|%0, %1}";
2990 if (REG_P (operands[0]) && REG_P (operands[1]))
2991 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2993 return "vmovsd\t{%1, %0|%0, %1}";
2996 return "movsd\t{%1, %0|%0, %1}";
2998 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3000 return "%vmovlps\t{%1, %d0|%d0, %1}";
3007 return "%vmovd\t{%1, %0|%0, %1}";
3013 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3014 (set (attr "prefix")
3015 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3016 (const_string "orig")
3017 (const_string "maybe_vex")))
3018 (set (attr "prefix_data16")
3019 (if_then_else (eq_attr "mode" "V1DF")
3021 (const_string "*")))
3023 (cond [(eq_attr "alternative" "0,1,2")
3025 (eq_attr "alternative" "3,4,9,10")
3028 /* For SSE1, we have many fewer alternatives. */
3029 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3030 (cond [(eq_attr "alternative" "5,6")
3031 (const_string "V4SF")
3033 (const_string "V2SF"))
3035 /* xorps is one byte shorter. */
3036 (eq_attr "alternative" "5")
3037 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3039 (const_string "V4SF")
3040 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3044 (const_string "V2DF"))
3046 /* For architectures resolving dependencies on
3047 whole SSE registers use APD move to break dependency
3048 chains, otherwise use short move to avoid extra work.
3050 movaps encodes one byte shorter. */
3051 (eq_attr "alternative" "6")
3053 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3055 (const_string "V4SF")
3056 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3058 (const_string "V2DF")
3060 (const_string "DF"))
3061 /* For architectures resolving dependencies on register
3062 parts we may avoid extra work to zero out upper part
3064 (eq_attr "alternative" "7")
3066 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3068 (const_string "V1DF")
3069 (const_string "DF"))
3071 (const_string "DF")))])
3073 (define_insn "*movdf_internal"
3074 [(set (match_operand:DF 0 "nonimmediate_operand"
3075 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3076 (match_operand:DF 1 "general_operand"
3077 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3078 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3079 && optimize_function_for_speed_p (cfun)
3080 && TARGET_INTEGER_DFMODE_MOVES
3081 && (reload_in_progress || reload_completed
3082 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3083 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3084 && optimize_function_for_size_p (cfun)
3085 && standard_80387_constant_p (operands[1]))
3086 || GET_CODE (operands[1]) != CONST_DOUBLE
3087 || memory_operand (operands[0], DFmode))"
3089 switch (which_alternative)
3093 return output_387_reg_move (insn, operands);
3096 return standard_80387_constant_opcode (operands[1]);
3103 switch (get_attr_mode (insn))
3106 return "xorps\t%0, %0";
3108 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3109 return "xorps\t%0, %0";
3111 return "xorpd\t%0, %0";
3113 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3114 return "xorps\t%0, %0";
3116 return "pxor\t%0, %0";
3123 switch (get_attr_mode (insn))
3126 return "movaps\t{%1, %0|%0, %1}";
3128 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3129 return "movaps\t{%1, %0|%0, %1}";
3131 return "movapd\t{%1, %0|%0, %1}";
3133 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3134 return "movaps\t{%1, %0|%0, %1}";
3136 return "movdqa\t{%1, %0|%0, %1}";
3138 return "movq\t{%1, %0|%0, %1}";
3140 return "movsd\t{%1, %0|%0, %1}";
3142 return "movlpd\t{%1, %0|%0, %1}";
3144 return "movlps\t{%1, %0|%0, %1}";
3153 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3154 (set (attr "prefix_data16")
3155 (if_then_else (eq_attr "mode" "V1DF")
3157 (const_string "*")))
3159 (cond [(eq_attr "alternative" "0,1,2")
3161 (eq_attr "alternative" "3,4")
3164 /* For SSE1, we have many fewer alternatives. */
3165 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3166 (cond [(eq_attr "alternative" "5,6")
3167 (const_string "V4SF")
3169 (const_string "V2SF"))
3171 /* xorps is one byte shorter. */
3172 (eq_attr "alternative" "5")
3173 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3175 (const_string "V4SF")
3176 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3180 (const_string "V2DF"))
3182 /* For architectures resolving dependencies on
3183 whole SSE registers use APD move to break dependency
3184 chains, otherwise use short move to avoid extra work.
3186 movaps encodes one byte shorter. */
3187 (eq_attr "alternative" "6")
3189 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3191 (const_string "V4SF")
3192 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3194 (const_string "V2DF")
3196 (const_string "DF"))
3197 /* For architectures resolving dependencies on register
3198 parts we may avoid extra work to zero out upper part
3200 (eq_attr "alternative" "7")
3202 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3204 (const_string "V1DF")
3205 (const_string "DF"))
3207 (const_string "DF")))])
3209 ;; Moving is usually shorter when only FP registers are used. This separate
3210 ;; movdf pattern avoids the use of integer registers for FP operations
3211 ;; when optimizing for size.
3213 (define_insn "*movdf_internal_nointeger"
3214 [(set (match_operand:DF 0 "nonimmediate_operand"
3215 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3216 (match_operand:DF 1 "general_operand"
3217 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3218 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3219 && ((optimize_function_for_size_p (cfun)
3220 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3221 && (reload_in_progress || reload_completed
3222 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3223 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3224 && optimize_function_for_size_p (cfun)
3225 && !memory_operand (operands[0], DFmode)
3226 && standard_80387_constant_p (operands[1]))
3227 || GET_CODE (operands[1]) != CONST_DOUBLE
3228 || ((optimize_function_for_size_p (cfun)
3229 || !TARGET_MEMORY_MISMATCH_STALL
3230 || reload_in_progress || reload_completed)
3231 && memory_operand (operands[0], DFmode)))"
3233 switch (which_alternative)
3237 return output_387_reg_move (insn, operands);
3240 return standard_80387_constant_opcode (operands[1]);
3246 switch (get_attr_mode (insn))
3249 return "%vxorps\t%0, %d0";
3251 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3252 return "%vxorps\t%0, %d0";
3254 return "%vxorpd\t%0, %d0";
3256 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3257 return "%vxorps\t%0, %d0";
3259 return "%vpxor\t%0, %d0";
3266 switch (get_attr_mode (insn))
3269 return "%vmovaps\t{%1, %0|%0, %1}";
3271 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3272 return "%vmovaps\t{%1, %0|%0, %1}";
3274 return "%vmovapd\t{%1, %0|%0, %1}";
3276 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3277 return "%vmovaps\t{%1, %0|%0, %1}";
3279 return "%vmovdqa\t{%1, %0|%0, %1}";
3281 return "%vmovq\t{%1, %0|%0, %1}";
3285 if (REG_P (operands[0]) && REG_P (operands[1]))
3286 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3288 return "vmovsd\t{%1, %0|%0, %1}";
3291 return "movsd\t{%1, %0|%0, %1}";
3295 if (REG_P (operands[0]))
3296 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3298 return "vmovlpd\t{%1, %0|%0, %1}";
3301 return "movlpd\t{%1, %0|%0, %1}";
3305 if (REG_P (operands[0]))
3306 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3308 return "vmovlps\t{%1, %0|%0, %1}";
3311 return "movlps\t{%1, %0|%0, %1}";
3320 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3321 (set (attr "prefix")
3322 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3323 (const_string "orig")
3324 (const_string "maybe_vex")))
3325 (set (attr "prefix_data16")
3326 (if_then_else (eq_attr "mode" "V1DF")
3328 (const_string "*")))
3330 (cond [(eq_attr "alternative" "0,1,2")
3332 (eq_attr "alternative" "3,4")
3335 /* For SSE1, we have many fewer alternatives. */
3336 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3337 (cond [(eq_attr "alternative" "5,6")
3338 (const_string "V4SF")
3340 (const_string "V2SF"))
3342 /* xorps is one byte shorter. */
3343 (eq_attr "alternative" "5")
3344 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3346 (const_string "V4SF")
3347 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3351 (const_string "V2DF"))
3353 /* For architectures resolving dependencies on
3354 whole SSE registers use APD move to break dependency
3355 chains, otherwise use short move to avoid extra work.
3357 movaps encodes one byte shorter. */
3358 (eq_attr "alternative" "6")
3360 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3362 (const_string "V4SF")
3363 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3365 (const_string "V2DF")
3367 (const_string "DF"))
3368 /* For architectures resolving dependencies on register
3369 parts we may avoid extra work to zero out upper part
3371 (eq_attr "alternative" "7")
3373 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3375 (const_string "V1DF")
3376 (const_string "DF"))
3378 (const_string "DF")))])
3381 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3382 (match_operand:DF 1 "general_operand" ""))]
3384 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3385 && ! (ANY_FP_REG_P (operands[0]) ||
3386 (GET_CODE (operands[0]) == SUBREG
3387 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3388 && ! (ANY_FP_REG_P (operands[1]) ||
3389 (GET_CODE (operands[1]) == SUBREG
3390 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3392 "ix86_split_long_move (operands); DONE;")
3394 (define_insn "*movsf_internal"
3395 [(set (match_operand:SF 0 "nonimmediate_operand"
3396 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3397 (match_operand:SF 1 "general_operand"
3398 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3399 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3400 && (reload_in_progress || reload_completed
3401 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3402 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3403 && standard_80387_constant_p (operands[1]))
3404 || GET_CODE (operands[1]) != CONST_DOUBLE
3405 || memory_operand (operands[0], SFmode))"
3407 switch (which_alternative)
3411 return output_387_reg_move (insn, operands);
3414 return standard_80387_constant_opcode (operands[1]);
3418 return "mov{l}\t{%1, %0|%0, %1}";
3420 if (get_attr_mode (insn) == MODE_TI)
3421 return "%vpxor\t%0, %d0";
3423 return "%vxorps\t%0, %d0";
3425 if (get_attr_mode (insn) == MODE_V4SF)
3426 return "%vmovaps\t{%1, %0|%0, %1}";
3428 return "%vmovss\t{%1, %d0|%d0, %1}";
3431 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3432 : "vmovss\t{%1, %0|%0, %1}";
3434 return "movss\t{%1, %0|%0, %1}";
3436 return "%vmovss\t{%1, %0|%0, %1}";
3438 case 9: case 10: case 14: case 15:
3439 return "movd\t{%1, %0|%0, %1}";
3441 return "%vmovd\t{%1, %0|%0, %1}";
3444 return "movq\t{%1, %0|%0, %1}";
3450 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3451 (set (attr "prefix")
3452 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3453 (const_string "maybe_vex")
3454 (const_string "orig")))
3456 (cond [(eq_attr "alternative" "3,4,9,10")
3458 (eq_attr "alternative" "5")
3460 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3462 (ne (symbol_ref "TARGET_SSE2")
3464 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3467 (const_string "V4SF"))
3468 /* For architectures resolving dependencies on
3469 whole SSE registers use APS move to break dependency
3470 chains, otherwise use short move to avoid extra work.
3472 Do the same for architectures resolving dependencies on
3473 the parts. While in DF mode it is better to always handle
3474 just register parts, the SF mode is different due to lack
3475 of instructions to load just part of the register. It is
3476 better to maintain the whole registers in single format
3477 to avoid problems on using packed logical operations. */
3478 (eq_attr "alternative" "6")
3480 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3482 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3484 (const_string "V4SF")
3485 (const_string "SF"))
3486 (eq_attr "alternative" "11")
3487 (const_string "DI")]
3488 (const_string "SF")))])
3491 [(set (match_operand 0 "register_operand" "")
3492 (match_operand 1 "memory_operand" ""))]
3494 && MEM_P (operands[1])
3495 && (GET_MODE (operands[0]) == TFmode
3496 || GET_MODE (operands[0]) == XFmode
3497 || GET_MODE (operands[0]) == DFmode
3498 || GET_MODE (operands[0]) == SFmode)
3499 && (operands[2] = find_constant_src (insn))"
3500 [(set (match_dup 0) (match_dup 2))]
3502 rtx c = operands[2];
3503 rtx r = operands[0];
3505 if (GET_CODE (r) == SUBREG)
3510 if (!standard_sse_constant_p (c))
3513 else if (FP_REG_P (r))
3515 if (!standard_80387_constant_p (c))
3518 else if (MMX_REG_P (r))
3523 [(set (match_operand 0 "register_operand" "")
3524 (float_extend (match_operand 1 "memory_operand" "")))]
3526 && MEM_P (operands[1])
3527 && (GET_MODE (operands[0]) == TFmode
3528 || GET_MODE (operands[0]) == XFmode
3529 || GET_MODE (operands[0]) == DFmode
3530 || GET_MODE (operands[0]) == SFmode)
3531 && (operands[2] = find_constant_src (insn))"
3532 [(set (match_dup 0) (match_dup 2))]
3534 rtx c = operands[2];
3535 rtx r = operands[0];
3537 if (GET_CODE (r) == SUBREG)
3542 if (!standard_sse_constant_p (c))
3545 else if (FP_REG_P (r))
3547 if (!standard_80387_constant_p (c))
3550 else if (MMX_REG_P (r))
3554 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3556 [(set (match_operand:X87MODEF 0 "register_operand" "")
3557 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3558 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3559 && (standard_80387_constant_p (operands[1]) == 8
3560 || standard_80387_constant_p (operands[1]) == 9)"
3561 [(set (match_dup 0)(match_dup 1))
3563 (neg:X87MODEF (match_dup 0)))]
3567 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3568 if (real_isnegzero (&r))
3569 operands[1] = CONST0_RTX (<MODE>mode);
3571 operands[1] = CONST1_RTX (<MODE>mode);
3574 (define_insn "swapxf"
3575 [(set (match_operand:XF 0 "register_operand" "+f")
3576 (match_operand:XF 1 "register_operand" "+f"))
3581 if (STACK_TOP_P (operands[0]))
3586 [(set_attr "type" "fxch")
3587 (set_attr "mode" "XF")])
3589 (define_insn "*swap<mode>"
3590 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3591 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3594 "TARGET_80387 || reload_completed"
3596 if (STACK_TOP_P (operands[0]))
3601 [(set_attr "type" "fxch")
3602 (set_attr "mode" "<MODE>")])
3604 ;; Zero extension instructions
3606 (define_expand "zero_extendhisi2"
3607 [(set (match_operand:SI 0 "register_operand" "")
3608 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3611 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3613 operands[1] = force_reg (HImode, operands[1]);
3614 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3619 (define_insn "zero_extendhisi2_and"
3620 [(set (match_operand:SI 0 "register_operand" "=r")
3621 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3622 (clobber (reg:CC FLAGS_REG))]
3623 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3625 [(set_attr "type" "alu1")
3626 (set_attr "mode" "SI")])
3629 [(set (match_operand:SI 0 "register_operand" "")
3630 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3631 (clobber (reg:CC FLAGS_REG))]
3632 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3633 && optimize_function_for_speed_p (cfun)"
3634 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3635 (clobber (reg:CC FLAGS_REG))])]
3638 (define_insn "*zero_extendhisi2_movzwl"
3639 [(set (match_operand:SI 0 "register_operand" "=r")
3640 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3641 "!TARGET_ZERO_EXTEND_WITH_AND
3642 || optimize_function_for_size_p (cfun)"
3643 "movz{wl|x}\t{%1, %0|%0, %1}"
3644 [(set_attr "type" "imovx")
3645 (set_attr "mode" "SI")])
3647 (define_expand "zero_extendqihi2"
3649 [(set (match_operand:HI 0 "register_operand" "")
3650 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3651 (clobber (reg:CC FLAGS_REG))])]
3655 (define_insn "*zero_extendqihi2_and"
3656 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3657 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3658 (clobber (reg:CC FLAGS_REG))]
3659 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3661 [(set_attr "type" "alu1")
3662 (set_attr "mode" "HI")])
3664 (define_insn "*zero_extendqihi2_movzbw_and"
3665 [(set (match_operand:HI 0 "register_operand" "=r,r")
3666 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3667 (clobber (reg:CC FLAGS_REG))]
3668 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3670 [(set_attr "type" "imovx,alu1")
3671 (set_attr "mode" "HI")])
3673 ; zero extend to SImode here to avoid partial register stalls
3674 (define_insn "*zero_extendqihi2_movzbl"
3675 [(set (match_operand:HI 0 "register_operand" "=r")
3676 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3677 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3678 && reload_completed"
3679 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3680 [(set_attr "type" "imovx")
3681 (set_attr "mode" "SI")])
3683 ;; For the movzbw case strip only the clobber
3685 [(set (match_operand:HI 0 "register_operand" "")
3686 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3687 (clobber (reg:CC FLAGS_REG))]
3689 && (!TARGET_ZERO_EXTEND_WITH_AND
3690 || optimize_function_for_size_p (cfun))
3691 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3692 [(set (match_operand:HI 0 "register_operand" "")
3693 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3695 ;; When source and destination does not overlap, clear destination
3696 ;; first and then do the movb
3698 [(set (match_operand:HI 0 "register_operand" "")
3699 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3700 (clobber (reg:CC FLAGS_REG))]
3702 && ANY_QI_REG_P (operands[0])
3703 && (TARGET_ZERO_EXTEND_WITH_AND
3704 && optimize_function_for_speed_p (cfun))
3705 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3706 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3708 operands[2] = gen_lowpart (QImode, operands[0]);
3709 ix86_expand_clear (operands[0]);
3712 ;; Rest is handled by single and.
3714 [(set (match_operand:HI 0 "register_operand" "")
3715 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3716 (clobber (reg:CC FLAGS_REG))]
3718 && true_regnum (operands[0]) == true_regnum (operands[1])"
3719 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3720 (clobber (reg:CC FLAGS_REG))])]
3723 (define_expand "zero_extendqisi2"
3725 [(set (match_operand:SI 0 "register_operand" "")
3726 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3727 (clobber (reg:CC FLAGS_REG))])]
3731 (define_insn "*zero_extendqisi2_and"
3732 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3733 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3734 (clobber (reg:CC FLAGS_REG))]
3735 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3737 [(set_attr "type" "alu1")
3738 (set_attr "mode" "SI")])
3740 (define_insn "*zero_extendqisi2_movzbl_and"
3741 [(set (match_operand:SI 0 "register_operand" "=r,r")
3742 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3743 (clobber (reg:CC FLAGS_REG))]
3744 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3746 [(set_attr "type" "imovx,alu1")
3747 (set_attr "mode" "SI")])
3749 (define_insn "*zero_extendqisi2_movzbl"
3750 [(set (match_operand:SI 0 "register_operand" "=r")
3751 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3752 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3753 && reload_completed"
3754 "movz{bl|x}\t{%1, %0|%0, %1}"
3755 [(set_attr "type" "imovx")
3756 (set_attr "mode" "SI")])
3758 ;; For the movzbl case strip only the clobber
3760 [(set (match_operand:SI 0 "register_operand" "")
3761 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3762 (clobber (reg:CC FLAGS_REG))]
3764 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3765 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3767 (zero_extend:SI (match_dup 1)))])
3769 ;; When source and destination does not overlap, clear destination
3770 ;; first and then do the movb
3772 [(set (match_operand:SI 0 "register_operand" "")
3773 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3774 (clobber (reg:CC FLAGS_REG))]
3776 && ANY_QI_REG_P (operands[0])
3777 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3778 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3779 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3780 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3782 operands[2] = gen_lowpart (QImode, operands[0]);
3783 ix86_expand_clear (operands[0]);
3786 ;; Rest is handled by single and.
3788 [(set (match_operand:SI 0 "register_operand" "")
3789 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3790 (clobber (reg:CC FLAGS_REG))]
3792 && true_regnum (operands[0]) == true_regnum (operands[1])"
3793 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3794 (clobber (reg:CC FLAGS_REG))])]
3797 ;; %%% Kill me once multi-word ops are sane.
3798 (define_expand "zero_extendsidi2"
3799 [(set (match_operand:DI 0 "register_operand" "")
3800 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3805 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3810 (define_insn "zero_extendsidi2_32"
3811 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3813 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3814 (clobber (reg:CC FLAGS_REG))]
3820 movd\t{%1, %0|%0, %1}
3821 movd\t{%1, %0|%0, %1}
3822 %vmovd\t{%1, %0|%0, %1}
3823 %vmovd\t{%1, %0|%0, %1}"
3824 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3825 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3826 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3828 (define_insn "zero_extendsidi2_rex64"
3829 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3831 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3834 mov\t{%k1, %k0|%k0, %k1}
3836 movd\t{%1, %0|%0, %1}
3837 movd\t{%1, %0|%0, %1}
3838 %vmovd\t{%1, %0|%0, %1}
3839 %vmovd\t{%1, %0|%0, %1}"
3840 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3841 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3842 (set_attr "prefix_0f" "0,*,*,*,*,*")
3843 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3846 [(set (match_operand:DI 0 "memory_operand" "")
3847 (zero_extend:DI (match_dup 0)))]
3849 [(set (match_dup 4) (const_int 0))]
3850 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3853 [(set (match_operand:DI 0 "register_operand" "")
3854 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3855 (clobber (reg:CC FLAGS_REG))]
3856 "!TARGET_64BIT && reload_completed
3857 && true_regnum (operands[0]) == true_regnum (operands[1])"
3858 [(set (match_dup 4) (const_int 0))]
3859 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3862 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3863 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3864 (clobber (reg:CC FLAGS_REG))]
3865 "!TARGET_64BIT && reload_completed
3866 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3867 [(set (match_dup 3) (match_dup 1))
3868 (set (match_dup 4) (const_int 0))]
3869 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3871 (define_insn "zero_extendhidi2"
3872 [(set (match_operand:DI 0 "register_operand" "=r")
3873 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3875 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3876 [(set_attr "type" "imovx")
3877 (set_attr "mode" "SI")])
3879 (define_insn "zero_extendqidi2"
3880 [(set (match_operand:DI 0 "register_operand" "=r")
3881 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3883 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3884 [(set_attr "type" "imovx")
3885 (set_attr "mode" "SI")])
3887 ;; Sign extension instructions
3889 (define_expand "extendsidi2"
3890 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3891 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3892 (clobber (reg:CC FLAGS_REG))
3893 (clobber (match_scratch:SI 2 ""))])]
3898 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3903 (define_insn "*extendsidi2_1"
3904 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3905 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3906 (clobber (reg:CC FLAGS_REG))
3907 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3911 (define_insn "extendsidi2_rex64"
3912 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3913 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3917 movs{lq|x}\t{%1, %0|%0, %1}"
3918 [(set_attr "type" "imovx")
3919 (set_attr "mode" "DI")
3920 (set_attr "prefix_0f" "0")
3921 (set_attr "modrm" "0,1")])
3923 (define_insn "extendhidi2"
3924 [(set (match_operand:DI 0 "register_operand" "=r")
3925 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3927 "movs{wq|x}\t{%1, %0|%0, %1}"
3928 [(set_attr "type" "imovx")
3929 (set_attr "mode" "DI")])
3931 (define_insn "extendqidi2"
3932 [(set (match_operand:DI 0 "register_operand" "=r")
3933 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3935 "movs{bq|x}\t{%1, %0|%0, %1}"
3936 [(set_attr "type" "imovx")
3937 (set_attr "mode" "DI")])
3939 ;; Extend to memory case when source register does die.
3941 [(set (match_operand:DI 0 "memory_operand" "")
3942 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3943 (clobber (reg:CC FLAGS_REG))
3944 (clobber (match_operand:SI 2 "register_operand" ""))]
3946 && dead_or_set_p (insn, operands[1])
3947 && !reg_mentioned_p (operands[1], operands[0]))"
3948 [(set (match_dup 3) (match_dup 1))
3949 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3950 (clobber (reg:CC FLAGS_REG))])
3951 (set (match_dup 4) (match_dup 1))]
3952 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3954 ;; Extend to memory case when source register does not die.
3956 [(set (match_operand:DI 0 "memory_operand" "")
3957 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3958 (clobber (reg:CC FLAGS_REG))
3959 (clobber (match_operand:SI 2 "register_operand" ""))]
3963 split_di (&operands[0], 1, &operands[3], &operands[4]);
3965 emit_move_insn (operands[3], operands[1]);
3967 /* Generate a cltd if possible and doing so it profitable. */
3968 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3969 && true_regnum (operands[1]) == AX_REG
3970 && true_regnum (operands[2]) == DX_REG)
3972 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3976 emit_move_insn (operands[2], operands[1]);
3977 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3979 emit_move_insn (operands[4], operands[2]);
3983 ;; Extend to register case. Optimize case where source and destination
3984 ;; registers match and cases where we can use cltd.
3986 [(set (match_operand:DI 0 "register_operand" "")
3987 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3988 (clobber (reg:CC FLAGS_REG))
3989 (clobber (match_scratch:SI 2 ""))]
3993 split_di (&operands[0], 1, &operands[3], &operands[4]);
3995 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3996 emit_move_insn (operands[3], operands[1]);
3998 /* Generate a cltd if possible and doing so it profitable. */
3999 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4000 && true_regnum (operands[3]) == AX_REG
4001 && true_regnum (operands[4]) == DX_REG)
4003 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4007 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4008 emit_move_insn (operands[4], operands[1]);
4010 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4014 (define_insn "extendhisi2"
4015 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4016 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4019 switch (get_attr_prefix_0f (insn))
4022 return "{cwtl|cwde}";
4024 return "movs{wl|x}\t{%1, %0|%0, %1}";
4027 [(set_attr "type" "imovx")
4028 (set_attr "mode" "SI")
4029 (set (attr "prefix_0f")
4030 ;; movsx is short decodable while cwtl is vector decoded.
4031 (if_then_else (and (eq_attr "cpu" "!k6")
4032 (eq_attr "alternative" "0"))
4034 (const_string "1")))
4036 (if_then_else (eq_attr "prefix_0f" "0")
4038 (const_string "1")))])
4040 (define_insn "*extendhisi2_zext"
4041 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4043 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4046 switch (get_attr_prefix_0f (insn))
4049 return "{cwtl|cwde}";
4051 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4054 [(set_attr "type" "imovx")
4055 (set_attr "mode" "SI")
4056 (set (attr "prefix_0f")
4057 ;; movsx is short decodable while cwtl is vector decoded.
4058 (if_then_else (and (eq_attr "cpu" "!k6")
4059 (eq_attr "alternative" "0"))
4061 (const_string "1")))
4063 (if_then_else (eq_attr "prefix_0f" "0")
4065 (const_string "1")))])
4067 (define_insn "extendqihi2"
4068 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4069 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4072 switch (get_attr_prefix_0f (insn))
4075 return "{cbtw|cbw}";
4077 return "movs{bw|x}\t{%1, %0|%0, %1}";
4080 [(set_attr "type" "imovx")
4081 (set_attr "mode" "HI")
4082 (set (attr "prefix_0f")
4083 ;; movsx is short decodable while cwtl is vector decoded.
4084 (if_then_else (and (eq_attr "cpu" "!k6")
4085 (eq_attr "alternative" "0"))
4087 (const_string "1")))
4089 (if_then_else (eq_attr "prefix_0f" "0")
4091 (const_string "1")))])
4093 (define_insn "extendqisi2"
4094 [(set (match_operand:SI 0 "register_operand" "=r")
4095 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4097 "movs{bl|x}\t{%1, %0|%0, %1}"
4098 [(set_attr "type" "imovx")
4099 (set_attr "mode" "SI")])
4101 (define_insn "*extendqisi2_zext"
4102 [(set (match_operand:DI 0 "register_operand" "=r")
4104 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4106 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4107 [(set_attr "type" "imovx")
4108 (set_attr "mode" "SI")])
4110 ;; Conversions between float and double.
4112 ;; These are all no-ops in the model used for the 80387. So just
4115 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4116 (define_insn "*dummy_extendsfdf2"
4117 [(set (match_operand:DF 0 "push_operand" "=<")
4118 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4123 [(set (match_operand:DF 0 "push_operand" "")
4124 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4126 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4127 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4129 (define_insn "*dummy_extendsfxf2"
4130 [(set (match_operand:XF 0 "push_operand" "=<")
4131 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4136 [(set (match_operand:XF 0 "push_operand" "")
4137 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4139 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4140 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4141 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4144 [(set (match_operand:XF 0 "push_operand" "")
4145 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4147 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4148 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4149 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4151 (define_expand "extendsfdf2"
4152 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4153 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4154 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4156 /* ??? Needed for compress_float_constant since all fp constants
4157 are LEGITIMATE_CONSTANT_P. */
4158 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4160 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4161 && standard_80387_constant_p (operands[1]) > 0)
4163 operands[1] = simplify_const_unary_operation
4164 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4165 emit_move_insn_1 (operands[0], operands[1]);
4168 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4172 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4174 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4176 We do the conversion post reload to avoid producing of 128bit spills
4177 that might lead to ICE on 32bit target. The sequence unlikely combine
4180 [(set (match_operand:DF 0 "register_operand" "")
4182 (match_operand:SF 1 "nonimmediate_operand" "")))]
4183 "TARGET_USE_VECTOR_FP_CONVERTS
4184 && optimize_insn_for_speed_p ()
4185 && reload_completed && SSE_REG_P (operands[0])"
4190 (parallel [(const_int 0) (const_int 1)]))))]
4192 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4193 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4194 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4195 Try to avoid move when unpacking can be done in source. */
4196 if (REG_P (operands[1]))
4198 /* If it is unsafe to overwrite upper half of source, we need
4199 to move to destination and unpack there. */
4200 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4201 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4202 && true_regnum (operands[0]) != true_regnum (operands[1]))
4204 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4205 emit_move_insn (tmp, operands[1]);
4208 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4209 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4213 emit_insn (gen_vec_setv4sf_0 (operands[3],
4214 CONST0_RTX (V4SFmode), operands[1]));
4217 (define_insn "*extendsfdf2_mixed"
4218 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4220 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4221 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4223 switch (which_alternative)
4227 return output_387_reg_move (insn, operands);
4230 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4236 [(set_attr "type" "fmov,fmov,ssecvt")
4237 (set_attr "prefix" "orig,orig,maybe_vex")
4238 (set_attr "mode" "SF,XF,DF")])
4240 (define_insn "*extendsfdf2_sse"
4241 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4242 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4243 "TARGET_SSE2 && TARGET_SSE_MATH"
4244 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4245 [(set_attr "type" "ssecvt")
4246 (set_attr "prefix" "maybe_vex")
4247 (set_attr "mode" "DF")])
4249 (define_insn "*extendsfdf2_i387"
4250 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4251 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4253 "* return output_387_reg_move (insn, operands);"
4254 [(set_attr "type" "fmov")
4255 (set_attr "mode" "SF,XF")])
4257 (define_expand "extend<mode>xf2"
4258 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4259 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4262 /* ??? Needed for compress_float_constant since all fp constants
4263 are LEGITIMATE_CONSTANT_P. */
4264 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4266 if (standard_80387_constant_p (operands[1]) > 0)
4268 operands[1] = simplify_const_unary_operation
4269 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4270 emit_move_insn_1 (operands[0], operands[1]);
4273 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4277 (define_insn "*extend<mode>xf2_i387"
4278 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4280 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4282 "* return output_387_reg_move (insn, operands);"
4283 [(set_attr "type" "fmov")
4284 (set_attr "mode" "<MODE>,XF")])
4286 ;; %%% This seems bad bad news.
4287 ;; This cannot output into an f-reg because there is no way to be sure
4288 ;; of truncating in that case. Otherwise this is just like a simple move
4289 ;; insn. So we pretend we can output to a reg in order to get better
4290 ;; register preferencing, but we really use a stack slot.
4292 ;; Conversion from DFmode to SFmode.
4294 (define_expand "truncdfsf2"
4295 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4297 (match_operand:DF 1 "nonimmediate_operand" "")))]
4298 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4300 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4302 else if (flag_unsafe_math_optimizations)
4306 enum ix86_stack_slot slot = (virtuals_instantiated
4309 rtx temp = assign_386_stack_local (SFmode, slot);
4310 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4315 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4317 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4319 We do the conversion post reload to avoid producing of 128bit spills
4320 that might lead to ICE on 32bit target. The sequence unlikely combine
4323 [(set (match_operand:SF 0 "register_operand" "")
4325 (match_operand:DF 1 "nonimmediate_operand" "")))]
4326 "TARGET_USE_VECTOR_FP_CONVERTS
4327 && optimize_insn_for_speed_p ()
4328 && reload_completed && SSE_REG_P (operands[0])"
4331 (float_truncate:V2SF
4335 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4336 operands[3] = CONST0_RTX (V2SFmode);
4337 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4338 /* Use movsd for loading from memory, unpcklpd for registers.
4339 Try to avoid move when unpacking can be done in source, or SSE3
4340 movddup is available. */
4341 if (REG_P (operands[1]))
4344 && true_regnum (operands[0]) != true_regnum (operands[1])
4345 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4346 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4348 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4349 emit_move_insn (tmp, operands[1]);
4352 else if (!TARGET_SSE3)
4353 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4354 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4357 emit_insn (gen_sse2_loadlpd (operands[4],
4358 CONST0_RTX (V2DFmode), operands[1]));
4361 (define_expand "truncdfsf2_with_temp"
4362 [(parallel [(set (match_operand:SF 0 "" "")
4363 (float_truncate:SF (match_operand:DF 1 "" "")))
4364 (clobber (match_operand:SF 2 "" ""))])]
4367 (define_insn "*truncdfsf_fast_mixed"
4368 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4370 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4371 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4373 switch (which_alternative)
4376 return output_387_reg_move (insn, operands);
4378 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4383 [(set_attr "type" "fmov,ssecvt")
4384 (set_attr "prefix" "orig,maybe_vex")
4385 (set_attr "mode" "SF")])
4387 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4388 ;; because nothing we do here is unsafe.
4389 (define_insn "*truncdfsf_fast_sse"
4390 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4392 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4393 "TARGET_SSE2 && TARGET_SSE_MATH"
4394 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4395 [(set_attr "type" "ssecvt")
4396 (set_attr "prefix" "maybe_vex")
4397 (set_attr "mode" "SF")])
4399 (define_insn "*truncdfsf_fast_i387"
4400 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4402 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4403 "TARGET_80387 && flag_unsafe_math_optimizations"
4404 "* return output_387_reg_move (insn, operands);"
4405 [(set_attr "type" "fmov")
4406 (set_attr "mode" "SF")])
4408 (define_insn "*truncdfsf_mixed"
4409 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4411 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4412 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4413 "TARGET_MIX_SSE_I387"
4415 switch (which_alternative)
4418 return output_387_reg_move (insn, operands);
4420 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4426 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4427 (set_attr "unit" "*,*,i387,i387,i387")
4428 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4429 (set_attr "mode" "SF")])
4431 (define_insn "*truncdfsf_i387"
4432 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4434 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4435 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4438 switch (which_alternative)
4441 return output_387_reg_move (insn, operands);
4447 [(set_attr "type" "fmov,multi,multi,multi")
4448 (set_attr "unit" "*,i387,i387,i387")
4449 (set_attr "mode" "SF")])
4451 (define_insn "*truncdfsf2_i387_1"
4452 [(set (match_operand:SF 0 "memory_operand" "=m")
4454 (match_operand:DF 1 "register_operand" "f")))]
4456 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4457 && !TARGET_MIX_SSE_I387"
4458 "* return output_387_reg_move (insn, operands);"
4459 [(set_attr "type" "fmov")
4460 (set_attr "mode" "SF")])
4463 [(set (match_operand:SF 0 "register_operand" "")
4465 (match_operand:DF 1 "fp_register_operand" "")))
4466 (clobber (match_operand 2 "" ""))]
4468 [(set (match_dup 2) (match_dup 1))
4469 (set (match_dup 0) (match_dup 2))]
4471 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4474 ;; Conversion from XFmode to {SF,DF}mode
4476 (define_expand "truncxf<mode>2"
4477 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4478 (float_truncate:MODEF
4479 (match_operand:XF 1 "register_operand" "")))
4480 (clobber (match_dup 2))])]
4483 if (flag_unsafe_math_optimizations)
4485 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4486 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4487 if (reg != operands[0])
4488 emit_move_insn (operands[0], reg);
4493 enum ix86_stack_slot slot = (virtuals_instantiated
4496 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4500 (define_insn "*truncxfsf2_mixed"
4501 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4503 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4504 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4507 gcc_assert (!which_alternative);
4508 return output_387_reg_move (insn, operands);
4510 [(set_attr "type" "fmov,multi,multi,multi")
4511 (set_attr "unit" "*,i387,i387,i387")
4512 (set_attr "mode" "SF")])
4514 (define_insn "*truncxfdf2_mixed"
4515 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4517 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4518 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4521 gcc_assert (!which_alternative);
4522 return output_387_reg_move (insn, operands);
4524 [(set_attr "type" "fmov,multi,multi,multi")
4525 (set_attr "unit" "*,i387,i387,i387")
4526 (set_attr "mode" "DF")])
4528 (define_insn "truncxf<mode>2_i387_noop"
4529 [(set (match_operand:MODEF 0 "register_operand" "=f")
4530 (float_truncate:MODEF
4531 (match_operand:XF 1 "register_operand" "f")))]
4532 "TARGET_80387 && flag_unsafe_math_optimizations"
4533 "* return output_387_reg_move (insn, operands);"
4534 [(set_attr "type" "fmov")
4535 (set_attr "mode" "<MODE>")])
4537 (define_insn "*truncxf<mode>2_i387"
4538 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4539 (float_truncate:MODEF
4540 (match_operand:XF 1 "register_operand" "f")))]
4542 "* return output_387_reg_move (insn, operands);"
4543 [(set_attr "type" "fmov")
4544 (set_attr "mode" "<MODE>")])
4547 [(set (match_operand:MODEF 0 "register_operand" "")
4548 (float_truncate:MODEF
4549 (match_operand:XF 1 "register_operand" "")))
4550 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4551 "TARGET_80387 && reload_completed"
4552 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4553 (set (match_dup 0) (match_dup 2))]
4557 [(set (match_operand:MODEF 0 "memory_operand" "")
4558 (float_truncate:MODEF
4559 (match_operand:XF 1 "register_operand" "")))
4560 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4562 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4565 ;; Signed conversion to DImode.
4567 (define_expand "fix_truncxfdi2"
4568 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4569 (fix:DI (match_operand:XF 1 "register_operand" "")))
4570 (clobber (reg:CC FLAGS_REG))])]
4575 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4580 (define_expand "fix_trunc<mode>di2"
4581 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4582 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4583 (clobber (reg:CC FLAGS_REG))])]
4584 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4587 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4589 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4592 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4594 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4595 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4596 if (out != operands[0])
4597 emit_move_insn (operands[0], out);
4602 ;; Signed conversion to SImode.
4604 (define_expand "fix_truncxfsi2"
4605 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4606 (fix:SI (match_operand:XF 1 "register_operand" "")))
4607 (clobber (reg:CC FLAGS_REG))])]
4612 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4617 (define_expand "fix_trunc<mode>si2"
4618 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4619 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4620 (clobber (reg:CC FLAGS_REG))])]
4621 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4624 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4626 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4629 if (SSE_FLOAT_MODE_P (<MODE>mode))
4631 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4632 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4633 if (out != operands[0])
4634 emit_move_insn (operands[0], out);
4639 ;; Signed conversion to HImode.
4641 (define_expand "fix_trunc<mode>hi2"
4642 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4643 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4644 (clobber (reg:CC FLAGS_REG))])]
4646 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4650 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4655 ;; Unsigned conversion to SImode.
4657 (define_expand "fixuns_trunc<mode>si2"
4659 [(set (match_operand:SI 0 "register_operand" "")
4661 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4663 (clobber (match_scratch:<ssevecmode> 3 ""))
4664 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4665 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4667 enum machine_mode mode = <MODE>mode;
4668 enum machine_mode vecmode = <ssevecmode>mode;
4669 REAL_VALUE_TYPE TWO31r;
4672 if (optimize_insn_for_size_p ())
4675 real_ldexp (&TWO31r, &dconst1, 31);
4676 two31 = const_double_from_real_value (TWO31r, mode);
4677 two31 = ix86_build_const_vector (mode, true, two31);
4678 operands[2] = force_reg (vecmode, two31);
4681 (define_insn_and_split "*fixuns_trunc<mode>_1"
4682 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4684 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4685 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4686 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4687 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4688 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4689 && optimize_function_for_speed_p (cfun)"
4691 "&& reload_completed"
4694 ix86_split_convert_uns_si_sse (operands);
4698 ;; Unsigned conversion to HImode.
4699 ;; Without these patterns, we'll try the unsigned SI conversion which
4700 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4702 (define_expand "fixuns_trunc<mode>hi2"
4704 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4705 (set (match_operand:HI 0 "nonimmediate_operand" "")
4706 (subreg:HI (match_dup 2) 0))]
4707 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4708 "operands[2] = gen_reg_rtx (SImode);")
4710 ;; When SSE is available, it is always faster to use it!
4711 (define_insn "fix_trunc<mode>di_sse"
4712 [(set (match_operand:DI 0 "register_operand" "=r,r")
4713 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4714 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4715 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4716 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4717 [(set_attr "type" "sseicvt")
4718 (set_attr "prefix" "maybe_vex")
4719 (set_attr "prefix_rex" "1")
4720 (set_attr "mode" "<MODE>")
4721 (set_attr "athlon_decode" "double,vector")
4722 (set_attr "amdfam10_decode" "double,double")])
4724 (define_insn "fix_trunc<mode>si_sse"
4725 [(set (match_operand:SI 0 "register_operand" "=r,r")
4726 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4727 "SSE_FLOAT_MODE_P (<MODE>mode)
4728 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4729 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4730 [(set_attr "type" "sseicvt")
4731 (set_attr "prefix" "maybe_vex")
4732 (set_attr "mode" "<MODE>")
4733 (set_attr "athlon_decode" "double,vector")
4734 (set_attr "amdfam10_decode" "double,double")])
4736 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4738 [(set (match_operand:MODEF 0 "register_operand" "")
4739 (match_operand:MODEF 1 "memory_operand" ""))
4740 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4741 (fix:SSEMODEI24 (match_dup 0)))]
4742 "TARGET_SHORTEN_X87_SSE
4743 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4744 && peep2_reg_dead_p (2, operands[0])"
4745 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4748 ;; Avoid vector decoded forms of the instruction.
4750 [(match_scratch:DF 2 "Y2")
4751 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4752 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4753 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4754 [(set (match_dup 2) (match_dup 1))
4755 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4759 [(match_scratch:SF 2 "x")
4760 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4761 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4762 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4763 [(set (match_dup 2) (match_dup 1))
4764 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4767 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4768 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4769 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4770 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4772 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4773 && (TARGET_64BIT || <MODE>mode != DImode))
4775 && can_create_pseudo_p ()"
4780 if (memory_operand (operands[0], VOIDmode))
4781 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4784 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4785 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4791 [(set_attr "type" "fisttp")
4792 (set_attr "mode" "<MODE>")])
4794 (define_insn "fix_trunc<mode>_i387_fisttp"
4795 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4796 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4797 (clobber (match_scratch:XF 2 "=&1f"))]
4798 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4800 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4801 && (TARGET_64BIT || <MODE>mode != DImode))
4802 && TARGET_SSE_MATH)"
4803 "* return output_fix_trunc (insn, operands, 1);"
4804 [(set_attr "type" "fisttp")
4805 (set_attr "mode" "<MODE>")])
4807 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4808 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4809 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4810 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4811 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4812 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4814 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4815 && (TARGET_64BIT || <MODE>mode != DImode))
4816 && TARGET_SSE_MATH)"
4818 [(set_attr "type" "fisttp")
4819 (set_attr "mode" "<MODE>")])
4822 [(set (match_operand:X87MODEI 0 "register_operand" "")
4823 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4824 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4825 (clobber (match_scratch 3 ""))]
4827 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4828 (clobber (match_dup 3))])
4829 (set (match_dup 0) (match_dup 2))]
4833 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4834 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4835 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4836 (clobber (match_scratch 3 ""))]
4838 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4839 (clobber (match_dup 3))])]
4842 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4843 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4844 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4845 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4846 ;; function in i386.c.
4847 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4848 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4849 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4850 (clobber (reg:CC FLAGS_REG))]
4851 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4853 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4854 && (TARGET_64BIT || <MODE>mode != DImode))
4855 && can_create_pseudo_p ()"
4860 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4862 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4863 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4864 if (memory_operand (operands[0], VOIDmode))
4865 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4866 operands[2], operands[3]));
4869 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4870 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4871 operands[2], operands[3],
4876 [(set_attr "type" "fistp")
4877 (set_attr "i387_cw" "trunc")
4878 (set_attr "mode" "<MODE>")])
4880 (define_insn "fix_truncdi_i387"
4881 [(set (match_operand:DI 0 "memory_operand" "=m")
4882 (fix:DI (match_operand 1 "register_operand" "f")))
4883 (use (match_operand:HI 2 "memory_operand" "m"))
4884 (use (match_operand:HI 3 "memory_operand" "m"))
4885 (clobber (match_scratch:XF 4 "=&1f"))]
4886 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4888 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4889 "* return output_fix_trunc (insn, operands, 0);"
4890 [(set_attr "type" "fistp")
4891 (set_attr "i387_cw" "trunc")
4892 (set_attr "mode" "DI")])
4894 (define_insn "fix_truncdi_i387_with_temp"
4895 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4896 (fix:DI (match_operand 1 "register_operand" "f,f")))
4897 (use (match_operand:HI 2 "memory_operand" "m,m"))
4898 (use (match_operand:HI 3 "memory_operand" "m,m"))
4899 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4900 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4901 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4903 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4905 [(set_attr "type" "fistp")
4906 (set_attr "i387_cw" "trunc")
4907 (set_attr "mode" "DI")])
4910 [(set (match_operand:DI 0 "register_operand" "")
4911 (fix:DI (match_operand 1 "register_operand" "")))
4912 (use (match_operand:HI 2 "memory_operand" ""))
4913 (use (match_operand:HI 3 "memory_operand" ""))
4914 (clobber (match_operand:DI 4 "memory_operand" ""))
4915 (clobber (match_scratch 5 ""))]
4917 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4920 (clobber (match_dup 5))])
4921 (set (match_dup 0) (match_dup 4))]
4925 [(set (match_operand:DI 0 "memory_operand" "")
4926 (fix:DI (match_operand 1 "register_operand" "")))
4927 (use (match_operand:HI 2 "memory_operand" ""))
4928 (use (match_operand:HI 3 "memory_operand" ""))
4929 (clobber (match_operand:DI 4 "memory_operand" ""))
4930 (clobber (match_scratch 5 ""))]
4932 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4935 (clobber (match_dup 5))])]
4938 (define_insn "fix_trunc<mode>_i387"
4939 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4940 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4941 (use (match_operand:HI 2 "memory_operand" "m"))
4942 (use (match_operand:HI 3 "memory_operand" "m"))]
4943 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4945 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4946 "* return output_fix_trunc (insn, operands, 0);"
4947 [(set_attr "type" "fistp")
4948 (set_attr "i387_cw" "trunc")
4949 (set_attr "mode" "<MODE>")])
4951 (define_insn "fix_trunc<mode>_i387_with_temp"
4952 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4953 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4954 (use (match_operand:HI 2 "memory_operand" "m,m"))
4955 (use (match_operand:HI 3 "memory_operand" "m,m"))
4956 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4957 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4959 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4961 [(set_attr "type" "fistp")
4962 (set_attr "i387_cw" "trunc")
4963 (set_attr "mode" "<MODE>")])
4966 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4967 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4968 (use (match_operand:HI 2 "memory_operand" ""))
4969 (use (match_operand:HI 3 "memory_operand" ""))
4970 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4972 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4974 (use (match_dup 3))])
4975 (set (match_dup 0) (match_dup 4))]
4979 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4980 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4981 (use (match_operand:HI 2 "memory_operand" ""))
4982 (use (match_operand:HI 3 "memory_operand" ""))
4983 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4985 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4987 (use (match_dup 3))])]
4990 (define_insn "x86_fnstcw_1"
4991 [(set (match_operand:HI 0 "memory_operand" "=m")
4992 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4995 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4996 (set_attr "mode" "HI")
4997 (set_attr "unit" "i387")])
4999 (define_insn "x86_fldcw_1"
5000 [(set (reg:HI FPCR_REG)
5001 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5004 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5005 (set_attr "mode" "HI")
5006 (set_attr "unit" "i387")
5007 (set_attr "athlon_decode" "vector")
5008 (set_attr "amdfam10_decode" "vector")])
5010 ;; Conversion between fixed point and floating point.
5012 ;; Even though we only accept memory inputs, the backend _really_
5013 ;; wants to be able to do this between registers.
5015 (define_expand "floathi<mode>2"
5016 [(set (match_operand:X87MODEF 0 "register_operand" "")
5017 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5019 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5020 || TARGET_MIX_SSE_I387)"
5023 ;; Pre-reload splitter to add memory clobber to the pattern.
5024 (define_insn_and_split "*floathi<mode>2_1"
5025 [(set (match_operand:X87MODEF 0 "register_operand" "")
5026 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5028 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5029 || TARGET_MIX_SSE_I387)
5030 && can_create_pseudo_p ()"
5033 [(parallel [(set (match_dup 0)
5034 (float:X87MODEF (match_dup 1)))
5035 (clobber (match_dup 2))])]
5036 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5038 (define_insn "*floathi<mode>2_i387_with_temp"
5039 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5040 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5041 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5043 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5044 || TARGET_MIX_SSE_I387)"
5046 [(set_attr "type" "fmov,multi")
5047 (set_attr "mode" "<MODE>")
5048 (set_attr "unit" "*,i387")
5049 (set_attr "fp_int_src" "true")])
5051 (define_insn "*floathi<mode>2_i387"
5052 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5053 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5055 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5056 || TARGET_MIX_SSE_I387)"
5058 [(set_attr "type" "fmov")
5059 (set_attr "mode" "<MODE>")
5060 (set_attr "fp_int_src" "true")])
5063 [(set (match_operand:X87MODEF 0 "register_operand" "")
5064 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5065 (clobber (match_operand:HI 2 "memory_operand" ""))]
5067 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5068 || TARGET_MIX_SSE_I387)
5069 && reload_completed"
5070 [(set (match_dup 2) (match_dup 1))
5071 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5075 [(set (match_operand:X87MODEF 0 "register_operand" "")
5076 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5077 (clobber (match_operand:HI 2 "memory_operand" ""))]
5079 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5080 || TARGET_MIX_SSE_I387)
5081 && reload_completed"
5082 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5085 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5086 [(set (match_operand:X87MODEF 0 "register_operand" "")
5088 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5090 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5091 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5093 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5094 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5095 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5097 rtx reg = gen_reg_rtx (XFmode);
5100 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5102 if (<X87MODEF:MODE>mode == SFmode)
5103 insn = gen_truncxfsf2 (operands[0], reg);
5104 else if (<X87MODEF:MODE>mode == DFmode)
5105 insn = gen_truncxfdf2 (operands[0], reg);
5114 ;; Pre-reload splitter to add memory clobber to the pattern.
5115 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5116 [(set (match_operand:X87MODEF 0 "register_operand" "")
5117 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5119 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5120 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5121 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5122 || TARGET_MIX_SSE_I387))
5123 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5124 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5125 && ((<SSEMODEI24:MODE>mode == SImode
5126 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5127 && optimize_function_for_speed_p (cfun)
5128 && flag_trapping_math)
5129 || !(TARGET_INTER_UNIT_CONVERSIONS
5130 || optimize_function_for_size_p (cfun)))))
5131 && can_create_pseudo_p ()"
5134 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5135 (clobber (match_dup 2))])]
5137 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5139 /* Avoid store forwarding (partial memory) stall penalty
5140 by passing DImode value through XMM registers. */
5141 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5142 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5143 && optimize_function_for_speed_p (cfun))
5145 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5152 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5153 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5155 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5156 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5157 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5158 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5160 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5161 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5162 (set_attr "unit" "*,i387,*,*,*")
5163 (set_attr "athlon_decode" "*,*,double,direct,double")
5164 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5165 (set_attr "fp_int_src" "true")])
5167 (define_insn "*floatsi<mode>2_vector_mixed"
5168 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5169 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5170 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5171 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5175 [(set_attr "type" "fmov,sseicvt")
5176 (set_attr "mode" "<MODE>,<ssevecmode>")
5177 (set_attr "unit" "i387,*")
5178 (set_attr "athlon_decode" "*,direct")
5179 (set_attr "amdfam10_decode" "*,double")
5180 (set_attr "fp_int_src" "true")])
5182 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5183 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5185 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5186 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5187 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5188 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5190 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5191 (set_attr "mode" "<MODEF:MODE>")
5192 (set_attr "unit" "*,i387,*,*")
5193 (set_attr "athlon_decode" "*,*,double,direct")
5194 (set_attr "amdfam10_decode" "*,*,vector,double")
5195 (set_attr "fp_int_src" "true")])
5198 [(set (match_operand:MODEF 0 "register_operand" "")
5199 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5200 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5201 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5202 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5203 && TARGET_INTER_UNIT_CONVERSIONS
5205 && (SSE_REG_P (operands[0])
5206 || (GET_CODE (operands[0]) == SUBREG
5207 && SSE_REG_P (operands[0])))"
5208 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5212 [(set (match_operand:MODEF 0 "register_operand" "")
5213 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5214 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5215 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5216 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5217 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5219 && (SSE_REG_P (operands[0])
5220 || (GET_CODE (operands[0]) == SUBREG
5221 && SSE_REG_P (operands[0])))"
5222 [(set (match_dup 2) (match_dup 1))
5223 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5226 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5227 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5229 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5230 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5231 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5232 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5235 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5236 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5237 [(set_attr "type" "fmov,sseicvt,sseicvt")
5238 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5239 (set_attr "mode" "<MODEF:MODE>")
5240 (set (attr "prefix_rex")
5242 (and (eq_attr "prefix" "maybe_vex")
5243 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5245 (const_string "*")))
5246 (set_attr "unit" "i387,*,*")
5247 (set_attr "athlon_decode" "*,double,direct")
5248 (set_attr "amdfam10_decode" "*,vector,double")
5249 (set_attr "fp_int_src" "true")])
5251 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5252 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5254 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5255 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5256 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5257 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5260 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5261 [(set_attr "type" "fmov,sseicvt")
5262 (set_attr "prefix" "orig,maybe_vex")
5263 (set_attr "mode" "<MODEF:MODE>")
5264 (set (attr "prefix_rex")
5266 (and (eq_attr "prefix" "maybe_vex")
5267 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5269 (const_string "*")))
5270 (set_attr "athlon_decode" "*,direct")
5271 (set_attr "amdfam10_decode" "*,double")
5272 (set_attr "fp_int_src" "true")])
5274 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5275 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5277 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5278 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5279 "TARGET_SSE2 && TARGET_SSE_MATH
5280 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5282 [(set_attr "type" "sseicvt")
5283 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5284 (set_attr "athlon_decode" "double,direct,double")
5285 (set_attr "amdfam10_decode" "vector,double,double")
5286 (set_attr "fp_int_src" "true")])
5288 (define_insn "*floatsi<mode>2_vector_sse"
5289 [(set (match_operand:MODEF 0 "register_operand" "=x")
5290 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5291 "TARGET_SSE2 && TARGET_SSE_MATH
5292 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5294 [(set_attr "type" "sseicvt")
5295 (set_attr "mode" "<MODE>")
5296 (set_attr "athlon_decode" "direct")
5297 (set_attr "amdfam10_decode" "double")
5298 (set_attr "fp_int_src" "true")])
5301 [(set (match_operand:MODEF 0 "register_operand" "")
5302 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5303 (clobber (match_operand:SI 2 "memory_operand" ""))]
5304 "TARGET_SSE2 && TARGET_SSE_MATH
5305 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5307 && (SSE_REG_P (operands[0])
5308 || (GET_CODE (operands[0]) == SUBREG
5309 && SSE_REG_P (operands[0])))"
5312 rtx op1 = operands[1];
5314 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5316 if (GET_CODE (op1) == SUBREG)
5317 op1 = SUBREG_REG (op1);
5319 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5321 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5322 emit_insn (gen_sse2_loadld (operands[4],
5323 CONST0_RTX (V4SImode), operands[1]));
5325 /* We can ignore possible trapping value in the
5326 high part of SSE register for non-trapping math. */
5327 else if (SSE_REG_P (op1) && !flag_trapping_math)
5328 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5331 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5332 emit_move_insn (operands[2], operands[1]);
5333 emit_insn (gen_sse2_loadld (operands[4],
5334 CONST0_RTX (V4SImode), operands[2]));
5337 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5342 [(set (match_operand:MODEF 0 "register_operand" "")
5343 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5344 (clobber (match_operand:SI 2 "memory_operand" ""))]
5345 "TARGET_SSE2 && TARGET_SSE_MATH
5346 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5348 && (SSE_REG_P (operands[0])
5349 || (GET_CODE (operands[0]) == SUBREG
5350 && SSE_REG_P (operands[0])))"
5353 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5355 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5357 emit_insn (gen_sse2_loadld (operands[4],
5358 CONST0_RTX (V4SImode), operands[1]));
5360 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5365 [(set (match_operand:MODEF 0 "register_operand" "")
5366 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5367 "TARGET_SSE2 && TARGET_SSE_MATH
5368 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5370 && (SSE_REG_P (operands[0])
5371 || (GET_CODE (operands[0]) == SUBREG
5372 && SSE_REG_P (operands[0])))"
5375 rtx op1 = operands[1];
5377 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5379 if (GET_CODE (op1) == SUBREG)
5380 op1 = SUBREG_REG (op1);
5382 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5384 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5385 emit_insn (gen_sse2_loadld (operands[4],
5386 CONST0_RTX (V4SImode), operands[1]));
5388 /* We can ignore possible trapping value in the
5389 high part of SSE register for non-trapping math. */
5390 else if (SSE_REG_P (op1) && !flag_trapping_math)
5391 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5395 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5400 [(set (match_operand:MODEF 0 "register_operand" "")
5401 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5402 "TARGET_SSE2 && TARGET_SSE_MATH
5403 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5405 && (SSE_REG_P (operands[0])
5406 || (GET_CODE (operands[0]) == SUBREG
5407 && SSE_REG_P (operands[0])))"
5410 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5412 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5414 emit_insn (gen_sse2_loadld (operands[4],
5415 CONST0_RTX (V4SImode), operands[1]));
5417 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5421 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5422 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5424 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5425 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5426 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5427 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5429 [(set_attr "type" "sseicvt")
5430 (set_attr "mode" "<MODEF:MODE>")
5431 (set_attr "athlon_decode" "double,direct")
5432 (set_attr "amdfam10_decode" "vector,double")
5433 (set_attr "fp_int_src" "true")])
5435 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5436 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5438 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5439 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5440 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5441 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5442 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5443 [(set_attr "type" "sseicvt")
5444 (set_attr "prefix" "maybe_vex")
5445 (set_attr "mode" "<MODEF:MODE>")
5446 (set (attr "prefix_rex")
5448 (and (eq_attr "prefix" "maybe_vex")
5449 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5451 (const_string "*")))
5452 (set_attr "athlon_decode" "double,direct")
5453 (set_attr "amdfam10_decode" "vector,double")
5454 (set_attr "fp_int_src" "true")])
5457 [(set (match_operand:MODEF 0 "register_operand" "")
5458 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5459 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5460 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5461 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5462 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5464 && (SSE_REG_P (operands[0])
5465 || (GET_CODE (operands[0]) == SUBREG
5466 && SSE_REG_P (operands[0])))"
5467 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5470 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5471 [(set (match_operand:MODEF 0 "register_operand" "=x")
5473 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5474 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5475 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5476 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5477 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5478 [(set_attr "type" "sseicvt")
5479 (set_attr "prefix" "maybe_vex")
5480 (set_attr "mode" "<MODEF:MODE>")
5481 (set (attr "prefix_rex")
5483 (and (eq_attr "prefix" "maybe_vex")
5484 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5486 (const_string "*")))
5487 (set_attr "athlon_decode" "direct")
5488 (set_attr "amdfam10_decode" "double")
5489 (set_attr "fp_int_src" "true")])
5492 [(set (match_operand:MODEF 0 "register_operand" "")
5493 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5494 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5495 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5496 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5497 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5499 && (SSE_REG_P (operands[0])
5500 || (GET_CODE (operands[0]) == SUBREG
5501 && SSE_REG_P (operands[0])))"
5502 [(set (match_dup 2) (match_dup 1))
5503 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5507 [(set (match_operand:MODEF 0 "register_operand" "")
5508 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5509 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5510 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5511 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5513 && (SSE_REG_P (operands[0])
5514 || (GET_CODE (operands[0]) == SUBREG
5515 && SSE_REG_P (operands[0])))"
5516 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5519 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5520 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5522 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5523 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5525 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5529 [(set_attr "type" "fmov,multi")
5530 (set_attr "mode" "<X87MODEF:MODE>")
5531 (set_attr "unit" "*,i387")
5532 (set_attr "fp_int_src" "true")])
5534 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5535 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5537 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5539 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5541 [(set_attr "type" "fmov")
5542 (set_attr "mode" "<X87MODEF:MODE>")
5543 (set_attr "fp_int_src" "true")])
5546 [(set (match_operand:X87MODEF 0 "register_operand" "")
5547 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5548 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5550 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5552 && FP_REG_P (operands[0])"
5553 [(set (match_dup 2) (match_dup 1))
5554 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5558 [(set (match_operand:X87MODEF 0 "register_operand" "")
5559 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5560 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5562 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5564 && FP_REG_P (operands[0])"
5565 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5568 ;; Avoid store forwarding (partial memory) stall penalty
5569 ;; by passing DImode value through XMM registers. */
5571 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5572 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5574 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5575 (clobber (match_scratch:V4SI 3 "=X,x"))
5576 (clobber (match_scratch:V4SI 4 "=X,x"))
5577 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5578 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5579 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5580 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5582 [(set_attr "type" "multi")
5583 (set_attr "mode" "<X87MODEF:MODE>")
5584 (set_attr "unit" "i387")
5585 (set_attr "fp_int_src" "true")])
5588 [(set (match_operand:X87MODEF 0 "register_operand" "")
5589 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5590 (clobber (match_scratch:V4SI 3 ""))
5591 (clobber (match_scratch:V4SI 4 ""))
5592 (clobber (match_operand:DI 2 "memory_operand" ""))]
5593 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5594 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5595 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5597 && FP_REG_P (operands[0])"
5598 [(set (match_dup 2) (match_dup 3))
5599 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5601 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5602 Assemble the 64-bit DImode value in an xmm register. */
5603 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5604 gen_rtx_SUBREG (SImode, operands[1], 0)));
5605 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5606 gen_rtx_SUBREG (SImode, operands[1], 4)));
5607 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5610 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5614 [(set (match_operand:X87MODEF 0 "register_operand" "")
5615 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5616 (clobber (match_scratch:V4SI 3 ""))
5617 (clobber (match_scratch:V4SI 4 ""))
5618 (clobber (match_operand:DI 2 "memory_operand" ""))]
5619 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5620 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5621 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5623 && FP_REG_P (operands[0])"
5624 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5627 ;; Avoid store forwarding (partial memory) stall penalty by extending
5628 ;; SImode value to DImode through XMM register instead of pushing two
5629 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5630 ;; targets benefit from this optimization. Also note that fild
5631 ;; loads from memory only.
5633 (define_insn "*floatunssi<mode>2_1"
5634 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5635 (unsigned_float:X87MODEF
5636 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5637 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5638 (clobber (match_scratch:SI 3 "=X,x"))]
5640 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5643 [(set_attr "type" "multi")
5644 (set_attr "mode" "<MODE>")])
5647 [(set (match_operand:X87MODEF 0 "register_operand" "")
5648 (unsigned_float:X87MODEF
5649 (match_operand:SI 1 "register_operand" "")))
5650 (clobber (match_operand:DI 2 "memory_operand" ""))
5651 (clobber (match_scratch:SI 3 ""))]
5653 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5655 && reload_completed"
5656 [(set (match_dup 2) (match_dup 1))
5658 (float:X87MODEF (match_dup 2)))]
5659 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5662 [(set (match_operand:X87MODEF 0 "register_operand" "")
5663 (unsigned_float:X87MODEF
5664 (match_operand:SI 1 "memory_operand" "")))
5665 (clobber (match_operand:DI 2 "memory_operand" ""))
5666 (clobber (match_scratch:SI 3 ""))]
5668 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5670 && reload_completed"
5671 [(set (match_dup 2) (match_dup 3))
5673 (float:X87MODEF (match_dup 2)))]
5675 emit_move_insn (operands[3], operands[1]);
5676 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5679 (define_expand "floatunssi<mode>2"
5681 [(set (match_operand:X87MODEF 0 "register_operand" "")
5682 (unsigned_float:X87MODEF
5683 (match_operand:SI 1 "nonimmediate_operand" "")))
5684 (clobber (match_dup 2))
5685 (clobber (match_scratch:SI 3 ""))])]
5687 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5689 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5691 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5693 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5698 enum ix86_stack_slot slot = (virtuals_instantiated
5701 operands[2] = assign_386_stack_local (DImode, slot);
5705 (define_expand "floatunsdisf2"
5706 [(use (match_operand:SF 0 "register_operand" ""))
5707 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5708 "TARGET_64BIT && TARGET_SSE_MATH"
5709 "x86_emit_floatuns (operands); DONE;")
5711 (define_expand "floatunsdidf2"
5712 [(use (match_operand:DF 0 "register_operand" ""))
5713 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5714 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5715 && TARGET_SSE2 && TARGET_SSE_MATH"
5718 x86_emit_floatuns (operands);
5720 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5726 (define_expand "add<mode>3"
5727 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5728 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5729 (match_operand:SDWIM 2 "<general_operand>" "")))]
5731 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5733 (define_insn_and_split "*add<dwi>3_doubleword"
5734 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5736 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5737 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5738 (clobber (reg:CC FLAGS_REG))]
5739 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5742 [(parallel [(set (reg:CC FLAGS_REG)
5743 (unspec:CC [(match_dup 1) (match_dup 2)]
5746 (plus:DWIH (match_dup 1) (match_dup 2)))])
5747 (parallel [(set (match_dup 3)
5751 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5753 (clobber (reg:CC FLAGS_REG))])]
5754 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5756 (define_insn "*add<mode>3_cc"
5757 [(set (reg:CC FLAGS_REG)
5759 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5760 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5762 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5763 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5764 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5765 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5766 [(set_attr "type" "alu")
5767 (set_attr "mode" "<MODE>")])
5769 (define_insn "addqi3_cc"
5770 [(set (reg:CC FLAGS_REG)
5772 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5773 (match_operand:QI 2 "general_operand" "qn,qm")]
5775 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5776 (plus:QI (match_dup 1) (match_dup 2)))]
5777 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5778 "add{b}\t{%2, %0|%0, %2}"
5779 [(set_attr "type" "alu")
5780 (set_attr "mode" "QI")])
5782 (define_insn "*lea_1"
5783 [(set (match_operand:DWIH 0 "register_operand" "=r")
5784 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5786 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5787 [(set_attr "type" "lea")
5788 (set_attr "mode" "<MODE>")])
5790 (define_insn "*lea_2"
5791 [(set (match_operand:SI 0 "register_operand" "=r")
5792 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5794 "lea{l}\t{%a1, %0|%0, %a1}"
5795 [(set_attr "type" "lea")
5796 (set_attr "mode" "SI")])
5798 (define_insn "*lea_2_zext"
5799 [(set (match_operand:DI 0 "register_operand" "=r")
5801 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5803 "lea{l}\t{%a1, %k0|%k0, %a1}"
5804 [(set_attr "type" "lea")
5805 (set_attr "mode" "SI")])
5807 (define_insn "*add<mode>_1"
5808 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5810 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5811 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5812 (clobber (reg:CC FLAGS_REG))]
5813 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5815 switch (get_attr_type (insn))
5818 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5819 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
5822 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5823 if (operands[2] == const1_rtx)
5824 return "inc{<imodesuffix>}\t%0";
5827 gcc_assert (operands[2] == constm1_rtx);
5828 return "dec{<imodesuffix>}\t%0";
5832 /* Use add as much as possible to replace lea for AGU optimization. */
5833 if (which_alternative == 2 && TARGET_OPT_AGU)
5834 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
5836 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5837 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5838 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5840 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5844 (cond [(and (eq_attr "alternative" "2")
5845 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
5846 (const_string "lea")
5847 (eq_attr "alternative" "3")
5848 (const_string "lea")
5849 (match_operand:SWI48 2 "incdec_operand" "")
5850 (const_string "incdec")
5852 (const_string "alu")))
5853 (set (attr "length_immediate")
5855 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5857 (const_string "*")))
5858 (set_attr "mode" "<MODE>")])
5860 ;; It may seem that nonimmediate operand is proper one for operand 1.
5861 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5862 ;; we take care in ix86_binary_operator_ok to not allow two memory
5863 ;; operands so proper swapping will be done in reload. This allow
5864 ;; patterns constructed from addsi_1 to match.
5866 (define_insn "*addsi_1_zext"
5867 [(set (match_operand:DI 0 "register_operand" "=r,r")
5869 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5870 (match_operand:SI 2 "general_operand" "g,li"))))
5871 (clobber (reg:CC FLAGS_REG))]
5872 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5874 switch (get_attr_type (insn))
5877 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
5878 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5881 if (operands[2] == const1_rtx)
5882 return "inc{l}\t%k0";
5885 gcc_assert (operands[2] == constm1_rtx);
5886 return "dec{l}\t%k0";
5890 if (x86_maybe_negate_const_int (&operands[2], SImode))
5891 return "sub{l}\t{%2, %k0|%k0, %2}";
5893 return "add{l}\t{%2, %k0|%k0, %2}";
5897 (cond [(eq_attr "alternative" "1")
5898 (const_string "lea")
5899 (match_operand:SI 2 "incdec_operand" "")
5900 (const_string "incdec")
5902 (const_string "alu")))
5903 (set (attr "length_immediate")
5905 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5907 (const_string "*")))
5908 (set_attr "mode" "SI")])
5910 (define_insn "*addhi_1"
5911 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5912 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5913 (match_operand:HI 2 "general_operand" "rn,rm")))
5914 (clobber (reg:CC FLAGS_REG))]
5915 "TARGET_PARTIAL_REG_STALL
5916 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5918 switch (get_attr_type (insn))
5921 if (operands[2] == const1_rtx)
5922 return "inc{w}\t%0";
5925 gcc_assert (operands[2] == constm1_rtx);
5926 return "dec{w}\t%0";
5930 if (x86_maybe_negate_const_int (&operands[2], HImode))
5931 return "sub{w}\t{%2, %0|%0, %2}";
5933 return "add{w}\t{%2, %0|%0, %2}";
5937 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5938 (const_string "incdec")
5939 (const_string "alu")))
5940 (set (attr "length_immediate")
5942 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5944 (const_string "*")))
5945 (set_attr "mode" "HI")])
5947 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5948 ;; type optimizations enabled by define-splits. This is not important
5949 ;; for PII, and in fact harmful because of partial register stalls.
5951 (define_insn "*addhi_1_lea"
5952 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5953 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5954 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
5955 (clobber (reg:CC FLAGS_REG))]
5956 "!TARGET_PARTIAL_REG_STALL
5957 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5959 switch (get_attr_type (insn))
5965 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5966 if (operands[2] == const1_rtx)
5967 return "inc{w}\t%0";
5970 gcc_assert (operands[2] == constm1_rtx);
5971 return "dec{w}\t%0";
5975 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5976 if (x86_maybe_negate_const_int (&operands[2], HImode))
5977 return "sub{w}\t{%2, %0|%0, %2}";
5979 return "add{w}\t{%2, %0|%0, %2}";
5983 (if_then_else (eq_attr "alternative" "2")
5984 (const_string "lea")
5985 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5986 (const_string "incdec")
5987 (const_string "alu"))))
5988 (set (attr "length_immediate")
5990 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5992 (const_string "*")))
5993 (set_attr "mode" "HI,HI,SI")])
5995 (define_insn "*addqi_1"
5996 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5997 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5998 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5999 (clobber (reg:CC FLAGS_REG))]
6000 "TARGET_PARTIAL_REG_STALL
6001 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6003 int widen = (which_alternative == 2);
6004 switch (get_attr_type (insn))
6007 if (operands[2] == const1_rtx)
6008 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6011 gcc_assert (operands[2] == constm1_rtx);
6012 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6016 if (x86_maybe_negate_const_int (&operands[2], QImode))
6019 return "sub{l}\t{%2, %k0|%k0, %2}";
6021 return "sub{b}\t{%2, %0|%0, %2}";
6024 return "add{l}\t{%k2, %k0|%k0, %k2}";
6026 return "add{b}\t{%2, %0|%0, %2}";
6030 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6031 (const_string "incdec")
6032 (const_string "alu")))
6033 (set (attr "length_immediate")
6035 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6037 (const_string "*")))
6038 (set_attr "mode" "QI,QI,SI")])
6040 ;; %%% Potential partial reg stall on alternative 2. What to do?
6041 (define_insn "*addqi_1_lea"
6042 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6043 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6044 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6045 (clobber (reg:CC FLAGS_REG))]
6046 "!TARGET_PARTIAL_REG_STALL
6047 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6049 int widen = (which_alternative == 2);
6050 switch (get_attr_type (insn))
6056 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6057 if (operands[2] == const1_rtx)
6058 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6061 gcc_assert (operands[2] == constm1_rtx);
6062 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6066 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6067 if (x86_maybe_negate_const_int (&operands[2], QImode))
6070 return "sub{l}\t{%2, %k0|%k0, %2}";
6072 return "sub{b}\t{%2, %0|%0, %2}";
6075 return "add{l}\t{%k2, %k0|%k0, %k2}";
6077 return "add{b}\t{%2, %0|%0, %2}";
6081 (if_then_else (eq_attr "alternative" "3")
6082 (const_string "lea")
6083 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6084 (const_string "incdec")
6085 (const_string "alu"))))
6086 (set (attr "length_immediate")
6088 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6090 (const_string "*")))
6091 (set_attr "mode" "QI,QI,SI,SI")])
6093 (define_insn "*addqi_1_slp"
6094 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6095 (plus:QI (match_dup 0)
6096 (match_operand:QI 1 "general_operand" "qn,qnm")))
6097 (clobber (reg:CC FLAGS_REG))]
6098 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6099 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6101 switch (get_attr_type (insn))
6104 if (operands[1] == const1_rtx)
6105 return "inc{b}\t%0";
6108 gcc_assert (operands[1] == constm1_rtx);
6109 return "dec{b}\t%0";
6113 if (x86_maybe_negate_const_int (&operands[1], QImode))
6114 return "sub{b}\t{%1, %0|%0, %1}";
6116 return "add{b}\t{%1, %0|%0, %1}";
6120 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6121 (const_string "incdec")
6122 (const_string "alu1")))
6123 (set (attr "memory")
6124 (if_then_else (match_operand 1 "memory_operand" "")
6125 (const_string "load")
6126 (const_string "none")))
6127 (set_attr "mode" "QI")])
6129 (define_insn "*add<mode>_2"
6130 [(set (reg FLAGS_REG)
6133 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6134 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6136 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6137 (plus:SWI (match_dup 1) (match_dup 2)))]
6138 "ix86_match_ccmode (insn, CCGOCmode)
6139 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6141 switch (get_attr_type (insn))
6144 if (operands[2] == const1_rtx)
6145 return "inc{<imodesuffix>}\t%0";
6148 gcc_assert (operands[2] == constm1_rtx);
6149 return "dec{<imodesuffix>}\t%0";
6153 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6154 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6156 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6160 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6161 (const_string "incdec")
6162 (const_string "alu")))
6163 (set (attr "length_immediate")
6165 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6167 (const_string "*")))
6168 (set_attr "mode" "<MODE>")])
6170 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6171 (define_insn "*addsi_2_zext"
6172 [(set (reg FLAGS_REG)
6174 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6175 (match_operand:SI 2 "general_operand" "g"))
6177 (set (match_operand:DI 0 "register_operand" "=r")
6178 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6179 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6180 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6182 switch (get_attr_type (insn))
6185 if (operands[2] == const1_rtx)
6186 return "inc{l}\t%k0";
6189 gcc_assert (operands[2] == constm1_rtx);
6190 return "dec{l}\t%k0";
6194 if (x86_maybe_negate_const_int (&operands[2], SImode))
6195 return "sub{l}\t{%2, %k0|%k0, %2}";
6197 return "add{l}\t{%2, %k0|%k0, %2}";
6201 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6202 (const_string "incdec")
6203 (const_string "alu")))
6204 (set (attr "length_immediate")
6206 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6208 (const_string "*")))
6209 (set_attr "mode" "SI")])
6211 (define_insn "*add<mode>_3"
6212 [(set (reg FLAGS_REG)
6214 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6215 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6216 (clobber (match_scratch:SWI 0 "=<r>"))]
6217 "ix86_match_ccmode (insn, CCZmode)
6218 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6220 switch (get_attr_type (insn))
6223 if (operands[2] == const1_rtx)
6224 return "inc{<imodesuffix>}\t%0";
6227 gcc_assert (operands[2] == constm1_rtx);
6228 return "dec{<imodesuffix>}\t%0";
6232 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6233 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6235 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6239 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6240 (const_string "incdec")
6241 (const_string "alu")))
6242 (set (attr "length_immediate")
6244 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6246 (const_string "*")))
6247 (set_attr "mode" "<MODE>")])
6249 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6250 (define_insn "*addsi_3_zext"
6251 [(set (reg FLAGS_REG)
6253 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6254 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6255 (set (match_operand:DI 0 "register_operand" "=r")
6256 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6257 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6258 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6260 switch (get_attr_type (insn))
6263 if (operands[2] == const1_rtx)
6264 return "inc{l}\t%k0";
6267 gcc_assert (operands[2] == constm1_rtx);
6268 return "dec{l}\t%k0";
6272 if (x86_maybe_negate_const_int (&operands[2], SImode))
6273 return "sub{l}\t{%2, %k0|%k0, %2}";
6275 return "add{l}\t{%2, %k0|%k0, %2}";
6279 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6280 (const_string "incdec")
6281 (const_string "alu")))
6282 (set (attr "length_immediate")
6284 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6286 (const_string "*")))
6287 (set_attr "mode" "SI")])
6289 ; For comparisons against 1, -1 and 128, we may generate better code
6290 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6291 ; is matched then. We can't accept general immediate, because for
6292 ; case of overflows, the result is messed up.
6293 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6294 ; only for comparisons not depending on it.
6296 (define_insn "*adddi_4"
6297 [(set (reg FLAGS_REG)
6299 (match_operand:DI 1 "nonimmediate_operand" "0")
6300 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6301 (clobber (match_scratch:DI 0 "=rm"))]
6303 && ix86_match_ccmode (insn, CCGCmode)"
6305 switch (get_attr_type (insn))
6308 if (operands[2] == constm1_rtx)
6309 return "inc{q}\t%0";
6312 gcc_assert (operands[2] == const1_rtx);
6313 return "dec{q}\t%0";
6317 if (x86_maybe_negate_const_int (&operands[2], DImode))
6318 return "add{q}\t{%2, %0|%0, %2}";
6320 return "sub{q}\t{%2, %0|%0, %2}";
6324 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6325 (const_string "incdec")
6326 (const_string "alu")))
6327 (set (attr "length_immediate")
6329 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6331 (const_string "*")))
6332 (set_attr "mode" "DI")])
6334 ; For comparisons against 1, -1 and 128, we may generate better code
6335 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6336 ; is matched then. We can't accept general immediate, because for
6337 ; case of overflows, the result is messed up.
6338 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6339 ; only for comparisons not depending on it.
6341 (define_insn "*add<mode>_4"
6342 [(set (reg FLAGS_REG)
6344 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6345 (match_operand:SWI124 2 "const_int_operand" "n")))
6346 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6347 "ix86_match_ccmode (insn, CCGCmode)"
6349 switch (get_attr_type (insn))
6352 if (operands[2] == constm1_rtx)
6353 return "inc{<imodesuffix>}\t%0";
6356 gcc_assert (operands[2] == const1_rtx);
6357 return "dec{<imodesuffix>}\t%0";
6361 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6362 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6364 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6368 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6369 (const_string "incdec")
6370 (const_string "alu")))
6371 (set (attr "length_immediate")
6373 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6375 (const_string "*")))
6376 (set_attr "mode" "<MODE>")])
6378 (define_insn "*add<mode>_5"
6379 [(set (reg FLAGS_REG)
6382 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6383 (match_operand:SWI 2 "<general_operand>" "<g>"))
6385 (clobber (match_scratch:SWI 0 "=<r>"))]
6386 "ix86_match_ccmode (insn, CCGOCmode)
6387 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6389 switch (get_attr_type (insn))
6392 if (operands[2] == const1_rtx)
6393 return "inc{<imodesuffix>}\t%0";
6396 gcc_assert (operands[2] == constm1_rtx);
6397 return "dec{<imodesuffix>}\t%0";
6401 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6402 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6404 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6408 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6409 (const_string "incdec")
6410 (const_string "alu")))
6411 (set (attr "length_immediate")
6413 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6415 (const_string "*")))
6416 (set_attr "mode" "<MODE>")])
6418 (define_insn "*addqi_ext_1_rex64"
6419 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6424 (match_operand 1 "ext_register_operand" "0")
6427 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6428 (clobber (reg:CC FLAGS_REG))]
6431 switch (get_attr_type (insn))
6434 if (operands[2] == const1_rtx)
6435 return "inc{b}\t%h0";
6438 gcc_assert (operands[2] == constm1_rtx);
6439 return "dec{b}\t%h0";
6443 return "add{b}\t{%2, %h0|%h0, %2}";
6447 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6448 (const_string "incdec")
6449 (const_string "alu")))
6450 (set_attr "modrm" "1")
6451 (set_attr "mode" "QI")])
6453 (define_insn "addqi_ext_1"
6454 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6459 (match_operand 1 "ext_register_operand" "0")
6462 (match_operand:QI 2 "general_operand" "Qmn")))
6463 (clobber (reg:CC FLAGS_REG))]
6466 switch (get_attr_type (insn))
6469 if (operands[2] == const1_rtx)
6470 return "inc{b}\t%h0";
6473 gcc_assert (operands[2] == constm1_rtx);
6474 return "dec{b}\t%h0";
6478 return "add{b}\t{%2, %h0|%h0, %2}";
6482 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6483 (const_string "incdec")
6484 (const_string "alu")))
6485 (set_attr "modrm" "1")
6486 (set_attr "mode" "QI")])
6488 (define_insn "*addqi_ext_2"
6489 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6494 (match_operand 1 "ext_register_operand" "%0")
6498 (match_operand 2 "ext_register_operand" "Q")
6501 (clobber (reg:CC FLAGS_REG))]
6503 "add{b}\t{%h2, %h0|%h0, %h2}"
6504 [(set_attr "type" "alu")
6505 (set_attr "mode" "QI")])
6507 ;; The lea patterns for non-Pmodes needs to be matched by
6508 ;; several insns converted to real lea by splitters.
6510 (define_insn_and_split "*lea_general_1"
6511 [(set (match_operand 0 "register_operand" "=r")
6512 (plus (plus (match_operand 1 "index_register_operand" "l")
6513 (match_operand 2 "register_operand" "r"))
6514 (match_operand 3 "immediate_operand" "i")))]
6515 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6516 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6517 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6518 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6519 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6520 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6521 || GET_MODE (operands[3]) == VOIDmode)"
6523 "&& reload_completed"
6527 operands[0] = gen_lowpart (SImode, operands[0]);
6528 operands[1] = gen_lowpart (Pmode, operands[1]);
6529 operands[2] = gen_lowpart (Pmode, operands[2]);
6530 operands[3] = gen_lowpart (Pmode, operands[3]);
6531 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6533 if (Pmode != SImode)
6534 pat = gen_rtx_SUBREG (SImode, pat, 0);
6535 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6538 [(set_attr "type" "lea")
6539 (set_attr "mode" "SI")])
6541 (define_insn_and_split "*lea_general_1_zext"
6542 [(set (match_operand:DI 0 "register_operand" "=r")
6545 (match_operand:SI 1 "index_register_operand" "l")
6546 (match_operand:SI 2 "register_operand" "r"))
6547 (match_operand:SI 3 "immediate_operand" "i"))))]
6550 "&& reload_completed"
6552 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6554 (match_dup 3)) 0)))]
6556 operands[1] = gen_lowpart (Pmode, operands[1]);
6557 operands[2] = gen_lowpart (Pmode, operands[2]);
6558 operands[3] = gen_lowpart (Pmode, operands[3]);
6560 [(set_attr "type" "lea")
6561 (set_attr "mode" "SI")])
6563 (define_insn_and_split "*lea_general_2"
6564 [(set (match_operand 0 "register_operand" "=r")
6565 (plus (mult (match_operand 1 "index_register_operand" "l")
6566 (match_operand 2 "const248_operand" "i"))
6567 (match_operand 3 "nonmemory_operand" "ri")))]
6568 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6569 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6570 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6571 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6572 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6573 || GET_MODE (operands[3]) == VOIDmode)"
6575 "&& reload_completed"
6579 operands[0] = gen_lowpart (SImode, operands[0]);
6580 operands[1] = gen_lowpart (Pmode, operands[1]);
6581 operands[3] = gen_lowpart (Pmode, operands[3]);
6582 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6584 if (Pmode != SImode)
6585 pat = gen_rtx_SUBREG (SImode, pat, 0);
6586 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6589 [(set_attr "type" "lea")
6590 (set_attr "mode" "SI")])
6592 (define_insn_and_split "*lea_general_2_zext"
6593 [(set (match_operand:DI 0 "register_operand" "=r")
6596 (match_operand:SI 1 "index_register_operand" "l")
6597 (match_operand:SI 2 "const248_operand" "n"))
6598 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6601 "&& reload_completed"
6603 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6605 (match_dup 3)) 0)))]
6607 operands[1] = gen_lowpart (Pmode, operands[1]);
6608 operands[3] = gen_lowpart (Pmode, operands[3]);
6610 [(set_attr "type" "lea")
6611 (set_attr "mode" "SI")])
6613 (define_insn_and_split "*lea_general_3"
6614 [(set (match_operand 0 "register_operand" "=r")
6615 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6616 (match_operand 2 "const248_operand" "i"))
6617 (match_operand 3 "register_operand" "r"))
6618 (match_operand 4 "immediate_operand" "i")))]
6619 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6620 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6621 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6622 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6623 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6625 "&& reload_completed"
6629 operands[0] = gen_lowpart (SImode, operands[0]);
6630 operands[1] = gen_lowpart (Pmode, operands[1]);
6631 operands[3] = gen_lowpart (Pmode, operands[3]);
6632 operands[4] = gen_lowpart (Pmode, operands[4]);
6633 pat = gen_rtx_PLUS (Pmode,
6634 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6638 if (Pmode != SImode)
6639 pat = gen_rtx_SUBREG (SImode, pat, 0);
6640 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6643 [(set_attr "type" "lea")
6644 (set_attr "mode" "SI")])
6646 (define_insn_and_split "*lea_general_3_zext"
6647 [(set (match_operand:DI 0 "register_operand" "=r")
6651 (match_operand:SI 1 "index_register_operand" "l")
6652 (match_operand:SI 2 "const248_operand" "n"))
6653 (match_operand:SI 3 "register_operand" "r"))
6654 (match_operand:SI 4 "immediate_operand" "i"))))]
6657 "&& reload_completed"
6659 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6662 (match_dup 4)) 0)))]
6664 operands[1] = gen_lowpart (Pmode, operands[1]);
6665 operands[3] = gen_lowpart (Pmode, operands[3]);
6666 operands[4] = gen_lowpart (Pmode, operands[4]);
6668 [(set_attr "type" "lea")
6669 (set_attr "mode" "SI")])
6671 ;; Convert lea to the lea pattern to avoid flags dependency.
6673 [(set (match_operand:DI 0 "register_operand" "")
6674 (plus:DI (match_operand:DI 1 "register_operand" "")
6675 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6676 (clobber (reg:CC FLAGS_REG))]
6677 "TARGET_64BIT && reload_completed
6678 && ix86_lea_for_add_ok (PLUS, insn, operands)"
6680 (plus:DI (match_dup 1)
6684 ;; Convert lea to the lea pattern to avoid flags dependency.
6686 [(set (match_operand 0 "register_operand" "")
6687 (plus (match_operand 1 "register_operand" "")
6688 (match_operand 2 "nonmemory_operand" "")))
6689 (clobber (reg:CC FLAGS_REG))]
6690 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
6694 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6695 may confuse gen_lowpart. */
6696 if (GET_MODE (operands[0]) != Pmode)
6698 operands[1] = gen_lowpart (Pmode, operands[1]);
6699 operands[2] = gen_lowpart (Pmode, operands[2]);
6701 operands[0] = gen_lowpart (SImode, operands[0]);
6702 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6703 if (Pmode != SImode)
6704 pat = gen_rtx_SUBREG (SImode, pat, 0);
6705 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6709 ;; Convert lea to the lea pattern to avoid flags dependency.
6711 [(set (match_operand:DI 0 "register_operand" "")
6713 (plus:SI (match_operand:SI 1 "register_operand" "")
6714 (match_operand:SI 2 "nonmemory_operand" ""))))
6715 (clobber (reg:CC FLAGS_REG))]
6716 "TARGET_64BIT && reload_completed
6717 && true_regnum (operands[0]) != true_regnum (operands[1])"
6719 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6721 operands[1] = gen_lowpart (Pmode, operands[1]);
6722 operands[2] = gen_lowpart (Pmode, operands[2]);
6725 ;; Subtract instructions
6727 (define_expand "sub<mode>3"
6728 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6729 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6730 (match_operand:SDWIM 2 "<general_operand>" "")))]
6732 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6734 (define_insn_and_split "*sub<dwi>3_doubleword"
6735 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6737 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6738 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6739 (clobber (reg:CC FLAGS_REG))]
6740 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6743 [(parallel [(set (reg:CC FLAGS_REG)
6744 (compare:CC (match_dup 1) (match_dup 2)))
6746 (minus:DWIH (match_dup 1) (match_dup 2)))])
6747 (parallel [(set (match_dup 3)
6751 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6753 (clobber (reg:CC FLAGS_REG))])]
6754 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6756 (define_insn "*sub<mode>_1"
6757 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6759 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6760 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6761 (clobber (reg:CC FLAGS_REG))]
6762 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6763 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6764 [(set_attr "type" "alu")
6765 (set_attr "mode" "<MODE>")])
6767 (define_insn "*subsi_1_zext"
6768 [(set (match_operand:DI 0 "register_operand" "=r")
6770 (minus:SI (match_operand:SI 1 "register_operand" "0")
6771 (match_operand:SI 2 "general_operand" "g"))))
6772 (clobber (reg:CC FLAGS_REG))]
6773 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6774 "sub{l}\t{%2, %k0|%k0, %2}"
6775 [(set_attr "type" "alu")
6776 (set_attr "mode" "SI")])
6778 (define_insn "*subqi_1_slp"
6779 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6780 (minus:QI (match_dup 0)
6781 (match_operand:QI 1 "general_operand" "qn,qm")))
6782 (clobber (reg:CC FLAGS_REG))]
6783 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6784 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6785 "sub{b}\t{%1, %0|%0, %1}"
6786 [(set_attr "type" "alu1")
6787 (set_attr "mode" "QI")])
6789 (define_insn "*sub<mode>_2"
6790 [(set (reg FLAGS_REG)
6793 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6794 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6796 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6797 (minus:SWI (match_dup 1) (match_dup 2)))]
6798 "ix86_match_ccmode (insn, CCGOCmode)
6799 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6800 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6801 [(set_attr "type" "alu")
6802 (set_attr "mode" "<MODE>")])
6804 (define_insn "*subsi_2_zext"
6805 [(set (reg FLAGS_REG)
6807 (minus:SI (match_operand:SI 1 "register_operand" "0")
6808 (match_operand:SI 2 "general_operand" "g"))
6810 (set (match_operand:DI 0 "register_operand" "=r")
6812 (minus:SI (match_dup 1)
6814 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6815 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6816 "sub{l}\t{%2, %k0|%k0, %2}"
6817 [(set_attr "type" "alu")
6818 (set_attr "mode" "SI")])
6820 (define_insn "*sub<mode>_3"
6821 [(set (reg FLAGS_REG)
6822 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6823 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6824 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6825 (minus:SWI (match_dup 1) (match_dup 2)))]
6826 "ix86_match_ccmode (insn, CCmode)
6827 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6828 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6829 [(set_attr "type" "alu")
6830 (set_attr "mode" "<MODE>")])
6832 (define_insn "*subsi_3_zext"
6833 [(set (reg FLAGS_REG)
6834 (compare (match_operand:SI 1 "register_operand" "0")
6835 (match_operand:SI 2 "general_operand" "g")))
6836 (set (match_operand:DI 0 "register_operand" "=r")
6838 (minus:SI (match_dup 1)
6840 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6841 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6842 "sub{l}\t{%2, %1|%1, %2}"
6843 [(set_attr "type" "alu")
6844 (set_attr "mode" "SI")])
6846 ;; Add with carry and subtract with borrow
6848 (define_expand "<plusminus_insn><mode>3_carry"
6850 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6852 (match_operand:SWI 1 "nonimmediate_operand" "")
6853 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6854 [(match_operand 3 "flags_reg_operand" "")
6856 (match_operand:SWI 2 "<general_operand>" ""))))
6857 (clobber (reg:CC FLAGS_REG))])]
6858 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6861 (define_insn "*<plusminus_insn><mode>3_carry"
6862 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6864 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6866 (match_operator 3 "ix86_carry_flag_operator"
6867 [(reg FLAGS_REG) (const_int 0)])
6868 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6869 (clobber (reg:CC FLAGS_REG))]
6870 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6871 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6872 [(set_attr "type" "alu")
6873 (set_attr "use_carry" "1")
6874 (set_attr "pent_pair" "pu")
6875 (set_attr "mode" "<MODE>")])
6877 (define_insn "*addsi3_carry_zext"
6878 [(set (match_operand:DI 0 "register_operand" "=r")
6880 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6881 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6882 [(reg FLAGS_REG) (const_int 0)])
6883 (match_operand:SI 2 "general_operand" "g")))))
6884 (clobber (reg:CC FLAGS_REG))]
6885 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6886 "adc{l}\t{%2, %k0|%k0, %2}"
6887 [(set_attr "type" "alu")
6888 (set_attr "use_carry" "1")
6889 (set_attr "pent_pair" "pu")
6890 (set_attr "mode" "SI")])
6892 (define_insn "*subsi3_carry_zext"
6893 [(set (match_operand:DI 0 "register_operand" "=r")
6895 (minus:SI (match_operand:SI 1 "register_operand" "0")
6896 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6897 [(reg FLAGS_REG) (const_int 0)])
6898 (match_operand:SI 2 "general_operand" "g")))))
6899 (clobber (reg:CC FLAGS_REG))]
6900 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6901 "sbb{l}\t{%2, %k0|%k0, %2}"
6902 [(set_attr "type" "alu")
6903 (set_attr "pent_pair" "pu")
6904 (set_attr "mode" "SI")])
6906 ;; Overflow setting add and subtract instructions
6908 (define_insn "*add<mode>3_cconly_overflow"
6909 [(set (reg:CCC FLAGS_REG)
6912 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6913 (match_operand:SWI 2 "<general_operand>" "<g>"))
6915 (clobber (match_scratch:SWI 0 "=<r>"))]
6916 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6917 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6918 [(set_attr "type" "alu")
6919 (set_attr "mode" "<MODE>")])
6921 (define_insn "*sub<mode>3_cconly_overflow"
6922 [(set (reg:CCC FLAGS_REG)
6925 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6926 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6929 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6930 [(set_attr "type" "icmp")
6931 (set_attr "mode" "<MODE>")])
6933 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6934 [(set (reg:CCC FLAGS_REG)
6937 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6938 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6940 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6941 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6942 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6943 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6944 [(set_attr "type" "alu")
6945 (set_attr "mode" "<MODE>")])
6947 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6948 [(set (reg:CCC FLAGS_REG)
6951 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6952 (match_operand:SI 2 "general_operand" "g"))
6954 (set (match_operand:DI 0 "register_operand" "=r")
6955 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6956 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6957 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6958 [(set_attr "type" "alu")
6959 (set_attr "mode" "SI")])
6961 ;; The patterns that match these are at the end of this file.
6963 (define_expand "<plusminus_insn>xf3"
6964 [(set (match_operand:XF 0 "register_operand" "")
6966 (match_operand:XF 1 "register_operand" "")
6967 (match_operand:XF 2 "register_operand" "")))]
6971 (define_expand "<plusminus_insn><mode>3"
6972 [(set (match_operand:MODEF 0 "register_operand" "")
6974 (match_operand:MODEF 1 "register_operand" "")
6975 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6976 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6977 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6980 ;; Multiply instructions
6982 (define_expand "mul<mode>3"
6983 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6985 (match_operand:SWIM248 1 "register_operand" "")
6986 (match_operand:SWIM248 2 "<general_operand>" "")))
6987 (clobber (reg:CC FLAGS_REG))])]
6991 (define_expand "mulqi3"
6992 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6994 (match_operand:QI 1 "register_operand" "")
6995 (match_operand:QI 2 "nonimmediate_operand" "")))
6996 (clobber (reg:CC FLAGS_REG))])]
6997 "TARGET_QIMODE_MATH"
7001 ;; IMUL reg32/64, reg32/64, imm8 Direct
7002 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7003 ;; IMUL reg32/64, reg32/64, imm32 Direct
7004 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7005 ;; IMUL reg32/64, reg32/64 Direct
7006 ;; IMUL reg32/64, mem32/64 Direct
7008 (define_insn "*mul<mode>3_1"
7009 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7011 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7012 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7013 (clobber (reg:CC FLAGS_REG))]
7014 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7016 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7017 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7018 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7019 [(set_attr "type" "imul")
7020 (set_attr "prefix_0f" "0,0,1")
7021 (set (attr "athlon_decode")
7022 (cond [(eq_attr "cpu" "athlon")
7023 (const_string "vector")
7024 (eq_attr "alternative" "1")
7025 (const_string "vector")
7026 (and (eq_attr "alternative" "2")
7027 (match_operand 1 "memory_operand" ""))
7028 (const_string "vector")]
7029 (const_string "direct")))
7030 (set (attr "amdfam10_decode")
7031 (cond [(and (eq_attr "alternative" "0,1")
7032 (match_operand 1 "memory_operand" ""))
7033 (const_string "vector")]
7034 (const_string "direct")))
7035 (set_attr "mode" "<MODE>")])
7037 (define_insn "*mulsi3_1_zext"
7038 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7040 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7041 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7042 (clobber (reg:CC FLAGS_REG))]
7044 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7046 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7047 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7048 imul{l}\t{%2, %k0|%k0, %2}"
7049 [(set_attr "type" "imul")
7050 (set_attr "prefix_0f" "0,0,1")
7051 (set (attr "athlon_decode")
7052 (cond [(eq_attr "cpu" "athlon")
7053 (const_string "vector")
7054 (eq_attr "alternative" "1")
7055 (const_string "vector")
7056 (and (eq_attr "alternative" "2")
7057 (match_operand 1 "memory_operand" ""))
7058 (const_string "vector")]
7059 (const_string "direct")))
7060 (set (attr "amdfam10_decode")
7061 (cond [(and (eq_attr "alternative" "0,1")
7062 (match_operand 1 "memory_operand" ""))
7063 (const_string "vector")]
7064 (const_string "direct")))
7065 (set_attr "mode" "SI")])
7068 ;; IMUL reg16, reg16, imm8 VectorPath
7069 ;; IMUL reg16, mem16, imm8 VectorPath
7070 ;; IMUL reg16, reg16, imm16 VectorPath
7071 ;; IMUL reg16, mem16, imm16 VectorPath
7072 ;; IMUL reg16, reg16 Direct
7073 ;; IMUL reg16, mem16 Direct
7075 (define_insn "*mulhi3_1"
7076 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7077 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7078 (match_operand:HI 2 "general_operand" "K,n,mr")))
7079 (clobber (reg:CC FLAGS_REG))]
7081 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7083 imul{w}\t{%2, %1, %0|%0, %1, %2}
7084 imul{w}\t{%2, %1, %0|%0, %1, %2}
7085 imul{w}\t{%2, %0|%0, %2}"
7086 [(set_attr "type" "imul")
7087 (set_attr "prefix_0f" "0,0,1")
7088 (set (attr "athlon_decode")
7089 (cond [(eq_attr "cpu" "athlon")
7090 (const_string "vector")
7091 (eq_attr "alternative" "1,2")
7092 (const_string "vector")]
7093 (const_string "direct")))
7094 (set (attr "amdfam10_decode")
7095 (cond [(eq_attr "alternative" "0,1")
7096 (const_string "vector")]
7097 (const_string "direct")))
7098 (set_attr "mode" "HI")])
7104 (define_insn "*mulqi3_1"
7105 [(set (match_operand:QI 0 "register_operand" "=a")
7106 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7107 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7108 (clobber (reg:CC FLAGS_REG))]
7110 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7112 [(set_attr "type" "imul")
7113 (set_attr "length_immediate" "0")
7114 (set (attr "athlon_decode")
7115 (if_then_else (eq_attr "cpu" "athlon")
7116 (const_string "vector")
7117 (const_string "direct")))
7118 (set_attr "amdfam10_decode" "direct")
7119 (set_attr "mode" "QI")])
7121 (define_expand "<u>mul<mode><dwi>3"
7122 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7125 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7127 (match_operand:DWIH 2 "register_operand" ""))))
7128 (clobber (reg:CC FLAGS_REG))])]
7132 (define_expand "<u>mulqihi3"
7133 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7136 (match_operand:QI 1 "nonimmediate_operand" ""))
7138 (match_operand:QI 2 "register_operand" ""))))
7139 (clobber (reg:CC FLAGS_REG))])]
7140 "TARGET_QIMODE_MATH"
7143 (define_insn "*<u>mul<mode><dwi>3_1"
7144 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7147 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7149 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7150 (clobber (reg:CC FLAGS_REG))]
7151 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7152 "<sgnprefix>mul{<imodesuffix>}\t%2"
7153 [(set_attr "type" "imul")
7154 (set_attr "length_immediate" "0")
7155 (set (attr "athlon_decode")
7156 (if_then_else (eq_attr "cpu" "athlon")
7157 (const_string "vector")
7158 (const_string "double")))
7159 (set_attr "amdfam10_decode" "double")
7160 (set_attr "mode" "<MODE>")])
7162 (define_insn "*<u>mulqihi3_1"
7163 [(set (match_operand:HI 0 "register_operand" "=a")
7166 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7168 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7169 (clobber (reg:CC FLAGS_REG))]
7171 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7172 "<sgnprefix>mul{b}\t%2"
7173 [(set_attr "type" "imul")
7174 (set_attr "length_immediate" "0")
7175 (set (attr "athlon_decode")
7176 (if_then_else (eq_attr "cpu" "athlon")
7177 (const_string "vector")
7178 (const_string "direct")))
7179 (set_attr "amdfam10_decode" "direct")
7180 (set_attr "mode" "QI")])
7182 (define_expand "<s>mul<mode>3_highpart"
7183 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7188 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7190 (match_operand:SWI48 2 "register_operand" "")))
7192 (clobber (match_scratch:SWI48 3 ""))
7193 (clobber (reg:CC FLAGS_REG))])]
7195 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7197 (define_insn "*<s>muldi3_highpart_1"
7198 [(set (match_operand:DI 0 "register_operand" "=d")
7203 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7205 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7207 (clobber (match_scratch:DI 3 "=1"))
7208 (clobber (reg:CC FLAGS_REG))]
7210 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7211 "<sgnprefix>mul{q}\t%2"
7212 [(set_attr "type" "imul")
7213 (set_attr "length_immediate" "0")
7214 (set (attr "athlon_decode")
7215 (if_then_else (eq_attr "cpu" "athlon")
7216 (const_string "vector")
7217 (const_string "double")))
7218 (set_attr "amdfam10_decode" "double")
7219 (set_attr "mode" "DI")])
7221 (define_insn "*<s>mulsi3_highpart_1"
7222 [(set (match_operand:SI 0 "register_operand" "=d")
7227 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7229 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7231 (clobber (match_scratch:SI 3 "=1"))
7232 (clobber (reg:CC FLAGS_REG))]
7233 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7234 "<sgnprefix>mul{l}\t%2"
7235 [(set_attr "type" "imul")
7236 (set_attr "length_immediate" "0")
7237 (set (attr "athlon_decode")
7238 (if_then_else (eq_attr "cpu" "athlon")
7239 (const_string "vector")
7240 (const_string "double")))
7241 (set_attr "amdfam10_decode" "double")
7242 (set_attr "mode" "SI")])
7244 (define_insn "*<s>mulsi3_highpart_zext"
7245 [(set (match_operand:DI 0 "register_operand" "=d")
7246 (zero_extend:DI (truncate:SI
7248 (mult:DI (any_extend:DI
7249 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7251 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7253 (clobber (match_scratch:SI 3 "=1"))
7254 (clobber (reg:CC FLAGS_REG))]
7256 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7257 "<sgnprefix>mul{l}\t%2"
7258 [(set_attr "type" "imul")
7259 (set_attr "length_immediate" "0")
7260 (set (attr "athlon_decode")
7261 (if_then_else (eq_attr "cpu" "athlon")
7262 (const_string "vector")
7263 (const_string "double")))
7264 (set_attr "amdfam10_decode" "double")
7265 (set_attr "mode" "SI")])
7267 ;; The patterns that match these are at the end of this file.
7269 (define_expand "mulxf3"
7270 [(set (match_operand:XF 0 "register_operand" "")
7271 (mult:XF (match_operand:XF 1 "register_operand" "")
7272 (match_operand:XF 2 "register_operand" "")))]
7276 (define_expand "mul<mode>3"
7277 [(set (match_operand:MODEF 0 "register_operand" "")
7278 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7279 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7280 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7281 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7284 ;; Divide instructions
7286 ;; The patterns that match these are at the end of this file.
7288 (define_expand "divxf3"
7289 [(set (match_operand:XF 0 "register_operand" "")
7290 (div:XF (match_operand:XF 1 "register_operand" "")
7291 (match_operand:XF 2 "register_operand" "")))]
7295 (define_expand "divdf3"
7296 [(set (match_operand:DF 0 "register_operand" "")
7297 (div:DF (match_operand:DF 1 "register_operand" "")
7298 (match_operand:DF 2 "nonimmediate_operand" "")))]
7299 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7300 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7303 (define_expand "divsf3"
7304 [(set (match_operand:SF 0 "register_operand" "")
7305 (div:SF (match_operand:SF 1 "register_operand" "")
7306 (match_operand:SF 2 "nonimmediate_operand" "")))]
7307 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7310 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7311 && flag_finite_math_only && !flag_trapping_math
7312 && flag_unsafe_math_optimizations)
7314 ix86_emit_swdivsf (operands[0], operands[1],
7315 operands[2], SFmode);
7320 ;; Divmod instructions.
7322 (define_expand "divmodqi4"
7323 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7325 (match_operand:QI 1 "register_operand" "")
7326 (match_operand:QI 2 "nonimmediate_operand" "")))
7327 (set (match_operand:QI 3 "register_operand" "")
7328 (mod:QI (match_dup 1) (match_dup 2)))
7329 (clobber (reg:CC FLAGS_REG))])]
7330 "TARGET_QIMODE_MATH"
7335 tmp0 = gen_reg_rtx (HImode);
7336 tmp1 = gen_reg_rtx (HImode);
7338 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7340 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7341 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7343 /* Extract remainder from AH. */
7344 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7345 insn = emit_move_insn (operands[3], tmp1);
7347 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7348 set_unique_reg_note (insn, REG_EQUAL, mod);
7350 /* Extract quotient from AL. */
7351 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7353 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7354 set_unique_reg_note (insn, REG_EQUAL, div);
7359 (define_expand "udivmodqi4"
7360 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7362 (match_operand:QI 1 "register_operand" "")
7363 (match_operand:QI 2 "nonimmediate_operand" "")))
7364 (set (match_operand:QI 3 "register_operand" "")
7365 (umod:QI (match_dup 1) (match_dup 2)))
7366 (clobber (reg:CC FLAGS_REG))])]
7367 "TARGET_QIMODE_MATH"
7372 tmp0 = gen_reg_rtx (HImode);
7373 tmp1 = gen_reg_rtx (HImode);
7375 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7377 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7378 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7380 /* Extract remainder from AH. */
7381 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7382 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7383 insn = emit_move_insn (operands[3], tmp1);
7385 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7386 set_unique_reg_note (insn, REG_EQUAL, mod);
7388 /* Extract quotient from AL. */
7389 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7391 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7392 set_unique_reg_note (insn, REG_EQUAL, div);
7397 ;; Divide AX by r/m8, with result stored in
7400 ;; Change div/mod to HImode and extend the second argument to HImode
7401 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7402 ;; combine may fail.
7403 (define_insn "divmodhiqi3"
7404 [(set (match_operand:HI 0 "register_operand" "=a")
7409 (mod:HI (match_operand:HI 1 "register_operand" "0")
7411 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7415 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7416 (clobber (reg:CC FLAGS_REG))]
7417 "TARGET_QIMODE_MATH"
7419 [(set_attr "type" "idiv")
7420 (set_attr "mode" "QI")])
7422 (define_insn "udivmodhiqi3"
7423 [(set (match_operand:HI 0 "register_operand" "=a")
7428 (mod:HI (match_operand:HI 1 "register_operand" "0")
7430 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7434 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7435 (clobber (reg:CC FLAGS_REG))]
7436 "TARGET_QIMODE_MATH"
7438 [(set_attr "type" "idiv")
7439 (set_attr "mode" "QI")])
7441 (define_expand "divmod<mode>4"
7442 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7444 (match_operand:SWIM248 1 "register_operand" "")
7445 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7446 (set (match_operand:SWIM248 3 "register_operand" "")
7447 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7448 (clobber (reg:CC FLAGS_REG))])]
7452 (define_insn_and_split "*divmod<mode>4"
7453 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7454 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7455 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7456 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7457 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7458 (clobber (reg:CC FLAGS_REG))]
7462 [(parallel [(set (match_dup 1)
7463 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7464 (clobber (reg:CC FLAGS_REG))])
7465 (parallel [(set (match_dup 0)
7466 (div:SWIM248 (match_dup 2) (match_dup 3)))
7468 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7470 (clobber (reg:CC FLAGS_REG))])]
7472 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7474 if (<MODE>mode != HImode
7475 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7476 operands[4] = operands[2];
7479 /* Avoid use of cltd in favor of a mov+shift. */
7480 emit_move_insn (operands[1], operands[2]);
7481 operands[4] = operands[1];
7484 [(set_attr "type" "multi")
7485 (set_attr "mode" "<MODE>")])
7487 (define_insn "*divmod<mode>4_noext"
7488 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7489 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7490 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7491 (set (match_operand:SWIM248 1 "register_operand" "=d")
7492 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7493 (use (match_operand:SWIM248 4 "register_operand" "1"))
7494 (clobber (reg:CC FLAGS_REG))]
7496 "idiv{<imodesuffix>}\t%3"
7497 [(set_attr "type" "idiv")
7498 (set_attr "mode" "<MODE>")])
7500 (define_expand "udivmod<mode>4"
7501 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7503 (match_operand:SWIM248 1 "register_operand" "")
7504 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7505 (set (match_operand:SWIM248 3 "register_operand" "")
7506 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7507 (clobber (reg:CC FLAGS_REG))])]
7511 (define_insn_and_split "*udivmod<mode>4"
7512 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7513 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7514 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7515 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7516 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7517 (clobber (reg:CC FLAGS_REG))]
7521 [(set (match_dup 1) (const_int 0))
7522 (parallel [(set (match_dup 0)
7523 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7525 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7527 (clobber (reg:CC FLAGS_REG))])]
7529 [(set_attr "type" "multi")
7530 (set_attr "mode" "<MODE>")])
7532 (define_insn "*udivmod<mode>4_noext"
7533 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7534 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7535 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7536 (set (match_operand:SWIM248 1 "register_operand" "=d")
7537 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7538 (use (match_operand:SWIM248 4 "register_operand" "1"))
7539 (clobber (reg:CC FLAGS_REG))]
7541 "div{<imodesuffix>}\t%3"
7542 [(set_attr "type" "idiv")
7543 (set_attr "mode" "<MODE>")])
7545 ;; We cannot use div/idiv for double division, because it causes
7546 ;; "division by zero" on the overflow and that's not what we expect
7547 ;; from truncate. Because true (non truncating) double division is
7548 ;; never generated, we can't create this insn anyway.
7551 ; [(set (match_operand:SI 0 "register_operand" "=a")
7553 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7555 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7556 ; (set (match_operand:SI 3 "register_operand" "=d")
7558 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7559 ; (clobber (reg:CC FLAGS_REG))]
7561 ; "div{l}\t{%2, %0|%0, %2}"
7562 ; [(set_attr "type" "idiv")])
7564 ;;- Logical AND instructions
7566 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7567 ;; Note that this excludes ah.
7569 (define_expand "testsi_ccno_1"
7570 [(set (reg:CCNO FLAGS_REG)
7572 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7573 (match_operand:SI 1 "nonmemory_operand" ""))
7578 (define_expand "testqi_ccz_1"
7579 [(set (reg:CCZ FLAGS_REG)
7580 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7581 (match_operand:QI 1 "nonmemory_operand" ""))
7586 (define_insn "*testdi_1"
7587 [(set (reg FLAGS_REG)
7590 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7591 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7593 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7594 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7596 test{l}\t{%k1, %k0|%k0, %k1}
7597 test{l}\t{%k1, %k0|%k0, %k1}
7598 test{q}\t{%1, %0|%0, %1}
7599 test{q}\t{%1, %0|%0, %1}
7600 test{q}\t{%1, %0|%0, %1}"
7601 [(set_attr "type" "test")
7602 (set_attr "modrm" "0,1,0,1,1")
7603 (set_attr "mode" "SI,SI,DI,DI,DI")])
7605 (define_insn "*testqi_1_maybe_si"
7606 [(set (reg FLAGS_REG)
7609 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7610 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7612 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7613 && ix86_match_ccmode (insn,
7614 CONST_INT_P (operands[1])
7615 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7617 if (which_alternative == 3)
7619 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7620 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7621 return "test{l}\t{%1, %k0|%k0, %1}";
7623 return "test{b}\t{%1, %0|%0, %1}";
7625 [(set_attr "type" "test")
7626 (set_attr "modrm" "0,1,1,1")
7627 (set_attr "mode" "QI,QI,QI,SI")
7628 (set_attr "pent_pair" "uv,np,uv,np")])
7630 (define_insn "*test<mode>_1"
7631 [(set (reg FLAGS_REG)
7634 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7635 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7637 "ix86_match_ccmode (insn, CCNOmode)
7638 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7639 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7640 [(set_attr "type" "test")
7641 (set_attr "modrm" "0,1,1")
7642 (set_attr "mode" "<MODE>")
7643 (set_attr "pent_pair" "uv,np,uv")])
7645 (define_expand "testqi_ext_ccno_0"
7646 [(set (reg:CCNO FLAGS_REG)
7650 (match_operand 0 "ext_register_operand" "")
7653 (match_operand 1 "const_int_operand" ""))
7658 (define_insn "*testqi_ext_0"
7659 [(set (reg FLAGS_REG)
7663 (match_operand 0 "ext_register_operand" "Q")
7666 (match_operand 1 "const_int_operand" "n"))
7668 "ix86_match_ccmode (insn, CCNOmode)"
7669 "test{b}\t{%1, %h0|%h0, %1}"
7670 [(set_attr "type" "test")
7671 (set_attr "mode" "QI")
7672 (set_attr "length_immediate" "1")
7673 (set_attr "modrm" "1")
7674 (set_attr "pent_pair" "np")])
7676 (define_insn "*testqi_ext_1_rex64"
7677 [(set (reg FLAGS_REG)
7681 (match_operand 0 "ext_register_operand" "Q")
7685 (match_operand:QI 1 "register_operand" "Q")))
7687 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7688 "test{b}\t{%1, %h0|%h0, %1}"
7689 [(set_attr "type" "test")
7690 (set_attr "mode" "QI")])
7692 (define_insn "*testqi_ext_1"
7693 [(set (reg FLAGS_REG)
7697 (match_operand 0 "ext_register_operand" "Q")
7701 (match_operand:QI 1 "general_operand" "Qm")))
7703 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7704 "test{b}\t{%1, %h0|%h0, %1}"
7705 [(set_attr "type" "test")
7706 (set_attr "mode" "QI")])
7708 (define_insn "*testqi_ext_2"
7709 [(set (reg FLAGS_REG)
7713 (match_operand 0 "ext_register_operand" "Q")
7717 (match_operand 1 "ext_register_operand" "Q")
7721 "ix86_match_ccmode (insn, CCNOmode)"
7722 "test{b}\t{%h1, %h0|%h0, %h1}"
7723 [(set_attr "type" "test")
7724 (set_attr "mode" "QI")])
7726 (define_insn "*testqi_ext_3_rex64"
7727 [(set (reg FLAGS_REG)
7728 (compare (zero_extract:DI
7729 (match_operand 0 "nonimmediate_operand" "rm")
7730 (match_operand:DI 1 "const_int_operand" "")
7731 (match_operand:DI 2 "const_int_operand" ""))
7734 && ix86_match_ccmode (insn, CCNOmode)
7735 && INTVAL (operands[1]) > 0
7736 && INTVAL (operands[2]) >= 0
7737 /* Ensure that resulting mask is zero or sign extended operand. */
7738 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7739 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7740 && INTVAL (operands[1]) > 32))
7741 && (GET_MODE (operands[0]) == SImode
7742 || GET_MODE (operands[0]) == DImode
7743 || GET_MODE (operands[0]) == HImode
7744 || GET_MODE (operands[0]) == QImode)"
7747 ;; Combine likes to form bit extractions for some tests. Humor it.
7748 (define_insn "*testqi_ext_3"
7749 [(set (reg FLAGS_REG)
7750 (compare (zero_extract:SI
7751 (match_operand 0 "nonimmediate_operand" "rm")
7752 (match_operand:SI 1 "const_int_operand" "")
7753 (match_operand:SI 2 "const_int_operand" ""))
7755 "ix86_match_ccmode (insn, CCNOmode)
7756 && INTVAL (operands[1]) > 0
7757 && INTVAL (operands[2]) >= 0
7758 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7759 && (GET_MODE (operands[0]) == SImode
7760 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7761 || GET_MODE (operands[0]) == HImode
7762 || GET_MODE (operands[0]) == QImode)"
7766 [(set (match_operand 0 "flags_reg_operand" "")
7767 (match_operator 1 "compare_operator"
7769 (match_operand 2 "nonimmediate_operand" "")
7770 (match_operand 3 "const_int_operand" "")
7771 (match_operand 4 "const_int_operand" ""))
7773 "ix86_match_ccmode (insn, CCNOmode)"
7774 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7776 rtx val = operands[2];
7777 HOST_WIDE_INT len = INTVAL (operands[3]);
7778 HOST_WIDE_INT pos = INTVAL (operands[4]);
7780 enum machine_mode mode, submode;
7782 mode = GET_MODE (val);
7785 /* ??? Combine likes to put non-volatile mem extractions in QImode
7786 no matter the size of the test. So find a mode that works. */
7787 if (! MEM_VOLATILE_P (val))
7789 mode = smallest_mode_for_size (pos + len, MODE_INT);
7790 val = adjust_address (val, mode, 0);
7793 else if (GET_CODE (val) == SUBREG
7794 && (submode = GET_MODE (SUBREG_REG (val)),
7795 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7796 && pos + len <= GET_MODE_BITSIZE (submode)
7797 && GET_MODE_CLASS (submode) == MODE_INT)
7799 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7801 val = SUBREG_REG (val);
7803 else if (mode == HImode && pos + len <= 8)
7805 /* Small HImode tests can be converted to QImode. */
7807 val = gen_lowpart (QImode, val);
7810 if (len == HOST_BITS_PER_WIDE_INT)
7813 mask = ((HOST_WIDE_INT)1 << len) - 1;
7816 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7819 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7820 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7821 ;; this is relatively important trick.
7822 ;; Do the conversion only post-reload to avoid limiting of the register class
7825 [(set (match_operand 0 "flags_reg_operand" "")
7826 (match_operator 1 "compare_operator"
7827 [(and (match_operand 2 "register_operand" "")
7828 (match_operand 3 "const_int_operand" ""))
7831 && QI_REG_P (operands[2])
7832 && GET_MODE (operands[2]) != QImode
7833 && ((ix86_match_ccmode (insn, CCZmode)
7834 && !(INTVAL (operands[3]) & ~(255 << 8)))
7835 || (ix86_match_ccmode (insn, CCNOmode)
7836 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7839 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7842 "operands[2] = gen_lowpart (SImode, operands[2]);
7843 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7846 [(set (match_operand 0 "flags_reg_operand" "")
7847 (match_operator 1 "compare_operator"
7848 [(and (match_operand 2 "nonimmediate_operand" "")
7849 (match_operand 3 "const_int_operand" ""))
7852 && GET_MODE (operands[2]) != QImode
7853 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7854 && ((ix86_match_ccmode (insn, CCZmode)
7855 && !(INTVAL (operands[3]) & ~255))
7856 || (ix86_match_ccmode (insn, CCNOmode)
7857 && !(INTVAL (operands[3]) & ~127)))"
7859 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7861 "operands[2] = gen_lowpart (QImode, operands[2]);
7862 operands[3] = gen_lowpart (QImode, operands[3]);")
7864 ;; %%% This used to optimize known byte-wide and operations to memory,
7865 ;; and sometimes to QImode registers. If this is considered useful,
7866 ;; it should be done with splitters.
7868 (define_expand "and<mode>3"
7869 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7870 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7871 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7873 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7875 (define_insn "*anddi_1"
7876 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7878 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7879 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7880 (clobber (reg:CC FLAGS_REG))]
7881 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7883 switch (get_attr_type (insn))
7887 enum machine_mode mode;
7889 gcc_assert (CONST_INT_P (operands[2]));
7890 if (INTVAL (operands[2]) == 0xff)
7894 gcc_assert (INTVAL (operands[2]) == 0xffff);
7898 operands[1] = gen_lowpart (mode, operands[1]);
7900 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7902 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7906 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7907 if (get_attr_mode (insn) == MODE_SI)
7908 return "and{l}\t{%k2, %k0|%k0, %k2}";
7910 return "and{q}\t{%2, %0|%0, %2}";
7913 [(set_attr "type" "alu,alu,alu,imovx")
7914 (set_attr "length_immediate" "*,*,*,0")
7915 (set (attr "prefix_rex")
7917 (and (eq_attr "type" "imovx")
7918 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7919 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7921 (const_string "*")))
7922 (set_attr "mode" "SI,DI,DI,SI")])
7924 (define_insn "*andsi_1"
7925 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7926 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7927 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7928 (clobber (reg:CC FLAGS_REG))]
7929 "ix86_binary_operator_ok (AND, SImode, operands)"
7931 switch (get_attr_type (insn))
7935 enum machine_mode mode;
7937 gcc_assert (CONST_INT_P (operands[2]));
7938 if (INTVAL (operands[2]) == 0xff)
7942 gcc_assert (INTVAL (operands[2]) == 0xffff);
7946 operands[1] = gen_lowpart (mode, operands[1]);
7948 return "movz{bl|x}\t{%1, %0|%0, %1}";
7950 return "movz{wl|x}\t{%1, %0|%0, %1}";
7954 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7955 return "and{l}\t{%2, %0|%0, %2}";
7958 [(set_attr "type" "alu,alu,imovx")
7959 (set (attr "prefix_rex")
7961 (and (eq_attr "type" "imovx")
7962 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7963 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7965 (const_string "*")))
7966 (set_attr "length_immediate" "*,*,0")
7967 (set_attr "mode" "SI")])
7969 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7970 (define_insn "*andsi_1_zext"
7971 [(set (match_operand:DI 0 "register_operand" "=r")
7973 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7974 (match_operand:SI 2 "general_operand" "g"))))
7975 (clobber (reg:CC FLAGS_REG))]
7976 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7977 "and{l}\t{%2, %k0|%k0, %2}"
7978 [(set_attr "type" "alu")
7979 (set_attr "mode" "SI")])
7981 (define_insn "*andhi_1"
7982 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7983 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7984 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7985 (clobber (reg:CC FLAGS_REG))]
7986 "ix86_binary_operator_ok (AND, HImode, operands)"
7988 switch (get_attr_type (insn))
7991 gcc_assert (CONST_INT_P (operands[2]));
7992 gcc_assert (INTVAL (operands[2]) == 0xff);
7993 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7996 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7998 return "and{w}\t{%2, %0|%0, %2}";
8001 [(set_attr "type" "alu,alu,imovx")
8002 (set_attr "length_immediate" "*,*,0")
8003 (set (attr "prefix_rex")
8005 (and (eq_attr "type" "imovx")
8006 (match_operand 1 "ext_QIreg_nomode_operand" ""))
8008 (const_string "*")))
8009 (set_attr "mode" "HI,HI,SI")])
8011 ;; %%% Potential partial reg stall on alternative 2. What to do?
8012 (define_insn "*andqi_1"
8013 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8014 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8015 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8016 (clobber (reg:CC FLAGS_REG))]
8017 "ix86_binary_operator_ok (AND, QImode, operands)"
8019 and{b}\t{%2, %0|%0, %2}
8020 and{b}\t{%2, %0|%0, %2}
8021 and{l}\t{%k2, %k0|%k0, %k2}"
8022 [(set_attr "type" "alu")
8023 (set_attr "mode" "QI,QI,SI")])
8025 (define_insn "*andqi_1_slp"
8026 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8027 (and:QI (match_dup 0)
8028 (match_operand:QI 1 "general_operand" "qn,qmn")))
8029 (clobber (reg:CC FLAGS_REG))]
8030 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8031 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8032 "and{b}\t{%1, %0|%0, %1}"
8033 [(set_attr "type" "alu1")
8034 (set_attr "mode" "QI")])
8037 [(set (match_operand 0 "register_operand" "")
8039 (const_int -65536)))
8040 (clobber (reg:CC FLAGS_REG))]
8041 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8042 || optimize_function_for_size_p (cfun)"
8043 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8044 "operands[1] = gen_lowpart (HImode, operands[0]);")
8047 [(set (match_operand 0 "ext_register_operand" "")
8050 (clobber (reg:CC FLAGS_REG))]
8051 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8052 && reload_completed"
8053 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8054 "operands[1] = gen_lowpart (QImode, operands[0]);")
8057 [(set (match_operand 0 "ext_register_operand" "")
8059 (const_int -65281)))
8060 (clobber (reg:CC FLAGS_REG))]
8061 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8062 && reload_completed"
8063 [(parallel [(set (zero_extract:SI (match_dup 0)
8067 (zero_extract:SI (match_dup 0)
8070 (zero_extract:SI (match_dup 0)
8073 (clobber (reg:CC FLAGS_REG))])]
8074 "operands[0] = gen_lowpart (SImode, operands[0]);")
8076 (define_insn "*anddi_2"
8077 [(set (reg FLAGS_REG)
8080 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8081 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8083 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8084 (and:DI (match_dup 1) (match_dup 2)))]
8085 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8086 && ix86_binary_operator_ok (AND, DImode, operands)"
8088 and{l}\t{%k2, %k0|%k0, %k2}
8089 and{q}\t{%2, %0|%0, %2}
8090 and{q}\t{%2, %0|%0, %2}"
8091 [(set_attr "type" "alu")
8092 (set_attr "mode" "SI,DI,DI")])
8094 (define_insn "*andqi_2_maybe_si"
8095 [(set (reg FLAGS_REG)
8097 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8098 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8100 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8101 (and:QI (match_dup 1) (match_dup 2)))]
8102 "ix86_binary_operator_ok (AND, QImode, operands)
8103 && ix86_match_ccmode (insn,
8104 CONST_INT_P (operands[2])
8105 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8107 if (which_alternative == 2)
8109 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8110 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8111 return "and{l}\t{%2, %k0|%k0, %2}";
8113 return "and{b}\t{%2, %0|%0, %2}";
8115 [(set_attr "type" "alu")
8116 (set_attr "mode" "QI,QI,SI")])
8118 (define_insn "*and<mode>_2"
8119 [(set (reg FLAGS_REG)
8120 (compare (and:SWI124
8121 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8122 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8124 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8125 (and:SWI124 (match_dup 1) (match_dup 2)))]
8126 "ix86_match_ccmode (insn, CCNOmode)
8127 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8128 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8129 [(set_attr "type" "alu")
8130 (set_attr "mode" "<MODE>")])
8132 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8133 (define_insn "*andsi_2_zext"
8134 [(set (reg FLAGS_REG)
8136 (match_operand:SI 1 "nonimmediate_operand" "%0")
8137 (match_operand:SI 2 "general_operand" "g"))
8139 (set (match_operand:DI 0 "register_operand" "=r")
8140 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8141 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8142 && ix86_binary_operator_ok (AND, SImode, operands)"
8143 "and{l}\t{%2, %k0|%k0, %2}"
8144 [(set_attr "type" "alu")
8145 (set_attr "mode" "SI")])
8147 (define_insn "*andqi_2_slp"
8148 [(set (reg FLAGS_REG)
8150 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8151 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8153 (set (strict_low_part (match_dup 0))
8154 (and:QI (match_dup 0) (match_dup 1)))]
8155 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8156 && ix86_match_ccmode (insn, CCNOmode)
8157 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8158 "and{b}\t{%1, %0|%0, %1}"
8159 [(set_attr "type" "alu1")
8160 (set_attr "mode" "QI")])
8162 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8163 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8164 ;; for a QImode operand, which of course failed.
8165 (define_insn "andqi_ext_0"
8166 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8171 (match_operand 1 "ext_register_operand" "0")
8174 (match_operand 2 "const_int_operand" "n")))
8175 (clobber (reg:CC FLAGS_REG))]
8177 "and{b}\t{%2, %h0|%h0, %2}"
8178 [(set_attr "type" "alu")
8179 (set_attr "length_immediate" "1")
8180 (set_attr "modrm" "1")
8181 (set_attr "mode" "QI")])
8183 ;; Generated by peephole translating test to and. This shows up
8184 ;; often in fp comparisons.
8185 (define_insn "*andqi_ext_0_cc"
8186 [(set (reg FLAGS_REG)
8190 (match_operand 1 "ext_register_operand" "0")
8193 (match_operand 2 "const_int_operand" "n"))
8195 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8204 "ix86_match_ccmode (insn, CCNOmode)"
8205 "and{b}\t{%2, %h0|%h0, %2}"
8206 [(set_attr "type" "alu")
8207 (set_attr "length_immediate" "1")
8208 (set_attr "modrm" "1")
8209 (set_attr "mode" "QI")])
8211 (define_insn "*andqi_ext_1_rex64"
8212 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8217 (match_operand 1 "ext_register_operand" "0")
8221 (match_operand 2 "ext_register_operand" "Q"))))
8222 (clobber (reg:CC FLAGS_REG))]
8224 "and{b}\t{%2, %h0|%h0, %2}"
8225 [(set_attr "type" "alu")
8226 (set_attr "length_immediate" "0")
8227 (set_attr "mode" "QI")])
8229 (define_insn "*andqi_ext_1"
8230 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8235 (match_operand 1 "ext_register_operand" "0")
8239 (match_operand:QI 2 "general_operand" "Qm"))))
8240 (clobber (reg:CC FLAGS_REG))]
8242 "and{b}\t{%2, %h0|%h0, %2}"
8243 [(set_attr "type" "alu")
8244 (set_attr "length_immediate" "0")
8245 (set_attr "mode" "QI")])
8247 (define_insn "*andqi_ext_2"
8248 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8253 (match_operand 1 "ext_register_operand" "%0")
8257 (match_operand 2 "ext_register_operand" "Q")
8260 (clobber (reg:CC FLAGS_REG))]
8262 "and{b}\t{%h2, %h0|%h0, %h2}"
8263 [(set_attr "type" "alu")
8264 (set_attr "length_immediate" "0")
8265 (set_attr "mode" "QI")])
8267 ;; Convert wide AND instructions with immediate operand to shorter QImode
8268 ;; equivalents when possible.
8269 ;; Don't do the splitting with memory operands, since it introduces risk
8270 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8271 ;; for size, but that can (should?) be handled by generic code instead.
8273 [(set (match_operand 0 "register_operand" "")
8274 (and (match_operand 1 "register_operand" "")
8275 (match_operand 2 "const_int_operand" "")))
8276 (clobber (reg:CC FLAGS_REG))]
8278 && QI_REG_P (operands[0])
8279 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8280 && !(~INTVAL (operands[2]) & ~(255 << 8))
8281 && GET_MODE (operands[0]) != QImode"
8282 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8283 (and:SI (zero_extract:SI (match_dup 1)
8284 (const_int 8) (const_int 8))
8286 (clobber (reg:CC FLAGS_REG))])]
8287 "operands[0] = gen_lowpart (SImode, operands[0]);
8288 operands[1] = gen_lowpart (SImode, operands[1]);
8289 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8291 ;; Since AND can be encoded with sign extended immediate, this is only
8292 ;; profitable when 7th bit is not set.
8294 [(set (match_operand 0 "register_operand" "")
8295 (and (match_operand 1 "general_operand" "")
8296 (match_operand 2 "const_int_operand" "")))
8297 (clobber (reg:CC FLAGS_REG))]
8299 && ANY_QI_REG_P (operands[0])
8300 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8301 && !(~INTVAL (operands[2]) & ~255)
8302 && !(INTVAL (operands[2]) & 128)
8303 && GET_MODE (operands[0]) != QImode"
8304 [(parallel [(set (strict_low_part (match_dup 0))
8305 (and:QI (match_dup 1)
8307 (clobber (reg:CC FLAGS_REG))])]
8308 "operands[0] = gen_lowpart (QImode, operands[0]);
8309 operands[1] = gen_lowpart (QImode, operands[1]);
8310 operands[2] = gen_lowpart (QImode, operands[2]);")
8312 ;; Logical inclusive and exclusive OR instructions
8314 ;; %%% This used to optimize known byte-wide and operations to memory.
8315 ;; If this is considered useful, it should be done with splitters.
8317 (define_expand "<code><mode>3"
8318 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8319 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8320 (match_operand:SWIM 2 "<general_operand>" "")))]
8322 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8324 (define_insn "*<code><mode>_1"
8325 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8327 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8328 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8329 (clobber (reg:CC FLAGS_REG))]
8330 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8331 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8332 [(set_attr "type" "alu")
8333 (set_attr "mode" "<MODE>")])
8335 ;; %%% Potential partial reg stall on alternative 2. What to do?
8336 (define_insn "*<code>qi_1"
8337 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8338 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8339 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8340 (clobber (reg:CC FLAGS_REG))]
8341 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8343 <logic>{b}\t{%2, %0|%0, %2}
8344 <logic>{b}\t{%2, %0|%0, %2}
8345 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8346 [(set_attr "type" "alu")
8347 (set_attr "mode" "QI,QI,SI")])
8349 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8350 (define_insn "*<code>si_1_zext"
8351 [(set (match_operand:DI 0 "register_operand" "=r")
8353 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8354 (match_operand:SI 2 "general_operand" "g"))))
8355 (clobber (reg:CC FLAGS_REG))]
8356 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8357 "<logic>{l}\t{%2, %k0|%k0, %2}"
8358 [(set_attr "type" "alu")
8359 (set_attr "mode" "SI")])
8361 (define_insn "*<code>si_1_zext_imm"
8362 [(set (match_operand:DI 0 "register_operand" "=r")
8364 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8365 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8366 (clobber (reg:CC FLAGS_REG))]
8367 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8368 "<logic>{l}\t{%2, %k0|%k0, %2}"
8369 [(set_attr "type" "alu")
8370 (set_attr "mode" "SI")])
8372 (define_insn "*<code>qi_1_slp"
8373 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8374 (any_or:QI (match_dup 0)
8375 (match_operand:QI 1 "general_operand" "qmn,qn")))
8376 (clobber (reg:CC FLAGS_REG))]
8377 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8378 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8379 "<logic>{b}\t{%1, %0|%0, %1}"
8380 [(set_attr "type" "alu1")
8381 (set_attr "mode" "QI")])
8383 (define_insn "*<code><mode>_2"
8384 [(set (reg FLAGS_REG)
8385 (compare (any_or:SWI
8386 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8387 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8389 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8390 (any_or:SWI (match_dup 1) (match_dup 2)))]
8391 "ix86_match_ccmode (insn, CCNOmode)
8392 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8393 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8394 [(set_attr "type" "alu")
8395 (set_attr "mode" "<MODE>")])
8397 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8398 ;; ??? Special case for immediate operand is missing - it is tricky.
8399 (define_insn "*<code>si_2_zext"
8400 [(set (reg FLAGS_REG)
8401 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8402 (match_operand:SI 2 "general_operand" "g"))
8404 (set (match_operand:DI 0 "register_operand" "=r")
8405 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8406 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8407 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8408 "<logic>{l}\t{%2, %k0|%k0, %2}"
8409 [(set_attr "type" "alu")
8410 (set_attr "mode" "SI")])
8412 (define_insn "*<code>si_2_zext_imm"
8413 [(set (reg FLAGS_REG)
8415 (match_operand:SI 1 "nonimmediate_operand" "%0")
8416 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8418 (set (match_operand:DI 0 "register_operand" "=r")
8419 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8420 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8421 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8422 "<logic>{l}\t{%2, %k0|%k0, %2}"
8423 [(set_attr "type" "alu")
8424 (set_attr "mode" "SI")])
8426 (define_insn "*<code>qi_2_slp"
8427 [(set (reg FLAGS_REG)
8428 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8429 (match_operand:QI 1 "general_operand" "qmn,qn"))
8431 (set (strict_low_part (match_dup 0))
8432 (any_or:QI (match_dup 0) (match_dup 1)))]
8433 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8434 && ix86_match_ccmode (insn, CCNOmode)
8435 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8436 "<logic>{b}\t{%1, %0|%0, %1}"
8437 [(set_attr "type" "alu1")
8438 (set_attr "mode" "QI")])
8440 (define_insn "*<code><mode>_3"
8441 [(set (reg FLAGS_REG)
8442 (compare (any_or:SWI
8443 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8444 (match_operand:SWI 2 "<general_operand>" "<g>"))
8446 (clobber (match_scratch:SWI 0 "=<r>"))]
8447 "ix86_match_ccmode (insn, CCNOmode)
8448 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8449 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8450 [(set_attr "type" "alu")
8451 (set_attr "mode" "<MODE>")])
8453 (define_insn "*<code>qi_ext_0"
8454 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8459 (match_operand 1 "ext_register_operand" "0")
8462 (match_operand 2 "const_int_operand" "n")))
8463 (clobber (reg:CC FLAGS_REG))]
8464 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8465 "<logic>{b}\t{%2, %h0|%h0, %2}"
8466 [(set_attr "type" "alu")
8467 (set_attr "length_immediate" "1")
8468 (set_attr "modrm" "1")
8469 (set_attr "mode" "QI")])
8471 (define_insn "*<code>qi_ext_1_rex64"
8472 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8477 (match_operand 1 "ext_register_operand" "0")
8481 (match_operand 2 "ext_register_operand" "Q"))))
8482 (clobber (reg:CC FLAGS_REG))]
8484 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8485 "<logic>{b}\t{%2, %h0|%h0, %2}"
8486 [(set_attr "type" "alu")
8487 (set_attr "length_immediate" "0")
8488 (set_attr "mode" "QI")])
8490 (define_insn "*<code>qi_ext_1"
8491 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8496 (match_operand 1 "ext_register_operand" "0")
8500 (match_operand:QI 2 "general_operand" "Qm"))))
8501 (clobber (reg:CC FLAGS_REG))]
8503 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8504 "<logic>{b}\t{%2, %h0|%h0, %2}"
8505 [(set_attr "type" "alu")
8506 (set_attr "length_immediate" "0")
8507 (set_attr "mode" "QI")])
8509 (define_insn "*<code>qi_ext_2"
8510 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8514 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8517 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8520 (clobber (reg:CC FLAGS_REG))]
8521 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8522 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8523 [(set_attr "type" "alu")
8524 (set_attr "length_immediate" "0")
8525 (set_attr "mode" "QI")])
8528 [(set (match_operand 0 "register_operand" "")
8529 (any_or (match_operand 1 "register_operand" "")
8530 (match_operand 2 "const_int_operand" "")))
8531 (clobber (reg:CC FLAGS_REG))]
8533 && QI_REG_P (operands[0])
8534 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8535 && !(INTVAL (operands[2]) & ~(255 << 8))
8536 && GET_MODE (operands[0]) != QImode"
8537 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8538 (any_or:SI (zero_extract:SI (match_dup 1)
8539 (const_int 8) (const_int 8))
8541 (clobber (reg:CC FLAGS_REG))])]
8542 "operands[0] = gen_lowpart (SImode, operands[0]);
8543 operands[1] = gen_lowpart (SImode, operands[1]);
8544 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8546 ;; Since OR can be encoded with sign extended immediate, this is only
8547 ;; profitable when 7th bit is set.
8549 [(set (match_operand 0 "register_operand" "")
8550 (any_or (match_operand 1 "general_operand" "")
8551 (match_operand 2 "const_int_operand" "")))
8552 (clobber (reg:CC FLAGS_REG))]
8554 && ANY_QI_REG_P (operands[0])
8555 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8556 && !(INTVAL (operands[2]) & ~255)
8557 && (INTVAL (operands[2]) & 128)
8558 && GET_MODE (operands[0]) != QImode"
8559 [(parallel [(set (strict_low_part (match_dup 0))
8560 (any_or:QI (match_dup 1)
8562 (clobber (reg:CC FLAGS_REG))])]
8563 "operands[0] = gen_lowpart (QImode, operands[0]);
8564 operands[1] = gen_lowpart (QImode, operands[1]);
8565 operands[2] = gen_lowpart (QImode, operands[2]);")
8567 (define_expand "xorqi_cc_ext_1"
8569 (set (reg:CCNO FLAGS_REG)
8573 (match_operand 1 "ext_register_operand" "")
8576 (match_operand:QI 2 "general_operand" ""))
8578 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8590 (define_insn "*xorqi_cc_ext_1_rex64"
8591 [(set (reg FLAGS_REG)
8595 (match_operand 1 "ext_register_operand" "0")
8598 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8600 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8609 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8610 "xor{b}\t{%2, %h0|%h0, %2}"
8611 [(set_attr "type" "alu")
8612 (set_attr "modrm" "1")
8613 (set_attr "mode" "QI")])
8615 (define_insn "*xorqi_cc_ext_1"
8616 [(set (reg FLAGS_REG)
8620 (match_operand 1 "ext_register_operand" "0")
8623 (match_operand:QI 2 "general_operand" "qmn"))
8625 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8634 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8635 "xor{b}\t{%2, %h0|%h0, %2}"
8636 [(set_attr "type" "alu")
8637 (set_attr "modrm" "1")
8638 (set_attr "mode" "QI")])
8640 ;; Negation instructions
8642 (define_expand "neg<mode>2"
8643 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8644 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8646 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8648 (define_insn_and_split "*neg<dwi>2_doubleword"
8649 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8650 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8651 (clobber (reg:CC FLAGS_REG))]
8652 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8656 [(set (reg:CCZ FLAGS_REG)
8657 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8658 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8661 (plus:DWIH (match_dup 3)
8662 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8664 (clobber (reg:CC FLAGS_REG))])
8667 (neg:DWIH (match_dup 2)))
8668 (clobber (reg:CC FLAGS_REG))])]
8669 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
8671 (define_insn "*neg<mode>2_1"
8672 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8673 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8674 (clobber (reg:CC FLAGS_REG))]
8675 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8676 "neg{<imodesuffix>}\t%0"
8677 [(set_attr "type" "negnot")
8678 (set_attr "mode" "<MODE>")])
8680 ;; Combine is quite creative about this pattern.
8681 (define_insn "*negsi2_1_zext"
8682 [(set (match_operand:DI 0 "register_operand" "=r")
8684 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8687 (clobber (reg:CC FLAGS_REG))]
8688 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8690 [(set_attr "type" "negnot")
8691 (set_attr "mode" "SI")])
8693 ;; The problem with neg is that it does not perform (compare x 0),
8694 ;; it really performs (compare 0 x), which leaves us with the zero
8695 ;; flag being the only useful item.
8697 (define_insn "*neg<mode>2_cmpz"
8698 [(set (reg:CCZ FLAGS_REG)
8700 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8702 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8703 (neg:SWI (match_dup 1)))]
8704 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8705 "neg{<imodesuffix>}\t%0"
8706 [(set_attr "type" "negnot")
8707 (set_attr "mode" "<MODE>")])
8709 (define_insn "*negsi2_cmpz_zext"
8710 [(set (reg:CCZ FLAGS_REG)
8714 (match_operand:DI 1 "register_operand" "0")
8718 (set (match_operand:DI 0 "register_operand" "=r")
8719 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8722 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8724 [(set_attr "type" "negnot")
8725 (set_attr "mode" "SI")])
8727 ;; Changing of sign for FP values is doable using integer unit too.
8729 (define_expand "<code><mode>2"
8730 [(set (match_operand:X87MODEF 0 "register_operand" "")
8731 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8732 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8733 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8735 (define_insn "*absneg<mode>2_mixed"
8736 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8737 (match_operator:MODEF 3 "absneg_operator"
8738 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8739 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8740 (clobber (reg:CC FLAGS_REG))]
8741 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8744 (define_insn "*absneg<mode>2_sse"
8745 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8746 (match_operator:MODEF 3 "absneg_operator"
8747 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8748 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8749 (clobber (reg:CC FLAGS_REG))]
8750 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8753 (define_insn "*absneg<mode>2_i387"
8754 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8755 (match_operator:X87MODEF 3 "absneg_operator"
8756 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8757 (use (match_operand 2 "" ""))
8758 (clobber (reg:CC FLAGS_REG))]
8759 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8762 (define_expand "<code>tf2"
8763 [(set (match_operand:TF 0 "register_operand" "")
8764 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8766 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8768 (define_insn "*absnegtf2_sse"
8769 [(set (match_operand:TF 0 "register_operand" "=x,x")
8770 (match_operator:TF 3 "absneg_operator"
8771 [(match_operand:TF 1 "register_operand" "0,x")]))
8772 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8773 (clobber (reg:CC FLAGS_REG))]
8777 ;; Splitters for fp abs and neg.
8780 [(set (match_operand 0 "fp_register_operand" "")
8781 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8782 (use (match_operand 2 "" ""))
8783 (clobber (reg:CC FLAGS_REG))]
8785 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8788 [(set (match_operand 0 "register_operand" "")
8789 (match_operator 3 "absneg_operator"
8790 [(match_operand 1 "register_operand" "")]))
8791 (use (match_operand 2 "nonimmediate_operand" ""))
8792 (clobber (reg:CC FLAGS_REG))]
8793 "reload_completed && SSE_REG_P (operands[0])"
8794 [(set (match_dup 0) (match_dup 3))]
8796 enum machine_mode mode = GET_MODE (operands[0]);
8797 enum machine_mode vmode = GET_MODE (operands[2]);
8800 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8801 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8802 if (operands_match_p (operands[0], operands[2]))
8805 operands[1] = operands[2];
8808 if (GET_CODE (operands[3]) == ABS)
8809 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8811 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8816 [(set (match_operand:SF 0 "register_operand" "")
8817 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8818 (use (match_operand:V4SF 2 "" ""))
8819 (clobber (reg:CC FLAGS_REG))]
8821 [(parallel [(set (match_dup 0) (match_dup 1))
8822 (clobber (reg:CC FLAGS_REG))])]
8825 operands[0] = gen_lowpart (SImode, operands[0]);
8826 if (GET_CODE (operands[1]) == ABS)
8828 tmp = gen_int_mode (0x7fffffff, SImode);
8829 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8833 tmp = gen_int_mode (0x80000000, SImode);
8834 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8840 [(set (match_operand:DF 0 "register_operand" "")
8841 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8842 (use (match_operand 2 "" ""))
8843 (clobber (reg:CC FLAGS_REG))]
8845 [(parallel [(set (match_dup 0) (match_dup 1))
8846 (clobber (reg:CC FLAGS_REG))])]
8851 tmp = gen_lowpart (DImode, operands[0]);
8852 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8855 if (GET_CODE (operands[1]) == ABS)
8858 tmp = gen_rtx_NOT (DImode, tmp);
8862 operands[0] = gen_highpart (SImode, operands[0]);
8863 if (GET_CODE (operands[1]) == ABS)
8865 tmp = gen_int_mode (0x7fffffff, SImode);
8866 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8870 tmp = gen_int_mode (0x80000000, SImode);
8871 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8878 [(set (match_operand:XF 0 "register_operand" "")
8879 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8880 (use (match_operand 2 "" ""))
8881 (clobber (reg:CC FLAGS_REG))]
8883 [(parallel [(set (match_dup 0) (match_dup 1))
8884 (clobber (reg:CC FLAGS_REG))])]
8887 operands[0] = gen_rtx_REG (SImode,
8888 true_regnum (operands[0])
8889 + (TARGET_64BIT ? 1 : 2));
8890 if (GET_CODE (operands[1]) == ABS)
8892 tmp = GEN_INT (0x7fff);
8893 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8897 tmp = GEN_INT (0x8000);
8898 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8903 ;; Conditionalize these after reload. If they match before reload, we
8904 ;; lose the clobber and ability to use integer instructions.
8906 (define_insn "*<code><mode>2_1"
8907 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8908 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8910 && (reload_completed
8911 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8912 "f<absneg_mnemonic>"
8913 [(set_attr "type" "fsgn")
8914 (set_attr "mode" "<MODE>")])
8916 (define_insn "*<code>extendsfdf2"
8917 [(set (match_operand:DF 0 "register_operand" "=f")
8918 (absneg:DF (float_extend:DF
8919 (match_operand:SF 1 "register_operand" "0"))))]
8920 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8921 "f<absneg_mnemonic>"
8922 [(set_attr "type" "fsgn")
8923 (set_attr "mode" "DF")])
8925 (define_insn "*<code>extendsfxf2"
8926 [(set (match_operand:XF 0 "register_operand" "=f")
8927 (absneg:XF (float_extend:XF
8928 (match_operand:SF 1 "register_operand" "0"))))]
8930 "f<absneg_mnemonic>"
8931 [(set_attr "type" "fsgn")
8932 (set_attr "mode" "XF")])
8934 (define_insn "*<code>extenddfxf2"
8935 [(set (match_operand:XF 0 "register_operand" "=f")
8936 (absneg:XF (float_extend:XF
8937 (match_operand:DF 1 "register_operand" "0"))))]
8939 "f<absneg_mnemonic>"
8940 [(set_attr "type" "fsgn")
8941 (set_attr "mode" "XF")])
8943 ;; Copysign instructions
8945 (define_mode_iterator CSGNMODE [SF DF TF])
8946 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8948 (define_expand "copysign<mode>3"
8949 [(match_operand:CSGNMODE 0 "register_operand" "")
8950 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8951 (match_operand:CSGNMODE 2 "register_operand" "")]
8952 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8953 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8955 ix86_expand_copysign (operands);
8959 (define_insn_and_split "copysign<mode>3_const"
8960 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8962 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8963 (match_operand:CSGNMODE 2 "register_operand" "0")
8964 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8966 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8967 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8969 "&& reload_completed"
8972 ix86_split_copysign_const (operands);
8976 (define_insn "copysign<mode>3_var"
8977 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8979 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8980 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8981 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8982 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8984 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8985 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8986 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8990 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8992 [(match_operand:CSGNMODE 2 "register_operand" "")
8993 (match_operand:CSGNMODE 3 "register_operand" "")
8994 (match_operand:<CSGNVMODE> 4 "" "")
8995 (match_operand:<CSGNVMODE> 5 "" "")]
8997 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8998 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8999 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9000 && reload_completed"
9003 ix86_split_copysign_var (operands);
9007 ;; One complement instructions
9009 (define_expand "one_cmpl<mode>2"
9010 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9011 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9013 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9015 (define_insn "*one_cmpl<mode>2_1"
9016 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9017 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9018 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9019 "not{<imodesuffix>}\t%0"
9020 [(set_attr "type" "negnot")
9021 (set_attr "mode" "<MODE>")])
9023 ;; %%% Potential partial reg stall on alternative 1. What to do?
9024 (define_insn "*one_cmplqi2_1"
9025 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9026 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9027 "ix86_unary_operator_ok (NOT, QImode, operands)"
9031 [(set_attr "type" "negnot")
9032 (set_attr "mode" "QI,SI")])
9034 ;; ??? Currently never generated - xor is used instead.
9035 (define_insn "*one_cmplsi2_1_zext"
9036 [(set (match_operand:DI 0 "register_operand" "=r")
9038 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9039 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9041 [(set_attr "type" "negnot")
9042 (set_attr "mode" "SI")])
9044 (define_insn "*one_cmpl<mode>2_2"
9045 [(set (reg FLAGS_REG)
9046 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9048 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9049 (not:SWI (match_dup 1)))]
9050 "ix86_match_ccmode (insn, CCNOmode)
9051 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9053 [(set_attr "type" "alu1")
9054 (set_attr "mode" "<MODE>")])
9057 [(set (match_operand 0 "flags_reg_operand" "")
9058 (match_operator 2 "compare_operator"
9059 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9061 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9062 (not:SWI (match_dup 3)))]
9063 "ix86_match_ccmode (insn, CCNOmode)"
9064 [(parallel [(set (match_dup 0)
9065 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9068 (xor:SWI (match_dup 3) (const_int -1)))])]
9071 ;; ??? Currently never generated - xor is used instead.
9072 (define_insn "*one_cmplsi2_2_zext"
9073 [(set (reg FLAGS_REG)
9074 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9076 (set (match_operand:DI 0 "register_operand" "=r")
9077 (zero_extend:DI (not:SI (match_dup 1))))]
9078 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9079 && ix86_unary_operator_ok (NOT, SImode, operands)"
9081 [(set_attr "type" "alu1")
9082 (set_attr "mode" "SI")])
9085 [(set (match_operand 0 "flags_reg_operand" "")
9086 (match_operator 2 "compare_operator"
9087 [(not:SI (match_operand:SI 3 "register_operand" ""))
9089 (set (match_operand:DI 1 "register_operand" "")
9090 (zero_extend:DI (not:SI (match_dup 3))))]
9091 "ix86_match_ccmode (insn, CCNOmode)"
9092 [(parallel [(set (match_dup 0)
9093 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9096 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9099 ;; Shift instructions
9101 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9102 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9103 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9104 ;; from the assembler input.
9106 ;; This instruction shifts the target reg/mem as usual, but instead of
9107 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9108 ;; is a left shift double, bits are taken from the high order bits of
9109 ;; reg, else if the insn is a shift right double, bits are taken from the
9110 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9111 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9113 ;; Since sh[lr]d does not change the `reg' operand, that is done
9114 ;; separately, making all shifts emit pairs of shift double and normal
9115 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9116 ;; support a 63 bit shift, each shift where the count is in a reg expands
9117 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9119 ;; If the shift count is a constant, we need never emit more than one
9120 ;; shift pair, instead using moves and sign extension for counts greater
9123 (define_expand "ashl<mode>3"
9124 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9125 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9126 (match_operand:QI 2 "nonmemory_operand" "")))]
9128 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9130 (define_insn "*ashl<mode>3_doubleword"
9131 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9132 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9133 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9134 (clobber (reg:CC FLAGS_REG))]
9137 [(set_attr "type" "multi")])
9140 [(set (match_operand:DWI 0 "register_operand" "")
9141 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9142 (match_operand:QI 2 "nonmemory_operand" "")))
9143 (clobber (reg:CC FLAGS_REG))]
9144 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9146 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9148 ;; By default we don't ask for a scratch register, because when DWImode
9149 ;; values are manipulated, registers are already at a premium. But if
9150 ;; we have one handy, we won't turn it away.
9153 [(match_scratch:DWIH 3 "r")
9154 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9156 (match_operand:<DWI> 1 "nonmemory_operand" "")
9157 (match_operand:QI 2 "nonmemory_operand" "")))
9158 (clobber (reg:CC FLAGS_REG))])
9162 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9164 (define_insn "x86_64_shld"
9165 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9166 (ior:DI (ashift:DI (match_dup 0)
9167 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9168 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9169 (minus:QI (const_int 64) (match_dup 2)))))
9170 (clobber (reg:CC FLAGS_REG))]
9172 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9173 [(set_attr "type" "ishift")
9174 (set_attr "prefix_0f" "1")
9175 (set_attr "mode" "DI")
9176 (set_attr "athlon_decode" "vector")
9177 (set_attr "amdfam10_decode" "vector")])
9179 (define_insn "x86_shld"
9180 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9181 (ior:SI (ashift:SI (match_dup 0)
9182 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9183 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9184 (minus:QI (const_int 32) (match_dup 2)))))
9185 (clobber (reg:CC FLAGS_REG))]
9187 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9188 [(set_attr "type" "ishift")
9189 (set_attr "prefix_0f" "1")
9190 (set_attr "mode" "SI")
9191 (set_attr "pent_pair" "np")
9192 (set_attr "athlon_decode" "vector")
9193 (set_attr "amdfam10_decode" "vector")])
9195 (define_expand "x86_shift<mode>_adj_1"
9196 [(set (reg:CCZ FLAGS_REG)
9197 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9200 (set (match_operand:SWI48 0 "register_operand" "")
9201 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9202 (match_operand:SWI48 1 "register_operand" "")
9205 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9206 (match_operand:SWI48 3 "register_operand" "r")
9209 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9211 (define_expand "x86_shift<mode>_adj_2"
9212 [(use (match_operand:SWI48 0 "register_operand" ""))
9213 (use (match_operand:SWI48 1 "register_operand" ""))
9214 (use (match_operand:QI 2 "register_operand" ""))]
9217 rtx label = gen_label_rtx ();
9220 emit_insn (gen_testqi_ccz_1 (operands[2],
9221 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9223 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9224 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9225 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9226 gen_rtx_LABEL_REF (VOIDmode, label),
9228 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9229 JUMP_LABEL (tmp) = label;
9231 emit_move_insn (operands[0], operands[1]);
9232 ix86_expand_clear (operands[1]);
9235 LABEL_NUSES (label) = 1;
9240 (define_insn "*ashl<mode>3_1"
9241 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9242 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9243 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9244 (clobber (reg:CC FLAGS_REG))]
9245 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9247 switch (get_attr_type (insn))
9253 gcc_assert (operands[2] == const1_rtx);
9254 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9255 return "add{<imodesuffix>}\t%0, %0";
9258 if (operands[2] == const1_rtx
9259 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9260 return "sal{<imodesuffix>}\t%0";
9262 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9266 (cond [(eq_attr "alternative" "1")
9267 (const_string "lea")
9268 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9270 (match_operand 0 "register_operand" ""))
9271 (match_operand 2 "const1_operand" ""))
9272 (const_string "alu")
9274 (const_string "ishift")))
9275 (set (attr "length_immediate")
9277 (ior (eq_attr "type" "alu")
9278 (and (eq_attr "type" "ishift")
9279 (and (match_operand 2 "const1_operand" "")
9280 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9283 (const_string "*")))
9284 (set_attr "mode" "<MODE>")])
9286 (define_insn "*ashlsi3_1_zext"
9287 [(set (match_operand:DI 0 "register_operand" "=r,r")
9289 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9290 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9291 (clobber (reg:CC FLAGS_REG))]
9292 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9294 switch (get_attr_type (insn))
9300 gcc_assert (operands[2] == const1_rtx);
9301 return "add{l}\t%k0, %k0";
9304 if (operands[2] == const1_rtx
9305 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9306 return "sal{l}\t%k0";
9308 return "sal{l}\t{%2, %k0|%k0, %2}";
9312 (cond [(eq_attr "alternative" "1")
9313 (const_string "lea")
9314 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9316 (match_operand 2 "const1_operand" ""))
9317 (const_string "alu")
9319 (const_string "ishift")))
9320 (set (attr "length_immediate")
9322 (ior (eq_attr "type" "alu")
9323 (and (eq_attr "type" "ishift")
9324 (and (match_operand 2 "const1_operand" "")
9325 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9328 (const_string "*")))
9329 (set_attr "mode" "SI")])
9331 (define_insn "*ashlhi3_1"
9332 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9333 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9334 (match_operand:QI 2 "nonmemory_operand" "cI")))
9335 (clobber (reg:CC FLAGS_REG))]
9336 "TARGET_PARTIAL_REG_STALL
9337 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9339 switch (get_attr_type (insn))
9342 gcc_assert (operands[2] == const1_rtx);
9343 return "add{w}\t%0, %0";
9346 if (operands[2] == const1_rtx
9347 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9348 return "sal{w}\t%0";
9350 return "sal{w}\t{%2, %0|%0, %2}";
9354 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9356 (match_operand 0 "register_operand" ""))
9357 (match_operand 2 "const1_operand" ""))
9358 (const_string "alu")
9360 (const_string "ishift")))
9361 (set (attr "length_immediate")
9363 (ior (eq_attr "type" "alu")
9364 (and (eq_attr "type" "ishift")
9365 (and (match_operand 2 "const1_operand" "")
9366 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9369 (const_string "*")))
9370 (set_attr "mode" "HI")])
9372 (define_insn "*ashlhi3_1_lea"
9373 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9374 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9375 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9376 (clobber (reg:CC FLAGS_REG))]
9377 "!TARGET_PARTIAL_REG_STALL
9378 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9380 switch (get_attr_type (insn))
9386 gcc_assert (operands[2] == const1_rtx);
9387 return "add{w}\t%0, %0";
9390 if (operands[2] == const1_rtx
9391 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9392 return "sal{w}\t%0";
9394 return "sal{w}\t{%2, %0|%0, %2}";
9398 (cond [(eq_attr "alternative" "1")
9399 (const_string "lea")
9400 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9402 (match_operand 0 "register_operand" ""))
9403 (match_operand 2 "const1_operand" ""))
9404 (const_string "alu")
9406 (const_string "ishift")))
9407 (set (attr "length_immediate")
9409 (ior (eq_attr "type" "alu")
9410 (and (eq_attr "type" "ishift")
9411 (and (match_operand 2 "const1_operand" "")
9412 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9415 (const_string "*")))
9416 (set_attr "mode" "HI,SI")])
9418 (define_insn "*ashlqi3_1"
9419 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9420 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9421 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9422 (clobber (reg:CC FLAGS_REG))]
9423 "TARGET_PARTIAL_REG_STALL
9424 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9426 switch (get_attr_type (insn))
9429 gcc_assert (operands[2] == const1_rtx);
9430 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9431 return "add{l}\t%k0, %k0";
9433 return "add{b}\t%0, %0";
9436 if (operands[2] == const1_rtx
9437 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9439 if (get_attr_mode (insn) == MODE_SI)
9440 return "sal{l}\t%k0";
9442 return "sal{b}\t%0";
9446 if (get_attr_mode (insn) == MODE_SI)
9447 return "sal{l}\t{%2, %k0|%k0, %2}";
9449 return "sal{b}\t{%2, %0|%0, %2}";
9454 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9456 (match_operand 0 "register_operand" ""))
9457 (match_operand 2 "const1_operand" ""))
9458 (const_string "alu")
9460 (const_string "ishift")))
9461 (set (attr "length_immediate")
9463 (ior (eq_attr "type" "alu")
9464 (and (eq_attr "type" "ishift")
9465 (and (match_operand 2 "const1_operand" "")
9466 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9469 (const_string "*")))
9470 (set_attr "mode" "QI,SI")])
9472 ;; %%% Potential partial reg stall on alternative 2. What to do?
9473 (define_insn "*ashlqi3_1_lea"
9474 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9475 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9476 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9477 (clobber (reg:CC FLAGS_REG))]
9478 "!TARGET_PARTIAL_REG_STALL
9479 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9481 switch (get_attr_type (insn))
9487 gcc_assert (operands[2] == const1_rtx);
9488 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9489 return "add{l}\t%k0, %k0";
9491 return "add{b}\t%0, %0";
9494 if (operands[2] == const1_rtx
9495 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9497 if (get_attr_mode (insn) == MODE_SI)
9498 return "sal{l}\t%k0";
9500 return "sal{b}\t%0";
9504 if (get_attr_mode (insn) == MODE_SI)
9505 return "sal{l}\t{%2, %k0|%k0, %2}";
9507 return "sal{b}\t{%2, %0|%0, %2}";
9512 (cond [(eq_attr "alternative" "2")
9513 (const_string "lea")
9514 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9516 (match_operand 0 "register_operand" ""))
9517 (match_operand 2 "const1_operand" ""))
9518 (const_string "alu")
9520 (const_string "ishift")))
9521 (set (attr "length_immediate")
9523 (ior (eq_attr "type" "alu")
9524 (and (eq_attr "type" "ishift")
9525 (and (match_operand 2 "const1_operand" "")
9526 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9529 (const_string "*")))
9530 (set_attr "mode" "QI,SI,SI")])
9532 (define_insn "*ashlqi3_1_slp"
9533 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9534 (ashift:QI (match_dup 0)
9535 (match_operand:QI 1 "nonmemory_operand" "cI")))
9536 (clobber (reg:CC FLAGS_REG))]
9537 "(optimize_function_for_size_p (cfun)
9538 || !TARGET_PARTIAL_FLAG_REG_STALL
9539 || (operands[1] == const1_rtx
9541 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9543 switch (get_attr_type (insn))
9546 gcc_assert (operands[1] == const1_rtx);
9547 return "add{b}\t%0, %0";
9550 if (operands[1] == const1_rtx
9551 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9552 return "sal{b}\t%0";
9554 return "sal{b}\t{%1, %0|%0, %1}";
9558 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9560 (match_operand 0 "register_operand" ""))
9561 (match_operand 1 "const1_operand" ""))
9562 (const_string "alu")
9564 (const_string "ishift1")))
9565 (set (attr "length_immediate")
9567 (ior (eq_attr "type" "alu")
9568 (and (eq_attr "type" "ishift1")
9569 (and (match_operand 1 "const1_operand" "")
9570 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9573 (const_string "*")))
9574 (set_attr "mode" "QI")])
9576 ;; Convert lea to the lea pattern to avoid flags dependency.
9578 [(set (match_operand:DI 0 "register_operand" "")
9579 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9580 (match_operand:QI 2 "const_int_operand" "")))
9581 (clobber (reg:CC FLAGS_REG))]
9582 "TARGET_64BIT && reload_completed
9583 && true_regnum (operands[0]) != true_regnum (operands[1])"
9585 (mult:DI (match_dup 1)
9587 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9589 ;; Convert lea to the lea pattern to avoid flags dependency.
9591 [(set (match_operand 0 "register_operand" "")
9592 (ashift (match_operand 1 "index_register_operand" "")
9593 (match_operand:QI 2 "const_int_operand" "")))
9594 (clobber (reg:CC FLAGS_REG))]
9596 && true_regnum (operands[0]) != true_regnum (operands[1])
9597 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
9601 enum machine_mode mode = GET_MODE (operands[0]);
9603 if (GET_MODE_SIZE (mode) < 4)
9604 operands[0] = gen_lowpart (SImode, operands[0]);
9606 operands[1] = gen_lowpart (Pmode, operands[1]);
9607 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9609 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9610 if (Pmode != SImode)
9611 pat = gen_rtx_SUBREG (SImode, pat, 0);
9612 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9616 ;; Rare case of shifting RSP is handled by generating move and shift
9618 [(set (match_operand 0 "register_operand" "")
9619 (ashift (match_operand 1 "register_operand" "")
9620 (match_operand:QI 2 "const_int_operand" "")))
9621 (clobber (reg:CC FLAGS_REG))]
9623 && true_regnum (operands[0]) != true_regnum (operands[1])"
9627 emit_move_insn (operands[0], operands[1]);
9628 pat = gen_rtx_SET (VOIDmode, operands[0],
9629 gen_rtx_ASHIFT (GET_MODE (operands[0]),
9630 operands[0], operands[2]));
9631 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
9632 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
9636 ;; Convert lea to the lea pattern to avoid flags dependency.
9638 [(set (match_operand:DI 0 "register_operand" "")
9640 (ashift:SI (match_operand:SI 1 "register_operand" "")
9641 (match_operand:QI 2 "const_int_operand" ""))))
9642 (clobber (reg:CC FLAGS_REG))]
9643 "TARGET_64BIT && reload_completed
9644 && true_regnum (operands[0]) != true_regnum (operands[1])"
9646 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9648 operands[1] = gen_lowpart (Pmode, operands[1]);
9649 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9652 ;; This pattern can't accept a variable shift count, since shifts by
9653 ;; zero don't affect the flags. We assume that shifts by constant
9654 ;; zero are optimized away.
9655 (define_insn "*ashl<mode>3_cmp"
9656 [(set (reg FLAGS_REG)
9658 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9659 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9661 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9662 (ashift:SWI (match_dup 1) (match_dup 2)))]
9663 "(optimize_function_for_size_p (cfun)
9664 || !TARGET_PARTIAL_FLAG_REG_STALL
9665 || (operands[2] == const1_rtx
9667 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9668 && ix86_match_ccmode (insn, CCGOCmode)
9669 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9671 switch (get_attr_type (insn))
9674 gcc_assert (operands[2] == const1_rtx);
9675 return "add{<imodesuffix>}\t%0, %0";
9678 if (operands[2] == const1_rtx
9679 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9680 return "sal{<imodesuffix>}\t%0";
9682 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9686 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9688 (match_operand 0 "register_operand" ""))
9689 (match_operand 2 "const1_operand" ""))
9690 (const_string "alu")
9692 (const_string "ishift")))
9693 (set (attr "length_immediate")
9695 (ior (eq_attr "type" "alu")
9696 (and (eq_attr "type" "ishift")
9697 (and (match_operand 2 "const1_operand" "")
9698 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9701 (const_string "*")))
9702 (set_attr "mode" "<MODE>")])
9704 (define_insn "*ashlsi3_cmp_zext"
9705 [(set (reg FLAGS_REG)
9707 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9708 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9710 (set (match_operand:DI 0 "register_operand" "=r")
9711 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9713 && (optimize_function_for_size_p (cfun)
9714 || !TARGET_PARTIAL_FLAG_REG_STALL
9715 || (operands[2] == const1_rtx
9717 || TARGET_DOUBLE_WITH_ADD)))
9718 && ix86_match_ccmode (insn, CCGOCmode)
9719 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9721 switch (get_attr_type (insn))
9724 gcc_assert (operands[2] == const1_rtx);
9725 return "add{l}\t%k0, %k0";
9728 if (operands[2] == const1_rtx
9729 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9730 return "sal{l}\t%k0";
9732 return "sal{l}\t{%2, %k0|%k0, %2}";
9736 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9738 (match_operand 2 "const1_operand" ""))
9739 (const_string "alu")
9741 (const_string "ishift")))
9742 (set (attr "length_immediate")
9744 (ior (eq_attr "type" "alu")
9745 (and (eq_attr "type" "ishift")
9746 (and (match_operand 2 "const1_operand" "")
9747 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9750 (const_string "*")))
9751 (set_attr "mode" "SI")])
9753 (define_insn "*ashl<mode>3_cconly"
9754 [(set (reg FLAGS_REG)
9756 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9757 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9759 (clobber (match_scratch:SWI 0 "=<r>"))]
9760 "(optimize_function_for_size_p (cfun)
9761 || !TARGET_PARTIAL_FLAG_REG_STALL
9762 || (operands[2] == const1_rtx
9764 || TARGET_DOUBLE_WITH_ADD)))
9765 && ix86_match_ccmode (insn, CCGOCmode)
9766 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9768 switch (get_attr_type (insn))
9771 gcc_assert (operands[2] == const1_rtx);
9772 return "add{<imodesuffix>}\t%0, %0";
9775 if (operands[2] == const1_rtx
9776 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9777 return "sal{<imodesuffix>}\t%0";
9779 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9783 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9785 (match_operand 0 "register_operand" ""))
9786 (match_operand 2 "const1_operand" ""))
9787 (const_string "alu")
9789 (const_string "ishift")))
9790 (set (attr "length_immediate")
9792 (ior (eq_attr "type" "alu")
9793 (and (eq_attr "type" "ishift")
9794 (and (match_operand 2 "const1_operand" "")
9795 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9798 (const_string "*")))
9799 (set_attr "mode" "<MODE>")])
9801 ;; See comment above `ashl<mode>3' about how this works.
9803 (define_expand "<shiftrt_insn><mode>3"
9804 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9805 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9806 (match_operand:QI 2 "nonmemory_operand" "")))]
9808 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9810 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9811 [(set (match_operand:DWI 0 "register_operand" "=r")
9812 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9813 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9814 (clobber (reg:CC FLAGS_REG))]
9817 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9819 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9820 [(set_attr "type" "multi")])
9822 ;; By default we don't ask for a scratch register, because when DWImode
9823 ;; values are manipulated, registers are already at a premium. But if
9824 ;; we have one handy, we won't turn it away.
9827 [(match_scratch:DWIH 3 "r")
9828 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9830 (match_operand:<DWI> 1 "register_operand" "")
9831 (match_operand:QI 2 "nonmemory_operand" "")))
9832 (clobber (reg:CC FLAGS_REG))])
9836 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9838 (define_insn "x86_64_shrd"
9839 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9840 (ior:DI (ashiftrt:DI (match_dup 0)
9841 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9842 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9843 (minus:QI (const_int 64) (match_dup 2)))))
9844 (clobber (reg:CC FLAGS_REG))]
9846 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9847 [(set_attr "type" "ishift")
9848 (set_attr "prefix_0f" "1")
9849 (set_attr "mode" "DI")
9850 (set_attr "athlon_decode" "vector")
9851 (set_attr "amdfam10_decode" "vector")])
9853 (define_insn "x86_shrd"
9854 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9855 (ior:SI (ashiftrt:SI (match_dup 0)
9856 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9857 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9858 (minus:QI (const_int 32) (match_dup 2)))))
9859 (clobber (reg:CC FLAGS_REG))]
9861 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9862 [(set_attr "type" "ishift")
9863 (set_attr "prefix_0f" "1")
9864 (set_attr "mode" "SI")
9865 (set_attr "pent_pair" "np")
9866 (set_attr "athlon_decode" "vector")
9867 (set_attr "amdfam10_decode" "vector")])
9869 (define_insn "ashrdi3_cvt"
9870 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9871 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9872 (match_operand:QI 2 "const_int_operand" "")))
9873 (clobber (reg:CC FLAGS_REG))]
9874 "TARGET_64BIT && INTVAL (operands[2]) == 63
9875 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9876 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9879 sar{q}\t{%2, %0|%0, %2}"
9880 [(set_attr "type" "imovx,ishift")
9881 (set_attr "prefix_0f" "0,*")
9882 (set_attr "length_immediate" "0,*")
9883 (set_attr "modrm" "0,1")
9884 (set_attr "mode" "DI")])
9886 (define_insn "ashrsi3_cvt"
9887 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9888 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9889 (match_operand:QI 2 "const_int_operand" "")))
9890 (clobber (reg:CC FLAGS_REG))]
9891 "INTVAL (operands[2]) == 31
9892 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9893 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9896 sar{l}\t{%2, %0|%0, %2}"
9897 [(set_attr "type" "imovx,ishift")
9898 (set_attr "prefix_0f" "0,*")
9899 (set_attr "length_immediate" "0,*")
9900 (set_attr "modrm" "0,1")
9901 (set_attr "mode" "SI")])
9903 (define_insn "*ashrsi3_cvt_zext"
9904 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9906 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9907 (match_operand:QI 2 "const_int_operand" ""))))
9908 (clobber (reg:CC FLAGS_REG))]
9909 "TARGET_64BIT && INTVAL (operands[2]) == 31
9910 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9911 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9914 sar{l}\t{%2, %k0|%k0, %2}"
9915 [(set_attr "type" "imovx,ishift")
9916 (set_attr "prefix_0f" "0,*")
9917 (set_attr "length_immediate" "0,*")
9918 (set_attr "modrm" "0,1")
9919 (set_attr "mode" "SI")])
9921 (define_expand "x86_shift<mode>_adj_3"
9922 [(use (match_operand:SWI48 0 "register_operand" ""))
9923 (use (match_operand:SWI48 1 "register_operand" ""))
9924 (use (match_operand:QI 2 "register_operand" ""))]
9927 rtx label = gen_label_rtx ();
9930 emit_insn (gen_testqi_ccz_1 (operands[2],
9931 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9933 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9934 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9935 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9936 gen_rtx_LABEL_REF (VOIDmode, label),
9938 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9939 JUMP_LABEL (tmp) = label;
9941 emit_move_insn (operands[0], operands[1]);
9942 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9943 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9945 LABEL_NUSES (label) = 1;
9950 (define_insn "*<shiftrt_insn><mode>3_1"
9951 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9952 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9953 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9954 (clobber (reg:CC FLAGS_REG))]
9955 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9957 if (operands[2] == const1_rtx
9958 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9959 return "<shiftrt>{<imodesuffix>}\t%0";
9961 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9963 [(set_attr "type" "ishift")
9964 (set (attr "length_immediate")
9966 (and (match_operand 2 "const1_operand" "")
9967 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9970 (const_string "*")))
9971 (set_attr "mode" "<MODE>")])
9973 (define_insn "*<shiftrt_insn>si3_1_zext"
9974 [(set (match_operand:DI 0 "register_operand" "=r")
9976 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9977 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9978 (clobber (reg:CC FLAGS_REG))]
9979 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9981 if (operands[2] == const1_rtx
9982 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9983 return "<shiftrt>{l}\t%k0";
9985 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9987 [(set_attr "type" "ishift")
9988 (set (attr "length_immediate")
9990 (and (match_operand 2 "const1_operand" "")
9991 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9994 (const_string "*")))
9995 (set_attr "mode" "SI")])
9997 (define_insn "*<shiftrt_insn>qi3_1_slp"
9998 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9999 (any_shiftrt:QI (match_dup 0)
10000 (match_operand:QI 1 "nonmemory_operand" "cI")))
10001 (clobber (reg:CC FLAGS_REG))]
10002 "(optimize_function_for_size_p (cfun)
10003 || !TARGET_PARTIAL_REG_STALL
10004 || (operands[1] == const1_rtx
10005 && TARGET_SHIFT1))"
10007 if (operands[1] == const1_rtx
10008 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10009 return "<shiftrt>{b}\t%0";
10011 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10013 [(set_attr "type" "ishift1")
10014 (set (attr "length_immediate")
10016 (and (match_operand 1 "const1_operand" "")
10017 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10020 (const_string "*")))
10021 (set_attr "mode" "QI")])
10023 ;; This pattern can't accept a variable shift count, since shifts by
10024 ;; zero don't affect the flags. We assume that shifts by constant
10025 ;; zero are optimized away.
10026 (define_insn "*<shiftrt_insn><mode>3_cmp"
10027 [(set (reg FLAGS_REG)
10030 (match_operand:SWI 1 "nonimmediate_operand" "0")
10031 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10033 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10034 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10035 "(optimize_function_for_size_p (cfun)
10036 || !TARGET_PARTIAL_FLAG_REG_STALL
10037 || (operands[2] == const1_rtx
10039 && ix86_match_ccmode (insn, CCGOCmode)
10040 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10042 if (operands[2] == const1_rtx
10043 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10044 return "<shiftrt>{<imodesuffix>}\t%0";
10046 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10048 [(set_attr "type" "ishift")
10049 (set (attr "length_immediate")
10051 (and (match_operand 2 "const1_operand" "")
10052 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10055 (const_string "*")))
10056 (set_attr "mode" "<MODE>")])
10058 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10059 [(set (reg FLAGS_REG)
10061 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10062 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10064 (set (match_operand:DI 0 "register_operand" "=r")
10065 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10067 && (optimize_function_for_size_p (cfun)
10068 || !TARGET_PARTIAL_FLAG_REG_STALL
10069 || (operands[2] == const1_rtx
10071 && ix86_match_ccmode (insn, CCGOCmode)
10072 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10074 if (operands[2] == const1_rtx
10075 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10076 return "<shiftrt>{l}\t%k0";
10078 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10080 [(set_attr "type" "ishift")
10081 (set (attr "length_immediate")
10083 (and (match_operand 2 "const1_operand" "")
10084 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10087 (const_string "*")))
10088 (set_attr "mode" "SI")])
10090 (define_insn "*<shiftrt_insn><mode>3_cconly"
10091 [(set (reg FLAGS_REG)
10094 (match_operand:SWI 1 "nonimmediate_operand" "0")
10095 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10097 (clobber (match_scratch:SWI 0 "=<r>"))]
10098 "(optimize_function_for_size_p (cfun)
10099 || !TARGET_PARTIAL_FLAG_REG_STALL
10100 || (operands[2] == const1_rtx
10102 && ix86_match_ccmode (insn, CCGOCmode)
10103 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10105 if (operands[2] == const1_rtx
10106 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10107 return "<shiftrt>{<imodesuffix>}\t%0";
10109 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10111 [(set_attr "type" "ishift")
10112 (set (attr "length_immediate")
10114 (and (match_operand 2 "const1_operand" "")
10115 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10118 (const_string "*")))
10119 (set_attr "mode" "<MODE>")])
10121 ;; Rotate instructions
10123 (define_expand "<rotate_insn>ti3"
10124 [(set (match_operand:TI 0 "register_operand" "")
10125 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10126 (match_operand:QI 2 "nonmemory_operand" "")))]
10129 if (const_1_to_63_operand (operands[2], VOIDmode))
10130 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10131 (operands[0], operands[1], operands[2]));
10138 (define_expand "<rotate_insn>di3"
10139 [(set (match_operand:DI 0 "shiftdi_operand" "")
10140 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10141 (match_operand:QI 2 "nonmemory_operand" "")))]
10145 ix86_expand_binary_operator (<CODE>, DImode, operands);
10146 else if (const_1_to_31_operand (operands[2], VOIDmode))
10147 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10148 (operands[0], operands[1], operands[2]));
10155 (define_expand "<rotate_insn><mode>3"
10156 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10157 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10158 (match_operand:QI 2 "nonmemory_operand" "")))]
10160 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10162 ;; Implement rotation using two double-precision
10163 ;; shift instructions and a scratch register.
10165 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10166 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10167 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10168 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10169 (clobber (reg:CC FLAGS_REG))
10170 (clobber (match_scratch:DWIH 3 "=&r"))]
10174 [(set (match_dup 3) (match_dup 4))
10176 [(set (match_dup 4)
10177 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10178 (lshiftrt:DWIH (match_dup 5)
10179 (minus:QI (match_dup 6) (match_dup 2)))))
10180 (clobber (reg:CC FLAGS_REG))])
10182 [(set (match_dup 5)
10183 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10184 (lshiftrt:DWIH (match_dup 3)
10185 (minus:QI (match_dup 6) (match_dup 2)))))
10186 (clobber (reg:CC FLAGS_REG))])]
10188 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10190 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10193 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10194 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10195 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10196 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10197 (clobber (reg:CC FLAGS_REG))
10198 (clobber (match_scratch:DWIH 3 "=&r"))]
10202 [(set (match_dup 3) (match_dup 4))
10204 [(set (match_dup 4)
10205 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10206 (ashift:DWIH (match_dup 5)
10207 (minus:QI (match_dup 6) (match_dup 2)))))
10208 (clobber (reg:CC FLAGS_REG))])
10210 [(set (match_dup 5)
10211 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10212 (ashift:DWIH (match_dup 3)
10213 (minus:QI (match_dup 6) (match_dup 2)))))
10214 (clobber (reg:CC FLAGS_REG))])]
10216 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10218 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10221 (define_insn "*<rotate_insn><mode>3_1"
10222 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10223 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10224 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10225 (clobber (reg:CC FLAGS_REG))]
10226 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10228 if (operands[2] == const1_rtx
10229 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10230 return "<rotate>{<imodesuffix>}\t%0";
10232 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10234 [(set_attr "type" "rotate")
10235 (set (attr "length_immediate")
10237 (and (match_operand 2 "const1_operand" "")
10238 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10241 (const_string "*")))
10242 (set_attr "mode" "<MODE>")])
10244 (define_insn "*<rotate_insn>si3_1_zext"
10245 [(set (match_operand:DI 0 "register_operand" "=r")
10247 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10248 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10249 (clobber (reg:CC FLAGS_REG))]
10250 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10252 if (operands[2] == const1_rtx
10253 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10254 return "<rotate>{l}\t%k0";
10256 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10258 [(set_attr "type" "rotate")
10259 (set (attr "length_immediate")
10261 (and (match_operand 2 "const1_operand" "")
10262 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10265 (const_string "*")))
10266 (set_attr "mode" "SI")])
10268 (define_insn "*<rotate_insn>qi3_1_slp"
10269 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10270 (any_rotate:QI (match_dup 0)
10271 (match_operand:QI 1 "nonmemory_operand" "cI")))
10272 (clobber (reg:CC FLAGS_REG))]
10273 "(optimize_function_for_size_p (cfun)
10274 || !TARGET_PARTIAL_REG_STALL
10275 || (operands[1] == const1_rtx
10276 && TARGET_SHIFT1))"
10278 if (operands[1] == const1_rtx
10279 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10280 return "<rotate>{b}\t%0";
10282 return "<rotate>{b}\t{%1, %0|%0, %1}";
10284 [(set_attr "type" "rotate1")
10285 (set (attr "length_immediate")
10287 (and (match_operand 1 "const1_operand" "")
10288 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10291 (const_string "*")))
10292 (set_attr "mode" "QI")])
10295 [(set (match_operand:HI 0 "register_operand" "")
10296 (any_rotate:HI (match_dup 0) (const_int 8)))
10297 (clobber (reg:CC FLAGS_REG))]
10299 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10300 [(parallel [(set (strict_low_part (match_dup 0))
10301 (bswap:HI (match_dup 0)))
10302 (clobber (reg:CC FLAGS_REG))])]
10305 ;; Bit set / bit test instructions
10307 (define_expand "extv"
10308 [(set (match_operand:SI 0 "register_operand" "")
10309 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10310 (match_operand:SI 2 "const8_operand" "")
10311 (match_operand:SI 3 "const8_operand" "")))]
10314 /* Handle extractions from %ah et al. */
10315 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10318 /* From mips.md: extract_bit_field doesn't verify that our source
10319 matches the predicate, so check it again here. */
10320 if (! ext_register_operand (operands[1], VOIDmode))
10324 (define_expand "extzv"
10325 [(set (match_operand:SI 0 "register_operand" "")
10326 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10327 (match_operand:SI 2 "const8_operand" "")
10328 (match_operand:SI 3 "const8_operand" "")))]
10331 /* Handle extractions from %ah et al. */
10332 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10335 /* From mips.md: extract_bit_field doesn't verify that our source
10336 matches the predicate, so check it again here. */
10337 if (! ext_register_operand (operands[1], VOIDmode))
10341 (define_expand "insv"
10342 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10343 (match_operand 1 "const8_operand" "")
10344 (match_operand 2 "const8_operand" ""))
10345 (match_operand 3 "register_operand" ""))]
10348 rtx (*gen_mov_insv_1) (rtx, rtx);
10350 /* Handle insertions to %ah et al. */
10351 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10354 /* From mips.md: insert_bit_field doesn't verify that our source
10355 matches the predicate, so check it again here. */
10356 if (! ext_register_operand (operands[0], VOIDmode))
10359 gen_mov_insv_1 = (TARGET_64BIT
10360 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10362 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10366 ;; %%% bts, btr, btc, bt.
10367 ;; In general these instructions are *slow* when applied to memory,
10368 ;; since they enforce atomic operation. When applied to registers,
10369 ;; it depends on the cpu implementation. They're never faster than
10370 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10371 ;; no point. But in 64-bit, we can't hold the relevant immediates
10372 ;; within the instruction itself, so operating on bits in the high
10373 ;; 32-bits of a register becomes easier.
10375 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10376 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10377 ;; negdf respectively, so they can never be disabled entirely.
10379 (define_insn "*btsq"
10380 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10382 (match_operand:DI 1 "const_0_to_63_operand" ""))
10384 (clobber (reg:CC FLAGS_REG))]
10385 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10386 "bts{q}\t{%1, %0|%0, %1}"
10387 [(set_attr "type" "alu1")
10388 (set_attr "prefix_0f" "1")
10389 (set_attr "mode" "DI")])
10391 (define_insn "*btrq"
10392 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10394 (match_operand:DI 1 "const_0_to_63_operand" ""))
10396 (clobber (reg:CC FLAGS_REG))]
10397 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10398 "btr{q}\t{%1, %0|%0, %1}"
10399 [(set_attr "type" "alu1")
10400 (set_attr "prefix_0f" "1")
10401 (set_attr "mode" "DI")])
10403 (define_insn "*btcq"
10404 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10406 (match_operand:DI 1 "const_0_to_63_operand" ""))
10407 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10408 (clobber (reg:CC FLAGS_REG))]
10409 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10410 "btc{q}\t{%1, %0|%0, %1}"
10411 [(set_attr "type" "alu1")
10412 (set_attr "prefix_0f" "1")
10413 (set_attr "mode" "DI")])
10415 ;; Allow Nocona to avoid these instructions if a register is available.
10418 [(match_scratch:DI 2 "r")
10419 (parallel [(set (zero_extract:DI
10420 (match_operand:DI 0 "register_operand" "")
10422 (match_operand:DI 1 "const_0_to_63_operand" ""))
10424 (clobber (reg:CC FLAGS_REG))])]
10425 "TARGET_64BIT && !TARGET_USE_BT"
10428 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10431 if (HOST_BITS_PER_WIDE_INT >= 64)
10432 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10433 else if (i < HOST_BITS_PER_WIDE_INT)
10434 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10436 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10438 op1 = immed_double_const (lo, hi, DImode);
10441 emit_move_insn (operands[2], op1);
10445 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10450 [(match_scratch:DI 2 "r")
10451 (parallel [(set (zero_extract:DI
10452 (match_operand:DI 0 "register_operand" "")
10454 (match_operand:DI 1 "const_0_to_63_operand" ""))
10456 (clobber (reg:CC FLAGS_REG))])]
10457 "TARGET_64BIT && !TARGET_USE_BT"
10460 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10463 if (HOST_BITS_PER_WIDE_INT >= 64)
10464 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10465 else if (i < HOST_BITS_PER_WIDE_INT)
10466 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10468 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10470 op1 = immed_double_const (~lo, ~hi, DImode);
10473 emit_move_insn (operands[2], op1);
10477 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10482 [(match_scratch:DI 2 "r")
10483 (parallel [(set (zero_extract:DI
10484 (match_operand:DI 0 "register_operand" "")
10486 (match_operand:DI 1 "const_0_to_63_operand" ""))
10487 (not:DI (zero_extract:DI
10488 (match_dup 0) (const_int 1) (match_dup 1))))
10489 (clobber (reg:CC FLAGS_REG))])]
10490 "TARGET_64BIT && !TARGET_USE_BT"
10493 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10496 if (HOST_BITS_PER_WIDE_INT >= 64)
10497 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10498 else if (i < HOST_BITS_PER_WIDE_INT)
10499 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10501 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10503 op1 = immed_double_const (lo, hi, DImode);
10506 emit_move_insn (operands[2], op1);
10510 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10514 (define_insn "*bt<mode>"
10515 [(set (reg:CCC FLAGS_REG)
10517 (zero_extract:SWI48
10518 (match_operand:SWI48 0 "register_operand" "r")
10520 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10522 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10523 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10524 [(set_attr "type" "alu1")
10525 (set_attr "prefix_0f" "1")
10526 (set_attr "mode" "<MODE>")])
10528 ;; Store-flag instructions.
10530 ;; For all sCOND expanders, also expand the compare or test insn that
10531 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10533 (define_insn_and_split "*setcc_di_1"
10534 [(set (match_operand:DI 0 "register_operand" "=q")
10535 (match_operator:DI 1 "ix86_comparison_operator"
10536 [(reg FLAGS_REG) (const_int 0)]))]
10537 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10539 "&& reload_completed"
10540 [(set (match_dup 2) (match_dup 1))
10541 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10543 PUT_MODE (operands[1], QImode);
10544 operands[2] = gen_lowpart (QImode, operands[0]);
10547 (define_insn_and_split "*setcc_si_1_and"
10548 [(set (match_operand:SI 0 "register_operand" "=q")
10549 (match_operator:SI 1 "ix86_comparison_operator"
10550 [(reg FLAGS_REG) (const_int 0)]))
10551 (clobber (reg:CC FLAGS_REG))]
10552 "!TARGET_PARTIAL_REG_STALL
10553 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10555 "&& reload_completed"
10556 [(set (match_dup 2) (match_dup 1))
10557 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10558 (clobber (reg:CC FLAGS_REG))])]
10560 PUT_MODE (operands[1], QImode);
10561 operands[2] = gen_lowpart (QImode, operands[0]);
10564 (define_insn_and_split "*setcc_si_1_movzbl"
10565 [(set (match_operand:SI 0 "register_operand" "=q")
10566 (match_operator:SI 1 "ix86_comparison_operator"
10567 [(reg FLAGS_REG) (const_int 0)]))]
10568 "!TARGET_PARTIAL_REG_STALL
10569 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10571 "&& reload_completed"
10572 [(set (match_dup 2) (match_dup 1))
10573 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10575 PUT_MODE (operands[1], QImode);
10576 operands[2] = gen_lowpart (QImode, operands[0]);
10579 (define_insn "*setcc_qi"
10580 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10581 (match_operator:QI 1 "ix86_comparison_operator"
10582 [(reg FLAGS_REG) (const_int 0)]))]
10585 [(set_attr "type" "setcc")
10586 (set_attr "mode" "QI")])
10588 (define_insn "*setcc_qi_slp"
10589 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10590 (match_operator:QI 1 "ix86_comparison_operator"
10591 [(reg FLAGS_REG) (const_int 0)]))]
10594 [(set_attr "type" "setcc")
10595 (set_attr "mode" "QI")])
10597 ;; In general it is not safe to assume too much about CCmode registers,
10598 ;; so simplify-rtx stops when it sees a second one. Under certain
10599 ;; conditions this is safe on x86, so help combine not create
10606 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10607 (ne:QI (match_operator 1 "ix86_comparison_operator"
10608 [(reg FLAGS_REG) (const_int 0)])
10611 [(set (match_dup 0) (match_dup 1))]
10613 PUT_MODE (operands[1], QImode);
10617 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10618 (ne:QI (match_operator 1 "ix86_comparison_operator"
10619 [(reg FLAGS_REG) (const_int 0)])
10622 [(set (match_dup 0) (match_dup 1))]
10624 PUT_MODE (operands[1], QImode);
10628 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10629 (eq:QI (match_operator 1 "ix86_comparison_operator"
10630 [(reg FLAGS_REG) (const_int 0)])
10633 [(set (match_dup 0) (match_dup 1))]
10635 rtx new_op1 = copy_rtx (operands[1]);
10636 operands[1] = new_op1;
10637 PUT_MODE (new_op1, QImode);
10638 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10639 GET_MODE (XEXP (new_op1, 0))));
10641 /* Make sure that (a) the CCmode we have for the flags is strong
10642 enough for the reversed compare or (b) we have a valid FP compare. */
10643 if (! ix86_comparison_operator (new_op1, VOIDmode))
10648 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10649 (eq:QI (match_operator 1 "ix86_comparison_operator"
10650 [(reg FLAGS_REG) (const_int 0)])
10653 [(set (match_dup 0) (match_dup 1))]
10655 rtx new_op1 = copy_rtx (operands[1]);
10656 operands[1] = new_op1;
10657 PUT_MODE (new_op1, QImode);
10658 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10659 GET_MODE (XEXP (new_op1, 0))));
10661 /* Make sure that (a) the CCmode we have for the flags is strong
10662 enough for the reversed compare or (b) we have a valid FP compare. */
10663 if (! ix86_comparison_operator (new_op1, VOIDmode))
10667 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10668 ;; subsequent logical operations are used to imitate conditional moves.
10669 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10672 (define_insn "*avx_setcc<mode>"
10673 [(set (match_operand:MODEF 0 "register_operand" "=x")
10674 (match_operator:MODEF 1 "avx_comparison_float_operator"
10675 [(match_operand:MODEF 2 "register_operand" "x")
10676 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10678 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10679 [(set_attr "type" "ssecmp")
10680 (set_attr "prefix" "vex")
10681 (set_attr "length_immediate" "1")
10682 (set_attr "mode" "<MODE>")])
10684 (define_insn "*sse_setcc<mode>"
10685 [(set (match_operand:MODEF 0 "register_operand" "=x")
10686 (match_operator:MODEF 1 "sse_comparison_operator"
10687 [(match_operand:MODEF 2 "register_operand" "0")
10688 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10689 "SSE_FLOAT_MODE_P (<MODE>mode)"
10690 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10691 [(set_attr "type" "ssecmp")
10692 (set_attr "length_immediate" "1")
10693 (set_attr "mode" "<MODE>")])
10695 ;; Basic conditional jump instructions.
10696 ;; We ignore the overflow flag for signed branch instructions.
10698 (define_insn "*jcc_1"
10700 (if_then_else (match_operator 1 "ix86_comparison_operator"
10701 [(reg FLAGS_REG) (const_int 0)])
10702 (label_ref (match_operand 0 "" ""))
10706 [(set_attr "type" "ibr")
10707 (set_attr "modrm" "0")
10708 (set (attr "length")
10709 (if_then_else (and (ge (minus (match_dup 0) (pc))
10711 (lt (minus (match_dup 0) (pc))
10716 (define_insn "*jcc_2"
10718 (if_then_else (match_operator 1 "ix86_comparison_operator"
10719 [(reg FLAGS_REG) (const_int 0)])
10721 (label_ref (match_operand 0 "" ""))))]
10724 [(set_attr "type" "ibr")
10725 (set_attr "modrm" "0")
10726 (set (attr "length")
10727 (if_then_else (and (ge (minus (match_dup 0) (pc))
10729 (lt (minus (match_dup 0) (pc))
10734 ;; In general it is not safe to assume too much about CCmode registers,
10735 ;; so simplify-rtx stops when it sees a second one. Under certain
10736 ;; conditions this is safe on x86, so help combine not create
10744 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10745 [(reg FLAGS_REG) (const_int 0)])
10747 (label_ref (match_operand 1 "" ""))
10751 (if_then_else (match_dup 0)
10752 (label_ref (match_dup 1))
10755 PUT_MODE (operands[0], VOIDmode);
10760 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10761 [(reg FLAGS_REG) (const_int 0)])
10763 (label_ref (match_operand 1 "" ""))
10767 (if_then_else (match_dup 0)
10768 (label_ref (match_dup 1))
10771 rtx new_op0 = copy_rtx (operands[0]);
10772 operands[0] = new_op0;
10773 PUT_MODE (new_op0, VOIDmode);
10774 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10775 GET_MODE (XEXP (new_op0, 0))));
10777 /* Make sure that (a) the CCmode we have for the flags is strong
10778 enough for the reversed compare or (b) we have a valid FP compare. */
10779 if (! ix86_comparison_operator (new_op0, VOIDmode))
10783 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10784 ;; pass generates from shift insn with QImode operand. Actually, the mode
10785 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10786 ;; appropriate modulo of the bit offset value.
10788 (define_insn_and_split "*jcc_bt<mode>"
10790 (if_then_else (match_operator 0 "bt_comparison_operator"
10791 [(zero_extract:SWI48
10792 (match_operand:SWI48 1 "register_operand" "r")
10795 (match_operand:QI 2 "register_operand" "r")))
10797 (label_ref (match_operand 3 "" ""))
10799 (clobber (reg:CC FLAGS_REG))]
10800 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10803 [(set (reg:CCC FLAGS_REG)
10805 (zero_extract:SWI48
10811 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10812 (label_ref (match_dup 3))
10815 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10817 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10820 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10821 ;; also for DImode, this is what combine produces.
10822 (define_insn_and_split "*jcc_bt<mode>_mask"
10824 (if_then_else (match_operator 0 "bt_comparison_operator"
10825 [(zero_extract:SWI48
10826 (match_operand:SWI48 1 "register_operand" "r")
10829 (match_operand:SI 2 "register_operand" "r")
10830 (match_operand:SI 3 "const_int_operand" "n")))])
10831 (label_ref (match_operand 4 "" ""))
10833 (clobber (reg:CC FLAGS_REG))]
10834 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10835 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10836 == GET_MODE_BITSIZE (<MODE>mode)-1"
10839 [(set (reg:CCC FLAGS_REG)
10841 (zero_extract:SWI48
10847 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10848 (label_ref (match_dup 4))
10851 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10853 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10856 (define_insn_and_split "*jcc_btsi_1"
10858 (if_then_else (match_operator 0 "bt_comparison_operator"
10861 (match_operand:SI 1 "register_operand" "r")
10862 (match_operand:QI 2 "register_operand" "r"))
10865 (label_ref (match_operand 3 "" ""))
10867 (clobber (reg:CC FLAGS_REG))]
10868 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10871 [(set (reg:CCC FLAGS_REG)
10879 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10880 (label_ref (match_dup 3))
10883 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10885 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10888 ;; avoid useless masking of bit offset operand
10889 (define_insn_and_split "*jcc_btsi_mask_1"
10892 (match_operator 0 "bt_comparison_operator"
10895 (match_operand:SI 1 "register_operand" "r")
10898 (match_operand:SI 2 "register_operand" "r")
10899 (match_operand:SI 3 "const_int_operand" "n")) 0))
10902 (label_ref (match_operand 4 "" ""))
10904 (clobber (reg:CC FLAGS_REG))]
10905 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10906 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10909 [(set (reg:CCC FLAGS_REG)
10917 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10918 (label_ref (match_dup 4))
10920 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10922 ;; Define combination compare-and-branch fp compare instructions to help
10925 (define_insn "*fp_jcc_1_387"
10927 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10928 [(match_operand 1 "register_operand" "f")
10929 (match_operand 2 "nonimmediate_operand" "fm")])
10930 (label_ref (match_operand 3 "" ""))
10932 (clobber (reg:CCFP FPSR_REG))
10933 (clobber (reg:CCFP FLAGS_REG))
10934 (clobber (match_scratch:HI 4 "=a"))]
10936 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10937 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10938 && SELECT_CC_MODE (GET_CODE (operands[0]),
10939 operands[1], operands[2]) == CCFPmode
10943 (define_insn "*fp_jcc_1r_387"
10945 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10946 [(match_operand 1 "register_operand" "f")
10947 (match_operand 2 "nonimmediate_operand" "fm")])
10949 (label_ref (match_operand 3 "" ""))))
10950 (clobber (reg:CCFP FPSR_REG))
10951 (clobber (reg:CCFP FLAGS_REG))
10952 (clobber (match_scratch:HI 4 "=a"))]
10954 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10955 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10956 && SELECT_CC_MODE (GET_CODE (operands[0]),
10957 operands[1], operands[2]) == CCFPmode
10961 (define_insn "*fp_jcc_2_387"
10963 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10964 [(match_operand 1 "register_operand" "f")
10965 (match_operand 2 "register_operand" "f")])
10966 (label_ref (match_operand 3 "" ""))
10968 (clobber (reg:CCFP FPSR_REG))
10969 (clobber (reg:CCFP FLAGS_REG))
10970 (clobber (match_scratch:HI 4 "=a"))]
10971 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10972 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10976 (define_insn "*fp_jcc_2r_387"
10978 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10979 [(match_operand 1 "register_operand" "f")
10980 (match_operand 2 "register_operand" "f")])
10982 (label_ref (match_operand 3 "" ""))))
10983 (clobber (reg:CCFP FPSR_REG))
10984 (clobber (reg:CCFP FLAGS_REG))
10985 (clobber (match_scratch:HI 4 "=a"))]
10986 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10987 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10991 (define_insn "*fp_jcc_3_387"
10993 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10994 [(match_operand 1 "register_operand" "f")
10995 (match_operand 2 "const0_operand" "")])
10996 (label_ref (match_operand 3 "" ""))
10998 (clobber (reg:CCFP FPSR_REG))
10999 (clobber (reg:CCFP FLAGS_REG))
11000 (clobber (match_scratch:HI 4 "=a"))]
11001 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11002 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11003 && SELECT_CC_MODE (GET_CODE (operands[0]),
11004 operands[1], operands[2]) == CCFPmode
11010 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11011 [(match_operand 1 "register_operand" "")
11012 (match_operand 2 "nonimmediate_operand" "")])
11013 (match_operand 3 "" "")
11014 (match_operand 4 "" "")))
11015 (clobber (reg:CCFP FPSR_REG))
11016 (clobber (reg:CCFP FLAGS_REG))]
11020 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11021 operands[3], operands[4], NULL_RTX, NULL_RTX);
11027 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11028 [(match_operand 1 "register_operand" "")
11029 (match_operand 2 "general_operand" "")])
11030 (match_operand 3 "" "")
11031 (match_operand 4 "" "")))
11032 (clobber (reg:CCFP FPSR_REG))
11033 (clobber (reg:CCFP FLAGS_REG))
11034 (clobber (match_scratch:HI 5 "=a"))]
11038 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11039 operands[3], operands[4], operands[5], NULL_RTX);
11043 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11044 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11045 ;; with a precedence over other operators and is always put in the first
11046 ;; place. Swap condition and operands to match ficom instruction.
11048 (define_insn "*fp_jcc_4_<mode>_387"
11051 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11052 [(match_operator 1 "float_operator"
11053 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11054 (match_operand 3 "register_operand" "f,f")])
11055 (label_ref (match_operand 4 "" ""))
11057 (clobber (reg:CCFP FPSR_REG))
11058 (clobber (reg:CCFP FLAGS_REG))
11059 (clobber (match_scratch:HI 5 "=a,a"))]
11060 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11061 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11062 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11063 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11070 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11071 [(match_operator 1 "float_operator"
11072 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11073 (match_operand 3 "register_operand" "")])
11074 (match_operand 4 "" "")
11075 (match_operand 5 "" "")))
11076 (clobber (reg:CCFP FPSR_REG))
11077 (clobber (reg:CCFP FLAGS_REG))
11078 (clobber (match_scratch:HI 6 "=a"))]
11082 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11084 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11085 operands[3], operands[7],
11086 operands[4], operands[5], operands[6], NULL_RTX);
11090 ;; %%% Kill this when reload knows how to do it.
11094 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11095 [(match_operator 1 "float_operator"
11096 [(match_operand:X87MODEI12 2 "register_operand" "")])
11097 (match_operand 3 "register_operand" "")])
11098 (match_operand 4 "" "")
11099 (match_operand 5 "" "")))
11100 (clobber (reg:CCFP FPSR_REG))
11101 (clobber (reg:CCFP FLAGS_REG))
11102 (clobber (match_scratch:HI 6 "=a"))]
11106 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11107 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11109 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11110 operands[3], operands[7],
11111 operands[4], operands[5], operands[6], operands[2]);
11115 ;; Unconditional and other jump instructions
11117 (define_insn "jump"
11119 (label_ref (match_operand 0 "" "")))]
11122 [(set_attr "type" "ibr")
11123 (set (attr "length")
11124 (if_then_else (and (ge (minus (match_dup 0) (pc))
11126 (lt (minus (match_dup 0) (pc))
11130 (set_attr "modrm" "0")])
11132 (define_expand "indirect_jump"
11133 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11137 (define_insn "*indirect_jump"
11138 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11141 [(set_attr "type" "ibr")
11142 (set_attr "length_immediate" "0")])
11144 (define_expand "tablejump"
11145 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11146 (use (label_ref (match_operand 1 "" "")))])]
11149 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11150 relative. Convert the relative address to an absolute address. */
11154 enum rtx_code code;
11156 /* We can't use @GOTOFF for text labels on VxWorks;
11157 see gotoff_operand. */
11158 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11162 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11164 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11168 op1 = pic_offset_table_rtx;
11173 op0 = pic_offset_table_rtx;
11177 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11182 (define_insn "*tablejump_1"
11183 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11184 (use (label_ref (match_operand 1 "" "")))]
11187 [(set_attr "type" "ibr")
11188 (set_attr "length_immediate" "0")])
11190 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11193 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11194 (set (match_operand:QI 1 "register_operand" "")
11195 (match_operator:QI 2 "ix86_comparison_operator"
11196 [(reg FLAGS_REG) (const_int 0)]))
11197 (set (match_operand 3 "q_regs_operand" "")
11198 (zero_extend (match_dup 1)))]
11199 "(peep2_reg_dead_p (3, operands[1])
11200 || operands_match_p (operands[1], operands[3]))
11201 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11202 [(set (match_dup 4) (match_dup 0))
11203 (set (strict_low_part (match_dup 5))
11206 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11207 operands[5] = gen_lowpart (QImode, operands[3]);
11208 ix86_expand_clear (operands[3]);
11211 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11214 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11215 (set (match_operand:QI 1 "register_operand" "")
11216 (match_operator:QI 2 "ix86_comparison_operator"
11217 [(reg FLAGS_REG) (const_int 0)]))
11218 (parallel [(set (match_operand 3 "q_regs_operand" "")
11219 (zero_extend (match_dup 1)))
11220 (clobber (reg:CC FLAGS_REG))])]
11221 "(peep2_reg_dead_p (3, operands[1])
11222 || operands_match_p (operands[1], operands[3]))
11223 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11224 [(set (match_dup 4) (match_dup 0))
11225 (set (strict_low_part (match_dup 5))
11228 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11229 operands[5] = gen_lowpart (QImode, operands[3]);
11230 ix86_expand_clear (operands[3]);
11233 ;; Call instructions.
11235 ;; The predicates normally associated with named expanders are not properly
11236 ;; checked for calls. This is a bug in the generic code, but it isn't that
11237 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11239 ;; P6 processors will jump to the address after the decrement when %esp
11240 ;; is used as a call operand, so they will execute return address as a code.
11241 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11243 ;; Call subroutine returning no value.
11245 (define_expand "call_pop"
11246 [(parallel [(call (match_operand:QI 0 "" "")
11247 (match_operand:SI 1 "" ""))
11248 (set (reg:SI SP_REG)
11249 (plus:SI (reg:SI SP_REG)
11250 (match_operand:SI 3 "" "")))])]
11253 ix86_expand_call (NULL, operands[0], operands[1],
11254 operands[2], operands[3], 0);
11258 (define_insn "*call_pop_0"
11259 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11260 (match_operand:SI 1 "" ""))
11261 (set (reg:SI SP_REG)
11262 (plus:SI (reg:SI SP_REG)
11263 (match_operand:SI 2 "immediate_operand" "")))]
11266 if (SIBLING_CALL_P (insn))
11269 return "call\t%P0";
11271 [(set_attr "type" "call")])
11273 (define_insn "*call_pop_1"
11274 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11275 (match_operand:SI 1 "" ""))
11276 (set (reg:SI SP_REG)
11277 (plus:SI (reg:SI SP_REG)
11278 (match_operand:SI 2 "immediate_operand" "i")))]
11279 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11281 if (constant_call_address_operand (operands[0], Pmode))
11282 return "call\t%P0";
11283 return "call\t%A0";
11285 [(set_attr "type" "call")])
11287 (define_insn "*sibcall_pop_1"
11288 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11289 (match_operand:SI 1 "" ""))
11290 (set (reg:SI SP_REG)
11291 (plus:SI (reg:SI SP_REG)
11292 (match_operand:SI 2 "immediate_operand" "i,i")))]
11293 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11297 [(set_attr "type" "call")])
11299 (define_expand "call"
11300 [(call (match_operand:QI 0 "" "")
11301 (match_operand 1 "" ""))
11302 (use (match_operand 2 "" ""))]
11305 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11309 (define_expand "sibcall"
11310 [(call (match_operand:QI 0 "" "")
11311 (match_operand 1 "" ""))
11312 (use (match_operand 2 "" ""))]
11315 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11319 (define_insn "*call_0"
11320 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11321 (match_operand 1 "" ""))]
11324 if (SIBLING_CALL_P (insn))
11327 return "call\t%P0";
11329 [(set_attr "type" "call")])
11331 (define_insn "*call_1"
11332 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11333 (match_operand 1 "" ""))]
11334 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11336 if (constant_call_address_operand (operands[0], Pmode))
11337 return "call\t%P0";
11338 return "call\t%A0";
11340 [(set_attr "type" "call")])
11342 (define_insn "*sibcall_1"
11343 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11344 (match_operand 1 "" ""))]
11345 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11349 [(set_attr "type" "call")])
11351 (define_insn "*call_1_rex64"
11352 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11353 (match_operand 1 "" ""))]
11354 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11355 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11357 if (constant_call_address_operand (operands[0], Pmode))
11358 return "call\t%P0";
11359 return "call\t%A0";
11361 [(set_attr "type" "call")])
11363 (define_insn "*call_1_rex64_ms_sysv"
11364 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11365 (match_operand 1 "" ""))
11366 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11367 (clobber (reg:TI XMM6_REG))
11368 (clobber (reg:TI XMM7_REG))
11369 (clobber (reg:TI XMM8_REG))
11370 (clobber (reg:TI XMM9_REG))
11371 (clobber (reg:TI XMM10_REG))
11372 (clobber (reg:TI XMM11_REG))
11373 (clobber (reg:TI XMM12_REG))
11374 (clobber (reg:TI XMM13_REG))
11375 (clobber (reg:TI XMM14_REG))
11376 (clobber (reg:TI XMM15_REG))
11377 (clobber (reg:DI SI_REG))
11378 (clobber (reg:DI DI_REG))]
11379 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11381 if (constant_call_address_operand (operands[0], Pmode))
11382 return "call\t%P0";
11383 return "call\t%A0";
11385 [(set_attr "type" "call")])
11387 (define_insn "*call_1_rex64_large"
11388 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11389 (match_operand 1 "" ""))]
11390 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11392 [(set_attr "type" "call")])
11394 (define_insn "*sibcall_1_rex64"
11395 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11396 (match_operand 1 "" ""))]
11397 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11401 [(set_attr "type" "call")])
11403 ;; Call subroutine, returning value in operand 0
11404 (define_expand "call_value_pop"
11405 [(parallel [(set (match_operand 0 "" "")
11406 (call (match_operand:QI 1 "" "")
11407 (match_operand:SI 2 "" "")))
11408 (set (reg:SI SP_REG)
11409 (plus:SI (reg:SI SP_REG)
11410 (match_operand:SI 4 "" "")))])]
11413 ix86_expand_call (operands[0], operands[1], operands[2],
11414 operands[3], operands[4], 0);
11418 (define_expand "call_value"
11419 [(set (match_operand 0 "" "")
11420 (call (match_operand:QI 1 "" "")
11421 (match_operand:SI 2 "" "")))
11422 (use (match_operand:SI 3 "" ""))]
11423 ;; Operand 3 is not used on the i386.
11426 ix86_expand_call (operands[0], operands[1], operands[2],
11427 operands[3], NULL, 0);
11431 (define_expand "sibcall_value"
11432 [(set (match_operand 0 "" "")
11433 (call (match_operand:QI 1 "" "")
11434 (match_operand:SI 2 "" "")))
11435 (use (match_operand:SI 3 "" ""))]
11436 ;; Operand 3 is not used on the i386.
11439 ix86_expand_call (operands[0], operands[1], operands[2],
11440 operands[3], NULL, 1);
11444 ;; Call subroutine returning any type.
11446 (define_expand "untyped_call"
11447 [(parallel [(call (match_operand 0 "" "")
11449 (match_operand 1 "" "")
11450 (match_operand 2 "" "")])]
11455 /* In order to give reg-stack an easier job in validating two
11456 coprocessor registers as containing a possible return value,
11457 simply pretend the untyped call returns a complex long double
11460 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11461 and should have the default ABI. */
11463 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11464 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11465 operands[0], const0_rtx,
11466 GEN_INT ((TARGET_64BIT
11467 ? (ix86_abi == SYSV_ABI
11468 ? X86_64_SSE_REGPARM_MAX
11469 : X86_64_MS_SSE_REGPARM_MAX)
11470 : X86_32_SSE_REGPARM_MAX)
11474 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11476 rtx set = XVECEXP (operands[2], 0, i);
11477 emit_move_insn (SET_DEST (set), SET_SRC (set));
11480 /* The optimizer does not know that the call sets the function value
11481 registers we stored in the result block. We avoid problems by
11482 claiming that all hard registers are used and clobbered at this
11484 emit_insn (gen_blockage ());
11489 ;; Prologue and epilogue instructions
11491 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11492 ;; all of memory. This blocks insns from being moved across this point.
11494 (define_insn "blockage"
11495 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11498 [(set_attr "length" "0")])
11500 ;; Do not schedule instructions accessing memory across this point.
11502 (define_expand "memory_blockage"
11503 [(set (match_dup 0)
11504 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11507 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11508 MEM_VOLATILE_P (operands[0]) = 1;
11511 (define_insn "*memory_blockage"
11512 [(set (match_operand:BLK 0 "" "")
11513 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11516 [(set_attr "length" "0")])
11518 ;; As USE insns aren't meaningful after reload, this is used instead
11519 ;; to prevent deleting instructions setting registers for PIC code
11520 (define_insn "prologue_use"
11521 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11524 [(set_attr "length" "0")])
11526 ;; Insn emitted into the body of a function to return from a function.
11527 ;; This is only done if the function's epilogue is known to be simple.
11528 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11530 (define_expand "return"
11532 "ix86_can_use_return_insn_p ()"
11534 if (crtl->args.pops_args)
11536 rtx popc = GEN_INT (crtl->args.pops_args);
11537 emit_jump_insn (gen_return_pop_internal (popc));
11542 (define_insn "return_internal"
11546 [(set_attr "length" "1")
11547 (set_attr "atom_unit" "jeu")
11548 (set_attr "length_immediate" "0")
11549 (set_attr "modrm" "0")])
11551 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11552 ;; instruction Athlon and K8 have.
11554 (define_insn "return_internal_long"
11556 (unspec [(const_int 0)] UNSPEC_REP)]
11559 [(set_attr "length" "2")
11560 (set_attr "atom_unit" "jeu")
11561 (set_attr "length_immediate" "0")
11562 (set_attr "prefix_rep" "1")
11563 (set_attr "modrm" "0")])
11565 (define_insn "return_pop_internal"
11567 (use (match_operand:SI 0 "const_int_operand" ""))]
11570 [(set_attr "length" "3")
11571 (set_attr "atom_unit" "jeu")
11572 (set_attr "length_immediate" "2")
11573 (set_attr "modrm" "0")])
11575 (define_insn "return_indirect_internal"
11577 (use (match_operand:SI 0 "register_operand" "r"))]
11580 [(set_attr "type" "ibr")
11581 (set_attr "length_immediate" "0")])
11587 [(set_attr "length" "1")
11588 (set_attr "length_immediate" "0")
11589 (set_attr "modrm" "0")])
11591 (define_insn "vswapmov"
11592 [(set (match_operand:SI 0 "register_operand" "=r")
11593 (match_operand:SI 1 "register_operand" "r"))
11594 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
11596 "movl.s\t{%1, %0|%0, %1}"
11597 [(set_attr "length" "2")
11598 (set_attr "length_immediate" "0")
11599 (set_attr "modrm" "0")])
11601 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11602 ;; branch prediction penalty for the third jump in a 16-byte
11606 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11609 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11610 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11612 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11613 The align insn is used to avoid 3 jump instructions in the row to improve
11614 branch prediction and the benefits hardly outweigh the cost of extra 8
11615 nops on the average inserted by full alignment pseudo operation. */
11619 [(set_attr "length" "16")])
11621 (define_expand "prologue"
11624 "ix86_expand_prologue (); DONE;")
11626 (define_insn "set_got"
11627 [(set (match_operand:SI 0 "register_operand" "=r")
11628 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11629 (clobber (reg:CC FLAGS_REG))]
11631 { return output_set_got (operands[0], NULL_RTX); }
11632 [(set_attr "type" "multi")
11633 (set_attr "length" "12")])
11635 (define_insn "set_got_labelled"
11636 [(set (match_operand:SI 0 "register_operand" "=r")
11637 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11639 (clobber (reg:CC FLAGS_REG))]
11641 { return output_set_got (operands[0], operands[1]); }
11642 [(set_attr "type" "multi")
11643 (set_attr "length" "12")])
11645 (define_insn "set_got_rex64"
11646 [(set (match_operand:DI 0 "register_operand" "=r")
11647 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11649 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11650 [(set_attr "type" "lea")
11651 (set_attr "length_address" "4")
11652 (set_attr "mode" "DI")])
11654 (define_insn "set_rip_rex64"
11655 [(set (match_operand:DI 0 "register_operand" "=r")
11656 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11658 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11659 [(set_attr "type" "lea")
11660 (set_attr "length_address" "4")
11661 (set_attr "mode" "DI")])
11663 (define_insn "set_got_offset_rex64"
11664 [(set (match_operand:DI 0 "register_operand" "=r")
11666 [(label_ref (match_operand 1 "" ""))]
11667 UNSPEC_SET_GOT_OFFSET))]
11669 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11670 [(set_attr "type" "imov")
11671 (set_attr "length_immediate" "0")
11672 (set_attr "length_address" "8")
11673 (set_attr "mode" "DI")])
11675 (define_expand "epilogue"
11678 "ix86_expand_epilogue (1); DONE;")
11680 (define_expand "sibcall_epilogue"
11683 "ix86_expand_epilogue (0); DONE;")
11685 (define_expand "eh_return"
11686 [(use (match_operand 0 "register_operand" ""))]
11689 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11691 /* Tricky bit: we write the address of the handler to which we will
11692 be returning into someone else's stack frame, one word below the
11693 stack address we wish to restore. */
11694 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11695 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11696 tmp = gen_rtx_MEM (Pmode, tmp);
11697 emit_move_insn (tmp, ra);
11699 emit_jump_insn (gen_eh_return_internal ());
11704 (define_insn_and_split "eh_return_internal"
11708 "epilogue_completed"
11710 "ix86_expand_epilogue (2); DONE;")
11712 (define_insn "leave"
11713 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11714 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11715 (clobber (mem:BLK (scratch)))]
11718 [(set_attr "type" "leave")])
11720 (define_insn "leave_rex64"
11721 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11722 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11723 (clobber (mem:BLK (scratch)))]
11726 [(set_attr "type" "leave")])
11728 ;; Bit manipulation instructions.
11730 (define_expand "ffs<mode>2"
11731 [(set (match_dup 2) (const_int -1))
11732 (parallel [(set (reg:CCZ FLAGS_REG)
11734 (match_operand:SWI48 1 "nonimmediate_operand" "")
11736 (set (match_operand:SWI48 0 "register_operand" "")
11737 (ctz:SWI48 (match_dup 1)))])
11738 (set (match_dup 0) (if_then_else:SWI48
11739 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11742 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11743 (clobber (reg:CC FLAGS_REG))])]
11746 if (<MODE>mode == SImode && !TARGET_CMOVE)
11748 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11751 operands[2] = gen_reg_rtx (<MODE>mode);
11754 (define_insn_and_split "ffssi2_no_cmove"
11755 [(set (match_operand:SI 0 "register_operand" "=r")
11756 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11757 (clobber (match_scratch:SI 2 "=&q"))
11758 (clobber (reg:CC FLAGS_REG))]
11761 "&& reload_completed"
11762 [(parallel [(set (reg:CCZ FLAGS_REG)
11763 (compare:CCZ (match_dup 1) (const_int 0)))
11764 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11765 (set (strict_low_part (match_dup 3))
11766 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11767 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11768 (clobber (reg:CC FLAGS_REG))])
11769 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11770 (clobber (reg:CC FLAGS_REG))])
11771 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11772 (clobber (reg:CC FLAGS_REG))])]
11774 operands[3] = gen_lowpart (QImode, operands[2]);
11775 ix86_expand_clear (operands[2]);
11778 (define_insn "*ffs<mode>_1"
11779 [(set (reg:CCZ FLAGS_REG)
11780 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11782 (set (match_operand:SWI48 0 "register_operand" "=r")
11783 (ctz:SWI48 (match_dup 1)))]
11785 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11786 [(set_attr "type" "alu1")
11787 (set_attr "prefix_0f" "1")
11788 (set_attr "mode" "<MODE>")])
11790 (define_insn "ctz<mode>2"
11791 [(set (match_operand:SWI48 0 "register_operand" "=r")
11792 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11793 (clobber (reg:CC FLAGS_REG))]
11795 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11796 [(set_attr "type" "alu1")
11797 (set_attr "prefix_0f" "1")
11798 (set_attr "mode" "<MODE>")])
11800 (define_expand "clz<mode>2"
11802 [(set (match_operand:SWI248 0 "register_operand" "")
11805 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11806 (clobber (reg:CC FLAGS_REG))])
11808 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11809 (clobber (reg:CC FLAGS_REG))])]
11814 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11817 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11820 (define_insn "clz<mode>2_abm"
11821 [(set (match_operand:SWI248 0 "register_operand" "=r")
11822 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11823 (clobber (reg:CC FLAGS_REG))]
11825 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11826 [(set_attr "prefix_rep" "1")
11827 (set_attr "type" "bitmanip")
11828 (set_attr "mode" "<MODE>")])
11830 (define_insn "bsr_rex64"
11831 [(set (match_operand:DI 0 "register_operand" "=r")
11832 (minus:DI (const_int 63)
11833 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11834 (clobber (reg:CC FLAGS_REG))]
11836 "bsr{q}\t{%1, %0|%0, %1}"
11837 [(set_attr "type" "alu1")
11838 (set_attr "prefix_0f" "1")
11839 (set_attr "mode" "DI")])
11842 [(set (match_operand:SI 0 "register_operand" "=r")
11843 (minus:SI (const_int 31)
11844 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11845 (clobber (reg:CC FLAGS_REG))]
11847 "bsr{l}\t{%1, %0|%0, %1}"
11848 [(set_attr "type" "alu1")
11849 (set_attr "prefix_0f" "1")
11850 (set_attr "mode" "SI")])
11852 (define_insn "*bsrhi"
11853 [(set (match_operand:HI 0 "register_operand" "=r")
11854 (minus:HI (const_int 15)
11855 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11856 (clobber (reg:CC FLAGS_REG))]
11858 "bsr{w}\t{%1, %0|%0, %1}"
11859 [(set_attr "type" "alu1")
11860 (set_attr "prefix_0f" "1")
11861 (set_attr "mode" "HI")])
11863 (define_insn "popcount<mode>2"
11864 [(set (match_operand:SWI248 0 "register_operand" "=r")
11866 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11867 (clobber (reg:CC FLAGS_REG))]
11871 return "popcnt\t{%1, %0|%0, %1}";
11873 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11876 [(set_attr "prefix_rep" "1")
11877 (set_attr "type" "bitmanip")
11878 (set_attr "mode" "<MODE>")])
11880 (define_insn "*popcount<mode>2_cmp"
11881 [(set (reg FLAGS_REG)
11884 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11886 (set (match_operand:SWI248 0 "register_operand" "=r")
11887 (popcount:SWI248 (match_dup 1)))]
11888 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11891 return "popcnt\t{%1, %0|%0, %1}";
11893 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11896 [(set_attr "prefix_rep" "1")
11897 (set_attr "type" "bitmanip")
11898 (set_attr "mode" "<MODE>")])
11900 (define_insn "*popcountsi2_cmp_zext"
11901 [(set (reg FLAGS_REG)
11903 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11905 (set (match_operand:DI 0 "register_operand" "=r")
11906 (zero_extend:DI(popcount:SI (match_dup 1))))]
11907 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11910 return "popcnt\t{%1, %0|%0, %1}";
11912 return "popcnt{l}\t{%1, %0|%0, %1}";
11915 [(set_attr "prefix_rep" "1")
11916 (set_attr "type" "bitmanip")
11917 (set_attr "mode" "SI")])
11919 (define_expand "bswap<mode>2"
11920 [(set (match_operand:SWI48 0 "register_operand" "")
11921 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11924 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11926 rtx x = operands[0];
11928 emit_move_insn (x, operands[1]);
11929 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11930 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11931 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11936 (define_insn "*bswap<mode>2_movbe"
11937 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11938 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11940 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11943 movbe\t{%1, %0|%0, %1}
11944 movbe\t{%1, %0|%0, %1}"
11945 [(set_attr "type" "bitmanip,imov,imov")
11946 (set_attr "modrm" "0,1,1")
11947 (set_attr "prefix_0f" "*,1,1")
11948 (set_attr "prefix_extra" "*,1,1")
11949 (set_attr "mode" "<MODE>")])
11951 (define_insn "*bswap<mode>2_1"
11952 [(set (match_operand:SWI48 0 "register_operand" "=r")
11953 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11956 [(set_attr "type" "bitmanip")
11957 (set_attr "modrm" "0")
11958 (set_attr "mode" "<MODE>")])
11960 (define_insn "*bswaphi_lowpart_1"
11961 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11962 (bswap:HI (match_dup 0)))
11963 (clobber (reg:CC FLAGS_REG))]
11964 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11966 xchg{b}\t{%h0, %b0|%b0, %h0}
11967 rol{w}\t{$8, %0|%0, 8}"
11968 [(set_attr "length" "2,4")
11969 (set_attr "mode" "QI,HI")])
11971 (define_insn "bswaphi_lowpart"
11972 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11973 (bswap:HI (match_dup 0)))
11974 (clobber (reg:CC FLAGS_REG))]
11976 "rol{w}\t{$8, %0|%0, 8}"
11977 [(set_attr "length" "4")
11978 (set_attr "mode" "HI")])
11980 (define_expand "paritydi2"
11981 [(set (match_operand:DI 0 "register_operand" "")
11982 (parity:DI (match_operand:DI 1 "register_operand" "")))]
11985 rtx scratch = gen_reg_rtx (QImode);
11988 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
11989 NULL_RTX, operands[1]));
11991 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11992 gen_rtx_REG (CCmode, FLAGS_REG),
11994 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11997 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12000 rtx tmp = gen_reg_rtx (SImode);
12002 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12003 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12008 (define_expand "paritysi2"
12009 [(set (match_operand:SI 0 "register_operand" "")
12010 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12013 rtx scratch = gen_reg_rtx (QImode);
12016 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12018 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12019 gen_rtx_REG (CCmode, FLAGS_REG),
12021 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12023 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12027 (define_insn_and_split "paritydi2_cmp"
12028 [(set (reg:CC FLAGS_REG)
12029 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12031 (clobber (match_scratch:DI 0 "=r"))
12032 (clobber (match_scratch:SI 1 "=&r"))
12033 (clobber (match_scratch:HI 2 "=Q"))]
12036 "&& reload_completed"
12038 [(set (match_dup 1)
12039 (xor:SI (match_dup 1) (match_dup 4)))
12040 (clobber (reg:CC FLAGS_REG))])
12042 [(set (reg:CC FLAGS_REG)
12043 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12044 (clobber (match_dup 1))
12045 (clobber (match_dup 2))])]
12047 operands[4] = gen_lowpart (SImode, operands[3]);
12051 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12052 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12055 operands[1] = gen_highpart (SImode, operands[3]);
12058 (define_insn_and_split "paritysi2_cmp"
12059 [(set (reg:CC FLAGS_REG)
12060 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12062 (clobber (match_scratch:SI 0 "=r"))
12063 (clobber (match_scratch:HI 1 "=&Q"))]
12066 "&& reload_completed"
12068 [(set (match_dup 1)
12069 (xor:HI (match_dup 1) (match_dup 3)))
12070 (clobber (reg:CC FLAGS_REG))])
12072 [(set (reg:CC FLAGS_REG)
12073 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12074 (clobber (match_dup 1))])]
12076 operands[3] = gen_lowpart (HImode, operands[2]);
12078 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12079 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12082 (define_insn "*parityhi2_cmp"
12083 [(set (reg:CC FLAGS_REG)
12084 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12086 (clobber (match_scratch:HI 0 "=Q"))]
12088 "xor{b}\t{%h0, %b0|%b0, %h0}"
12089 [(set_attr "length" "2")
12090 (set_attr "mode" "HI")])
12092 ;; Thread-local storage patterns for ELF.
12094 ;; Note that these code sequences must appear exactly as shown
12095 ;; in order to allow linker relaxation.
12097 (define_insn "*tls_global_dynamic_32_gnu"
12098 [(set (match_operand:SI 0 "register_operand" "=a")
12099 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12100 (match_operand:SI 2 "tls_symbolic_operand" "")
12101 (match_operand:SI 3 "call_insn_operand" "")]
12103 (clobber (match_scratch:SI 4 "=d"))
12104 (clobber (match_scratch:SI 5 "=c"))
12105 (clobber (reg:CC FLAGS_REG))]
12106 "!TARGET_64BIT && TARGET_GNU_TLS"
12107 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12108 [(set_attr "type" "multi")
12109 (set_attr "length" "12")])
12111 (define_expand "tls_global_dynamic_32"
12112 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12115 (match_operand:SI 1 "tls_symbolic_operand" "")
12118 (clobber (match_scratch:SI 4 ""))
12119 (clobber (match_scratch:SI 5 ""))
12120 (clobber (reg:CC FLAGS_REG))])]
12124 operands[2] = pic_offset_table_rtx;
12127 operands[2] = gen_reg_rtx (Pmode);
12128 emit_insn (gen_set_got (operands[2]));
12130 if (TARGET_GNU2_TLS)
12132 emit_insn (gen_tls_dynamic_gnu2_32
12133 (operands[0], operands[1], operands[2]));
12136 operands[3] = ix86_tls_get_addr ();
12139 (define_insn "*tls_global_dynamic_64"
12140 [(set (match_operand:DI 0 "register_operand" "=a")
12141 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12142 (match_operand:DI 3 "" "")))
12143 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12146 { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
12147 [(set_attr "type" "multi")
12148 (set_attr "length" "16")])
12150 (define_expand "tls_global_dynamic_64"
12151 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12152 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12153 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12157 if (TARGET_GNU2_TLS)
12159 emit_insn (gen_tls_dynamic_gnu2_64
12160 (operands[0], operands[1]));
12163 operands[2] = ix86_tls_get_addr ();
12166 (define_insn "*tls_local_dynamic_base_32_gnu"
12167 [(set (match_operand:SI 0 "register_operand" "=a")
12168 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12169 (match_operand:SI 2 "call_insn_operand" "")]
12170 UNSPEC_TLS_LD_BASE))
12171 (clobber (match_scratch:SI 3 "=d"))
12172 (clobber (match_scratch:SI 4 "=c"))
12173 (clobber (reg:CC FLAGS_REG))]
12174 "!TARGET_64BIT && TARGET_GNU_TLS"
12175 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12176 [(set_attr "type" "multi")
12177 (set_attr "length" "11")])
12179 (define_expand "tls_local_dynamic_base_32"
12180 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12181 (unspec:SI [(match_dup 1) (match_dup 2)]
12182 UNSPEC_TLS_LD_BASE))
12183 (clobber (match_scratch:SI 3 ""))
12184 (clobber (match_scratch:SI 4 ""))
12185 (clobber (reg:CC FLAGS_REG))])]
12189 operands[1] = pic_offset_table_rtx;
12192 operands[1] = gen_reg_rtx (Pmode);
12193 emit_insn (gen_set_got (operands[1]));
12195 if (TARGET_GNU2_TLS)
12197 emit_insn (gen_tls_dynamic_gnu2_32
12198 (operands[0], ix86_tls_module_base (), operands[1]));
12201 operands[2] = ix86_tls_get_addr ();
12204 (define_insn "*tls_local_dynamic_base_64"
12205 [(set (match_operand:DI 0 "register_operand" "=a")
12206 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12207 (match_operand:DI 2 "" "")))
12208 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12210 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12211 [(set_attr "type" "multi")
12212 (set_attr "length" "12")])
12214 (define_expand "tls_local_dynamic_base_64"
12215 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12216 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12217 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12220 if (TARGET_GNU2_TLS)
12222 emit_insn (gen_tls_dynamic_gnu2_64
12223 (operands[0], ix86_tls_module_base ()));
12226 operands[1] = ix86_tls_get_addr ();
12229 ;; Local dynamic of a single variable is a lose. Show combine how
12230 ;; to convert that back to global dynamic.
12232 (define_insn_and_split "*tls_local_dynamic_32_once"
12233 [(set (match_operand:SI 0 "register_operand" "=a")
12234 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12235 (match_operand:SI 2 "call_insn_operand" "")]
12236 UNSPEC_TLS_LD_BASE)
12237 (const:SI (unspec:SI
12238 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12240 (clobber (match_scratch:SI 4 "=d"))
12241 (clobber (match_scratch:SI 5 "=c"))
12242 (clobber (reg:CC FLAGS_REG))]
12246 [(parallel [(set (match_dup 0)
12247 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12249 (clobber (match_dup 4))
12250 (clobber (match_dup 5))
12251 (clobber (reg:CC FLAGS_REG))])]
12254 ;; Load and add the thread base pointer from %gs:0.
12256 (define_insn "*load_tp_si"
12257 [(set (match_operand:SI 0 "register_operand" "=r")
12258 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12260 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12261 [(set_attr "type" "imov")
12262 (set_attr "modrm" "0")
12263 (set_attr "length" "7")
12264 (set_attr "memory" "load")
12265 (set_attr "imm_disp" "false")])
12267 (define_insn "*add_tp_si"
12268 [(set (match_operand:SI 0 "register_operand" "=r")
12269 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12270 (match_operand:SI 1 "register_operand" "0")))
12271 (clobber (reg:CC FLAGS_REG))]
12273 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12274 [(set_attr "type" "alu")
12275 (set_attr "modrm" "0")
12276 (set_attr "length" "7")
12277 (set_attr "memory" "load")
12278 (set_attr "imm_disp" "false")])
12280 (define_insn "*load_tp_di"
12281 [(set (match_operand:DI 0 "register_operand" "=r")
12282 (unspec:DI [(const_int 0)] UNSPEC_TP))]
12284 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12285 [(set_attr "type" "imov")
12286 (set_attr "modrm" "0")
12287 (set_attr "length" "7")
12288 (set_attr "memory" "load")
12289 (set_attr "imm_disp" "false")])
12291 (define_insn "*add_tp_di"
12292 [(set (match_operand:DI 0 "register_operand" "=r")
12293 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12294 (match_operand:DI 1 "register_operand" "0")))
12295 (clobber (reg:CC FLAGS_REG))]
12297 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12298 [(set_attr "type" "alu")
12299 (set_attr "modrm" "0")
12300 (set_attr "length" "7")
12301 (set_attr "memory" "load")
12302 (set_attr "imm_disp" "false")])
12304 ;; GNU2 TLS patterns can be split.
12306 (define_expand "tls_dynamic_gnu2_32"
12307 [(set (match_dup 3)
12308 (plus:SI (match_operand:SI 2 "register_operand" "")
12310 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12313 [(set (match_operand:SI 0 "register_operand" "")
12314 (unspec:SI [(match_dup 1) (match_dup 3)
12315 (match_dup 2) (reg:SI SP_REG)]
12317 (clobber (reg:CC FLAGS_REG))])]
12318 "!TARGET_64BIT && TARGET_GNU2_TLS"
12320 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12321 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12324 (define_insn "*tls_dynamic_lea_32"
12325 [(set (match_operand:SI 0 "register_operand" "=r")
12326 (plus:SI (match_operand:SI 1 "register_operand" "b")
12328 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12329 UNSPEC_TLSDESC))))]
12330 "!TARGET_64BIT && TARGET_GNU2_TLS"
12331 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12332 [(set_attr "type" "lea")
12333 (set_attr "mode" "SI")
12334 (set_attr "length" "6")
12335 (set_attr "length_address" "4")])
12337 (define_insn "*tls_dynamic_call_32"
12338 [(set (match_operand:SI 0 "register_operand" "=a")
12339 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12340 (match_operand:SI 2 "register_operand" "0")
12341 ;; we have to make sure %ebx still points to the GOT
12342 (match_operand:SI 3 "register_operand" "b")
12345 (clobber (reg:CC FLAGS_REG))]
12346 "!TARGET_64BIT && TARGET_GNU2_TLS"
12347 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12348 [(set_attr "type" "call")
12349 (set_attr "length" "2")
12350 (set_attr "length_address" "0")])
12352 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12353 [(set (match_operand:SI 0 "register_operand" "=&a")
12355 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12356 (match_operand:SI 4 "" "")
12357 (match_operand:SI 2 "register_operand" "b")
12360 (const:SI (unspec:SI
12361 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12363 (clobber (reg:CC FLAGS_REG))]
12364 "!TARGET_64BIT && TARGET_GNU2_TLS"
12367 [(set (match_dup 0) (match_dup 5))]
12369 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12370 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12373 (define_expand "tls_dynamic_gnu2_64"
12374 [(set (match_dup 2)
12375 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12378 [(set (match_operand:DI 0 "register_operand" "")
12379 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12381 (clobber (reg:CC FLAGS_REG))])]
12382 "TARGET_64BIT && TARGET_GNU2_TLS"
12384 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12385 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12388 (define_insn "*tls_dynamic_lea_64"
12389 [(set (match_operand:DI 0 "register_operand" "=r")
12390 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12392 "TARGET_64BIT && TARGET_GNU2_TLS"
12393 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12394 [(set_attr "type" "lea")
12395 (set_attr "mode" "DI")
12396 (set_attr "length" "7")
12397 (set_attr "length_address" "4")])
12399 (define_insn "*tls_dynamic_call_64"
12400 [(set (match_operand:DI 0 "register_operand" "=a")
12401 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12402 (match_operand:DI 2 "register_operand" "0")
12405 (clobber (reg:CC FLAGS_REG))]
12406 "TARGET_64BIT && TARGET_GNU2_TLS"
12407 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12408 [(set_attr "type" "call")
12409 (set_attr "length" "2")
12410 (set_attr "length_address" "0")])
12412 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12413 [(set (match_operand:DI 0 "register_operand" "=&a")
12415 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12416 (match_operand:DI 3 "" "")
12419 (const:DI (unspec:DI
12420 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12422 (clobber (reg:CC FLAGS_REG))]
12423 "TARGET_64BIT && TARGET_GNU2_TLS"
12426 [(set (match_dup 0) (match_dup 4))]
12428 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12429 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12434 ;; These patterns match the binary 387 instructions for addM3, subM3,
12435 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12436 ;; SFmode. The first is the normal insn, the second the same insn but
12437 ;; with one operand a conversion, and the third the same insn but with
12438 ;; the other operand a conversion. The conversion may be SFmode or
12439 ;; SImode if the target mode DFmode, but only SImode if the target mode
12442 ;; Gcc is slightly more smart about handling normal two address instructions
12443 ;; so use special patterns for add and mull.
12445 (define_insn "*fop_<mode>_comm_mixed_avx"
12446 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12447 (match_operator:MODEF 3 "binary_fp_operator"
12448 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12449 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12450 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12451 && COMMUTATIVE_ARITH_P (operands[3])
12452 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12453 "* return output_387_binary_op (insn, operands);"
12454 [(set (attr "type")
12455 (if_then_else (eq_attr "alternative" "1")
12456 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12457 (const_string "ssemul")
12458 (const_string "sseadd"))
12459 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12460 (const_string "fmul")
12461 (const_string "fop"))))
12462 (set_attr "prefix" "orig,maybe_vex")
12463 (set_attr "mode" "<MODE>")])
12465 (define_insn "*fop_<mode>_comm_mixed"
12466 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12467 (match_operator:MODEF 3 "binary_fp_operator"
12468 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12469 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12470 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12471 && COMMUTATIVE_ARITH_P (operands[3])
12472 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12473 "* return output_387_binary_op (insn, operands);"
12474 [(set (attr "type")
12475 (if_then_else (eq_attr "alternative" "1")
12476 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12477 (const_string "ssemul")
12478 (const_string "sseadd"))
12479 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12480 (const_string "fmul")
12481 (const_string "fop"))))
12482 (set_attr "mode" "<MODE>")])
12484 (define_insn "*fop_<mode>_comm_avx"
12485 [(set (match_operand:MODEF 0 "register_operand" "=x")
12486 (match_operator:MODEF 3 "binary_fp_operator"
12487 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12488 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12489 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12490 && COMMUTATIVE_ARITH_P (operands[3])
12491 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12492 "* return output_387_binary_op (insn, operands);"
12493 [(set (attr "type")
12494 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12495 (const_string "ssemul")
12496 (const_string "sseadd")))
12497 (set_attr "prefix" "vex")
12498 (set_attr "mode" "<MODE>")])
12500 (define_insn "*fop_<mode>_comm_sse"
12501 [(set (match_operand:MODEF 0 "register_operand" "=x")
12502 (match_operator:MODEF 3 "binary_fp_operator"
12503 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12504 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12505 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12506 && COMMUTATIVE_ARITH_P (operands[3])
12507 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12508 "* return output_387_binary_op (insn, operands);"
12509 [(set (attr "type")
12510 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12511 (const_string "ssemul")
12512 (const_string "sseadd")))
12513 (set_attr "mode" "<MODE>")])
12515 (define_insn "*fop_<mode>_comm_i387"
12516 [(set (match_operand:MODEF 0 "register_operand" "=f")
12517 (match_operator:MODEF 3 "binary_fp_operator"
12518 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12519 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12520 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12521 && COMMUTATIVE_ARITH_P (operands[3])
12522 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12523 "* return output_387_binary_op (insn, operands);"
12524 [(set (attr "type")
12525 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12526 (const_string "fmul")
12527 (const_string "fop")))
12528 (set_attr "mode" "<MODE>")])
12530 (define_insn "*fop_<mode>_1_mixed_avx"
12531 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12532 (match_operator:MODEF 3 "binary_fp_operator"
12533 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12534 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12535 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12536 && !COMMUTATIVE_ARITH_P (operands[3])
12537 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12538 "* return output_387_binary_op (insn, operands);"
12539 [(set (attr "type")
12540 (cond [(and (eq_attr "alternative" "2")
12541 (match_operand:MODEF 3 "mult_operator" ""))
12542 (const_string "ssemul")
12543 (and (eq_attr "alternative" "2")
12544 (match_operand:MODEF 3 "div_operator" ""))
12545 (const_string "ssediv")
12546 (eq_attr "alternative" "2")
12547 (const_string "sseadd")
12548 (match_operand:MODEF 3 "mult_operator" "")
12549 (const_string "fmul")
12550 (match_operand:MODEF 3 "div_operator" "")
12551 (const_string "fdiv")
12553 (const_string "fop")))
12554 (set_attr "prefix" "orig,orig,maybe_vex")
12555 (set_attr "mode" "<MODE>")])
12557 (define_insn "*fop_<mode>_1_mixed"
12558 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12559 (match_operator:MODEF 3 "binary_fp_operator"
12560 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12561 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12562 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12563 && !COMMUTATIVE_ARITH_P (operands[3])
12564 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12565 "* return output_387_binary_op (insn, operands);"
12566 [(set (attr "type")
12567 (cond [(and (eq_attr "alternative" "2")
12568 (match_operand:MODEF 3 "mult_operator" ""))
12569 (const_string "ssemul")
12570 (and (eq_attr "alternative" "2")
12571 (match_operand:MODEF 3 "div_operator" ""))
12572 (const_string "ssediv")
12573 (eq_attr "alternative" "2")
12574 (const_string "sseadd")
12575 (match_operand:MODEF 3 "mult_operator" "")
12576 (const_string "fmul")
12577 (match_operand:MODEF 3 "div_operator" "")
12578 (const_string "fdiv")
12580 (const_string "fop")))
12581 (set_attr "mode" "<MODE>")])
12583 (define_insn "*rcpsf2_sse"
12584 [(set (match_operand:SF 0 "register_operand" "=x")
12585 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12588 "%vrcpss\t{%1, %d0|%d0, %1}"
12589 [(set_attr "type" "sse")
12590 (set_attr "atom_sse_attr" "rcp")
12591 (set_attr "prefix" "maybe_vex")
12592 (set_attr "mode" "SF")])
12594 (define_insn "*fop_<mode>_1_avx"
12595 [(set (match_operand:MODEF 0 "register_operand" "=x")
12596 (match_operator:MODEF 3 "binary_fp_operator"
12597 [(match_operand:MODEF 1 "register_operand" "x")
12598 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12599 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12600 && !COMMUTATIVE_ARITH_P (operands[3])"
12601 "* return output_387_binary_op (insn, operands);"
12602 [(set (attr "type")
12603 (cond [(match_operand:MODEF 3 "mult_operator" "")
12604 (const_string "ssemul")
12605 (match_operand:MODEF 3 "div_operator" "")
12606 (const_string "ssediv")
12608 (const_string "sseadd")))
12609 (set_attr "prefix" "vex")
12610 (set_attr "mode" "<MODE>")])
12612 (define_insn "*fop_<mode>_1_sse"
12613 [(set (match_operand:MODEF 0 "register_operand" "=x")
12614 (match_operator:MODEF 3 "binary_fp_operator"
12615 [(match_operand:MODEF 1 "register_operand" "0")
12616 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12617 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12618 && !COMMUTATIVE_ARITH_P (operands[3])"
12619 "* return output_387_binary_op (insn, operands);"
12620 [(set (attr "type")
12621 (cond [(match_operand:MODEF 3 "mult_operator" "")
12622 (const_string "ssemul")
12623 (match_operand:MODEF 3 "div_operator" "")
12624 (const_string "ssediv")
12626 (const_string "sseadd")))
12627 (set_attr "mode" "<MODE>")])
12629 ;; This pattern is not fully shadowed by the pattern above.
12630 (define_insn "*fop_<mode>_1_i387"
12631 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12632 (match_operator:MODEF 3 "binary_fp_operator"
12633 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12634 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12635 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12636 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12637 && !COMMUTATIVE_ARITH_P (operands[3])
12638 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12639 "* return output_387_binary_op (insn, operands);"
12640 [(set (attr "type")
12641 (cond [(match_operand:MODEF 3 "mult_operator" "")
12642 (const_string "fmul")
12643 (match_operand:MODEF 3 "div_operator" "")
12644 (const_string "fdiv")
12646 (const_string "fop")))
12647 (set_attr "mode" "<MODE>")])
12649 ;; ??? Add SSE splitters for these!
12650 (define_insn "*fop_<MODEF:mode>_2_i387"
12651 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12652 (match_operator:MODEF 3 "binary_fp_operator"
12654 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12655 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12656 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12657 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12658 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12659 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12660 [(set (attr "type")
12661 (cond [(match_operand:MODEF 3 "mult_operator" "")
12662 (const_string "fmul")
12663 (match_operand:MODEF 3 "div_operator" "")
12664 (const_string "fdiv")
12666 (const_string "fop")))
12667 (set_attr "fp_int_src" "true")
12668 (set_attr "mode" "<X87MODEI12:MODE>")])
12670 (define_insn "*fop_<MODEF:mode>_3_i387"
12671 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12672 (match_operator:MODEF 3 "binary_fp_operator"
12673 [(match_operand:MODEF 1 "register_operand" "0,0")
12675 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12676 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12677 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12678 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12679 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12680 [(set (attr "type")
12681 (cond [(match_operand:MODEF 3 "mult_operator" "")
12682 (const_string "fmul")
12683 (match_operand:MODEF 3 "div_operator" "")
12684 (const_string "fdiv")
12686 (const_string "fop")))
12687 (set_attr "fp_int_src" "true")
12688 (set_attr "mode" "<MODE>")])
12690 (define_insn "*fop_df_4_i387"
12691 [(set (match_operand:DF 0 "register_operand" "=f,f")
12692 (match_operator:DF 3 "binary_fp_operator"
12694 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12695 (match_operand:DF 2 "register_operand" "0,f")]))]
12696 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12697 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12698 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12699 "* return output_387_binary_op (insn, operands);"
12700 [(set (attr "type")
12701 (cond [(match_operand:DF 3 "mult_operator" "")
12702 (const_string "fmul")
12703 (match_operand:DF 3 "div_operator" "")
12704 (const_string "fdiv")
12706 (const_string "fop")))
12707 (set_attr "mode" "SF")])
12709 (define_insn "*fop_df_5_i387"
12710 [(set (match_operand:DF 0 "register_operand" "=f,f")
12711 (match_operator:DF 3 "binary_fp_operator"
12712 [(match_operand:DF 1 "register_operand" "0,f")
12714 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12715 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12716 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12717 "* return output_387_binary_op (insn, operands);"
12718 [(set (attr "type")
12719 (cond [(match_operand:DF 3 "mult_operator" "")
12720 (const_string "fmul")
12721 (match_operand:DF 3 "div_operator" "")
12722 (const_string "fdiv")
12724 (const_string "fop")))
12725 (set_attr "mode" "SF")])
12727 (define_insn "*fop_df_6_i387"
12728 [(set (match_operand:DF 0 "register_operand" "=f,f")
12729 (match_operator:DF 3 "binary_fp_operator"
12731 (match_operand:SF 1 "register_operand" "0,f"))
12733 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12734 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12735 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12736 "* return output_387_binary_op (insn, operands);"
12737 [(set (attr "type")
12738 (cond [(match_operand:DF 3 "mult_operator" "")
12739 (const_string "fmul")
12740 (match_operand:DF 3 "div_operator" "")
12741 (const_string "fdiv")
12743 (const_string "fop")))
12744 (set_attr "mode" "SF")])
12746 (define_insn "*fop_xf_comm_i387"
12747 [(set (match_operand:XF 0 "register_operand" "=f")
12748 (match_operator:XF 3 "binary_fp_operator"
12749 [(match_operand:XF 1 "register_operand" "%0")
12750 (match_operand:XF 2 "register_operand" "f")]))]
12752 && COMMUTATIVE_ARITH_P (operands[3])"
12753 "* return output_387_binary_op (insn, operands);"
12754 [(set (attr "type")
12755 (if_then_else (match_operand:XF 3 "mult_operator" "")
12756 (const_string "fmul")
12757 (const_string "fop")))
12758 (set_attr "mode" "XF")])
12760 (define_insn "*fop_xf_1_i387"
12761 [(set (match_operand:XF 0 "register_operand" "=f,f")
12762 (match_operator:XF 3 "binary_fp_operator"
12763 [(match_operand:XF 1 "register_operand" "0,f")
12764 (match_operand:XF 2 "register_operand" "f,0")]))]
12766 && !COMMUTATIVE_ARITH_P (operands[3])"
12767 "* return output_387_binary_op (insn, operands);"
12768 [(set (attr "type")
12769 (cond [(match_operand:XF 3 "mult_operator" "")
12770 (const_string "fmul")
12771 (match_operand:XF 3 "div_operator" "")
12772 (const_string "fdiv")
12774 (const_string "fop")))
12775 (set_attr "mode" "XF")])
12777 (define_insn "*fop_xf_2_i387"
12778 [(set (match_operand:XF 0 "register_operand" "=f,f")
12779 (match_operator:XF 3 "binary_fp_operator"
12781 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12782 (match_operand:XF 2 "register_operand" "0,0")]))]
12783 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12784 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12785 [(set (attr "type")
12786 (cond [(match_operand:XF 3 "mult_operator" "")
12787 (const_string "fmul")
12788 (match_operand:XF 3 "div_operator" "")
12789 (const_string "fdiv")
12791 (const_string "fop")))
12792 (set_attr "fp_int_src" "true")
12793 (set_attr "mode" "<MODE>")])
12795 (define_insn "*fop_xf_3_i387"
12796 [(set (match_operand:XF 0 "register_operand" "=f,f")
12797 (match_operator:XF 3 "binary_fp_operator"
12798 [(match_operand:XF 1 "register_operand" "0,0")
12800 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12801 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12802 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12803 [(set (attr "type")
12804 (cond [(match_operand:XF 3 "mult_operator" "")
12805 (const_string "fmul")
12806 (match_operand:XF 3 "div_operator" "")
12807 (const_string "fdiv")
12809 (const_string "fop")))
12810 (set_attr "fp_int_src" "true")
12811 (set_attr "mode" "<MODE>")])
12813 (define_insn "*fop_xf_4_i387"
12814 [(set (match_operand:XF 0 "register_operand" "=f,f")
12815 (match_operator:XF 3 "binary_fp_operator"
12817 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12818 (match_operand:XF 2 "register_operand" "0,f")]))]
12820 "* return output_387_binary_op (insn, operands);"
12821 [(set (attr "type")
12822 (cond [(match_operand:XF 3 "mult_operator" "")
12823 (const_string "fmul")
12824 (match_operand:XF 3 "div_operator" "")
12825 (const_string "fdiv")
12827 (const_string "fop")))
12828 (set_attr "mode" "<MODE>")])
12830 (define_insn "*fop_xf_5_i387"
12831 [(set (match_operand:XF 0 "register_operand" "=f,f")
12832 (match_operator:XF 3 "binary_fp_operator"
12833 [(match_operand:XF 1 "register_operand" "0,f")
12835 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12837 "* return output_387_binary_op (insn, operands);"
12838 [(set (attr "type")
12839 (cond [(match_operand:XF 3 "mult_operator" "")
12840 (const_string "fmul")
12841 (match_operand:XF 3 "div_operator" "")
12842 (const_string "fdiv")
12844 (const_string "fop")))
12845 (set_attr "mode" "<MODE>")])
12847 (define_insn "*fop_xf_6_i387"
12848 [(set (match_operand:XF 0 "register_operand" "=f,f")
12849 (match_operator:XF 3 "binary_fp_operator"
12851 (match_operand:MODEF 1 "register_operand" "0,f"))
12853 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12855 "* return output_387_binary_op (insn, operands);"
12856 [(set (attr "type")
12857 (cond [(match_operand:XF 3 "mult_operator" "")
12858 (const_string "fmul")
12859 (match_operand:XF 3 "div_operator" "")
12860 (const_string "fdiv")
12862 (const_string "fop")))
12863 (set_attr "mode" "<MODE>")])
12866 [(set (match_operand 0 "register_operand" "")
12867 (match_operator 3 "binary_fp_operator"
12868 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12869 (match_operand 2 "register_operand" "")]))]
12871 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12872 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12875 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12876 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12877 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12878 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12879 GET_MODE (operands[3]),
12882 ix86_free_from_memory (GET_MODE (operands[1]));
12887 [(set (match_operand 0 "register_operand" "")
12888 (match_operator 3 "binary_fp_operator"
12889 [(match_operand 1 "register_operand" "")
12890 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12892 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12893 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12896 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12897 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12898 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12899 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12900 GET_MODE (operands[3]),
12903 ix86_free_from_memory (GET_MODE (operands[2]));
12907 ;; FPU special functions.
12909 ;; This pattern implements a no-op XFmode truncation for
12910 ;; all fancy i386 XFmode math functions.
12912 (define_insn "truncxf<mode>2_i387_noop_unspec"
12913 [(set (match_operand:MODEF 0 "register_operand" "=f")
12914 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12915 UNSPEC_TRUNC_NOOP))]
12916 "TARGET_USE_FANCY_MATH_387"
12917 "* return output_387_reg_move (insn, operands);"
12918 [(set_attr "type" "fmov")
12919 (set_attr "mode" "<MODE>")])
12921 (define_insn "sqrtxf2"
12922 [(set (match_operand:XF 0 "register_operand" "=f")
12923 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12924 "TARGET_USE_FANCY_MATH_387"
12926 [(set_attr "type" "fpspc")
12927 (set_attr "mode" "XF")
12928 (set_attr "athlon_decode" "direct")
12929 (set_attr "amdfam10_decode" "direct")])
12931 (define_insn "sqrt_extend<mode>xf2_i387"
12932 [(set (match_operand:XF 0 "register_operand" "=f")
12935 (match_operand:MODEF 1 "register_operand" "0"))))]
12936 "TARGET_USE_FANCY_MATH_387"
12938 [(set_attr "type" "fpspc")
12939 (set_attr "mode" "XF")
12940 (set_attr "athlon_decode" "direct")
12941 (set_attr "amdfam10_decode" "direct")])
12943 (define_insn "*rsqrtsf2_sse"
12944 [(set (match_operand:SF 0 "register_operand" "=x")
12945 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12948 "%vrsqrtss\t{%1, %d0|%d0, %1}"
12949 [(set_attr "type" "sse")
12950 (set_attr "atom_sse_attr" "rcp")
12951 (set_attr "prefix" "maybe_vex")
12952 (set_attr "mode" "SF")])
12954 (define_expand "rsqrtsf2"
12955 [(set (match_operand:SF 0 "register_operand" "")
12956 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
12960 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12964 (define_insn "*sqrt<mode>2_sse"
12965 [(set (match_operand:MODEF 0 "register_operand" "=x")
12967 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12968 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12969 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
12970 [(set_attr "type" "sse")
12971 (set_attr "atom_sse_attr" "sqrt")
12972 (set_attr "prefix" "maybe_vex")
12973 (set_attr "mode" "<MODE>")
12974 (set_attr "athlon_decode" "*")
12975 (set_attr "amdfam10_decode" "*")])
12977 (define_expand "sqrt<mode>2"
12978 [(set (match_operand:MODEF 0 "register_operand" "")
12980 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
12981 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12982 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12984 if (<MODE>mode == SFmode
12985 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
12986 && flag_finite_math_only && !flag_trapping_math
12987 && flag_unsafe_math_optimizations)
12989 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12993 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12995 rtx op0 = gen_reg_rtx (XFmode);
12996 rtx op1 = force_reg (<MODE>mode, operands[1]);
12998 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
12999 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13004 (define_insn "fpremxf4_i387"
13005 [(set (match_operand:XF 0 "register_operand" "=f")
13006 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13007 (match_operand:XF 3 "register_operand" "1")]
13009 (set (match_operand:XF 1 "register_operand" "=u")
13010 (unspec:XF [(match_dup 2) (match_dup 3)]
13012 (set (reg:CCFP FPSR_REG)
13013 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13015 "TARGET_USE_FANCY_MATH_387"
13017 [(set_attr "type" "fpspc")
13018 (set_attr "mode" "XF")])
13020 (define_expand "fmodxf3"
13021 [(use (match_operand:XF 0 "register_operand" ""))
13022 (use (match_operand:XF 1 "general_operand" ""))
13023 (use (match_operand:XF 2 "general_operand" ""))]
13024 "TARGET_USE_FANCY_MATH_387"
13026 rtx label = gen_label_rtx ();
13028 rtx op1 = gen_reg_rtx (XFmode);
13029 rtx op2 = gen_reg_rtx (XFmode);
13031 emit_move_insn (op2, operands[2]);
13032 emit_move_insn (op1, operands[1]);
13034 emit_label (label);
13035 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13036 ix86_emit_fp_unordered_jump (label);
13037 LABEL_NUSES (label) = 1;
13039 emit_move_insn (operands[0], op1);
13043 (define_expand "fmod<mode>3"
13044 [(use (match_operand:MODEF 0 "register_operand" ""))
13045 (use (match_operand:MODEF 1 "general_operand" ""))
13046 (use (match_operand:MODEF 2 "general_operand" ""))]
13047 "TARGET_USE_FANCY_MATH_387"
13049 rtx (*gen_truncxf) (rtx, rtx);
13051 rtx label = gen_label_rtx ();
13053 rtx op1 = gen_reg_rtx (XFmode);
13054 rtx op2 = gen_reg_rtx (XFmode);
13056 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13057 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13059 emit_label (label);
13060 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13061 ix86_emit_fp_unordered_jump (label);
13062 LABEL_NUSES (label) = 1;
13064 /* Truncate the result properly for strict SSE math. */
13065 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13066 && !TARGET_MIX_SSE_I387)
13067 gen_truncxf = gen_truncxf<mode>2;
13069 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13071 emit_insn (gen_truncxf (operands[0], op1));
13075 (define_insn "fprem1xf4_i387"
13076 [(set (match_operand:XF 0 "register_operand" "=f")
13077 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13078 (match_operand:XF 3 "register_operand" "1")]
13080 (set (match_operand:XF 1 "register_operand" "=u")
13081 (unspec:XF [(match_dup 2) (match_dup 3)]
13083 (set (reg:CCFP FPSR_REG)
13084 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13086 "TARGET_USE_FANCY_MATH_387"
13088 [(set_attr "type" "fpspc")
13089 (set_attr "mode" "XF")])
13091 (define_expand "remainderxf3"
13092 [(use (match_operand:XF 0 "register_operand" ""))
13093 (use (match_operand:XF 1 "general_operand" ""))
13094 (use (match_operand:XF 2 "general_operand" ""))]
13095 "TARGET_USE_FANCY_MATH_387"
13097 rtx label = gen_label_rtx ();
13099 rtx op1 = gen_reg_rtx (XFmode);
13100 rtx op2 = gen_reg_rtx (XFmode);
13102 emit_move_insn (op2, operands[2]);
13103 emit_move_insn (op1, operands[1]);
13105 emit_label (label);
13106 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13107 ix86_emit_fp_unordered_jump (label);
13108 LABEL_NUSES (label) = 1;
13110 emit_move_insn (operands[0], op1);
13114 (define_expand "remainder<mode>3"
13115 [(use (match_operand:MODEF 0 "register_operand" ""))
13116 (use (match_operand:MODEF 1 "general_operand" ""))
13117 (use (match_operand:MODEF 2 "general_operand" ""))]
13118 "TARGET_USE_FANCY_MATH_387"
13120 rtx (*gen_truncxf) (rtx, rtx);
13122 rtx label = gen_label_rtx ();
13124 rtx op1 = gen_reg_rtx (XFmode);
13125 rtx op2 = gen_reg_rtx (XFmode);
13127 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13128 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13130 emit_label (label);
13132 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13133 ix86_emit_fp_unordered_jump (label);
13134 LABEL_NUSES (label) = 1;
13136 /* Truncate the result properly for strict SSE math. */
13137 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13138 && !TARGET_MIX_SSE_I387)
13139 gen_truncxf = gen_truncxf<mode>2;
13141 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13143 emit_insn (gen_truncxf (operands[0], op1));
13147 (define_insn "*sinxf2_i387"
13148 [(set (match_operand:XF 0 "register_operand" "=f")
13149 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13150 "TARGET_USE_FANCY_MATH_387
13151 && flag_unsafe_math_optimizations"
13153 [(set_attr "type" "fpspc")
13154 (set_attr "mode" "XF")])
13156 (define_insn "*sin_extend<mode>xf2_i387"
13157 [(set (match_operand:XF 0 "register_operand" "=f")
13158 (unspec:XF [(float_extend:XF
13159 (match_operand:MODEF 1 "register_operand" "0"))]
13161 "TARGET_USE_FANCY_MATH_387
13162 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13163 || TARGET_MIX_SSE_I387)
13164 && flag_unsafe_math_optimizations"
13166 [(set_attr "type" "fpspc")
13167 (set_attr "mode" "XF")])
13169 (define_insn "*cosxf2_i387"
13170 [(set (match_operand:XF 0 "register_operand" "=f")
13171 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13172 "TARGET_USE_FANCY_MATH_387
13173 && flag_unsafe_math_optimizations"
13175 [(set_attr "type" "fpspc")
13176 (set_attr "mode" "XF")])
13178 (define_insn "*cos_extend<mode>xf2_i387"
13179 [(set (match_operand:XF 0 "register_operand" "=f")
13180 (unspec:XF [(float_extend:XF
13181 (match_operand:MODEF 1 "register_operand" "0"))]
13183 "TARGET_USE_FANCY_MATH_387
13184 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13185 || TARGET_MIX_SSE_I387)
13186 && flag_unsafe_math_optimizations"
13188 [(set_attr "type" "fpspc")
13189 (set_attr "mode" "XF")])
13191 ;; When sincos pattern is defined, sin and cos builtin functions will be
13192 ;; expanded to sincos pattern with one of its outputs left unused.
13193 ;; CSE pass will figure out if two sincos patterns can be combined,
13194 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13195 ;; depending on the unused output.
13197 (define_insn "sincosxf3"
13198 [(set (match_operand:XF 0 "register_operand" "=f")
13199 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13200 UNSPEC_SINCOS_COS))
13201 (set (match_operand:XF 1 "register_operand" "=u")
13202 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13203 "TARGET_USE_FANCY_MATH_387
13204 && flag_unsafe_math_optimizations"
13206 [(set_attr "type" "fpspc")
13207 (set_attr "mode" "XF")])
13210 [(set (match_operand:XF 0 "register_operand" "")
13211 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13212 UNSPEC_SINCOS_COS))
13213 (set (match_operand:XF 1 "register_operand" "")
13214 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13215 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13216 && !(reload_completed || reload_in_progress)"
13217 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13221 [(set (match_operand:XF 0 "register_operand" "")
13222 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13223 UNSPEC_SINCOS_COS))
13224 (set (match_operand:XF 1 "register_operand" "")
13225 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13226 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13227 && !(reload_completed || reload_in_progress)"
13228 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13231 (define_insn "sincos_extend<mode>xf3_i387"
13232 [(set (match_operand:XF 0 "register_operand" "=f")
13233 (unspec:XF [(float_extend:XF
13234 (match_operand:MODEF 2 "register_operand" "0"))]
13235 UNSPEC_SINCOS_COS))
13236 (set (match_operand:XF 1 "register_operand" "=u")
13237 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13238 "TARGET_USE_FANCY_MATH_387
13239 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13240 || TARGET_MIX_SSE_I387)
13241 && flag_unsafe_math_optimizations"
13243 [(set_attr "type" "fpspc")
13244 (set_attr "mode" "XF")])
13247 [(set (match_operand:XF 0 "register_operand" "")
13248 (unspec:XF [(float_extend:XF
13249 (match_operand:MODEF 2 "register_operand" ""))]
13250 UNSPEC_SINCOS_COS))
13251 (set (match_operand:XF 1 "register_operand" "")
13252 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13253 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13254 && !(reload_completed || reload_in_progress)"
13255 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13259 [(set (match_operand:XF 0 "register_operand" "")
13260 (unspec:XF [(float_extend:XF
13261 (match_operand:MODEF 2 "register_operand" ""))]
13262 UNSPEC_SINCOS_COS))
13263 (set (match_operand:XF 1 "register_operand" "")
13264 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13265 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13266 && !(reload_completed || reload_in_progress)"
13267 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13270 (define_expand "sincos<mode>3"
13271 [(use (match_operand:MODEF 0 "register_operand" ""))
13272 (use (match_operand:MODEF 1 "register_operand" ""))
13273 (use (match_operand:MODEF 2 "register_operand" ""))]
13274 "TARGET_USE_FANCY_MATH_387
13275 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13276 || TARGET_MIX_SSE_I387)
13277 && flag_unsafe_math_optimizations"
13279 rtx op0 = gen_reg_rtx (XFmode);
13280 rtx op1 = gen_reg_rtx (XFmode);
13282 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13283 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13284 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13288 (define_insn "fptanxf4_i387"
13289 [(set (match_operand:XF 0 "register_operand" "=f")
13290 (match_operand:XF 3 "const_double_operand" "F"))
13291 (set (match_operand:XF 1 "register_operand" "=u")
13292 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13294 "TARGET_USE_FANCY_MATH_387
13295 && flag_unsafe_math_optimizations
13296 && standard_80387_constant_p (operands[3]) == 2"
13298 [(set_attr "type" "fpspc")
13299 (set_attr "mode" "XF")])
13301 (define_insn "fptan_extend<mode>xf4_i387"
13302 [(set (match_operand:MODEF 0 "register_operand" "=f")
13303 (match_operand:MODEF 3 "const_double_operand" "F"))
13304 (set (match_operand:XF 1 "register_operand" "=u")
13305 (unspec:XF [(float_extend:XF
13306 (match_operand:MODEF 2 "register_operand" "0"))]
13308 "TARGET_USE_FANCY_MATH_387
13309 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13310 || TARGET_MIX_SSE_I387)
13311 && flag_unsafe_math_optimizations
13312 && standard_80387_constant_p (operands[3]) == 2"
13314 [(set_attr "type" "fpspc")
13315 (set_attr "mode" "XF")])
13317 (define_expand "tanxf2"
13318 [(use (match_operand:XF 0 "register_operand" ""))
13319 (use (match_operand:XF 1 "register_operand" ""))]
13320 "TARGET_USE_FANCY_MATH_387
13321 && flag_unsafe_math_optimizations"
13323 rtx one = gen_reg_rtx (XFmode);
13324 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13326 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13330 (define_expand "tan<mode>2"
13331 [(use (match_operand:MODEF 0 "register_operand" ""))
13332 (use (match_operand:MODEF 1 "register_operand" ""))]
13333 "TARGET_USE_FANCY_MATH_387
13334 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13335 || TARGET_MIX_SSE_I387)
13336 && flag_unsafe_math_optimizations"
13338 rtx op0 = gen_reg_rtx (XFmode);
13340 rtx one = gen_reg_rtx (<MODE>mode);
13341 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13343 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13344 operands[1], op2));
13345 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13349 (define_insn "*fpatanxf3_i387"
13350 [(set (match_operand:XF 0 "register_operand" "=f")
13351 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13352 (match_operand:XF 2 "register_operand" "u")]
13354 (clobber (match_scratch:XF 3 "=2"))]
13355 "TARGET_USE_FANCY_MATH_387
13356 && flag_unsafe_math_optimizations"
13358 [(set_attr "type" "fpspc")
13359 (set_attr "mode" "XF")])
13361 (define_insn "fpatan_extend<mode>xf3_i387"
13362 [(set (match_operand:XF 0 "register_operand" "=f")
13363 (unspec:XF [(float_extend:XF
13364 (match_operand:MODEF 1 "register_operand" "0"))
13366 (match_operand:MODEF 2 "register_operand" "u"))]
13368 (clobber (match_scratch:XF 3 "=2"))]
13369 "TARGET_USE_FANCY_MATH_387
13370 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13371 || TARGET_MIX_SSE_I387)
13372 && flag_unsafe_math_optimizations"
13374 [(set_attr "type" "fpspc")
13375 (set_attr "mode" "XF")])
13377 (define_expand "atan2xf3"
13378 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13379 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13380 (match_operand:XF 1 "register_operand" "")]
13382 (clobber (match_scratch:XF 3 ""))])]
13383 "TARGET_USE_FANCY_MATH_387
13384 && flag_unsafe_math_optimizations"
13387 (define_expand "atan2<mode>3"
13388 [(use (match_operand:MODEF 0 "register_operand" ""))
13389 (use (match_operand:MODEF 1 "register_operand" ""))
13390 (use (match_operand:MODEF 2 "register_operand" ""))]
13391 "TARGET_USE_FANCY_MATH_387
13392 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13393 || TARGET_MIX_SSE_I387)
13394 && flag_unsafe_math_optimizations"
13396 rtx op0 = gen_reg_rtx (XFmode);
13398 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13399 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13403 (define_expand "atanxf2"
13404 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13405 (unspec:XF [(match_dup 2)
13406 (match_operand:XF 1 "register_operand" "")]
13408 (clobber (match_scratch:XF 3 ""))])]
13409 "TARGET_USE_FANCY_MATH_387
13410 && flag_unsafe_math_optimizations"
13412 operands[2] = gen_reg_rtx (XFmode);
13413 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13416 (define_expand "atan<mode>2"
13417 [(use (match_operand:MODEF 0 "register_operand" ""))
13418 (use (match_operand:MODEF 1 "register_operand" ""))]
13419 "TARGET_USE_FANCY_MATH_387
13420 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13421 || TARGET_MIX_SSE_I387)
13422 && flag_unsafe_math_optimizations"
13424 rtx op0 = gen_reg_rtx (XFmode);
13426 rtx op2 = gen_reg_rtx (<MODE>mode);
13427 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13429 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13430 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13434 (define_expand "asinxf2"
13435 [(set (match_dup 2)
13436 (mult:XF (match_operand:XF 1 "register_operand" "")
13438 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13439 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13440 (parallel [(set (match_operand:XF 0 "register_operand" "")
13441 (unspec:XF [(match_dup 5) (match_dup 1)]
13443 (clobber (match_scratch:XF 6 ""))])]
13444 "TARGET_USE_FANCY_MATH_387
13445 && flag_unsafe_math_optimizations"
13449 if (optimize_insn_for_size_p ())
13452 for (i = 2; i < 6; i++)
13453 operands[i] = gen_reg_rtx (XFmode);
13455 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13458 (define_expand "asin<mode>2"
13459 [(use (match_operand:MODEF 0 "register_operand" ""))
13460 (use (match_operand:MODEF 1 "general_operand" ""))]
13461 "TARGET_USE_FANCY_MATH_387
13462 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13463 || TARGET_MIX_SSE_I387)
13464 && flag_unsafe_math_optimizations"
13466 rtx op0 = gen_reg_rtx (XFmode);
13467 rtx op1 = gen_reg_rtx (XFmode);
13469 if (optimize_insn_for_size_p ())
13472 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13473 emit_insn (gen_asinxf2 (op0, op1));
13474 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13478 (define_expand "acosxf2"
13479 [(set (match_dup 2)
13480 (mult:XF (match_operand:XF 1 "register_operand" "")
13482 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13483 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13484 (parallel [(set (match_operand:XF 0 "register_operand" "")
13485 (unspec:XF [(match_dup 1) (match_dup 5)]
13487 (clobber (match_scratch:XF 6 ""))])]
13488 "TARGET_USE_FANCY_MATH_387
13489 && flag_unsafe_math_optimizations"
13493 if (optimize_insn_for_size_p ())
13496 for (i = 2; i < 6; i++)
13497 operands[i] = gen_reg_rtx (XFmode);
13499 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13502 (define_expand "acos<mode>2"
13503 [(use (match_operand:MODEF 0 "register_operand" ""))
13504 (use (match_operand:MODEF 1 "general_operand" ""))]
13505 "TARGET_USE_FANCY_MATH_387
13506 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13507 || TARGET_MIX_SSE_I387)
13508 && flag_unsafe_math_optimizations"
13510 rtx op0 = gen_reg_rtx (XFmode);
13511 rtx op1 = gen_reg_rtx (XFmode);
13513 if (optimize_insn_for_size_p ())
13516 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13517 emit_insn (gen_acosxf2 (op0, op1));
13518 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13522 (define_insn "fyl2xxf3_i387"
13523 [(set (match_operand:XF 0 "register_operand" "=f")
13524 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13525 (match_operand:XF 2 "register_operand" "u")]
13527 (clobber (match_scratch:XF 3 "=2"))]
13528 "TARGET_USE_FANCY_MATH_387
13529 && flag_unsafe_math_optimizations"
13531 [(set_attr "type" "fpspc")
13532 (set_attr "mode" "XF")])
13534 (define_insn "fyl2x_extend<mode>xf3_i387"
13535 [(set (match_operand:XF 0 "register_operand" "=f")
13536 (unspec:XF [(float_extend:XF
13537 (match_operand:MODEF 1 "register_operand" "0"))
13538 (match_operand:XF 2 "register_operand" "u")]
13540 (clobber (match_scratch:XF 3 "=2"))]
13541 "TARGET_USE_FANCY_MATH_387
13542 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13543 || TARGET_MIX_SSE_I387)
13544 && flag_unsafe_math_optimizations"
13546 [(set_attr "type" "fpspc")
13547 (set_attr "mode" "XF")])
13549 (define_expand "logxf2"
13550 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13551 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13552 (match_dup 2)] UNSPEC_FYL2X))
13553 (clobber (match_scratch:XF 3 ""))])]
13554 "TARGET_USE_FANCY_MATH_387
13555 && flag_unsafe_math_optimizations"
13557 operands[2] = gen_reg_rtx (XFmode);
13558 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13561 (define_expand "log<mode>2"
13562 [(use (match_operand:MODEF 0 "register_operand" ""))
13563 (use (match_operand:MODEF 1 "register_operand" ""))]
13564 "TARGET_USE_FANCY_MATH_387
13565 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13566 || TARGET_MIX_SSE_I387)
13567 && flag_unsafe_math_optimizations"
13569 rtx op0 = gen_reg_rtx (XFmode);
13571 rtx op2 = gen_reg_rtx (XFmode);
13572 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13574 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13575 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13579 (define_expand "log10xf2"
13580 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13581 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13582 (match_dup 2)] UNSPEC_FYL2X))
13583 (clobber (match_scratch:XF 3 ""))])]
13584 "TARGET_USE_FANCY_MATH_387
13585 && flag_unsafe_math_optimizations"
13587 operands[2] = gen_reg_rtx (XFmode);
13588 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13591 (define_expand "log10<mode>2"
13592 [(use (match_operand:MODEF 0 "register_operand" ""))
13593 (use (match_operand:MODEF 1 "register_operand" ""))]
13594 "TARGET_USE_FANCY_MATH_387
13595 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13596 || TARGET_MIX_SSE_I387)
13597 && flag_unsafe_math_optimizations"
13599 rtx op0 = gen_reg_rtx (XFmode);
13601 rtx op2 = gen_reg_rtx (XFmode);
13602 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13604 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13605 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13609 (define_expand "log2xf2"
13610 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13611 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13612 (match_dup 2)] UNSPEC_FYL2X))
13613 (clobber (match_scratch:XF 3 ""))])]
13614 "TARGET_USE_FANCY_MATH_387
13615 && flag_unsafe_math_optimizations"
13617 operands[2] = gen_reg_rtx (XFmode);
13618 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13621 (define_expand "log2<mode>2"
13622 [(use (match_operand:MODEF 0 "register_operand" ""))
13623 (use (match_operand:MODEF 1 "register_operand" ""))]
13624 "TARGET_USE_FANCY_MATH_387
13625 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13626 || TARGET_MIX_SSE_I387)
13627 && flag_unsafe_math_optimizations"
13629 rtx op0 = gen_reg_rtx (XFmode);
13631 rtx op2 = gen_reg_rtx (XFmode);
13632 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13634 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13635 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13639 (define_insn "fyl2xp1xf3_i387"
13640 [(set (match_operand:XF 0 "register_operand" "=f")
13641 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13642 (match_operand:XF 2 "register_operand" "u")]
13644 (clobber (match_scratch:XF 3 "=2"))]
13645 "TARGET_USE_FANCY_MATH_387
13646 && flag_unsafe_math_optimizations"
13648 [(set_attr "type" "fpspc")
13649 (set_attr "mode" "XF")])
13651 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13652 [(set (match_operand:XF 0 "register_operand" "=f")
13653 (unspec:XF [(float_extend:XF
13654 (match_operand:MODEF 1 "register_operand" "0"))
13655 (match_operand:XF 2 "register_operand" "u")]
13657 (clobber (match_scratch:XF 3 "=2"))]
13658 "TARGET_USE_FANCY_MATH_387
13659 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13660 || TARGET_MIX_SSE_I387)
13661 && flag_unsafe_math_optimizations"
13663 [(set_attr "type" "fpspc")
13664 (set_attr "mode" "XF")])
13666 (define_expand "log1pxf2"
13667 [(use (match_operand:XF 0 "register_operand" ""))
13668 (use (match_operand:XF 1 "register_operand" ""))]
13669 "TARGET_USE_FANCY_MATH_387
13670 && flag_unsafe_math_optimizations"
13672 if (optimize_insn_for_size_p ())
13675 ix86_emit_i387_log1p (operands[0], operands[1]);
13679 (define_expand "log1p<mode>2"
13680 [(use (match_operand:MODEF 0 "register_operand" ""))
13681 (use (match_operand:MODEF 1 "register_operand" ""))]
13682 "TARGET_USE_FANCY_MATH_387
13683 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13684 || TARGET_MIX_SSE_I387)
13685 && flag_unsafe_math_optimizations"
13689 if (optimize_insn_for_size_p ())
13692 op0 = gen_reg_rtx (XFmode);
13694 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13696 ix86_emit_i387_log1p (op0, operands[1]);
13697 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13701 (define_insn "fxtractxf3_i387"
13702 [(set (match_operand:XF 0 "register_operand" "=f")
13703 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13704 UNSPEC_XTRACT_FRACT))
13705 (set (match_operand:XF 1 "register_operand" "=u")
13706 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13707 "TARGET_USE_FANCY_MATH_387
13708 && flag_unsafe_math_optimizations"
13710 [(set_attr "type" "fpspc")
13711 (set_attr "mode" "XF")])
13713 (define_insn "fxtract_extend<mode>xf3_i387"
13714 [(set (match_operand:XF 0 "register_operand" "=f")
13715 (unspec:XF [(float_extend:XF
13716 (match_operand:MODEF 2 "register_operand" "0"))]
13717 UNSPEC_XTRACT_FRACT))
13718 (set (match_operand:XF 1 "register_operand" "=u")
13719 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13720 "TARGET_USE_FANCY_MATH_387
13721 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13722 || TARGET_MIX_SSE_I387)
13723 && flag_unsafe_math_optimizations"
13725 [(set_attr "type" "fpspc")
13726 (set_attr "mode" "XF")])
13728 (define_expand "logbxf2"
13729 [(parallel [(set (match_dup 2)
13730 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13731 UNSPEC_XTRACT_FRACT))
13732 (set (match_operand:XF 0 "register_operand" "")
13733 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13734 "TARGET_USE_FANCY_MATH_387
13735 && flag_unsafe_math_optimizations"
13737 operands[2] = gen_reg_rtx (XFmode);
13740 (define_expand "logb<mode>2"
13741 [(use (match_operand:MODEF 0 "register_operand" ""))
13742 (use (match_operand:MODEF 1 "register_operand" ""))]
13743 "TARGET_USE_FANCY_MATH_387
13744 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13745 || TARGET_MIX_SSE_I387)
13746 && flag_unsafe_math_optimizations"
13748 rtx op0 = gen_reg_rtx (XFmode);
13749 rtx op1 = gen_reg_rtx (XFmode);
13751 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13752 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13756 (define_expand "ilogbxf2"
13757 [(use (match_operand:SI 0 "register_operand" ""))
13758 (use (match_operand:XF 1 "register_operand" ""))]
13759 "TARGET_USE_FANCY_MATH_387
13760 && flag_unsafe_math_optimizations"
13764 if (optimize_insn_for_size_p ())
13767 op0 = gen_reg_rtx (XFmode);
13768 op1 = gen_reg_rtx (XFmode);
13770 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13771 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13775 (define_expand "ilogb<mode>2"
13776 [(use (match_operand:SI 0 "register_operand" ""))
13777 (use (match_operand:MODEF 1 "register_operand" ""))]
13778 "TARGET_USE_FANCY_MATH_387
13779 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13780 || TARGET_MIX_SSE_I387)
13781 && flag_unsafe_math_optimizations"
13785 if (optimize_insn_for_size_p ())
13788 op0 = gen_reg_rtx (XFmode);
13789 op1 = gen_reg_rtx (XFmode);
13791 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13792 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13796 (define_insn "*f2xm1xf2_i387"
13797 [(set (match_operand:XF 0 "register_operand" "=f")
13798 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13800 "TARGET_USE_FANCY_MATH_387
13801 && flag_unsafe_math_optimizations"
13803 [(set_attr "type" "fpspc")
13804 (set_attr "mode" "XF")])
13806 (define_insn "*fscalexf4_i387"
13807 [(set (match_operand:XF 0 "register_operand" "=f")
13808 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13809 (match_operand:XF 3 "register_operand" "1")]
13810 UNSPEC_FSCALE_FRACT))
13811 (set (match_operand:XF 1 "register_operand" "=u")
13812 (unspec:XF [(match_dup 2) (match_dup 3)]
13813 UNSPEC_FSCALE_EXP))]
13814 "TARGET_USE_FANCY_MATH_387
13815 && flag_unsafe_math_optimizations"
13817 [(set_attr "type" "fpspc")
13818 (set_attr "mode" "XF")])
13820 (define_expand "expNcorexf3"
13821 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13822 (match_operand:XF 2 "register_operand" "")))
13823 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13824 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13825 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13826 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13827 (parallel [(set (match_operand:XF 0 "register_operand" "")
13828 (unspec:XF [(match_dup 8) (match_dup 4)]
13829 UNSPEC_FSCALE_FRACT))
13831 (unspec:XF [(match_dup 8) (match_dup 4)]
13832 UNSPEC_FSCALE_EXP))])]
13833 "TARGET_USE_FANCY_MATH_387
13834 && flag_unsafe_math_optimizations"
13838 if (optimize_insn_for_size_p ())
13841 for (i = 3; i < 10; i++)
13842 operands[i] = gen_reg_rtx (XFmode);
13844 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13847 (define_expand "expxf2"
13848 [(use (match_operand:XF 0 "register_operand" ""))
13849 (use (match_operand:XF 1 "register_operand" ""))]
13850 "TARGET_USE_FANCY_MATH_387
13851 && flag_unsafe_math_optimizations"
13855 if (optimize_insn_for_size_p ())
13858 op2 = gen_reg_rtx (XFmode);
13859 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13861 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13865 (define_expand "exp<mode>2"
13866 [(use (match_operand:MODEF 0 "register_operand" ""))
13867 (use (match_operand:MODEF 1 "general_operand" ""))]
13868 "TARGET_USE_FANCY_MATH_387
13869 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13870 || TARGET_MIX_SSE_I387)
13871 && flag_unsafe_math_optimizations"
13875 if (optimize_insn_for_size_p ())
13878 op0 = gen_reg_rtx (XFmode);
13879 op1 = gen_reg_rtx (XFmode);
13881 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13882 emit_insn (gen_expxf2 (op0, op1));
13883 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13887 (define_expand "exp10xf2"
13888 [(use (match_operand:XF 0 "register_operand" ""))
13889 (use (match_operand:XF 1 "register_operand" ""))]
13890 "TARGET_USE_FANCY_MATH_387
13891 && flag_unsafe_math_optimizations"
13895 if (optimize_insn_for_size_p ())
13898 op2 = gen_reg_rtx (XFmode);
13899 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13901 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13905 (define_expand "exp10<mode>2"
13906 [(use (match_operand:MODEF 0 "register_operand" ""))
13907 (use (match_operand:MODEF 1 "general_operand" ""))]
13908 "TARGET_USE_FANCY_MATH_387
13909 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13910 || TARGET_MIX_SSE_I387)
13911 && flag_unsafe_math_optimizations"
13915 if (optimize_insn_for_size_p ())
13918 op0 = gen_reg_rtx (XFmode);
13919 op1 = gen_reg_rtx (XFmode);
13921 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13922 emit_insn (gen_exp10xf2 (op0, op1));
13923 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13927 (define_expand "exp2xf2"
13928 [(use (match_operand:XF 0 "register_operand" ""))
13929 (use (match_operand:XF 1 "register_operand" ""))]
13930 "TARGET_USE_FANCY_MATH_387
13931 && flag_unsafe_math_optimizations"
13935 if (optimize_insn_for_size_p ())
13938 op2 = gen_reg_rtx (XFmode);
13939 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13941 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13945 (define_expand "exp2<mode>2"
13946 [(use (match_operand:MODEF 0 "register_operand" ""))
13947 (use (match_operand:MODEF 1 "general_operand" ""))]
13948 "TARGET_USE_FANCY_MATH_387
13949 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13950 || TARGET_MIX_SSE_I387)
13951 && flag_unsafe_math_optimizations"
13955 if (optimize_insn_for_size_p ())
13958 op0 = gen_reg_rtx (XFmode);
13959 op1 = gen_reg_rtx (XFmode);
13961 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13962 emit_insn (gen_exp2xf2 (op0, op1));
13963 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13967 (define_expand "expm1xf2"
13968 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13970 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13971 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13972 (set (match_dup 9) (float_extend:XF (match_dup 13)))
13973 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13974 (parallel [(set (match_dup 7)
13975 (unspec:XF [(match_dup 6) (match_dup 4)]
13976 UNSPEC_FSCALE_FRACT))
13978 (unspec:XF [(match_dup 6) (match_dup 4)]
13979 UNSPEC_FSCALE_EXP))])
13980 (parallel [(set (match_dup 10)
13981 (unspec:XF [(match_dup 9) (match_dup 8)]
13982 UNSPEC_FSCALE_FRACT))
13983 (set (match_dup 11)
13984 (unspec:XF [(match_dup 9) (match_dup 8)]
13985 UNSPEC_FSCALE_EXP))])
13986 (set (match_dup 12) (minus:XF (match_dup 10)
13987 (float_extend:XF (match_dup 13))))
13988 (set (match_operand:XF 0 "register_operand" "")
13989 (plus:XF (match_dup 12) (match_dup 7)))]
13990 "TARGET_USE_FANCY_MATH_387
13991 && flag_unsafe_math_optimizations"
13995 if (optimize_insn_for_size_p ())
13998 for (i = 2; i < 13; i++)
13999 operands[i] = gen_reg_rtx (XFmode);
14002 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14004 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14007 (define_expand "expm1<mode>2"
14008 [(use (match_operand:MODEF 0 "register_operand" ""))
14009 (use (match_operand:MODEF 1 "general_operand" ""))]
14010 "TARGET_USE_FANCY_MATH_387
14011 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14012 || TARGET_MIX_SSE_I387)
14013 && flag_unsafe_math_optimizations"
14017 if (optimize_insn_for_size_p ())
14020 op0 = gen_reg_rtx (XFmode);
14021 op1 = gen_reg_rtx (XFmode);
14023 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14024 emit_insn (gen_expm1xf2 (op0, op1));
14025 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14029 (define_expand "ldexpxf3"
14030 [(set (match_dup 3)
14031 (float:XF (match_operand:SI 2 "register_operand" "")))
14032 (parallel [(set (match_operand:XF 0 " register_operand" "")
14033 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14035 UNSPEC_FSCALE_FRACT))
14037 (unspec:XF [(match_dup 1) (match_dup 3)]
14038 UNSPEC_FSCALE_EXP))])]
14039 "TARGET_USE_FANCY_MATH_387
14040 && flag_unsafe_math_optimizations"
14042 if (optimize_insn_for_size_p ())
14045 operands[3] = gen_reg_rtx (XFmode);
14046 operands[4] = gen_reg_rtx (XFmode);
14049 (define_expand "ldexp<mode>3"
14050 [(use (match_operand:MODEF 0 "register_operand" ""))
14051 (use (match_operand:MODEF 1 "general_operand" ""))
14052 (use (match_operand:SI 2 "register_operand" ""))]
14053 "TARGET_USE_FANCY_MATH_387
14054 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14055 || TARGET_MIX_SSE_I387)
14056 && flag_unsafe_math_optimizations"
14060 if (optimize_insn_for_size_p ())
14063 op0 = gen_reg_rtx (XFmode);
14064 op1 = gen_reg_rtx (XFmode);
14066 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14067 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14068 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14072 (define_expand "scalbxf3"
14073 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14074 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14075 (match_operand:XF 2 "register_operand" "")]
14076 UNSPEC_FSCALE_FRACT))
14078 (unspec:XF [(match_dup 1) (match_dup 2)]
14079 UNSPEC_FSCALE_EXP))])]
14080 "TARGET_USE_FANCY_MATH_387
14081 && flag_unsafe_math_optimizations"
14083 if (optimize_insn_for_size_p ())
14086 operands[3] = gen_reg_rtx (XFmode);
14089 (define_expand "scalb<mode>3"
14090 [(use (match_operand:MODEF 0 "register_operand" ""))
14091 (use (match_operand:MODEF 1 "general_operand" ""))
14092 (use (match_operand:MODEF 2 "general_operand" ""))]
14093 "TARGET_USE_FANCY_MATH_387
14094 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14095 || TARGET_MIX_SSE_I387)
14096 && flag_unsafe_math_optimizations"
14100 if (optimize_insn_for_size_p ())
14103 op0 = gen_reg_rtx (XFmode);
14104 op1 = gen_reg_rtx (XFmode);
14105 op2 = gen_reg_rtx (XFmode);
14107 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14108 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14109 emit_insn (gen_scalbxf3 (op0, op1, op2));
14110 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14114 (define_expand "significandxf2"
14115 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14116 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14117 UNSPEC_XTRACT_FRACT))
14119 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14120 "TARGET_USE_FANCY_MATH_387
14121 && flag_unsafe_math_optimizations"
14123 operands[2] = gen_reg_rtx (XFmode);
14126 (define_expand "significand<mode>2"
14127 [(use (match_operand:MODEF 0 "register_operand" ""))
14128 (use (match_operand:MODEF 1 "register_operand" ""))]
14129 "TARGET_USE_FANCY_MATH_387
14130 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14131 || TARGET_MIX_SSE_I387)
14132 && flag_unsafe_math_optimizations"
14134 rtx op0 = gen_reg_rtx (XFmode);
14135 rtx op1 = gen_reg_rtx (XFmode);
14137 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14138 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14143 (define_insn "sse4_1_round<mode>2"
14144 [(set (match_operand:MODEF 0 "register_operand" "=x")
14145 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14146 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14149 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14150 [(set_attr "type" "ssecvt")
14151 (set_attr "prefix_extra" "1")
14152 (set_attr "prefix" "maybe_vex")
14153 (set_attr "mode" "<MODE>")])
14155 (define_insn "rintxf2"
14156 [(set (match_operand:XF 0 "register_operand" "=f")
14157 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14159 "TARGET_USE_FANCY_MATH_387
14160 && flag_unsafe_math_optimizations"
14162 [(set_attr "type" "fpspc")
14163 (set_attr "mode" "XF")])
14165 (define_expand "rint<mode>2"
14166 [(use (match_operand:MODEF 0 "register_operand" ""))
14167 (use (match_operand:MODEF 1 "register_operand" ""))]
14168 "(TARGET_USE_FANCY_MATH_387
14169 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14170 || TARGET_MIX_SSE_I387)
14171 && flag_unsafe_math_optimizations)
14172 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14173 && !flag_trapping_math)"
14175 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14176 && !flag_trapping_math)
14178 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14181 emit_insn (gen_sse4_1_round<mode>2
14182 (operands[0], operands[1], GEN_INT (0x04)));
14184 ix86_expand_rint (operand0, operand1);
14188 rtx op0 = gen_reg_rtx (XFmode);
14189 rtx op1 = gen_reg_rtx (XFmode);
14191 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14192 emit_insn (gen_rintxf2 (op0, op1));
14194 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14199 (define_expand "round<mode>2"
14200 [(match_operand:MODEF 0 "register_operand" "")
14201 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14202 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14203 && !flag_trapping_math && !flag_rounding_math"
14205 if (optimize_insn_for_size_p ())
14207 if (TARGET_64BIT || (<MODE>mode != DFmode))
14208 ix86_expand_round (operand0, operand1);
14210 ix86_expand_rounddf_32 (operand0, operand1);
14214 (define_insn_and_split "*fistdi2_1"
14215 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14216 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14218 "TARGET_USE_FANCY_MATH_387
14219 && can_create_pseudo_p ()"
14224 if (memory_operand (operands[0], VOIDmode))
14225 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14228 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14229 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14234 [(set_attr "type" "fpspc")
14235 (set_attr "mode" "DI")])
14237 (define_insn "fistdi2"
14238 [(set (match_operand:DI 0 "memory_operand" "=m")
14239 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14241 (clobber (match_scratch:XF 2 "=&1f"))]
14242 "TARGET_USE_FANCY_MATH_387"
14243 "* return output_fix_trunc (insn, operands, 0);"
14244 [(set_attr "type" "fpspc")
14245 (set_attr "mode" "DI")])
14247 (define_insn "fistdi2_with_temp"
14248 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14249 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14251 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14252 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14253 "TARGET_USE_FANCY_MATH_387"
14255 [(set_attr "type" "fpspc")
14256 (set_attr "mode" "DI")])
14259 [(set (match_operand:DI 0 "register_operand" "")
14260 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14262 (clobber (match_operand:DI 2 "memory_operand" ""))
14263 (clobber (match_scratch 3 ""))]
14265 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14266 (clobber (match_dup 3))])
14267 (set (match_dup 0) (match_dup 2))]
14271 [(set (match_operand:DI 0 "memory_operand" "")
14272 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14274 (clobber (match_operand:DI 2 "memory_operand" ""))
14275 (clobber (match_scratch 3 ""))]
14277 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14278 (clobber (match_dup 3))])]
14281 (define_insn_and_split "*fist<mode>2_1"
14282 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14283 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14285 "TARGET_USE_FANCY_MATH_387
14286 && can_create_pseudo_p ()"
14291 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14292 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14296 [(set_attr "type" "fpspc")
14297 (set_attr "mode" "<MODE>")])
14299 (define_insn "fist<mode>2"
14300 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14301 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14303 "TARGET_USE_FANCY_MATH_387"
14304 "* return output_fix_trunc (insn, operands, 0);"
14305 [(set_attr "type" "fpspc")
14306 (set_attr "mode" "<MODE>")])
14308 (define_insn "fist<mode>2_with_temp"
14309 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14310 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14312 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14313 "TARGET_USE_FANCY_MATH_387"
14315 [(set_attr "type" "fpspc")
14316 (set_attr "mode" "<MODE>")])
14319 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14320 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14322 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14324 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14325 (set (match_dup 0) (match_dup 2))]
14329 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14330 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14332 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14334 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14337 (define_expand "lrintxf<mode>2"
14338 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14339 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14341 "TARGET_USE_FANCY_MATH_387"
14344 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14345 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14346 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14347 UNSPEC_FIX_NOTRUNC))]
14348 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14349 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14352 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14353 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14354 (match_operand:MODEF 1 "register_operand" "")]
14355 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14356 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14357 && !flag_trapping_math && !flag_rounding_math"
14359 if (optimize_insn_for_size_p ())
14361 ix86_expand_lround (operand0, operand1);
14365 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14366 (define_insn_and_split "frndintxf2_floor"
14367 [(set (match_operand:XF 0 "register_operand" "")
14368 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14369 UNSPEC_FRNDINT_FLOOR))
14370 (clobber (reg:CC FLAGS_REG))]
14371 "TARGET_USE_FANCY_MATH_387
14372 && flag_unsafe_math_optimizations
14373 && can_create_pseudo_p ()"
14378 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14380 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14381 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14383 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14384 operands[2], operands[3]));
14387 [(set_attr "type" "frndint")
14388 (set_attr "i387_cw" "floor")
14389 (set_attr "mode" "XF")])
14391 (define_insn "frndintxf2_floor_i387"
14392 [(set (match_operand:XF 0 "register_operand" "=f")
14393 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14394 UNSPEC_FRNDINT_FLOOR))
14395 (use (match_operand:HI 2 "memory_operand" "m"))
14396 (use (match_operand:HI 3 "memory_operand" "m"))]
14397 "TARGET_USE_FANCY_MATH_387
14398 && flag_unsafe_math_optimizations"
14399 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14400 [(set_attr "type" "frndint")
14401 (set_attr "i387_cw" "floor")
14402 (set_attr "mode" "XF")])
14404 (define_expand "floorxf2"
14405 [(use (match_operand:XF 0 "register_operand" ""))
14406 (use (match_operand:XF 1 "register_operand" ""))]
14407 "TARGET_USE_FANCY_MATH_387
14408 && flag_unsafe_math_optimizations"
14410 if (optimize_insn_for_size_p ())
14412 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14416 (define_expand "floor<mode>2"
14417 [(use (match_operand:MODEF 0 "register_operand" ""))
14418 (use (match_operand:MODEF 1 "register_operand" ""))]
14419 "(TARGET_USE_FANCY_MATH_387
14420 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14421 || TARGET_MIX_SSE_I387)
14422 && flag_unsafe_math_optimizations)
14423 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14424 && !flag_trapping_math)"
14426 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14427 && !flag_trapping_math
14428 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14430 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14433 emit_insn (gen_sse4_1_round<mode>2
14434 (operands[0], operands[1], GEN_INT (0x01)));
14435 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14436 ix86_expand_floorceil (operand0, operand1, true);
14438 ix86_expand_floorceildf_32 (operand0, operand1, true);
14444 if (optimize_insn_for_size_p ())
14447 op0 = gen_reg_rtx (XFmode);
14448 op1 = gen_reg_rtx (XFmode);
14449 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14450 emit_insn (gen_frndintxf2_floor (op0, op1));
14452 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14457 (define_insn_and_split "*fist<mode>2_floor_1"
14458 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14459 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14460 UNSPEC_FIST_FLOOR))
14461 (clobber (reg:CC FLAGS_REG))]
14462 "TARGET_USE_FANCY_MATH_387
14463 && flag_unsafe_math_optimizations
14464 && can_create_pseudo_p ()"
14469 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14471 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14472 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14473 if (memory_operand (operands[0], VOIDmode))
14474 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14475 operands[2], operands[3]));
14478 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14479 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14480 operands[2], operands[3],
14485 [(set_attr "type" "fistp")
14486 (set_attr "i387_cw" "floor")
14487 (set_attr "mode" "<MODE>")])
14489 (define_insn "fistdi2_floor"
14490 [(set (match_operand:DI 0 "memory_operand" "=m")
14491 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14492 UNSPEC_FIST_FLOOR))
14493 (use (match_operand:HI 2 "memory_operand" "m"))
14494 (use (match_operand:HI 3 "memory_operand" "m"))
14495 (clobber (match_scratch:XF 4 "=&1f"))]
14496 "TARGET_USE_FANCY_MATH_387
14497 && flag_unsafe_math_optimizations"
14498 "* return output_fix_trunc (insn, operands, 0);"
14499 [(set_attr "type" "fistp")
14500 (set_attr "i387_cw" "floor")
14501 (set_attr "mode" "DI")])
14503 (define_insn "fistdi2_floor_with_temp"
14504 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14505 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14506 UNSPEC_FIST_FLOOR))
14507 (use (match_operand:HI 2 "memory_operand" "m,m"))
14508 (use (match_operand:HI 3 "memory_operand" "m,m"))
14509 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14510 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14511 "TARGET_USE_FANCY_MATH_387
14512 && flag_unsafe_math_optimizations"
14514 [(set_attr "type" "fistp")
14515 (set_attr "i387_cw" "floor")
14516 (set_attr "mode" "DI")])
14519 [(set (match_operand:DI 0 "register_operand" "")
14520 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14521 UNSPEC_FIST_FLOOR))
14522 (use (match_operand:HI 2 "memory_operand" ""))
14523 (use (match_operand:HI 3 "memory_operand" ""))
14524 (clobber (match_operand:DI 4 "memory_operand" ""))
14525 (clobber (match_scratch 5 ""))]
14527 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14528 (use (match_dup 2))
14529 (use (match_dup 3))
14530 (clobber (match_dup 5))])
14531 (set (match_dup 0) (match_dup 4))]
14535 [(set (match_operand:DI 0 "memory_operand" "")
14536 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14537 UNSPEC_FIST_FLOOR))
14538 (use (match_operand:HI 2 "memory_operand" ""))
14539 (use (match_operand:HI 3 "memory_operand" ""))
14540 (clobber (match_operand:DI 4 "memory_operand" ""))
14541 (clobber (match_scratch 5 ""))]
14543 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14544 (use (match_dup 2))
14545 (use (match_dup 3))
14546 (clobber (match_dup 5))])]
14549 (define_insn "fist<mode>2_floor"
14550 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14551 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14552 UNSPEC_FIST_FLOOR))
14553 (use (match_operand:HI 2 "memory_operand" "m"))
14554 (use (match_operand:HI 3 "memory_operand" "m"))]
14555 "TARGET_USE_FANCY_MATH_387
14556 && flag_unsafe_math_optimizations"
14557 "* return output_fix_trunc (insn, operands, 0);"
14558 [(set_attr "type" "fistp")
14559 (set_attr "i387_cw" "floor")
14560 (set_attr "mode" "<MODE>")])
14562 (define_insn "fist<mode>2_floor_with_temp"
14563 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14564 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14565 UNSPEC_FIST_FLOOR))
14566 (use (match_operand:HI 2 "memory_operand" "m,m"))
14567 (use (match_operand:HI 3 "memory_operand" "m,m"))
14568 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14569 "TARGET_USE_FANCY_MATH_387
14570 && flag_unsafe_math_optimizations"
14572 [(set_attr "type" "fistp")
14573 (set_attr "i387_cw" "floor")
14574 (set_attr "mode" "<MODE>")])
14577 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14578 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14579 UNSPEC_FIST_FLOOR))
14580 (use (match_operand:HI 2 "memory_operand" ""))
14581 (use (match_operand:HI 3 "memory_operand" ""))
14582 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14584 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14585 UNSPEC_FIST_FLOOR))
14586 (use (match_dup 2))
14587 (use (match_dup 3))])
14588 (set (match_dup 0) (match_dup 4))]
14592 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14593 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14594 UNSPEC_FIST_FLOOR))
14595 (use (match_operand:HI 2 "memory_operand" ""))
14596 (use (match_operand:HI 3 "memory_operand" ""))
14597 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14599 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14600 UNSPEC_FIST_FLOOR))
14601 (use (match_dup 2))
14602 (use (match_dup 3))])]
14605 (define_expand "lfloorxf<mode>2"
14606 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14607 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14608 UNSPEC_FIST_FLOOR))
14609 (clobber (reg:CC FLAGS_REG))])]
14610 "TARGET_USE_FANCY_MATH_387
14611 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14612 && flag_unsafe_math_optimizations"
14615 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14616 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14617 (match_operand:MODEF 1 "register_operand" "")]
14618 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14619 && !flag_trapping_math"
14621 if (TARGET_64BIT && optimize_insn_for_size_p ())
14623 ix86_expand_lfloorceil (operand0, operand1, true);
14627 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14628 (define_insn_and_split "frndintxf2_ceil"
14629 [(set (match_operand:XF 0 "register_operand" "")
14630 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14631 UNSPEC_FRNDINT_CEIL))
14632 (clobber (reg:CC FLAGS_REG))]
14633 "TARGET_USE_FANCY_MATH_387
14634 && flag_unsafe_math_optimizations
14635 && can_create_pseudo_p ()"
14640 ix86_optimize_mode_switching[I387_CEIL] = 1;
14642 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14643 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14645 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14646 operands[2], operands[3]));
14649 [(set_attr "type" "frndint")
14650 (set_attr "i387_cw" "ceil")
14651 (set_attr "mode" "XF")])
14653 (define_insn "frndintxf2_ceil_i387"
14654 [(set (match_operand:XF 0 "register_operand" "=f")
14655 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14656 UNSPEC_FRNDINT_CEIL))
14657 (use (match_operand:HI 2 "memory_operand" "m"))
14658 (use (match_operand:HI 3 "memory_operand" "m"))]
14659 "TARGET_USE_FANCY_MATH_387
14660 && flag_unsafe_math_optimizations"
14661 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14662 [(set_attr "type" "frndint")
14663 (set_attr "i387_cw" "ceil")
14664 (set_attr "mode" "XF")])
14666 (define_expand "ceilxf2"
14667 [(use (match_operand:XF 0 "register_operand" ""))
14668 (use (match_operand:XF 1 "register_operand" ""))]
14669 "TARGET_USE_FANCY_MATH_387
14670 && flag_unsafe_math_optimizations"
14672 if (optimize_insn_for_size_p ())
14674 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14678 (define_expand "ceil<mode>2"
14679 [(use (match_operand:MODEF 0 "register_operand" ""))
14680 (use (match_operand:MODEF 1 "register_operand" ""))]
14681 "(TARGET_USE_FANCY_MATH_387
14682 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14683 || TARGET_MIX_SSE_I387)
14684 && flag_unsafe_math_optimizations)
14685 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14686 && !flag_trapping_math)"
14688 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14689 && !flag_trapping_math
14690 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14693 emit_insn (gen_sse4_1_round<mode>2
14694 (operands[0], operands[1], GEN_INT (0x02)));
14695 else if (optimize_insn_for_size_p ())
14697 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14698 ix86_expand_floorceil (operand0, operand1, false);
14700 ix86_expand_floorceildf_32 (operand0, operand1, false);
14706 if (optimize_insn_for_size_p ())
14709 op0 = gen_reg_rtx (XFmode);
14710 op1 = gen_reg_rtx (XFmode);
14711 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14712 emit_insn (gen_frndintxf2_ceil (op0, op1));
14714 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14719 (define_insn_and_split "*fist<mode>2_ceil_1"
14720 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14721 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14723 (clobber (reg:CC FLAGS_REG))]
14724 "TARGET_USE_FANCY_MATH_387
14725 && flag_unsafe_math_optimizations
14726 && can_create_pseudo_p ()"
14731 ix86_optimize_mode_switching[I387_CEIL] = 1;
14733 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14734 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14735 if (memory_operand (operands[0], VOIDmode))
14736 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14737 operands[2], operands[3]));
14740 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14741 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14742 operands[2], operands[3],
14747 [(set_attr "type" "fistp")
14748 (set_attr "i387_cw" "ceil")
14749 (set_attr "mode" "<MODE>")])
14751 (define_insn "fistdi2_ceil"
14752 [(set (match_operand:DI 0 "memory_operand" "=m")
14753 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14755 (use (match_operand:HI 2 "memory_operand" "m"))
14756 (use (match_operand:HI 3 "memory_operand" "m"))
14757 (clobber (match_scratch:XF 4 "=&1f"))]
14758 "TARGET_USE_FANCY_MATH_387
14759 && flag_unsafe_math_optimizations"
14760 "* return output_fix_trunc (insn, operands, 0);"
14761 [(set_attr "type" "fistp")
14762 (set_attr "i387_cw" "ceil")
14763 (set_attr "mode" "DI")])
14765 (define_insn "fistdi2_ceil_with_temp"
14766 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14767 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14769 (use (match_operand:HI 2 "memory_operand" "m,m"))
14770 (use (match_operand:HI 3 "memory_operand" "m,m"))
14771 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14772 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14773 "TARGET_USE_FANCY_MATH_387
14774 && flag_unsafe_math_optimizations"
14776 [(set_attr "type" "fistp")
14777 (set_attr "i387_cw" "ceil")
14778 (set_attr "mode" "DI")])
14781 [(set (match_operand:DI 0 "register_operand" "")
14782 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14784 (use (match_operand:HI 2 "memory_operand" ""))
14785 (use (match_operand:HI 3 "memory_operand" ""))
14786 (clobber (match_operand:DI 4 "memory_operand" ""))
14787 (clobber (match_scratch 5 ""))]
14789 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14790 (use (match_dup 2))
14791 (use (match_dup 3))
14792 (clobber (match_dup 5))])
14793 (set (match_dup 0) (match_dup 4))]
14797 [(set (match_operand:DI 0 "memory_operand" "")
14798 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14800 (use (match_operand:HI 2 "memory_operand" ""))
14801 (use (match_operand:HI 3 "memory_operand" ""))
14802 (clobber (match_operand:DI 4 "memory_operand" ""))
14803 (clobber (match_scratch 5 ""))]
14805 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14806 (use (match_dup 2))
14807 (use (match_dup 3))
14808 (clobber (match_dup 5))])]
14811 (define_insn "fist<mode>2_ceil"
14812 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14813 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14815 (use (match_operand:HI 2 "memory_operand" "m"))
14816 (use (match_operand:HI 3 "memory_operand" "m"))]
14817 "TARGET_USE_FANCY_MATH_387
14818 && flag_unsafe_math_optimizations"
14819 "* return output_fix_trunc (insn, operands, 0);"
14820 [(set_attr "type" "fistp")
14821 (set_attr "i387_cw" "ceil")
14822 (set_attr "mode" "<MODE>")])
14824 (define_insn "fist<mode>2_ceil_with_temp"
14825 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14826 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14828 (use (match_operand:HI 2 "memory_operand" "m,m"))
14829 (use (match_operand:HI 3 "memory_operand" "m,m"))
14830 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14831 "TARGET_USE_FANCY_MATH_387
14832 && flag_unsafe_math_optimizations"
14834 [(set_attr "type" "fistp")
14835 (set_attr "i387_cw" "ceil")
14836 (set_attr "mode" "<MODE>")])
14839 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14840 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14842 (use (match_operand:HI 2 "memory_operand" ""))
14843 (use (match_operand:HI 3 "memory_operand" ""))
14844 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14846 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14848 (use (match_dup 2))
14849 (use (match_dup 3))])
14850 (set (match_dup 0) (match_dup 4))]
14854 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14855 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14857 (use (match_operand:HI 2 "memory_operand" ""))
14858 (use (match_operand:HI 3 "memory_operand" ""))
14859 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14861 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14863 (use (match_dup 2))
14864 (use (match_dup 3))])]
14867 (define_expand "lceilxf<mode>2"
14868 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14869 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14871 (clobber (reg:CC FLAGS_REG))])]
14872 "TARGET_USE_FANCY_MATH_387
14873 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14874 && flag_unsafe_math_optimizations"
14877 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14878 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14879 (match_operand:MODEF 1 "register_operand" "")]
14880 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14881 && !flag_trapping_math"
14883 ix86_expand_lfloorceil (operand0, operand1, false);
14887 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14888 (define_insn_and_split "frndintxf2_trunc"
14889 [(set (match_operand:XF 0 "register_operand" "")
14890 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14891 UNSPEC_FRNDINT_TRUNC))
14892 (clobber (reg:CC FLAGS_REG))]
14893 "TARGET_USE_FANCY_MATH_387
14894 && flag_unsafe_math_optimizations
14895 && can_create_pseudo_p ()"
14900 ix86_optimize_mode_switching[I387_TRUNC] = 1;
14902 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14903 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14905 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14906 operands[2], operands[3]));
14909 [(set_attr "type" "frndint")
14910 (set_attr "i387_cw" "trunc")
14911 (set_attr "mode" "XF")])
14913 (define_insn "frndintxf2_trunc_i387"
14914 [(set (match_operand:XF 0 "register_operand" "=f")
14915 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14916 UNSPEC_FRNDINT_TRUNC))
14917 (use (match_operand:HI 2 "memory_operand" "m"))
14918 (use (match_operand:HI 3 "memory_operand" "m"))]
14919 "TARGET_USE_FANCY_MATH_387
14920 && flag_unsafe_math_optimizations"
14921 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14922 [(set_attr "type" "frndint")
14923 (set_attr "i387_cw" "trunc")
14924 (set_attr "mode" "XF")])
14926 (define_expand "btruncxf2"
14927 [(use (match_operand:XF 0 "register_operand" ""))
14928 (use (match_operand:XF 1 "register_operand" ""))]
14929 "TARGET_USE_FANCY_MATH_387
14930 && flag_unsafe_math_optimizations"
14932 if (optimize_insn_for_size_p ())
14934 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14938 (define_expand "btrunc<mode>2"
14939 [(use (match_operand:MODEF 0 "register_operand" ""))
14940 (use (match_operand:MODEF 1 "register_operand" ""))]
14941 "(TARGET_USE_FANCY_MATH_387
14942 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14943 || TARGET_MIX_SSE_I387)
14944 && flag_unsafe_math_optimizations)
14945 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14946 && !flag_trapping_math)"
14948 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14949 && !flag_trapping_math
14950 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14953 emit_insn (gen_sse4_1_round<mode>2
14954 (operands[0], operands[1], GEN_INT (0x03)));
14955 else if (optimize_insn_for_size_p ())
14957 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14958 ix86_expand_trunc (operand0, operand1);
14960 ix86_expand_truncdf_32 (operand0, operand1);
14966 if (optimize_insn_for_size_p ())
14969 op0 = gen_reg_rtx (XFmode);
14970 op1 = gen_reg_rtx (XFmode);
14971 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14972 emit_insn (gen_frndintxf2_trunc (op0, op1));
14974 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14979 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14980 (define_insn_and_split "frndintxf2_mask_pm"
14981 [(set (match_operand:XF 0 "register_operand" "")
14982 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14983 UNSPEC_FRNDINT_MASK_PM))
14984 (clobber (reg:CC FLAGS_REG))]
14985 "TARGET_USE_FANCY_MATH_387
14986 && flag_unsafe_math_optimizations
14987 && can_create_pseudo_p ()"
14992 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14994 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14995 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14997 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14998 operands[2], operands[3]));
15001 [(set_attr "type" "frndint")
15002 (set_attr "i387_cw" "mask_pm")
15003 (set_attr "mode" "XF")])
15005 (define_insn "frndintxf2_mask_pm_i387"
15006 [(set (match_operand:XF 0 "register_operand" "=f")
15007 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15008 UNSPEC_FRNDINT_MASK_PM))
15009 (use (match_operand:HI 2 "memory_operand" "m"))
15010 (use (match_operand:HI 3 "memory_operand" "m"))]
15011 "TARGET_USE_FANCY_MATH_387
15012 && flag_unsafe_math_optimizations"
15013 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15014 [(set_attr "type" "frndint")
15015 (set_attr "i387_cw" "mask_pm")
15016 (set_attr "mode" "XF")])
15018 (define_expand "nearbyintxf2"
15019 [(use (match_operand:XF 0 "register_operand" ""))
15020 (use (match_operand:XF 1 "register_operand" ""))]
15021 "TARGET_USE_FANCY_MATH_387
15022 && flag_unsafe_math_optimizations"
15024 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15029 (define_expand "nearbyint<mode>2"
15030 [(use (match_operand:MODEF 0 "register_operand" ""))
15031 (use (match_operand:MODEF 1 "register_operand" ""))]
15032 "TARGET_USE_FANCY_MATH_387
15033 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15034 || TARGET_MIX_SSE_I387)
15035 && flag_unsafe_math_optimizations"
15037 rtx op0 = gen_reg_rtx (XFmode);
15038 rtx op1 = gen_reg_rtx (XFmode);
15040 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15041 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15043 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15047 (define_insn "fxam<mode>2_i387"
15048 [(set (match_operand:HI 0 "register_operand" "=a")
15050 [(match_operand:X87MODEF 1 "register_operand" "f")]
15052 "TARGET_USE_FANCY_MATH_387"
15053 "fxam\n\tfnstsw\t%0"
15054 [(set_attr "type" "multi")
15055 (set_attr "length" "4")
15056 (set_attr "unit" "i387")
15057 (set_attr "mode" "<MODE>")])
15059 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15060 [(set (match_operand:HI 0 "register_operand" "")
15062 [(match_operand:MODEF 1 "memory_operand" "")]
15064 "TARGET_USE_FANCY_MATH_387
15065 && can_create_pseudo_p ()"
15068 [(set (match_dup 2)(match_dup 1))
15070 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15072 operands[2] = gen_reg_rtx (<MODE>mode);
15074 MEM_VOLATILE_P (operands[1]) = 1;
15076 [(set_attr "type" "multi")
15077 (set_attr "unit" "i387")
15078 (set_attr "mode" "<MODE>")])
15080 (define_expand "isinfxf2"
15081 [(use (match_operand:SI 0 "register_operand" ""))
15082 (use (match_operand:XF 1 "register_operand" ""))]
15083 "TARGET_USE_FANCY_MATH_387
15084 && TARGET_C99_FUNCTIONS"
15086 rtx mask = GEN_INT (0x45);
15087 rtx val = GEN_INT (0x05);
15091 rtx scratch = gen_reg_rtx (HImode);
15092 rtx res = gen_reg_rtx (QImode);
15094 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15096 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15097 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15098 cond = gen_rtx_fmt_ee (EQ, QImode,
15099 gen_rtx_REG (CCmode, FLAGS_REG),
15101 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15102 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15106 (define_expand "isinf<mode>2"
15107 [(use (match_operand:SI 0 "register_operand" ""))
15108 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15109 "TARGET_USE_FANCY_MATH_387
15110 && TARGET_C99_FUNCTIONS
15111 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15113 rtx mask = GEN_INT (0x45);
15114 rtx val = GEN_INT (0x05);
15118 rtx scratch = gen_reg_rtx (HImode);
15119 rtx res = gen_reg_rtx (QImode);
15121 /* Remove excess precision by forcing value through memory. */
15122 if (memory_operand (operands[1], VOIDmode))
15123 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15126 enum ix86_stack_slot slot = (virtuals_instantiated
15129 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15131 emit_move_insn (temp, operands[1]);
15132 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15135 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15136 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15137 cond = gen_rtx_fmt_ee (EQ, QImode,
15138 gen_rtx_REG (CCmode, FLAGS_REG),
15140 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15141 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15145 (define_expand "signbit<mode>2"
15146 [(use (match_operand:SI 0 "register_operand" ""))
15147 (use (match_operand:X87MODEF 1 "register_operand" ""))]
15148 "TARGET_USE_FANCY_MATH_387
15149 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15151 rtx mask = GEN_INT (0x0200);
15153 rtx scratch = gen_reg_rtx (HImode);
15155 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15156 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15160 ;; Block operation instructions
15163 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15166 [(set_attr "length" "1")
15167 (set_attr "length_immediate" "0")
15168 (set_attr "modrm" "0")])
15170 (define_expand "movmemsi"
15171 [(use (match_operand:BLK 0 "memory_operand" ""))
15172 (use (match_operand:BLK 1 "memory_operand" ""))
15173 (use (match_operand:SI 2 "nonmemory_operand" ""))
15174 (use (match_operand:SI 3 "const_int_operand" ""))
15175 (use (match_operand:SI 4 "const_int_operand" ""))
15176 (use (match_operand:SI 5 "const_int_operand" ""))]
15179 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15180 operands[4], operands[5]))
15186 (define_expand "movmemdi"
15187 [(use (match_operand:BLK 0 "memory_operand" ""))
15188 (use (match_operand:BLK 1 "memory_operand" ""))
15189 (use (match_operand:DI 2 "nonmemory_operand" ""))
15190 (use (match_operand:DI 3 "const_int_operand" ""))
15191 (use (match_operand:SI 4 "const_int_operand" ""))
15192 (use (match_operand:SI 5 "const_int_operand" ""))]
15195 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15196 operands[4], operands[5]))
15202 ;; Most CPUs don't like single string operations
15203 ;; Handle this case here to simplify previous expander.
15205 (define_expand "strmov"
15206 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15207 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15208 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15209 (clobber (reg:CC FLAGS_REG))])
15210 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15211 (clobber (reg:CC FLAGS_REG))])]
15214 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15216 /* If .md ever supports :P for Pmode, these can be directly
15217 in the pattern above. */
15218 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15219 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15221 /* Can't use this if the user has appropriated esi or edi. */
15222 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15223 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15225 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15226 operands[2], operands[3],
15227 operands[5], operands[6]));
15231 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15234 (define_expand "strmov_singleop"
15235 [(parallel [(set (match_operand 1 "memory_operand" "")
15236 (match_operand 3 "memory_operand" ""))
15237 (set (match_operand 0 "register_operand" "")
15238 (match_operand 4 "" ""))
15239 (set (match_operand 2 "register_operand" "")
15240 (match_operand 5 "" ""))])]
15242 "ix86_current_function_needs_cld = 1;")
15244 (define_insn "*strmovdi_rex_1"
15245 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15246 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15247 (set (match_operand:DI 0 "register_operand" "=D")
15248 (plus:DI (match_dup 2)
15250 (set (match_operand:DI 1 "register_operand" "=S")
15251 (plus:DI (match_dup 3)
15255 [(set_attr "type" "str")
15256 (set_attr "mode" "DI")
15257 (set_attr "memory" "both")])
15259 (define_insn "*strmovsi_1"
15260 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15261 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15262 (set (match_operand:SI 0 "register_operand" "=D")
15263 (plus:SI (match_dup 2)
15265 (set (match_operand:SI 1 "register_operand" "=S")
15266 (plus:SI (match_dup 3)
15270 [(set_attr "type" "str")
15271 (set_attr "mode" "SI")
15272 (set_attr "memory" "both")])
15274 (define_insn "*strmovsi_rex_1"
15275 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15276 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15277 (set (match_operand:DI 0 "register_operand" "=D")
15278 (plus:DI (match_dup 2)
15280 (set (match_operand:DI 1 "register_operand" "=S")
15281 (plus:DI (match_dup 3)
15285 [(set_attr "type" "str")
15286 (set_attr "mode" "SI")
15287 (set_attr "memory" "both")])
15289 (define_insn "*strmovhi_1"
15290 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15291 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15292 (set (match_operand:SI 0 "register_operand" "=D")
15293 (plus:SI (match_dup 2)
15295 (set (match_operand:SI 1 "register_operand" "=S")
15296 (plus:SI (match_dup 3)
15300 [(set_attr "type" "str")
15301 (set_attr "memory" "both")
15302 (set_attr "mode" "HI")])
15304 (define_insn "*strmovhi_rex_1"
15305 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15306 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15307 (set (match_operand:DI 0 "register_operand" "=D")
15308 (plus:DI (match_dup 2)
15310 (set (match_operand:DI 1 "register_operand" "=S")
15311 (plus:DI (match_dup 3)
15315 [(set_attr "type" "str")
15316 (set_attr "memory" "both")
15317 (set_attr "mode" "HI")])
15319 (define_insn "*strmovqi_1"
15320 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15321 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15322 (set (match_operand:SI 0 "register_operand" "=D")
15323 (plus:SI (match_dup 2)
15325 (set (match_operand:SI 1 "register_operand" "=S")
15326 (plus:SI (match_dup 3)
15330 [(set_attr "type" "str")
15331 (set_attr "memory" "both")
15332 (set_attr "mode" "QI")])
15334 (define_insn "*strmovqi_rex_1"
15335 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15336 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15337 (set (match_operand:DI 0 "register_operand" "=D")
15338 (plus:DI (match_dup 2)
15340 (set (match_operand:DI 1 "register_operand" "=S")
15341 (plus:DI (match_dup 3)
15345 [(set_attr "type" "str")
15346 (set_attr "memory" "both")
15347 (set_attr "prefix_rex" "0")
15348 (set_attr "mode" "QI")])
15350 (define_expand "rep_mov"
15351 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15352 (set (match_operand 0 "register_operand" "")
15353 (match_operand 5 "" ""))
15354 (set (match_operand 2 "register_operand" "")
15355 (match_operand 6 "" ""))
15356 (set (match_operand 1 "memory_operand" "")
15357 (match_operand 3 "memory_operand" ""))
15358 (use (match_dup 4))])]
15360 "ix86_current_function_needs_cld = 1;")
15362 (define_insn "*rep_movdi_rex64"
15363 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15364 (set (match_operand:DI 0 "register_operand" "=D")
15365 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15367 (match_operand:DI 3 "register_operand" "0")))
15368 (set (match_operand:DI 1 "register_operand" "=S")
15369 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15370 (match_operand:DI 4 "register_operand" "1")))
15371 (set (mem:BLK (match_dup 3))
15372 (mem:BLK (match_dup 4)))
15373 (use (match_dup 5))]
15376 [(set_attr "type" "str")
15377 (set_attr "prefix_rep" "1")
15378 (set_attr "memory" "both")
15379 (set_attr "mode" "DI")])
15381 (define_insn "*rep_movsi"
15382 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15383 (set (match_operand:SI 0 "register_operand" "=D")
15384 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15386 (match_operand:SI 3 "register_operand" "0")))
15387 (set (match_operand:SI 1 "register_operand" "=S")
15388 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15389 (match_operand:SI 4 "register_operand" "1")))
15390 (set (mem:BLK (match_dup 3))
15391 (mem:BLK (match_dup 4)))
15392 (use (match_dup 5))]
15394 "rep{%;} movs{l|d}"
15395 [(set_attr "type" "str")
15396 (set_attr "prefix_rep" "1")
15397 (set_attr "memory" "both")
15398 (set_attr "mode" "SI")])
15400 (define_insn "*rep_movsi_rex64"
15401 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15402 (set (match_operand:DI 0 "register_operand" "=D")
15403 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15405 (match_operand:DI 3 "register_operand" "0")))
15406 (set (match_operand:DI 1 "register_operand" "=S")
15407 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15408 (match_operand:DI 4 "register_operand" "1")))
15409 (set (mem:BLK (match_dup 3))
15410 (mem:BLK (match_dup 4)))
15411 (use (match_dup 5))]
15413 "rep{%;} movs{l|d}"
15414 [(set_attr "type" "str")
15415 (set_attr "prefix_rep" "1")
15416 (set_attr "memory" "both")
15417 (set_attr "mode" "SI")])
15419 (define_insn "*rep_movqi"
15420 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15421 (set (match_operand:SI 0 "register_operand" "=D")
15422 (plus:SI (match_operand:SI 3 "register_operand" "0")
15423 (match_operand:SI 5 "register_operand" "2")))
15424 (set (match_operand:SI 1 "register_operand" "=S")
15425 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15426 (set (mem:BLK (match_dup 3))
15427 (mem:BLK (match_dup 4)))
15428 (use (match_dup 5))]
15431 [(set_attr "type" "str")
15432 (set_attr "prefix_rep" "1")
15433 (set_attr "memory" "both")
15434 (set_attr "mode" "SI")])
15436 (define_insn "*rep_movqi_rex64"
15437 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15438 (set (match_operand:DI 0 "register_operand" "=D")
15439 (plus:DI (match_operand:DI 3 "register_operand" "0")
15440 (match_operand:DI 5 "register_operand" "2")))
15441 (set (match_operand:DI 1 "register_operand" "=S")
15442 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15443 (set (mem:BLK (match_dup 3))
15444 (mem:BLK (match_dup 4)))
15445 (use (match_dup 5))]
15448 [(set_attr "type" "str")
15449 (set_attr "prefix_rep" "1")
15450 (set_attr "memory" "both")
15451 (set_attr "mode" "SI")])
15453 (define_expand "setmemsi"
15454 [(use (match_operand:BLK 0 "memory_operand" ""))
15455 (use (match_operand:SI 1 "nonmemory_operand" ""))
15456 (use (match_operand 2 "const_int_operand" ""))
15457 (use (match_operand 3 "const_int_operand" ""))
15458 (use (match_operand:SI 4 "const_int_operand" ""))
15459 (use (match_operand:SI 5 "const_int_operand" ""))]
15462 if (ix86_expand_setmem (operands[0], operands[1],
15463 operands[2], operands[3],
15464 operands[4], operands[5]))
15470 (define_expand "setmemdi"
15471 [(use (match_operand:BLK 0 "memory_operand" ""))
15472 (use (match_operand:DI 1 "nonmemory_operand" ""))
15473 (use (match_operand 2 "const_int_operand" ""))
15474 (use (match_operand 3 "const_int_operand" ""))
15475 (use (match_operand 4 "const_int_operand" ""))
15476 (use (match_operand 5 "const_int_operand" ""))]
15479 if (ix86_expand_setmem (operands[0], operands[1],
15480 operands[2], operands[3],
15481 operands[4], operands[5]))
15487 ;; Most CPUs don't like single string operations
15488 ;; Handle this case here to simplify previous expander.
15490 (define_expand "strset"
15491 [(set (match_operand 1 "memory_operand" "")
15492 (match_operand 2 "register_operand" ""))
15493 (parallel [(set (match_operand 0 "register_operand" "")
15495 (clobber (reg:CC FLAGS_REG))])]
15498 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15499 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15501 /* If .md ever supports :P for Pmode, this can be directly
15502 in the pattern above. */
15503 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15504 GEN_INT (GET_MODE_SIZE (GET_MODE
15506 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15508 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15514 (define_expand "strset_singleop"
15515 [(parallel [(set (match_operand 1 "memory_operand" "")
15516 (match_operand 2 "register_operand" ""))
15517 (set (match_operand 0 "register_operand" "")
15518 (match_operand 3 "" ""))])]
15520 "ix86_current_function_needs_cld = 1;")
15522 (define_insn "*strsetdi_rex_1"
15523 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15524 (match_operand:DI 2 "register_operand" "a"))
15525 (set (match_operand:DI 0 "register_operand" "=D")
15526 (plus:DI (match_dup 1)
15530 [(set_attr "type" "str")
15531 (set_attr "memory" "store")
15532 (set_attr "mode" "DI")])
15534 (define_insn "*strsetsi_1"
15535 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15536 (match_operand:SI 2 "register_operand" "a"))
15537 (set (match_operand:SI 0 "register_operand" "=D")
15538 (plus:SI (match_dup 1)
15542 [(set_attr "type" "str")
15543 (set_attr "memory" "store")
15544 (set_attr "mode" "SI")])
15546 (define_insn "*strsetsi_rex_1"
15547 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15548 (match_operand:SI 2 "register_operand" "a"))
15549 (set (match_operand:DI 0 "register_operand" "=D")
15550 (plus:DI (match_dup 1)
15554 [(set_attr "type" "str")
15555 (set_attr "memory" "store")
15556 (set_attr "mode" "SI")])
15558 (define_insn "*strsethi_1"
15559 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15560 (match_operand:HI 2 "register_operand" "a"))
15561 (set (match_operand:SI 0 "register_operand" "=D")
15562 (plus:SI (match_dup 1)
15566 [(set_attr "type" "str")
15567 (set_attr "memory" "store")
15568 (set_attr "mode" "HI")])
15570 (define_insn "*strsethi_rex_1"
15571 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15572 (match_operand:HI 2 "register_operand" "a"))
15573 (set (match_operand:DI 0 "register_operand" "=D")
15574 (plus:DI (match_dup 1)
15578 [(set_attr "type" "str")
15579 (set_attr "memory" "store")
15580 (set_attr "mode" "HI")])
15582 (define_insn "*strsetqi_1"
15583 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15584 (match_operand:QI 2 "register_operand" "a"))
15585 (set (match_operand:SI 0 "register_operand" "=D")
15586 (plus:SI (match_dup 1)
15590 [(set_attr "type" "str")
15591 (set_attr "memory" "store")
15592 (set_attr "mode" "QI")])
15594 (define_insn "*strsetqi_rex_1"
15595 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15596 (match_operand:QI 2 "register_operand" "a"))
15597 (set (match_operand:DI 0 "register_operand" "=D")
15598 (plus:DI (match_dup 1)
15602 [(set_attr "type" "str")
15603 (set_attr "memory" "store")
15604 (set_attr "prefix_rex" "0")
15605 (set_attr "mode" "QI")])
15607 (define_expand "rep_stos"
15608 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15609 (set (match_operand 0 "register_operand" "")
15610 (match_operand 4 "" ""))
15611 (set (match_operand 2 "memory_operand" "") (const_int 0))
15612 (use (match_operand 3 "register_operand" ""))
15613 (use (match_dup 1))])]
15615 "ix86_current_function_needs_cld = 1;")
15617 (define_insn "*rep_stosdi_rex64"
15618 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15619 (set (match_operand:DI 0 "register_operand" "=D")
15620 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15622 (match_operand:DI 3 "register_operand" "0")))
15623 (set (mem:BLK (match_dup 3))
15625 (use (match_operand:DI 2 "register_operand" "a"))
15626 (use (match_dup 4))]
15629 [(set_attr "type" "str")
15630 (set_attr "prefix_rep" "1")
15631 (set_attr "memory" "store")
15632 (set_attr "mode" "DI")])
15634 (define_insn "*rep_stossi"
15635 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15636 (set (match_operand:SI 0 "register_operand" "=D")
15637 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15639 (match_operand:SI 3 "register_operand" "0")))
15640 (set (mem:BLK (match_dup 3))
15642 (use (match_operand:SI 2 "register_operand" "a"))
15643 (use (match_dup 4))]
15645 "rep{%;} stos{l|d}"
15646 [(set_attr "type" "str")
15647 (set_attr "prefix_rep" "1")
15648 (set_attr "memory" "store")
15649 (set_attr "mode" "SI")])
15651 (define_insn "*rep_stossi_rex64"
15652 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15653 (set (match_operand:DI 0 "register_operand" "=D")
15654 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15656 (match_operand:DI 3 "register_operand" "0")))
15657 (set (mem:BLK (match_dup 3))
15659 (use (match_operand:SI 2 "register_operand" "a"))
15660 (use (match_dup 4))]
15662 "rep{%;} stos{l|d}"
15663 [(set_attr "type" "str")
15664 (set_attr "prefix_rep" "1")
15665 (set_attr "memory" "store")
15666 (set_attr "mode" "SI")])
15668 (define_insn "*rep_stosqi"
15669 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15670 (set (match_operand:SI 0 "register_operand" "=D")
15671 (plus:SI (match_operand:SI 3 "register_operand" "0")
15672 (match_operand:SI 4 "register_operand" "1")))
15673 (set (mem:BLK (match_dup 3))
15675 (use (match_operand:QI 2 "register_operand" "a"))
15676 (use (match_dup 4))]
15679 [(set_attr "type" "str")
15680 (set_attr "prefix_rep" "1")
15681 (set_attr "memory" "store")
15682 (set_attr "mode" "QI")])
15684 (define_insn "*rep_stosqi_rex64"
15685 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15686 (set (match_operand:DI 0 "register_operand" "=D")
15687 (plus:DI (match_operand:DI 3 "register_operand" "0")
15688 (match_operand:DI 4 "register_operand" "1")))
15689 (set (mem:BLK (match_dup 3))
15691 (use (match_operand:QI 2 "register_operand" "a"))
15692 (use (match_dup 4))]
15695 [(set_attr "type" "str")
15696 (set_attr "prefix_rep" "1")
15697 (set_attr "memory" "store")
15698 (set_attr "prefix_rex" "0")
15699 (set_attr "mode" "QI")])
15701 (define_expand "cmpstrnsi"
15702 [(set (match_operand:SI 0 "register_operand" "")
15703 (compare:SI (match_operand:BLK 1 "general_operand" "")
15704 (match_operand:BLK 2 "general_operand" "")))
15705 (use (match_operand 3 "general_operand" ""))
15706 (use (match_operand 4 "immediate_operand" ""))]
15709 rtx addr1, addr2, out, outlow, count, countreg, align;
15711 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15714 /* Can't use this if the user has appropriated esi or edi. */
15715 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15720 out = gen_reg_rtx (SImode);
15722 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15723 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15724 if (addr1 != XEXP (operands[1], 0))
15725 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15726 if (addr2 != XEXP (operands[2], 0))
15727 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15729 count = operands[3];
15730 countreg = ix86_zero_extend_to_Pmode (count);
15732 /* %%% Iff we are testing strict equality, we can use known alignment
15733 to good advantage. This may be possible with combine, particularly
15734 once cc0 is dead. */
15735 align = operands[4];
15737 if (CONST_INT_P (count))
15739 if (INTVAL (count) == 0)
15741 emit_move_insn (operands[0], const0_rtx);
15744 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15745 operands[1], operands[2]));
15749 rtx (*gen_cmp) (rtx, rtx);
15751 gen_cmp = (TARGET_64BIT
15752 ? gen_cmpdi_1 : gen_cmpsi_1);
15754 emit_insn (gen_cmp (countreg, countreg));
15755 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15756 operands[1], operands[2]));
15759 outlow = gen_lowpart (QImode, out);
15760 emit_insn (gen_cmpintqi (outlow));
15761 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15763 if (operands[0] != out)
15764 emit_move_insn (operands[0], out);
15769 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15771 (define_expand "cmpintqi"
15772 [(set (match_dup 1)
15773 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15775 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15776 (parallel [(set (match_operand:QI 0 "register_operand" "")
15777 (minus:QI (match_dup 1)
15779 (clobber (reg:CC FLAGS_REG))])]
15781 "operands[1] = gen_reg_rtx (QImode);
15782 operands[2] = gen_reg_rtx (QImode);")
15784 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15785 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15787 (define_expand "cmpstrnqi_nz_1"
15788 [(parallel [(set (reg:CC FLAGS_REG)
15789 (compare:CC (match_operand 4 "memory_operand" "")
15790 (match_operand 5 "memory_operand" "")))
15791 (use (match_operand 2 "register_operand" ""))
15792 (use (match_operand:SI 3 "immediate_operand" ""))
15793 (clobber (match_operand 0 "register_operand" ""))
15794 (clobber (match_operand 1 "register_operand" ""))
15795 (clobber (match_dup 2))])]
15797 "ix86_current_function_needs_cld = 1;")
15799 (define_insn "*cmpstrnqi_nz_1"
15800 [(set (reg:CC FLAGS_REG)
15801 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15802 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15803 (use (match_operand:SI 6 "register_operand" "2"))
15804 (use (match_operand:SI 3 "immediate_operand" "i"))
15805 (clobber (match_operand:SI 0 "register_operand" "=S"))
15806 (clobber (match_operand:SI 1 "register_operand" "=D"))
15807 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15810 [(set_attr "type" "str")
15811 (set_attr "mode" "QI")
15812 (set_attr "prefix_rep" "1")])
15814 (define_insn "*cmpstrnqi_nz_rex_1"
15815 [(set (reg:CC FLAGS_REG)
15816 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15817 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15818 (use (match_operand:DI 6 "register_operand" "2"))
15819 (use (match_operand:SI 3 "immediate_operand" "i"))
15820 (clobber (match_operand:DI 0 "register_operand" "=S"))
15821 (clobber (match_operand:DI 1 "register_operand" "=D"))
15822 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15825 [(set_attr "type" "str")
15826 (set_attr "mode" "QI")
15827 (set_attr "prefix_rex" "0")
15828 (set_attr "prefix_rep" "1")])
15830 ;; The same, but the count is not known to not be zero.
15832 (define_expand "cmpstrnqi_1"
15833 [(parallel [(set (reg:CC FLAGS_REG)
15834 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15836 (compare:CC (match_operand 4 "memory_operand" "")
15837 (match_operand 5 "memory_operand" ""))
15839 (use (match_operand:SI 3 "immediate_operand" ""))
15840 (use (reg:CC FLAGS_REG))
15841 (clobber (match_operand 0 "register_operand" ""))
15842 (clobber (match_operand 1 "register_operand" ""))
15843 (clobber (match_dup 2))])]
15845 "ix86_current_function_needs_cld = 1;")
15847 (define_insn "*cmpstrnqi_1"
15848 [(set (reg:CC FLAGS_REG)
15849 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15851 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15852 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15854 (use (match_operand:SI 3 "immediate_operand" "i"))
15855 (use (reg:CC FLAGS_REG))
15856 (clobber (match_operand:SI 0 "register_operand" "=S"))
15857 (clobber (match_operand:SI 1 "register_operand" "=D"))
15858 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15861 [(set_attr "type" "str")
15862 (set_attr "mode" "QI")
15863 (set_attr "prefix_rep" "1")])
15865 (define_insn "*cmpstrnqi_rex_1"
15866 [(set (reg:CC FLAGS_REG)
15867 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15869 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15870 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15872 (use (match_operand:SI 3 "immediate_operand" "i"))
15873 (use (reg:CC FLAGS_REG))
15874 (clobber (match_operand:DI 0 "register_operand" "=S"))
15875 (clobber (match_operand:DI 1 "register_operand" "=D"))
15876 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15879 [(set_attr "type" "str")
15880 (set_attr "mode" "QI")
15881 (set_attr "prefix_rex" "0")
15882 (set_attr "prefix_rep" "1")])
15884 (define_expand "strlensi"
15885 [(set (match_operand:SI 0 "register_operand" "")
15886 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15887 (match_operand:QI 2 "immediate_operand" "")
15888 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15891 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15897 (define_expand "strlendi"
15898 [(set (match_operand:DI 0 "register_operand" "")
15899 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15900 (match_operand:QI 2 "immediate_operand" "")
15901 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15904 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15910 (define_expand "strlenqi_1"
15911 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
15912 (clobber (match_operand 1 "register_operand" ""))
15913 (clobber (reg:CC FLAGS_REG))])]
15915 "ix86_current_function_needs_cld = 1;")
15917 (define_insn "*strlenqi_1"
15918 [(set (match_operand:SI 0 "register_operand" "=&c")
15919 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15920 (match_operand:QI 2 "register_operand" "a")
15921 (match_operand:SI 3 "immediate_operand" "i")
15922 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15923 (clobber (match_operand:SI 1 "register_operand" "=D"))
15924 (clobber (reg:CC FLAGS_REG))]
15927 [(set_attr "type" "str")
15928 (set_attr "mode" "QI")
15929 (set_attr "prefix_rep" "1")])
15931 (define_insn "*strlenqi_rex_1"
15932 [(set (match_operand:DI 0 "register_operand" "=&c")
15933 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15934 (match_operand:QI 2 "register_operand" "a")
15935 (match_operand:DI 3 "immediate_operand" "i")
15936 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15937 (clobber (match_operand:DI 1 "register_operand" "=D"))
15938 (clobber (reg:CC FLAGS_REG))]
15941 [(set_attr "type" "str")
15942 (set_attr "mode" "QI")
15943 (set_attr "prefix_rex" "0")
15944 (set_attr "prefix_rep" "1")])
15946 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15947 ;; handled in combine, but it is not currently up to the task.
15948 ;; When used for their truth value, the cmpstrn* expanders generate
15957 ;; The intermediate three instructions are unnecessary.
15959 ;; This one handles cmpstrn*_nz_1...
15962 (set (reg:CC FLAGS_REG)
15963 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15964 (mem:BLK (match_operand 5 "register_operand" ""))))
15965 (use (match_operand 6 "register_operand" ""))
15966 (use (match_operand:SI 3 "immediate_operand" ""))
15967 (clobber (match_operand 0 "register_operand" ""))
15968 (clobber (match_operand 1 "register_operand" ""))
15969 (clobber (match_operand 2 "register_operand" ""))])
15970 (set (match_operand:QI 7 "register_operand" "")
15971 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15972 (set (match_operand:QI 8 "register_operand" "")
15973 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15974 (set (reg FLAGS_REG)
15975 (compare (match_dup 7) (match_dup 8)))
15977 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15979 (set (reg:CC FLAGS_REG)
15980 (compare:CC (mem:BLK (match_dup 4))
15981 (mem:BLK (match_dup 5))))
15982 (use (match_dup 6))
15983 (use (match_dup 3))
15984 (clobber (match_dup 0))
15985 (clobber (match_dup 1))
15986 (clobber (match_dup 2))])]
15989 ;; ...and this one handles cmpstrn*_1.
15992 (set (reg:CC FLAGS_REG)
15993 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15995 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15996 (mem:BLK (match_operand 5 "register_operand" "")))
15998 (use (match_operand:SI 3 "immediate_operand" ""))
15999 (use (reg:CC FLAGS_REG))
16000 (clobber (match_operand 0 "register_operand" ""))
16001 (clobber (match_operand 1 "register_operand" ""))
16002 (clobber (match_operand 2 "register_operand" ""))])
16003 (set (match_operand:QI 7 "register_operand" "")
16004 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16005 (set (match_operand:QI 8 "register_operand" "")
16006 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16007 (set (reg FLAGS_REG)
16008 (compare (match_dup 7) (match_dup 8)))
16010 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16012 (set (reg:CC FLAGS_REG)
16013 (if_then_else:CC (ne (match_dup 6)
16015 (compare:CC (mem:BLK (match_dup 4))
16016 (mem:BLK (match_dup 5)))
16018 (use (match_dup 3))
16019 (use (reg:CC FLAGS_REG))
16020 (clobber (match_dup 0))
16021 (clobber (match_dup 1))
16022 (clobber (match_dup 2))])]
16027 ;; Conditional move instructions.
16029 (define_expand "mov<mode>cc"
16030 [(set (match_operand:SWIM 0 "register_operand" "")
16031 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
16032 (match_operand:SWIM 2 "general_operand" "")
16033 (match_operand:SWIM 3 "general_operand" "")))]
16035 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16037 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16038 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16039 ;; So just document what we're doing explicitly.
16041 (define_expand "x86_mov<mode>cc_0_m1"
16043 [(set (match_operand:SWI48 0 "register_operand" "")
16044 (if_then_else:SWI48
16045 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16046 [(match_operand 1 "flags_reg_operand" "")
16050 (clobber (reg:CC FLAGS_REG))])]
16054 (define_insn "*x86_mov<mode>cc_0_m1"
16055 [(set (match_operand:SWI48 0 "register_operand" "=r")
16056 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16057 [(reg FLAGS_REG) (const_int 0)])
16060 (clobber (reg:CC FLAGS_REG))]
16062 "sbb{<imodesuffix>}\t%0, %0"
16063 ; Since we don't have the proper number of operands for an alu insn,
16064 ; fill in all the blanks.
16065 [(set_attr "type" "alu")
16066 (set_attr "use_carry" "1")
16067 (set_attr "pent_pair" "pu")
16068 (set_attr "memory" "none")
16069 (set_attr "imm_disp" "false")
16070 (set_attr "mode" "<MODE>")
16071 (set_attr "length_immediate" "0")])
16073 (define_insn "*x86_mov<mode>cc_0_m1_se"
16074 [(set (match_operand:SWI48 0 "register_operand" "=r")
16075 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16076 [(reg FLAGS_REG) (const_int 0)])
16079 (clobber (reg:CC FLAGS_REG))]
16081 "sbb{<imodesuffix>}\t%0, %0"
16082 [(set_attr "type" "alu")
16083 (set_attr "use_carry" "1")
16084 (set_attr "pent_pair" "pu")
16085 (set_attr "memory" "none")
16086 (set_attr "imm_disp" "false")
16087 (set_attr "mode" "<MODE>")
16088 (set_attr "length_immediate" "0")])
16090 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16091 [(set (match_operand:SWI48 0 "register_operand" "=r")
16092 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16093 [(reg FLAGS_REG) (const_int 0)])))]
16095 "sbb{<imodesuffix>}\t%0, %0"
16096 [(set_attr "type" "alu")
16097 (set_attr "use_carry" "1")
16098 (set_attr "pent_pair" "pu")
16099 (set_attr "memory" "none")
16100 (set_attr "imm_disp" "false")
16101 (set_attr "mode" "<MODE>")
16102 (set_attr "length_immediate" "0")])
16104 (define_insn "*mov<mode>cc_noc"
16105 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16106 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16107 [(reg FLAGS_REG) (const_int 0)])
16108 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16109 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16110 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16112 cmov%O2%C1\t{%2, %0|%0, %2}
16113 cmov%O2%c1\t{%3, %0|%0, %3}"
16114 [(set_attr "type" "icmov")
16115 (set_attr "mode" "<MODE>")])
16117 (define_insn_and_split "*movqicc_noc"
16118 [(set (match_operand:QI 0 "register_operand" "=r,r")
16119 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16120 [(match_operand 4 "flags_reg_operand" "")
16122 (match_operand:QI 2 "register_operand" "r,0")
16123 (match_operand:QI 3 "register_operand" "0,r")))]
16124 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16126 "&& reload_completed"
16127 [(set (match_dup 0)
16128 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16131 "operands[0] = gen_lowpart (SImode, operands[0]);
16132 operands[2] = gen_lowpart (SImode, operands[2]);
16133 operands[3] = gen_lowpart (SImode, operands[3]);"
16134 [(set_attr "type" "icmov")
16135 (set_attr "mode" "SI")])
16137 (define_expand "mov<mode>cc"
16138 [(set (match_operand:X87MODEF 0 "register_operand" "")
16139 (if_then_else:X87MODEF
16140 (match_operand 1 "ix86_fp_comparison_operator" "")
16141 (match_operand:X87MODEF 2 "register_operand" "")
16142 (match_operand:X87MODEF 3 "register_operand" "")))]
16143 "(TARGET_80387 && TARGET_CMOVE)
16144 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16145 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16147 (define_insn "*movsfcc_1_387"
16148 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16149 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16150 [(reg FLAGS_REG) (const_int 0)])
16151 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16152 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16153 "TARGET_80387 && TARGET_CMOVE
16154 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16156 fcmov%F1\t{%2, %0|%0, %2}
16157 fcmov%f1\t{%3, %0|%0, %3}
16158 cmov%O2%C1\t{%2, %0|%0, %2}
16159 cmov%O2%c1\t{%3, %0|%0, %3}"
16160 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16161 (set_attr "mode" "SF,SF,SI,SI")])
16163 (define_insn "*movdfcc_1"
16164 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16165 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16166 [(reg FLAGS_REG) (const_int 0)])
16167 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16168 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16169 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16170 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16172 fcmov%F1\t{%2, %0|%0, %2}
16173 fcmov%f1\t{%3, %0|%0, %3}
16176 [(set_attr "type" "fcmov,fcmov,multi,multi")
16177 (set_attr "mode" "DF")])
16179 (define_insn "*movdfcc_1_rex64"
16180 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16181 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16182 [(reg FLAGS_REG) (const_int 0)])
16183 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16184 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16185 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16186 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16188 fcmov%F1\t{%2, %0|%0, %2}
16189 fcmov%f1\t{%3, %0|%0, %3}
16190 cmov%O2%C1\t{%2, %0|%0, %2}
16191 cmov%O2%c1\t{%3, %0|%0, %3}"
16192 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16193 (set_attr "mode" "DF")])
16196 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16197 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16198 [(match_operand 4 "flags_reg_operand" "")
16200 (match_operand:DF 2 "nonimmediate_operand" "")
16201 (match_operand:DF 3 "nonimmediate_operand" "")))]
16202 "!TARGET_64BIT && reload_completed"
16203 [(set (match_dup 2)
16204 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16208 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16212 split_di (&operands[2], 2, &operands[5], &operands[7]);
16213 split_di (&operands[0], 1, &operands[2], &operands[3]);
16216 (define_insn "*movxfcc_1"
16217 [(set (match_operand:XF 0 "register_operand" "=f,f")
16218 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16219 [(reg FLAGS_REG) (const_int 0)])
16220 (match_operand:XF 2 "register_operand" "f,0")
16221 (match_operand:XF 3 "register_operand" "0,f")))]
16222 "TARGET_80387 && TARGET_CMOVE"
16224 fcmov%F1\t{%2, %0|%0, %2}
16225 fcmov%f1\t{%3, %0|%0, %3}"
16226 [(set_attr "type" "fcmov")
16227 (set_attr "mode" "XF")])
16229 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16230 ;; the scalar versions to have only XMM registers as operands.
16232 ;; XOP conditional move
16233 (define_insn "*xop_pcmov_<mode>"
16234 [(set (match_operand:MODEF 0 "register_operand" "=x")
16235 (if_then_else:MODEF
16236 (match_operand:MODEF 1 "register_operand" "x")
16237 (match_operand:MODEF 2 "register_operand" "x")
16238 (match_operand:MODEF 3 "register_operand" "x")))]
16240 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16241 [(set_attr "type" "sse4arg")])
16243 ;; These versions of the min/max patterns are intentionally ignorant of
16244 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16245 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16246 ;; are undefined in this condition, we're certain this is correct.
16248 (define_insn "*avx_<code><mode>3"
16249 [(set (match_operand:MODEF 0 "register_operand" "=x")
16251 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16252 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16253 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16254 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16255 [(set_attr "type" "sseadd")
16256 (set_attr "prefix" "vex")
16257 (set_attr "mode" "<MODE>")])
16259 (define_insn "<code><mode>3"
16260 [(set (match_operand:MODEF 0 "register_operand" "=x")
16262 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16263 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16264 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16265 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16266 [(set_attr "type" "sseadd")
16267 (set_attr "mode" "<MODE>")])
16269 ;; These versions of the min/max patterns implement exactly the operations
16270 ;; min = (op1 < op2 ? op1 : op2)
16271 ;; max = (!(op1 < op2) ? op1 : op2)
16272 ;; Their operands are not commutative, and thus they may be used in the
16273 ;; presence of -0.0 and NaN.
16275 (define_insn "*avx_ieee_smin<mode>3"
16276 [(set (match_operand:MODEF 0 "register_operand" "=x")
16278 [(match_operand:MODEF 1 "register_operand" "x")
16279 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16281 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16282 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16283 [(set_attr "type" "sseadd")
16284 (set_attr "prefix" "vex")
16285 (set_attr "mode" "<MODE>")])
16287 (define_insn "*ieee_smin<mode>3"
16288 [(set (match_operand:MODEF 0 "register_operand" "=x")
16290 [(match_operand:MODEF 1 "register_operand" "0")
16291 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16293 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16294 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16295 [(set_attr "type" "sseadd")
16296 (set_attr "mode" "<MODE>")])
16298 (define_insn "*avx_ieee_smax<mode>3"
16299 [(set (match_operand:MODEF 0 "register_operand" "=x")
16301 [(match_operand:MODEF 1 "register_operand" "0")
16302 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16304 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16305 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16306 [(set_attr "type" "sseadd")
16307 (set_attr "prefix" "vex")
16308 (set_attr "mode" "<MODE>")])
16310 (define_insn "*ieee_smax<mode>3"
16311 [(set (match_operand:MODEF 0 "register_operand" "=x")
16313 [(match_operand:MODEF 1 "register_operand" "0")
16314 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16316 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16317 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16318 [(set_attr "type" "sseadd")
16319 (set_attr "mode" "<MODE>")])
16321 ;; Make two stack loads independent:
16323 ;; fld %st(0) -> fld bb
16324 ;; fmul bb fmul %st(1), %st
16326 ;; Actually we only match the last two instructions for simplicity.
16328 [(set (match_operand 0 "fp_register_operand" "")
16329 (match_operand 1 "fp_register_operand" ""))
16331 (match_operator 2 "binary_fp_operator"
16333 (match_operand 3 "memory_operand" "")]))]
16334 "REGNO (operands[0]) != REGNO (operands[1])"
16335 [(set (match_dup 0) (match_dup 3))
16336 (set (match_dup 0) (match_dup 4))]
16338 ;; The % modifier is not operational anymore in peephole2's, so we have to
16339 ;; swap the operands manually in the case of addition and multiplication.
16340 "if (COMMUTATIVE_ARITH_P (operands[2]))
16341 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16342 operands[0], operands[1]);
16344 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16345 operands[1], operands[0]);")
16347 ;; Conditional addition patterns
16348 (define_expand "add<mode>cc"
16349 [(match_operand:SWI 0 "register_operand" "")
16350 (match_operand 1 "comparison_operator" "")
16351 (match_operand:SWI 2 "register_operand" "")
16352 (match_operand:SWI 3 "const_int_operand" "")]
16354 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16357 ;; Misc patterns (?)
16359 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16360 ;; Otherwise there will be nothing to keep
16362 ;; [(set (reg ebp) (reg esp))]
16363 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16364 ;; (clobber (eflags)]
16365 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16367 ;; in proper program order.
16369 (define_insn "pro_epilogue_adjust_stack_<mode>_1"
16370 [(set (match_operand:P 0 "register_operand" "=r,r")
16371 (plus:P (match_operand:P 1 "register_operand" "0,r")
16372 (match_operand:P 2 "<immediate_operand>" "<i>,<i>")))
16373 (clobber (reg:CC FLAGS_REG))
16374 (clobber (mem:BLK (scratch)))]
16377 switch (get_attr_type (insn))
16380 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16383 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16384 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16385 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16387 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16390 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16391 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16394 [(set (attr "type")
16395 (cond [(and (eq_attr "alternative" "0")
16396 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16397 (const_string "alu")
16398 (match_operand:<MODE> 2 "const0_operand" "")
16399 (const_string "imov")
16401 (const_string "lea")))
16402 (set (attr "length_immediate")
16403 (cond [(eq_attr "type" "imov")
16405 (and (eq_attr "type" "alu")
16406 (match_operand 2 "const128_operand" ""))
16409 (const_string "*")))
16410 (set_attr "mode" "<MODE>")])
16412 (define_insn "pro_epilogue_adjust_stack_di_2"
16413 [(set (match_operand:DI 0 "register_operand" "=r,r")
16414 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16415 (match_operand:DI 3 "immediate_operand" "i,i")))
16416 (use (match_operand:DI 2 "register_operand" "r,r"))
16417 (clobber (reg:CC FLAGS_REG))
16418 (clobber (mem:BLK (scratch)))]
16421 switch (get_attr_type (insn))
16424 return "add{q}\t{%2, %0|%0, %2}";
16427 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16428 return "lea{q}\t{%a2, %0|%0, %a2}";
16431 gcc_unreachable ();
16434 [(set_attr "type" "alu,lea")
16435 (set_attr "mode" "DI")])
16437 (define_insn "allocate_stack_worker_32"
16438 [(set (match_operand:SI 0 "register_operand" "=a")
16439 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16440 UNSPECV_STACK_PROBE))
16441 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16442 (clobber (reg:CC FLAGS_REG))]
16443 "!TARGET_64BIT && ix86_target_stack_probe ()"
16445 [(set_attr "type" "multi")
16446 (set_attr "length" "5")])
16448 (define_insn "allocate_stack_worker_64"
16449 [(set (match_operand:DI 0 "register_operand" "=a")
16450 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
16451 UNSPECV_STACK_PROBE))
16452 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
16453 (clobber (reg:DI R10_REG))
16454 (clobber (reg:DI R11_REG))
16455 (clobber (reg:CC FLAGS_REG))]
16456 "TARGET_64BIT && ix86_target_stack_probe ()"
16458 [(set_attr "type" "multi")
16459 (set_attr "length" "5")])
16461 (define_expand "allocate_stack"
16462 [(match_operand 0 "register_operand" "")
16463 (match_operand 1 "general_operand" "")]
16464 "ix86_target_stack_probe ()"
16468 #ifndef CHECK_STACK_LIMIT
16469 #define CHECK_STACK_LIMIT 0
16472 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16473 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16475 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16476 stack_pointer_rtx, 0, OPTAB_DIRECT);
16477 if (x != stack_pointer_rtx)
16478 emit_move_insn (stack_pointer_rtx, x);
16482 rtx (*gen_allocate_stack_worker) (rtx, rtx);
16485 gen_allocate_stack_worker = gen_allocate_stack_worker_64;
16487 gen_allocate_stack_worker = gen_allocate_stack_worker_32;
16489 x = copy_to_mode_reg (Pmode, operands[1]);
16490 emit_insn (gen_allocate_stack_worker (x, x));
16493 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16497 ;; Use IOR for stack probes, this is shorter.
16498 (define_expand "probe_stack"
16499 [(match_operand 0 "memory_operand" "")]
16502 rtx (*gen_ior3) (rtx, rtx, rtx);
16504 gen_ior3 = (GET_MODE (operands[0]) == DImode
16505 ? gen_iordi3 : gen_iorsi3);
16507 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16511 (define_insn "adjust_stack_and_probe<mode>"
16512 [(set (match_operand:P 0 "register_operand" "=r")
16513 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16514 UNSPECV_PROBE_STACK_RANGE))
16515 (set (reg:P SP_REG)
16516 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16517 (clobber (reg:CC FLAGS_REG))
16518 (clobber (mem:BLK (scratch)))]
16520 "* return output_adjust_stack_and_probe (operands[0]);"
16521 [(set_attr "type" "multi")])
16523 (define_insn "probe_stack_range<mode>"
16524 [(set (match_operand:P 0 "register_operand" "=r")
16525 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16526 (match_operand:P 2 "const_int_operand" "n")]
16527 UNSPECV_PROBE_STACK_RANGE))
16528 (clobber (reg:CC FLAGS_REG))]
16530 "* return output_probe_stack_range (operands[0], operands[2]);"
16531 [(set_attr "type" "multi")])
16533 (define_expand "builtin_setjmp_receiver"
16534 [(label_ref (match_operand 0 "" ""))]
16535 "!TARGET_64BIT && flag_pic"
16541 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16542 rtx label_rtx = gen_label_rtx ();
16543 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16544 xops[0] = xops[1] = picreg;
16545 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16546 ix86_expand_binary_operator (MINUS, SImode, xops);
16550 emit_insn (gen_set_got (pic_offset_table_rtx));
16554 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16557 [(set (match_operand 0 "register_operand" "")
16558 (match_operator 3 "promotable_binary_operator"
16559 [(match_operand 1 "register_operand" "")
16560 (match_operand 2 "aligned_operand" "")]))
16561 (clobber (reg:CC FLAGS_REG))]
16562 "! TARGET_PARTIAL_REG_STALL && reload_completed
16563 && ((GET_MODE (operands[0]) == HImode
16564 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16565 /* ??? next two lines just !satisfies_constraint_K (...) */
16566 || !CONST_INT_P (operands[2])
16567 || satisfies_constraint_K (operands[2])))
16568 || (GET_MODE (operands[0]) == QImode
16569 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16570 [(parallel [(set (match_dup 0)
16571 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16572 (clobber (reg:CC FLAGS_REG))])]
16573 "operands[0] = gen_lowpart (SImode, operands[0]);
16574 operands[1] = gen_lowpart (SImode, operands[1]);
16575 if (GET_CODE (operands[3]) != ASHIFT)
16576 operands[2] = gen_lowpart (SImode, operands[2]);
16577 PUT_MODE (operands[3], SImode);")
16579 ; Promote the QImode tests, as i386 has encoding of the AND
16580 ; instruction with 32-bit sign-extended immediate and thus the
16581 ; instruction size is unchanged, except in the %eax case for
16582 ; which it is increased by one byte, hence the ! optimize_size.
16584 [(set (match_operand 0 "flags_reg_operand" "")
16585 (match_operator 2 "compare_operator"
16586 [(and (match_operand 3 "aligned_operand" "")
16587 (match_operand 4 "const_int_operand" ""))
16589 (set (match_operand 1 "register_operand" "")
16590 (and (match_dup 3) (match_dup 4)))]
16591 "! TARGET_PARTIAL_REG_STALL && reload_completed
16592 && optimize_insn_for_speed_p ()
16593 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16594 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16595 /* Ensure that the operand will remain sign-extended immediate. */
16596 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16597 [(parallel [(set (match_dup 0)
16598 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16601 (and:SI (match_dup 3) (match_dup 4)))])]
16604 = gen_int_mode (INTVAL (operands[4])
16605 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16606 operands[1] = gen_lowpart (SImode, operands[1]);
16607 operands[3] = gen_lowpart (SImode, operands[3]);
16610 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16611 ; the TEST instruction with 32-bit sign-extended immediate and thus
16612 ; the instruction size would at least double, which is not what we
16613 ; want even with ! optimize_size.
16615 [(set (match_operand 0 "flags_reg_operand" "")
16616 (match_operator 1 "compare_operator"
16617 [(and (match_operand:HI 2 "aligned_operand" "")
16618 (match_operand:HI 3 "const_int_operand" ""))
16620 "! TARGET_PARTIAL_REG_STALL && reload_completed
16621 && ! TARGET_FAST_PREFIX
16622 && optimize_insn_for_speed_p ()
16623 /* Ensure that the operand will remain sign-extended immediate. */
16624 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16625 [(set (match_dup 0)
16626 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16630 = gen_int_mode (INTVAL (operands[3])
16631 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16632 operands[2] = gen_lowpart (SImode, operands[2]);
16636 [(set (match_operand 0 "register_operand" "")
16637 (neg (match_operand 1 "register_operand" "")))
16638 (clobber (reg:CC FLAGS_REG))]
16639 "! TARGET_PARTIAL_REG_STALL && reload_completed
16640 && (GET_MODE (operands[0]) == HImode
16641 || (GET_MODE (operands[0]) == QImode
16642 && (TARGET_PROMOTE_QImode
16643 || optimize_insn_for_size_p ())))"
16644 [(parallel [(set (match_dup 0)
16645 (neg:SI (match_dup 1)))
16646 (clobber (reg:CC FLAGS_REG))])]
16647 "operands[0] = gen_lowpart (SImode, operands[0]);
16648 operands[1] = gen_lowpart (SImode, operands[1]);")
16651 [(set (match_operand 0 "register_operand" "")
16652 (not (match_operand 1 "register_operand" "")))]
16653 "! TARGET_PARTIAL_REG_STALL && reload_completed
16654 && (GET_MODE (operands[0]) == HImode
16655 || (GET_MODE (operands[0]) == QImode
16656 && (TARGET_PROMOTE_QImode
16657 || optimize_insn_for_size_p ())))"
16658 [(set (match_dup 0)
16659 (not:SI (match_dup 1)))]
16660 "operands[0] = gen_lowpart (SImode, operands[0]);
16661 operands[1] = gen_lowpart (SImode, operands[1]);")
16664 [(set (match_operand 0 "register_operand" "")
16665 (if_then_else (match_operator 1 "comparison_operator"
16666 [(reg FLAGS_REG) (const_int 0)])
16667 (match_operand 2 "register_operand" "")
16668 (match_operand 3 "register_operand" "")))]
16669 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16670 && (GET_MODE (operands[0]) == HImode
16671 || (GET_MODE (operands[0]) == QImode
16672 && (TARGET_PROMOTE_QImode
16673 || optimize_insn_for_size_p ())))"
16674 [(set (match_dup 0)
16675 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16676 "operands[0] = gen_lowpart (SImode, operands[0]);
16677 operands[2] = gen_lowpart (SImode, operands[2]);
16678 operands[3] = gen_lowpart (SImode, operands[3]);")
16681 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16682 ;; transform a complex memory operation into two memory to register operations.
16684 ;; Don't push memory operands
16686 [(set (match_operand:SI 0 "push_operand" "")
16687 (match_operand:SI 1 "memory_operand" ""))
16688 (match_scratch:SI 2 "r")]
16689 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16690 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16691 [(set (match_dup 2) (match_dup 1))
16692 (set (match_dup 0) (match_dup 2))]
16696 [(set (match_operand:DI 0 "push_operand" "")
16697 (match_operand:DI 1 "memory_operand" ""))
16698 (match_scratch:DI 2 "r")]
16699 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16700 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16701 [(set (match_dup 2) (match_dup 1))
16702 (set (match_dup 0) (match_dup 2))]
16705 ;; We need to handle SFmode only, because DFmode and XFmode is split to
16708 [(set (match_operand:SF 0 "push_operand" "")
16709 (match_operand:SF 1 "memory_operand" ""))
16710 (match_scratch:SF 2 "r")]
16711 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16712 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16713 [(set (match_dup 2) (match_dup 1))
16714 (set (match_dup 0) (match_dup 2))]
16718 [(set (match_operand:HI 0 "push_operand" "")
16719 (match_operand:HI 1 "memory_operand" ""))
16720 (match_scratch:HI 2 "r")]
16721 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16722 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16723 [(set (match_dup 2) (match_dup 1))
16724 (set (match_dup 0) (match_dup 2))]
16728 [(set (match_operand:QI 0 "push_operand" "")
16729 (match_operand:QI 1 "memory_operand" ""))
16730 (match_scratch:QI 2 "q")]
16731 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16732 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16733 [(set (match_dup 2) (match_dup 1))
16734 (set (match_dup 0) (match_dup 2))]
16737 ;; Don't move an immediate directly to memory when the instruction
16740 [(match_scratch:SI 1 "r")
16741 (set (match_operand:SI 0 "memory_operand" "")
16743 "optimize_insn_for_speed_p ()
16744 && ! TARGET_USE_MOV0
16745 && TARGET_SPLIT_LONG_MOVES
16746 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16747 && peep2_regno_dead_p (0, FLAGS_REG)"
16748 [(parallel [(set (match_dup 1) (const_int 0))
16749 (clobber (reg:CC FLAGS_REG))])
16750 (set (match_dup 0) (match_dup 1))]
16754 [(match_scratch:HI 1 "r")
16755 (set (match_operand:HI 0 "memory_operand" "")
16757 "optimize_insn_for_speed_p ()
16758 && ! TARGET_USE_MOV0
16759 && TARGET_SPLIT_LONG_MOVES
16760 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16761 && peep2_regno_dead_p (0, FLAGS_REG)"
16762 [(parallel [(set (match_dup 2) (const_int 0))
16763 (clobber (reg:CC FLAGS_REG))])
16764 (set (match_dup 0) (match_dup 1))]
16765 "operands[2] = gen_lowpart (SImode, operands[1]);")
16768 [(match_scratch:QI 1 "q")
16769 (set (match_operand:QI 0 "memory_operand" "")
16771 "optimize_insn_for_speed_p ()
16772 && ! TARGET_USE_MOV0
16773 && TARGET_SPLIT_LONG_MOVES
16774 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16775 && peep2_regno_dead_p (0, FLAGS_REG)"
16776 [(parallel [(set (match_dup 2) (const_int 0))
16777 (clobber (reg:CC FLAGS_REG))])
16778 (set (match_dup 0) (match_dup 1))]
16779 "operands[2] = gen_lowpart (SImode, operands[1]);")
16782 [(match_scratch:SI 2 "r")
16783 (set (match_operand:SI 0 "memory_operand" "")
16784 (match_operand:SI 1 "immediate_operand" ""))]
16785 "optimize_insn_for_speed_p ()
16786 && TARGET_SPLIT_LONG_MOVES
16787 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16788 [(set (match_dup 2) (match_dup 1))
16789 (set (match_dup 0) (match_dup 2))]
16793 [(match_scratch:HI 2 "r")
16794 (set (match_operand:HI 0 "memory_operand" "")
16795 (match_operand:HI 1 "immediate_operand" ""))]
16796 "optimize_insn_for_speed_p ()
16797 && TARGET_SPLIT_LONG_MOVES
16798 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16799 [(set (match_dup 2) (match_dup 1))
16800 (set (match_dup 0) (match_dup 2))]
16804 [(match_scratch:QI 2 "q")
16805 (set (match_operand:QI 0 "memory_operand" "")
16806 (match_operand:QI 1 "immediate_operand" ""))]
16807 "optimize_insn_for_speed_p ()
16808 && TARGET_SPLIT_LONG_MOVES
16809 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16810 [(set (match_dup 2) (match_dup 1))
16811 (set (match_dup 0) (match_dup 2))]
16814 ;; Don't compare memory with zero, load and use a test instead.
16816 [(set (match_operand 0 "flags_reg_operand" "")
16817 (match_operator 1 "compare_operator"
16818 [(match_operand:SI 2 "memory_operand" "")
16820 (match_scratch:SI 3 "r")]
16821 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16822 [(set (match_dup 3) (match_dup 2))
16823 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
16826 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16827 ;; Don't split NOTs with a displacement operand, because resulting XOR
16828 ;; will not be pairable anyway.
16830 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16831 ;; represented using a modRM byte. The XOR replacement is long decoded,
16832 ;; so this split helps here as well.
16834 ;; Note: Can't do this as a regular split because we can't get proper
16835 ;; lifetime information then.
16838 [(set (match_operand:SI 0 "nonimmediate_operand" "")
16839 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
16840 "optimize_insn_for_speed_p ()
16841 && ((TARGET_NOT_UNPAIRABLE
16842 && (!MEM_P (operands[0])
16843 || !memory_displacement_operand (operands[0], SImode)))
16844 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
16845 && peep2_regno_dead_p (0, FLAGS_REG)"
16846 [(parallel [(set (match_dup 0)
16847 (xor:SI (match_dup 1) (const_int -1)))
16848 (clobber (reg:CC FLAGS_REG))])]
16852 [(set (match_operand:HI 0 "nonimmediate_operand" "")
16853 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
16854 "optimize_insn_for_speed_p ()
16855 && ((TARGET_NOT_UNPAIRABLE
16856 && (!MEM_P (operands[0])
16857 || !memory_displacement_operand (operands[0], HImode)))
16858 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
16859 && peep2_regno_dead_p (0, FLAGS_REG)"
16860 [(parallel [(set (match_dup 0)
16861 (xor:HI (match_dup 1) (const_int -1)))
16862 (clobber (reg:CC FLAGS_REG))])]
16866 [(set (match_operand:QI 0 "nonimmediate_operand" "")
16867 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
16868 "optimize_insn_for_speed_p ()
16869 && ((TARGET_NOT_UNPAIRABLE
16870 && (!MEM_P (operands[0])
16871 || !memory_displacement_operand (operands[0], QImode)))
16872 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
16873 && peep2_regno_dead_p (0, FLAGS_REG)"
16874 [(parallel [(set (match_dup 0)
16875 (xor:QI (match_dup 1) (const_int -1)))
16876 (clobber (reg:CC FLAGS_REG))])]
16879 ;; Non pairable "test imm, reg" instructions can be translated to
16880 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16881 ;; byte opcode instead of two, have a short form for byte operands),
16882 ;; so do it for other CPUs as well. Given that the value was dead,
16883 ;; this should not create any new dependencies. Pass on the sub-word
16884 ;; versions if we're concerned about partial register stalls.
16887 [(set (match_operand 0 "flags_reg_operand" "")
16888 (match_operator 1 "compare_operator"
16889 [(and:SI (match_operand:SI 2 "register_operand" "")
16890 (match_operand:SI 3 "immediate_operand" ""))
16892 "ix86_match_ccmode (insn, CCNOmode)
16893 && (true_regnum (operands[2]) != AX_REG
16894 || satisfies_constraint_K (operands[3]))
16895 && peep2_reg_dead_p (1, operands[2])"
16897 [(set (match_dup 0)
16898 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16901 (and:SI (match_dup 2) (match_dup 3)))])]
16904 ;; We don't need to handle HImode case, because it will be promoted to SImode
16905 ;; on ! TARGET_PARTIAL_REG_STALL
16908 [(set (match_operand 0 "flags_reg_operand" "")
16909 (match_operator 1 "compare_operator"
16910 [(and:QI (match_operand:QI 2 "register_operand" "")
16911 (match_operand:QI 3 "immediate_operand" ""))
16913 "! TARGET_PARTIAL_REG_STALL
16914 && ix86_match_ccmode (insn, CCNOmode)
16915 && true_regnum (operands[2]) != AX_REG
16916 && peep2_reg_dead_p (1, operands[2])"
16918 [(set (match_dup 0)
16919 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16922 (and:QI (match_dup 2) (match_dup 3)))])]
16926 [(set (match_operand 0 "flags_reg_operand" "")
16927 (match_operator 1 "compare_operator"
16930 (match_operand 2 "ext_register_operand" "")
16933 (match_operand 3 "const_int_operand" ""))
16935 "! TARGET_PARTIAL_REG_STALL
16936 && ix86_match_ccmode (insn, CCNOmode)
16937 && true_regnum (operands[2]) != AX_REG
16938 && peep2_reg_dead_p (1, operands[2])"
16939 [(parallel [(set (match_dup 0)
16948 (set (zero_extract:SI (match_dup 2)
16959 ;; Don't do logical operations with memory inputs.
16961 [(match_scratch:SI 2 "r")
16962 (parallel [(set (match_operand:SI 0 "register_operand" "")
16963 (match_operator:SI 3 "arith_or_logical_operator"
16965 (match_operand:SI 1 "memory_operand" "")]))
16966 (clobber (reg:CC FLAGS_REG))])]
16967 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16968 [(set (match_dup 2) (match_dup 1))
16969 (parallel [(set (match_dup 0)
16970 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16971 (clobber (reg:CC FLAGS_REG))])]
16975 [(match_scratch:SI 2 "r")
16976 (parallel [(set (match_operand:SI 0 "register_operand" "")
16977 (match_operator:SI 3 "arith_or_logical_operator"
16978 [(match_operand:SI 1 "memory_operand" "")
16980 (clobber (reg:CC FLAGS_REG))])]
16981 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16982 [(set (match_dup 2) (match_dup 1))
16983 (parallel [(set (match_dup 0)
16984 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16985 (clobber (reg:CC FLAGS_REG))])]
16988 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16989 ;; refers to the destination of the load!
16992 [(set (match_operand:SI 0 "register_operand" "")
16993 (match_operand:SI 1 "register_operand" ""))
16994 (parallel [(set (match_dup 0)
16995 (match_operator:SI 3 "commutative_operator"
16997 (match_operand:SI 2 "memory_operand" "")]))
16998 (clobber (reg:CC FLAGS_REG))])]
16999 "REGNO (operands[0]) != REGNO (operands[1])
17000 && GENERAL_REGNO_P (REGNO (operands[0]))
17001 && GENERAL_REGNO_P (REGNO (operands[1]))"
17002 [(set (match_dup 0) (match_dup 4))
17003 (parallel [(set (match_dup 0)
17004 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17005 (clobber (reg:CC FLAGS_REG))])]
17006 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17009 [(set (match_operand 0 "register_operand" "")
17010 (match_operand 1 "register_operand" ""))
17012 (match_operator 3 "commutative_operator"
17014 (match_operand 2 "memory_operand" "")]))]
17015 "REGNO (operands[0]) != REGNO (operands[1])
17016 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17017 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17018 [(set (match_dup 0) (match_dup 2))
17020 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
17023 ; Don't do logical operations with memory outputs
17025 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17026 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17027 ; the same decoder scheduling characteristics as the original.
17030 [(match_scratch:SI 2 "r")
17031 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17032 (match_operator:SI 3 "arith_or_logical_operator"
17034 (match_operand:SI 1 "nonmemory_operand" "")]))
17035 (clobber (reg:CC FLAGS_REG))])]
17036 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17037 /* Do not split stack checking probes. */
17038 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17039 [(set (match_dup 2) (match_dup 0))
17040 (parallel [(set (match_dup 2)
17041 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17042 (clobber (reg:CC FLAGS_REG))])
17043 (set (match_dup 0) (match_dup 2))]
17047 [(match_scratch:SI 2 "r")
17048 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17049 (match_operator:SI 3 "arith_or_logical_operator"
17050 [(match_operand:SI 1 "nonmemory_operand" "")
17052 (clobber (reg:CC FLAGS_REG))])]
17053 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17054 /* Do not split stack checking probes. */
17055 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17056 [(set (match_dup 2) (match_dup 0))
17057 (parallel [(set (match_dup 2)
17058 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17059 (clobber (reg:CC FLAGS_REG))])
17060 (set (match_dup 0) (match_dup 2))]
17063 ;; Attempt to always use XOR for zeroing registers.
17065 [(set (match_operand 0 "register_operand" "")
17066 (match_operand 1 "const0_operand" ""))]
17067 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17068 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17069 && GENERAL_REG_P (operands[0])
17070 && peep2_regno_dead_p (0, FLAGS_REG)"
17071 [(parallel [(set (match_dup 0) (const_int 0))
17072 (clobber (reg:CC FLAGS_REG))])]
17074 operands[0] = gen_lowpart (word_mode, operands[0]);
17078 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17080 "(GET_MODE (operands[0]) == QImode
17081 || GET_MODE (operands[0]) == HImode)
17082 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17083 && peep2_regno_dead_p (0, FLAGS_REG)"
17084 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17085 (clobber (reg:CC FLAGS_REG))])])
17087 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17089 [(set (match_operand 0 "register_operand" "")
17091 "(GET_MODE (operands[0]) == HImode
17092 || GET_MODE (operands[0]) == SImode
17093 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17094 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17095 && peep2_regno_dead_p (0, FLAGS_REG)"
17096 [(parallel [(set (match_dup 0) (const_int -1))
17097 (clobber (reg:CC FLAGS_REG))])]
17098 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17101 ;; Attempt to convert simple leas to adds. These can be created by
17104 [(set (match_operand:SI 0 "register_operand" "")
17105 (plus:SI (match_dup 0)
17106 (match_operand:SI 1 "nonmemory_operand" "")))]
17107 "peep2_regno_dead_p (0, FLAGS_REG)"
17108 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17109 (clobber (reg:CC FLAGS_REG))])]
17113 [(set (match_operand:SI 0 "register_operand" "")
17114 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17115 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17116 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17117 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17118 (clobber (reg:CC FLAGS_REG))])]
17119 "operands[2] = gen_lowpart (SImode, operands[2]);")
17122 [(set (match_operand:DI 0 "register_operand" "")
17123 (plus:DI (match_dup 0)
17124 (match_operand:DI 1 "x86_64_general_operand" "")))]
17125 "peep2_regno_dead_p (0, FLAGS_REG)"
17126 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17127 (clobber (reg:CC FLAGS_REG))])]
17131 [(set (match_operand:SI 0 "register_operand" "")
17132 (mult:SI (match_dup 0)
17133 (match_operand:SI 1 "const_int_operand" "")))]
17134 "exact_log2 (INTVAL (operands[1])) >= 0
17135 && peep2_regno_dead_p (0, FLAGS_REG)"
17136 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17137 (clobber (reg:CC FLAGS_REG))])]
17138 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17141 [(set (match_operand:DI 0 "register_operand" "")
17142 (mult:DI (match_dup 0)
17143 (match_operand:DI 1 "const_int_operand" "")))]
17144 "exact_log2 (INTVAL (operands[1])) >= 0
17145 && peep2_regno_dead_p (0, FLAGS_REG)"
17146 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17147 (clobber (reg:CC FLAGS_REG))])]
17148 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17151 [(set (match_operand:SI 0 "register_operand" "")
17152 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17153 (match_operand:DI 2 "const_int_operand" "")) 0))]
17154 "exact_log2 (INTVAL (operands[2])) >= 0
17155 && REGNO (operands[0]) == REGNO (operands[1])
17156 && peep2_regno_dead_p (0, FLAGS_REG)"
17157 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17158 (clobber (reg:CC FLAGS_REG))])]
17159 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17161 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17162 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17163 ;; many CPUs it is also faster, since special hardware to avoid esp
17164 ;; dependencies is present.
17166 ;; While some of these conversions may be done using splitters, we use peepholes
17167 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17169 ;; Convert prologue esp subtractions to push.
17170 ;; We need register to push. In order to keep verify_flow_info happy we have
17172 ;; - use scratch and clobber it in order to avoid dependencies
17173 ;; - use already live register
17174 ;; We can't use the second way right now, since there is no reliable way how to
17175 ;; verify that given register is live. First choice will also most likely in
17176 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17177 ;; call clobbered registers are dead. We may want to use base pointer as an
17178 ;; alternative when no register is available later.
17181 [(match_scratch:SI 0 "r")
17182 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17183 (clobber (reg:CC FLAGS_REG))
17184 (clobber (mem:BLK (scratch)))])]
17185 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17186 [(clobber (match_dup 0))
17187 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17188 (clobber (mem:BLK (scratch)))])])
17191 [(match_scratch:SI 0 "r")
17192 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17193 (clobber (reg:CC FLAGS_REG))
17194 (clobber (mem:BLK (scratch)))])]
17195 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17196 [(clobber (match_dup 0))
17197 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17198 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17199 (clobber (mem:BLK (scratch)))])])
17201 ;; Convert esp subtractions to push.
17203 [(match_scratch:SI 0 "r")
17204 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17205 (clobber (reg:CC FLAGS_REG))])]
17206 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17207 [(clobber (match_dup 0))
17208 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17211 [(match_scratch:SI 0 "r")
17212 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17213 (clobber (reg:CC FLAGS_REG))])]
17214 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17215 [(clobber (match_dup 0))
17216 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17217 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17219 ;; Convert epilogue deallocator to pop.
17221 [(match_scratch:SI 0 "r")
17222 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17223 (clobber (reg:CC FLAGS_REG))
17224 (clobber (mem:BLK (scratch)))])]
17225 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17226 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17227 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17228 (clobber (mem:BLK (scratch)))])]
17231 ;; Two pops case is tricky, since pop causes dependency on destination register.
17232 ;; We use two registers if available.
17234 [(match_scratch:SI 0 "r")
17235 (match_scratch:SI 1 "r")
17236 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17237 (clobber (reg:CC FLAGS_REG))
17238 (clobber (mem:BLK (scratch)))])]
17239 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17240 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17241 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17242 (clobber (mem:BLK (scratch)))])
17243 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17244 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17248 [(match_scratch:SI 0 "r")
17249 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17250 (clobber (reg:CC FLAGS_REG))
17251 (clobber (mem:BLK (scratch)))])]
17252 "optimize_insn_for_size_p ()"
17253 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17254 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17255 (clobber (mem:BLK (scratch)))])
17256 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17257 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17260 ;; Convert esp additions to pop.
17262 [(match_scratch:SI 0 "r")
17263 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17264 (clobber (reg:CC FLAGS_REG))])]
17266 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17267 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17270 ;; Two pops case is tricky, since pop causes dependency on destination register.
17271 ;; We use two registers if available.
17273 [(match_scratch:SI 0 "r")
17274 (match_scratch:SI 1 "r")
17275 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17276 (clobber (reg:CC FLAGS_REG))])]
17278 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17279 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17280 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17281 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17285 [(match_scratch:SI 0 "r")
17286 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17287 (clobber (reg:CC FLAGS_REG))])]
17288 "optimize_insn_for_size_p ()"
17289 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17290 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17291 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17292 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17295 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17296 ;; required and register dies. Similarly for 128 to -128.
17298 [(set (match_operand 0 "flags_reg_operand" "")
17299 (match_operator 1 "compare_operator"
17300 [(match_operand 2 "register_operand" "")
17301 (match_operand 3 "const_int_operand" "")]))]
17302 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17303 && incdec_operand (operands[3], GET_MODE (operands[3])))
17304 || (!TARGET_FUSE_CMP_AND_BRANCH
17305 && INTVAL (operands[3]) == 128))
17306 && ix86_match_ccmode (insn, CCGCmode)
17307 && peep2_reg_dead_p (1, operands[2])"
17308 [(parallel [(set (match_dup 0)
17309 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17310 (clobber (match_dup 2))])]
17314 [(match_scratch:DI 0 "r")
17315 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17316 (clobber (reg:CC FLAGS_REG))
17317 (clobber (mem:BLK (scratch)))])]
17318 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17319 [(clobber (match_dup 0))
17320 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17321 (clobber (mem:BLK (scratch)))])])
17324 [(match_scratch:DI 0 "r")
17325 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17326 (clobber (reg:CC FLAGS_REG))
17327 (clobber (mem:BLK (scratch)))])]
17328 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17329 [(clobber (match_dup 0))
17330 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17331 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17332 (clobber (mem:BLK (scratch)))])])
17334 ;; Convert esp subtractions to push.
17336 [(match_scratch:DI 0 "r")
17337 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17338 (clobber (reg:CC FLAGS_REG))])]
17339 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17340 [(clobber (match_dup 0))
17341 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17344 [(match_scratch:DI 0 "r")
17345 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17346 (clobber (reg:CC FLAGS_REG))])]
17347 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17348 [(clobber (match_dup 0))
17349 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17350 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17352 ;; Convert epilogue deallocator to pop.
17354 [(match_scratch:DI 0 "r")
17355 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17356 (clobber (reg:CC FLAGS_REG))
17357 (clobber (mem:BLK (scratch)))])]
17358 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17359 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17360 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17361 (clobber (mem:BLK (scratch)))])]
17364 ;; Two pops case is tricky, since pop causes dependency on destination register.
17365 ;; We use two registers if available.
17367 [(match_scratch:DI 0 "r")
17368 (match_scratch:DI 1 "r")
17369 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17370 (clobber (reg:CC FLAGS_REG))
17371 (clobber (mem:BLK (scratch)))])]
17372 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17373 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17374 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17375 (clobber (mem:BLK (scratch)))])
17376 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17377 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17381 [(match_scratch:DI 0 "r")
17382 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17383 (clobber (reg:CC FLAGS_REG))
17384 (clobber (mem:BLK (scratch)))])]
17385 "optimize_insn_for_size_p ()"
17386 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17387 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17388 (clobber (mem:BLK (scratch)))])
17389 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17390 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17393 ;; Convert esp additions to pop.
17395 [(match_scratch:DI 0 "r")
17396 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17397 (clobber (reg:CC FLAGS_REG))])]
17399 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17400 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17403 ;; Two pops case is tricky, since pop causes dependency on destination register.
17404 ;; We use two registers if available.
17406 [(match_scratch:DI 0 "r")
17407 (match_scratch:DI 1 "r")
17408 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17409 (clobber (reg:CC FLAGS_REG))])]
17411 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17412 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17413 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17414 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17418 [(match_scratch:DI 0 "r")
17419 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17420 (clobber (reg:CC FLAGS_REG))])]
17421 "optimize_insn_for_size_p ()"
17422 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17423 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17424 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17425 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17428 ;; Convert imul by three, five and nine into lea
17431 [(set (match_operand:SI 0 "register_operand" "")
17432 (mult:SI (match_operand:SI 1 "register_operand" "")
17433 (match_operand:SI 2 "const_int_operand" "")))
17434 (clobber (reg:CC FLAGS_REG))])]
17435 "INTVAL (operands[2]) == 3
17436 || INTVAL (operands[2]) == 5
17437 || INTVAL (operands[2]) == 9"
17438 [(set (match_dup 0)
17439 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
17441 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17445 [(set (match_operand:SI 0 "register_operand" "")
17446 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17447 (match_operand:SI 2 "const_int_operand" "")))
17448 (clobber (reg:CC FLAGS_REG))])]
17449 "optimize_insn_for_speed_p ()
17450 && (INTVAL (operands[2]) == 3
17451 || INTVAL (operands[2]) == 5
17452 || INTVAL (operands[2]) == 9)"
17453 [(set (match_dup 0) (match_dup 1))
17455 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
17457 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17461 [(set (match_operand:DI 0 "register_operand" "")
17462 (mult:DI (match_operand:DI 1 "register_operand" "")
17463 (match_operand:DI 2 "const_int_operand" "")))
17464 (clobber (reg:CC FLAGS_REG))])]
17466 && (INTVAL (operands[2]) == 3
17467 || INTVAL (operands[2]) == 5
17468 || INTVAL (operands[2]) == 9)"
17469 [(set (match_dup 0)
17470 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
17472 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17476 [(set (match_operand:DI 0 "register_operand" "")
17477 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17478 (match_operand:DI 2 "const_int_operand" "")))
17479 (clobber (reg:CC FLAGS_REG))])]
17481 && optimize_insn_for_speed_p ()
17482 && (INTVAL (operands[2]) == 3
17483 || INTVAL (operands[2]) == 5
17484 || INTVAL (operands[2]) == 9)"
17485 [(set (match_dup 0) (match_dup 1))
17487 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
17489 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17491 ;; Imul $32bit_imm, mem, reg is vector decoded, while
17492 ;; imul $32bit_imm, reg, reg is direct decoded.
17494 [(match_scratch:DI 3 "r")
17495 (parallel [(set (match_operand:DI 0 "register_operand" "")
17496 (mult:DI (match_operand:DI 1 "memory_operand" "")
17497 (match_operand:DI 2 "immediate_operand" "")))
17498 (clobber (reg:CC FLAGS_REG))])]
17499 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17500 && !satisfies_constraint_K (operands[2])"
17501 [(set (match_dup 3) (match_dup 1))
17502 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
17503 (clobber (reg:CC FLAGS_REG))])]
17507 [(match_scratch:SI 3 "r")
17508 (parallel [(set (match_operand:SI 0 "register_operand" "")
17509 (mult:SI (match_operand:SI 1 "memory_operand" "")
17510 (match_operand:SI 2 "immediate_operand" "")))
17511 (clobber (reg:CC FLAGS_REG))])]
17512 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17513 && !satisfies_constraint_K (operands[2])"
17514 [(set (match_dup 3) (match_dup 1))
17515 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
17516 (clobber (reg:CC FLAGS_REG))])]
17520 [(match_scratch:SI 3 "r")
17521 (parallel [(set (match_operand:DI 0 "register_operand" "")
17523 (mult:SI (match_operand:SI 1 "memory_operand" "")
17524 (match_operand:SI 2 "immediate_operand" ""))))
17525 (clobber (reg:CC FLAGS_REG))])]
17526 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17527 && !satisfies_constraint_K (operands[2])"
17528 [(set (match_dup 3) (match_dup 1))
17529 (parallel [(set (match_dup 0)
17530 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17531 (clobber (reg:CC FLAGS_REG))])]
17534 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17535 ;; Convert it into imul reg, reg
17536 ;; It would be better to force assembler to encode instruction using long
17537 ;; immediate, but there is apparently no way to do so.
17539 [(parallel [(set (match_operand:DI 0 "register_operand" "")
17540 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17541 (match_operand:DI 2 "const_int_operand" "")))
17542 (clobber (reg:CC FLAGS_REG))])
17543 (match_scratch:DI 3 "r")]
17544 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17545 && satisfies_constraint_K (operands[2])"
17546 [(set (match_dup 3) (match_dup 2))
17547 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
17548 (clobber (reg:CC FLAGS_REG))])]
17550 if (!rtx_equal_p (operands[0], operands[1]))
17551 emit_move_insn (operands[0], operands[1]);
17555 [(parallel [(set (match_operand:SI 0 "register_operand" "")
17556 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17557 (match_operand:SI 2 "const_int_operand" "")))
17558 (clobber (reg:CC FLAGS_REG))])
17559 (match_scratch:SI 3 "r")]
17560 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17561 && satisfies_constraint_K (operands[2])"
17562 [(set (match_dup 3) (match_dup 2))
17563 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
17564 (clobber (reg:CC FLAGS_REG))])]
17566 if (!rtx_equal_p (operands[0], operands[1]))
17567 emit_move_insn (operands[0], operands[1]);
17571 [(parallel [(set (match_operand:HI 0 "register_operand" "")
17572 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
17573 (match_operand:HI 2 "immediate_operand" "")))
17574 (clobber (reg:CC FLAGS_REG))])
17575 (match_scratch:HI 3 "r")]
17576 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
17577 [(set (match_dup 3) (match_dup 2))
17578 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
17579 (clobber (reg:CC FLAGS_REG))])]
17581 if (!rtx_equal_p (operands[0], operands[1]))
17582 emit_move_insn (operands[0], operands[1]);
17585 ;; After splitting up read-modify operations, array accesses with memory
17586 ;; operands might end up in form:
17588 ;; movl 4(%esp), %edx
17590 ;; instead of pre-splitting:
17592 ;; addl 4(%esp), %eax
17594 ;; movl 4(%esp), %edx
17595 ;; leal (%edx,%eax,4), %eax
17598 [(match_scratch:P 5 "r")
17599 (parallel [(set (match_operand 0 "register_operand" "")
17600 (ashift (match_operand 1 "register_operand" "")
17601 (match_operand 2 "const_int_operand" "")))
17602 (clobber (reg:CC FLAGS_REG))])
17603 (parallel [(set (match_operand 3 "register_operand" "")
17604 (plus (match_dup 0)
17605 (match_operand 4 "x86_64_general_operand" "")))
17606 (clobber (reg:CC FLAGS_REG))])]
17607 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17608 /* Validate MODE for lea. */
17609 && ((!TARGET_PARTIAL_REG_STALL
17610 && (GET_MODE (operands[0]) == QImode
17611 || GET_MODE (operands[0]) == HImode))
17612 || GET_MODE (operands[0]) == SImode
17613 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17614 && (rtx_equal_p (operands[0], operands[3])
17615 || peep2_reg_dead_p (2, operands[0]))
17616 /* We reorder load and the shift. */
17617 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17618 [(set (match_dup 5) (match_dup 4))
17619 (set (match_dup 0) (match_dup 1))]
17621 enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17622 int scale = 1 << INTVAL (operands[2]);
17623 rtx index = gen_lowpart (Pmode, operands[1]);
17624 rtx base = gen_lowpart (Pmode, operands[5]);
17625 rtx dest = gen_lowpart (mode, operands[3]);
17627 operands[1] = gen_rtx_PLUS (Pmode, base,
17628 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17629 operands[5] = base;
17632 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17633 operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17635 operands[0] = dest;
17638 ;; Call-value patterns last so that the wildcard operand does not
17639 ;; disrupt insn-recog's switch tables.
17641 (define_insn "*call_value_pop_0"
17642 [(set (match_operand 0 "" "")
17643 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17644 (match_operand:SI 2 "" "")))
17645 (set (reg:SI SP_REG)
17646 (plus:SI (reg:SI SP_REG)
17647 (match_operand:SI 3 "immediate_operand" "")))]
17650 if (SIBLING_CALL_P (insn))
17653 return "call\t%P1";
17655 [(set_attr "type" "callv")])
17657 (define_insn "*call_value_pop_1"
17658 [(set (match_operand 0 "" "")
17659 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17660 (match_operand:SI 2 "" "")))
17661 (set (reg:SI SP_REG)
17662 (plus:SI (reg:SI SP_REG)
17663 (match_operand:SI 3 "immediate_operand" "i")))]
17664 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17666 if (constant_call_address_operand (operands[1], Pmode))
17667 return "call\t%P1";
17668 return "call\t%A1";
17670 [(set_attr "type" "callv")])
17672 (define_insn "*sibcall_value_pop_1"
17673 [(set (match_operand 0 "" "")
17674 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17675 (match_operand:SI 2 "" "")))
17676 (set (reg:SI SP_REG)
17677 (plus:SI (reg:SI SP_REG)
17678 (match_operand:SI 3 "immediate_operand" "i,i")))]
17679 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17683 [(set_attr "type" "callv")])
17685 (define_insn "*call_value_0"
17686 [(set (match_operand 0 "" "")
17687 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17688 (match_operand:SI 2 "" "")))]
17691 if (SIBLING_CALL_P (insn))
17694 return "call\t%P1";
17696 [(set_attr "type" "callv")])
17698 (define_insn "*call_value_0_rex64"
17699 [(set (match_operand 0 "" "")
17700 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17701 (match_operand:DI 2 "const_int_operand" "")))]
17704 if (SIBLING_CALL_P (insn))
17707 return "call\t%P1";
17709 [(set_attr "type" "callv")])
17711 (define_insn "*call_value_0_rex64_ms_sysv"
17712 [(set (match_operand 0 "" "")
17713 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17714 (match_operand:DI 2 "const_int_operand" "")))
17715 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17716 (clobber (reg:TI XMM6_REG))
17717 (clobber (reg:TI XMM7_REG))
17718 (clobber (reg:TI XMM8_REG))
17719 (clobber (reg:TI XMM9_REG))
17720 (clobber (reg:TI XMM10_REG))
17721 (clobber (reg:TI XMM11_REG))
17722 (clobber (reg:TI XMM12_REG))
17723 (clobber (reg:TI XMM13_REG))
17724 (clobber (reg:TI XMM14_REG))
17725 (clobber (reg:TI XMM15_REG))
17726 (clobber (reg:DI SI_REG))
17727 (clobber (reg:DI DI_REG))]
17728 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17730 if (SIBLING_CALL_P (insn))
17733 return "call\t%P1";
17735 [(set_attr "type" "callv")])
17737 (define_insn "*call_value_1"
17738 [(set (match_operand 0 "" "")
17739 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17740 (match_operand:SI 2 "" "")))]
17741 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17743 if (constant_call_address_operand (operands[1], Pmode))
17744 return "call\t%P1";
17745 return "call\t%A1";
17747 [(set_attr "type" "callv")])
17749 (define_insn "*sibcall_value_1"
17750 [(set (match_operand 0 "" "")
17751 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17752 (match_operand:SI 2 "" "")))]
17753 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17757 [(set_attr "type" "callv")])
17759 (define_insn "*call_value_1_rex64"
17760 [(set (match_operand 0 "" "")
17761 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17762 (match_operand:DI 2 "" "")))]
17763 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17764 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17766 if (constant_call_address_operand (operands[1], Pmode))
17767 return "call\t%P1";
17768 return "call\t%A1";
17770 [(set_attr "type" "callv")])
17772 (define_insn "*call_value_1_rex64_ms_sysv"
17773 [(set (match_operand 0 "" "")
17774 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17775 (match_operand:DI 2 "" "")))
17776 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17777 (clobber (reg:TI XMM6_REG))
17778 (clobber (reg:TI XMM7_REG))
17779 (clobber (reg:TI XMM8_REG))
17780 (clobber (reg:TI XMM9_REG))
17781 (clobber (reg:TI XMM10_REG))
17782 (clobber (reg:TI XMM11_REG))
17783 (clobber (reg:TI XMM12_REG))
17784 (clobber (reg:TI XMM13_REG))
17785 (clobber (reg:TI XMM14_REG))
17786 (clobber (reg:TI XMM15_REG))
17787 (clobber (reg:DI SI_REG))
17788 (clobber (reg:DI DI_REG))]
17789 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17791 if (constant_call_address_operand (operands[1], Pmode))
17792 return "call\t%P1";
17793 return "call\t%A1";
17795 [(set_attr "type" "callv")])
17797 (define_insn "*call_value_1_rex64_large"
17798 [(set (match_operand 0 "" "")
17799 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17800 (match_operand:DI 2 "" "")))]
17801 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17803 [(set_attr "type" "callv")])
17805 (define_insn "*sibcall_value_1_rex64"
17806 [(set (match_operand 0 "" "")
17807 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17808 (match_operand:DI 2 "" "")))]
17809 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17813 [(set_attr "type" "callv")])
17815 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17816 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17817 ;; caught for use by garbage collectors and the like. Using an insn that
17818 ;; maps to SIGILL makes it more likely the program will rightfully die.
17819 ;; Keeping with tradition, "6" is in honor of #UD.
17820 (define_insn "trap"
17821 [(trap_if (const_int 1) (const_int 6))]
17823 { return ASM_SHORT "0x0b0f"; }
17824 [(set_attr "length" "2")])
17826 (define_expand "prefetch"
17827 [(prefetch (match_operand 0 "address_operand" "")
17828 (match_operand:SI 1 "const_int_operand" "")
17829 (match_operand:SI 2 "const_int_operand" ""))]
17830 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17832 int rw = INTVAL (operands[1]);
17833 int locality = INTVAL (operands[2]);
17835 gcc_assert (rw == 0 || rw == 1);
17836 gcc_assert (locality >= 0 && locality <= 3);
17837 gcc_assert (GET_MODE (operands[0]) == Pmode
17838 || GET_MODE (operands[0]) == VOIDmode);
17840 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17841 supported by SSE counterpart or the SSE prefetch is not available
17842 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17844 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17845 operands[2] = GEN_INT (3);
17847 operands[1] = const0_rtx;
17850 (define_insn "*prefetch_sse_<mode>"
17851 [(prefetch (match_operand:P 0 "address_operand" "p")
17853 (match_operand:SI 1 "const_int_operand" ""))]
17854 "TARGET_PREFETCH_SSE"
17856 static const char * const patterns[4] = {
17857 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17860 int locality = INTVAL (operands[1]);
17861 gcc_assert (locality >= 0 && locality <= 3);
17863 return patterns[locality];
17865 [(set_attr "type" "sse")
17866 (set_attr "atom_sse_attr" "prefetch")
17867 (set (attr "length_address")
17868 (symbol_ref "memory_address_length (operands[0])"))
17869 (set_attr "memory" "none")])
17871 (define_insn "*prefetch_3dnow_<mode>"
17872 [(prefetch (match_operand:P 0 "address_operand" "p")
17873 (match_operand:SI 1 "const_int_operand" "n")
17877 if (INTVAL (operands[1]) == 0)
17878 return "prefetch\t%a0";
17880 return "prefetchw\t%a0";
17882 [(set_attr "type" "mmx")
17883 (set (attr "length_address")
17884 (symbol_ref "memory_address_length (operands[0])"))
17885 (set_attr "memory" "none")])
17887 (define_expand "stack_protect_set"
17888 [(match_operand 0 "memory_operand" "")
17889 (match_operand 1 "memory_operand" "")]
17892 #ifdef TARGET_THREAD_SSP_OFFSET
17894 emit_insn (gen_stack_tls_protect_set_di (operands[0],
17895 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17897 emit_insn (gen_stack_tls_protect_set_si (operands[0],
17898 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17901 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
17903 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
17908 (define_insn "stack_protect_set_si"
17909 [(set (match_operand:SI 0 "memory_operand" "=m")
17910 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
17911 (set (match_scratch:SI 2 "=&r") (const_int 0))
17912 (clobber (reg:CC FLAGS_REG))]
17914 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
17915 [(set_attr "type" "multi")])
17917 (define_insn "stack_protect_set_di"
17918 [(set (match_operand:DI 0 "memory_operand" "=m")
17919 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
17920 (set (match_scratch:DI 2 "=&r") (const_int 0))
17921 (clobber (reg:CC FLAGS_REG))]
17923 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17924 [(set_attr "type" "multi")])
17926 (define_insn "stack_tls_protect_set_si"
17927 [(set (match_operand:SI 0 "memory_operand" "=m")
17928 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")]
17929 UNSPEC_SP_TLS_SET))
17930 (set (match_scratch:SI 2 "=&r") (const_int 0))
17931 (clobber (reg:CC FLAGS_REG))]
17933 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
17934 [(set_attr "type" "multi")])
17936 (define_insn "stack_tls_protect_set_di"
17937 [(set (match_operand:DI 0 "memory_operand" "=m")
17938 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")]
17939 UNSPEC_SP_TLS_SET))
17940 (set (match_scratch:DI 2 "=&r") (const_int 0))
17941 (clobber (reg:CC FLAGS_REG))]
17944 /* The kernel uses a different segment register for performance reasons; a
17945 system call would not have to trash the userspace segment register,
17946 which would be expensive */
17947 if (ix86_cmodel != CM_KERNEL)
17948 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
17950 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
17952 [(set_attr "type" "multi")])
17954 (define_expand "stack_protect_test"
17955 [(match_operand 0 "memory_operand" "")
17956 (match_operand 1 "memory_operand" "")
17957 (match_operand 2 "" "")]
17960 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17962 #ifdef TARGET_THREAD_SSP_OFFSET
17964 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
17965 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17967 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
17968 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17971 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
17973 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
17976 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17977 flags, const0_rtx, operands[2]));
17981 (define_insn "stack_protect_test_si"
17982 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17983 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
17984 (match_operand:SI 2 "memory_operand" "m")]
17986 (clobber (match_scratch:SI 3 "=&r"))]
17988 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
17989 [(set_attr "type" "multi")])
17991 (define_insn "stack_protect_test_di"
17992 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17993 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
17994 (match_operand:DI 2 "memory_operand" "m")]
17996 (clobber (match_scratch:DI 3 "=&r"))]
17998 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
17999 [(set_attr "type" "multi")])
18001 (define_insn "stack_tls_protect_test_si"
18002 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18003 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18004 (match_operand:SI 2 "const_int_operand" "i")]
18005 UNSPEC_SP_TLS_TEST))
18006 (clobber (match_scratch:SI 3 "=r"))]
18008 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18009 [(set_attr "type" "multi")])
18011 (define_insn "stack_tls_protect_test_di"
18012 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18013 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18014 (match_operand:DI 2 "const_int_operand" "i")]
18015 UNSPEC_SP_TLS_TEST))
18016 (clobber (match_scratch:DI 3 "=r"))]
18019 /* The kernel uses a different segment register for performance reasons; a
18020 system call would not have to trash the userspace segment register,
18021 which would be expensive */
18022 if (ix86_cmodel != CM_KERNEL)
18023 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18025 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18027 [(set_attr "type" "multi")])
18029 (define_insn "sse4_2_crc32<mode>"
18030 [(set (match_operand:SI 0 "register_operand" "=r")
18032 [(match_operand:SI 1 "register_operand" "0")
18033 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18035 "TARGET_SSE4_2 || TARGET_CRC32"
18036 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18037 [(set_attr "type" "sselog1")
18038 (set_attr "prefix_rep" "1")
18039 (set_attr "prefix_extra" "1")
18040 (set (attr "prefix_data16")
18041 (if_then_else (match_operand:HI 2 "" "")
18043 (const_string "*")))
18044 (set (attr "prefix_rex")
18045 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18047 (const_string "*")))
18048 (set_attr "mode" "SI")])
18050 (define_insn "sse4_2_crc32di"
18051 [(set (match_operand:DI 0 "register_operand" "=r")
18053 [(match_operand:DI 1 "register_operand" "0")
18054 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18056 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18057 "crc32{q}\t{%2, %0|%0, %2}"
18058 [(set_attr "type" "sselog1")
18059 (set_attr "prefix_rep" "1")
18060 (set_attr "prefix_extra" "1")
18061 (set_attr "mode" "DI")])
18063 (define_expand "rdpmc"
18064 [(match_operand:DI 0 "register_operand" "")
18065 (match_operand:SI 1 "register_operand" "")]
18068 rtx reg = gen_reg_rtx (DImode);
18071 /* Force operand 1 into ECX. */
18072 rtx ecx = gen_rtx_REG (SImode, CX_REG);
18073 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18074 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18079 rtvec vec = rtvec_alloc (2);
18080 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18081 rtx upper = gen_reg_rtx (DImode);
18082 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18083 gen_rtvec (1, const0_rtx),
18085 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18086 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18088 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18089 NULL, 1, OPTAB_DIRECT);
18090 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18094 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18095 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18099 (define_insn "*rdpmc"
18100 [(set (match_operand:DI 0 "register_operand" "=A")
18101 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18105 [(set_attr "type" "other")
18106 (set_attr "length" "2")])
18108 (define_insn "*rdpmc_rex64"
18109 [(set (match_operand:DI 0 "register_operand" "=a")
18110 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18112 (set (match_operand:DI 1 "register_operand" "=d")
18113 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18116 [(set_attr "type" "other")
18117 (set_attr "length" "2")])
18119 (define_expand "rdtsc"
18120 [(set (match_operand:DI 0 "register_operand" "")
18121 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18126 rtvec vec = rtvec_alloc (2);
18127 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18128 rtx upper = gen_reg_rtx (DImode);
18129 rtx lower = gen_reg_rtx (DImode);
18130 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18131 gen_rtvec (1, const0_rtx),
18133 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18134 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18136 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18137 NULL, 1, OPTAB_DIRECT);
18138 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18140 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18145 (define_insn "*rdtsc"
18146 [(set (match_operand:DI 0 "register_operand" "=A")
18147 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18150 [(set_attr "type" "other")
18151 (set_attr "length" "2")])
18153 (define_insn "*rdtsc_rex64"
18154 [(set (match_operand:DI 0 "register_operand" "=a")
18155 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18156 (set (match_operand:DI 1 "register_operand" "=d")
18157 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18160 [(set_attr "type" "other")
18161 (set_attr "length" "2")])
18163 (define_expand "rdtscp"
18164 [(match_operand:DI 0 "register_operand" "")
18165 (match_operand:SI 1 "memory_operand" "")]
18168 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18169 gen_rtvec (1, const0_rtx),
18171 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18172 gen_rtvec (1, const0_rtx),
18174 rtx reg = gen_reg_rtx (DImode);
18175 rtx tmp = gen_reg_rtx (SImode);
18179 rtvec vec = rtvec_alloc (3);
18180 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18181 rtx upper = gen_reg_rtx (DImode);
18182 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18183 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18184 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18186 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18187 NULL, 1, OPTAB_DIRECT);
18188 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18193 rtvec vec = rtvec_alloc (2);
18194 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18195 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18196 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18199 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18200 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18204 (define_insn "*rdtscp"
18205 [(set (match_operand:DI 0 "register_operand" "=A")
18206 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18207 (set (match_operand:SI 1 "register_operand" "=c")
18208 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18211 [(set_attr "type" "other")
18212 (set_attr "length" "3")])
18214 (define_insn "*rdtscp_rex64"
18215 [(set (match_operand:DI 0 "register_operand" "=a")
18216 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18217 (set (match_operand:DI 1 "register_operand" "=d")
18218 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18219 (set (match_operand:SI 2 "register_operand" "=c")
18220 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18223 [(set_attr "type" "other")
18224 (set_attr "length" "3")])
18226 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18228 ;; LWP instructions
18230 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18232 (define_expand "lwp_llwpcb"
18233 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18234 UNSPECV_LLWP_INTRINSIC)]
18238 (define_insn "*lwp_llwpcb<mode>1"
18239 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18240 UNSPECV_LLWP_INTRINSIC)]
18243 [(set_attr "type" "lwp")
18244 (set_attr "mode" "<MODE>")
18245 (set_attr "length" "5")])
18247 (define_expand "lwp_slwpcb"
18248 [(set (match_operand 0 "register_operand" "=r")
18249 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18253 emit_insn (gen_lwp_slwpcbdi (operands[0]));
18255 emit_insn (gen_lwp_slwpcbsi (operands[0]));
18259 (define_insn "lwp_slwpcb<mode>"
18260 [(set (match_operand:P 0 "register_operand" "=r")
18261 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18264 [(set_attr "type" "lwp")
18265 (set_attr "mode" "<MODE>")
18266 (set_attr "length" "5")])
18268 (define_expand "lwp_lwpval<mode>3"
18269 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18270 (match_operand:SI 2 "nonimmediate_operand" "rm")
18271 (match_operand:SI 3 "const_int_operand" "i")]
18272 UNSPECV_LWPVAL_INTRINSIC)]
18274 "/* Avoid unused variable warning. */
18277 (define_insn "*lwp_lwpval<mode>3_1"
18278 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18279 (match_operand:SI 1 "nonimmediate_operand" "rm")
18280 (match_operand:SI 2 "const_int_operand" "i")]
18281 UNSPECV_LWPVAL_INTRINSIC)]
18283 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18284 [(set_attr "type" "lwp")
18285 (set_attr "mode" "<MODE>")
18286 (set (attr "length")
18287 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18289 (define_expand "lwp_lwpins<mode>3"
18290 [(set (reg:CCC FLAGS_REG)
18291 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18292 (match_operand:SI 2 "nonimmediate_operand" "rm")
18293 (match_operand:SI 3 "const_int_operand" "i")]
18294 UNSPECV_LWPINS_INTRINSIC))
18295 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18296 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18300 (define_insn "*lwp_lwpins<mode>3_1"
18301 [(set (reg:CCC FLAGS_REG)
18302 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18303 (match_operand:SI 1 "nonimmediate_operand" "rm")
18304 (match_operand:SI 2 "const_int_operand" "i")]
18305 UNSPECV_LWPINS_INTRINSIC))]
18307 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18308 [(set_attr "type" "lwp")
18309 (set_attr "mode" "<MODE>")
18310 (set (attr "length")
18311 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18313 (define_insn "rdfsbase<mode>"
18314 [(set (match_operand:SWI48 0 "register_operand" "=r")
18315 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18316 "TARGET_64BIT && TARGET_FSGSBASE"
18318 [(set_attr "type" "other")
18319 (set_attr "prefix_extra" "2")])
18321 (define_insn "rdgsbase<mode>"
18322 [(set (match_operand:SWI48 0 "register_operand" "=r")
18323 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18324 "TARGET_64BIT && TARGET_FSGSBASE"
18326 [(set_attr "type" "other")
18327 (set_attr "prefix_extra" "2")])
18329 (define_insn "wrfsbase<mode>"
18330 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18332 "TARGET_64BIT && TARGET_FSGSBASE"
18334 [(set_attr "type" "other")
18335 (set_attr "prefix_extra" "2")])
18337 (define_insn "wrgsbase<mode>"
18338 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18340 "TARGET_64BIT && TARGET_FSGSBASE"
18342 [(set_attr "type" "other")
18343 (set_attr "prefix_extra" "2")])
18345 (define_expand "rdrand<mode>"
18346 [(set (match_operand:SWI248 0 "register_operand" "=r")
18347 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
18350 rtx retry_label, insn, ccc;
18352 retry_label = gen_label_rtx ();
18354 emit_label (retry_label);
18356 /* Generate rdrand. */
18357 emit_insn (gen_rdrand<mode>_1 (operands[0]));
18359 /* Retry if the carry flag isn't valid. */
18360 ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
18361 ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
18362 ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
18363 gen_rtx_LABEL_REF (VOIDmode, retry_label));
18364 insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
18365 JUMP_LABEL (insn) = retry_label;
18370 (define_insn "rdrand<mode>_1"
18371 [(set (match_operand:SWI248 0 "register_operand" "=r")
18372 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
18375 [(set_attr "type" "other")
18376 (set_attr "prefix_extra" "1")])
18380 (include "sync.md")