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
82 UNSPEC_SSE_PROLOGUE_SAVE
87 UNSPEC_MEMORY_BLOCKAGE
88 UNSPEC_SSE_PROLOGUE_SAVE_LOW
96 ;; Other random patterns
105 UNSPEC_LD_MPIC ; load_macho_picbase
108 ;; For SSE/MMX support:
126 UNSPEC_MS_TO_SYSV_CALL
128 ;; Generic math support
130 UNSPEC_IEEE_MIN ; not commutative
131 UNSPEC_IEEE_MAX ; not commutative
133 ;; x87 Floating point
149 UNSPEC_FRNDINT_MASK_PM
153 ;; x87 Double output FP
185 ;; For SSE4.1 support
195 ;; For SSE4.2 support
201 UNSPEC_FMA4_INTRINSIC
204 UNSPEC_XOP_UNSIGNED_CMP
215 UNSPEC_AESKEYGENASSIST
217 ;; For PCLMUL support
231 (define_c_enum "unspecv" [
253 UNSPECV_LLWP_INTRINSIC
254 UNSPECV_SLWP_INTRINSIC
255 UNSPECV_LWPVAL_INTRINSIC
256 UNSPECV_LWPINS_INTRINSIC
259 ;; Constants to represent pcomtrue/pcomfalse variants
269 ;; Constants used in the XOP pperm instruction
271 [(PPERM_SRC 0x00) /* copy source */
272 (PPERM_INVERT 0x20) /* invert source */
273 (PPERM_REVERSE 0x40) /* bit reverse source */
274 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
275 (PPERM_ZERO 0x80) /* all 0's */
276 (PPERM_ONES 0xa0) /* all 1's */
277 (PPERM_SIGN 0xc0) /* propagate sign bit */
278 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
279 (PPERM_SRC1 0x00) /* use first source byte */
280 (PPERM_SRC2 0x10) /* use second source byte */
283 ;; Registers by name.
336 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
339 ;; In C guard expressions, put expressions which may be compile-time
340 ;; constants first. This allows for better optimization. For
341 ;; example, write "TARGET_64BIT && reload_completed", not
342 ;; "reload_completed && TARGET_64BIT".
346 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
347 generic64,amdfam10,bdver1"
348 (const (symbol_ref "ix86_schedule")))
350 ;; A basic instruction type. Refinements due to arguments to be
351 ;; provided in other attributes.
354 alu,alu1,negnot,imov,imovx,lea,
355 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
356 icmp,test,ibr,setcc,icmov,
357 push,pop,call,callv,leave,
359 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
360 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
361 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
362 ssemuladd,sse4arg,lwp,
363 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
364 (const_string "other"))
366 ;; Main data type used by the insn
368 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
369 (const_string "unknown"))
371 ;; The CPU unit operations uses.
372 (define_attr "unit" "integer,i387,sse,mmx,unknown"
373 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
374 (const_string "i387")
375 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
376 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
377 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
379 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
381 (eq_attr "type" "other")
382 (const_string "unknown")]
383 (const_string "integer")))
385 ;; The (bounding maximum) length of an instruction immediate.
386 (define_attr "length_immediate" ""
387 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
390 (eq_attr "unit" "i387,sse,mmx")
392 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
394 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
395 (eq_attr "type" "imov,test")
396 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
397 (eq_attr "type" "call")
398 (if_then_else (match_operand 0 "constant_call_address_operand" "")
401 (eq_attr "type" "callv")
402 (if_then_else (match_operand 1 "constant_call_address_operand" "")
405 ;; We don't know the size before shorten_branches. Expect
406 ;; the instruction to fit for better scheduling.
407 (eq_attr "type" "ibr")
410 (symbol_ref "/* Update immediate_length and other attributes! */
411 gcc_unreachable (),1")))
413 ;; The (bounding maximum) length of an instruction address.
414 (define_attr "length_address" ""
415 (cond [(eq_attr "type" "str,other,multi,fxch")
417 (and (eq_attr "type" "call")
418 (match_operand 0 "constant_call_address_operand" ""))
420 (and (eq_attr "type" "callv")
421 (match_operand 1 "constant_call_address_operand" ""))
424 (symbol_ref "ix86_attr_length_address_default (insn)")))
426 ;; Set when length prefix is used.
427 (define_attr "prefix_data16" ""
428 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
430 (eq_attr "mode" "HI")
432 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
437 ;; Set when string REP prefix is used.
438 (define_attr "prefix_rep" ""
439 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
441 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
446 ;; Set when 0f opcode prefix is used.
447 (define_attr "prefix_0f" ""
449 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
450 (eq_attr "unit" "sse,mmx"))
454 ;; Set when REX opcode prefix is used.
455 (define_attr "prefix_rex" ""
456 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
458 (and (eq_attr "mode" "DI")
459 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
460 (eq_attr "unit" "!mmx")))
462 (and (eq_attr "mode" "QI")
463 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
466 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
469 (and (eq_attr "type" "imovx")
470 (match_operand:QI 1 "ext_QIreg_operand" ""))
475 ;; There are also additional prefixes in 3DNOW, SSSE3.
476 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
477 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
478 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
479 (define_attr "prefix_extra" ""
480 (cond [(eq_attr "type" "ssemuladd,sse4arg")
482 (eq_attr "type" "sseiadd1,ssecvt1")
487 ;; Prefix used: original, VEX or maybe VEX.
488 (define_attr "prefix" "orig,vex,maybe_vex"
489 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
491 (const_string "orig")))
493 ;; VEX W bit is used.
494 (define_attr "prefix_vex_w" "" (const_int 0))
496 ;; The length of VEX prefix
497 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
498 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
499 ;; still prefix_0f 1, with prefix_extra 1.
500 (define_attr "length_vex" ""
501 (if_then_else (and (eq_attr "prefix_0f" "1")
502 (eq_attr "prefix_extra" "0"))
503 (if_then_else (eq_attr "prefix_vex_w" "1")
504 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
505 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
506 (if_then_else (eq_attr "prefix_vex_w" "1")
507 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
508 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
510 ;; Set when modrm byte is used.
511 (define_attr "modrm" ""
512 (cond [(eq_attr "type" "str,leave")
514 (eq_attr "unit" "i387")
516 (and (eq_attr "type" "incdec")
517 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
518 (ior (match_operand:SI 1 "register_operand" "")
519 (match_operand:HI 1 "register_operand" ""))))
521 (and (eq_attr "type" "push")
522 (not (match_operand 1 "memory_operand" "")))
524 (and (eq_attr "type" "pop")
525 (not (match_operand 0 "memory_operand" "")))
527 (and (eq_attr "type" "imov")
528 (and (not (eq_attr "mode" "DI"))
529 (ior (and (match_operand 0 "register_operand" "")
530 (match_operand 1 "immediate_operand" ""))
531 (ior (and (match_operand 0 "ax_reg_operand" "")
532 (match_operand 1 "memory_displacement_only_operand" ""))
533 (and (match_operand 0 "memory_displacement_only_operand" "")
534 (match_operand 1 "ax_reg_operand" ""))))))
536 (and (eq_attr "type" "call")
537 (match_operand 0 "constant_call_address_operand" ""))
539 (and (eq_attr "type" "callv")
540 (match_operand 1 "constant_call_address_operand" ""))
542 (and (eq_attr "type" "alu,alu1,icmp,test")
543 (match_operand 0 "ax_reg_operand" ""))
544 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
548 ;; The (bounding maximum) length of an instruction in bytes.
549 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
550 ;; Later we may want to split them and compute proper length as for
552 (define_attr "length" ""
553 (cond [(eq_attr "type" "other,multi,fistp,frndint")
555 (eq_attr "type" "fcmp")
557 (eq_attr "unit" "i387")
559 (plus (attr "prefix_data16")
560 (attr "length_address")))
561 (ior (eq_attr "prefix" "vex")
562 (and (eq_attr "prefix" "maybe_vex")
563 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
564 (plus (attr "length_vex")
565 (plus (attr "length_immediate")
567 (attr "length_address"))))]
568 (plus (plus (attr "modrm")
569 (plus (attr "prefix_0f")
570 (plus (attr "prefix_rex")
571 (plus (attr "prefix_extra")
573 (plus (attr "prefix_rep")
574 (plus (attr "prefix_data16")
575 (plus (attr "length_immediate")
576 (attr "length_address")))))))
578 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
579 ;; `store' if there is a simple memory reference therein, or `unknown'
580 ;; if the instruction is complex.
582 (define_attr "memory" "none,load,store,both,unknown"
583 (cond [(eq_attr "type" "other,multi,str,lwp")
584 (const_string "unknown")
585 (eq_attr "type" "lea,fcmov,fpspc")
586 (const_string "none")
587 (eq_attr "type" "fistp,leave")
588 (const_string "both")
589 (eq_attr "type" "frndint")
590 (const_string "load")
591 (eq_attr "type" "push")
592 (if_then_else (match_operand 1 "memory_operand" "")
593 (const_string "both")
594 (const_string "store"))
595 (eq_attr "type" "pop")
596 (if_then_else (match_operand 0 "memory_operand" "")
597 (const_string "both")
598 (const_string "load"))
599 (eq_attr "type" "setcc")
600 (if_then_else (match_operand 0 "memory_operand" "")
601 (const_string "store")
602 (const_string "none"))
603 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
604 (if_then_else (ior (match_operand 0 "memory_operand" "")
605 (match_operand 1 "memory_operand" ""))
606 (const_string "load")
607 (const_string "none"))
608 (eq_attr "type" "ibr")
609 (if_then_else (match_operand 0 "memory_operand" "")
610 (const_string "load")
611 (const_string "none"))
612 (eq_attr "type" "call")
613 (if_then_else (match_operand 0 "constant_call_address_operand" "")
614 (const_string "none")
615 (const_string "load"))
616 (eq_attr "type" "callv")
617 (if_then_else (match_operand 1 "constant_call_address_operand" "")
618 (const_string "none")
619 (const_string "load"))
620 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
621 (match_operand 1 "memory_operand" ""))
622 (const_string "both")
623 (and (match_operand 0 "memory_operand" "")
624 (match_operand 1 "memory_operand" ""))
625 (const_string "both")
626 (match_operand 0 "memory_operand" "")
627 (const_string "store")
628 (match_operand 1 "memory_operand" "")
629 (const_string "load")
631 "!alu1,negnot,ishift1,
632 imov,imovx,icmp,test,bitmanip,
634 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
635 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
636 (match_operand 2 "memory_operand" ""))
637 (const_string "load")
638 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
639 (match_operand 3 "memory_operand" ""))
640 (const_string "load")
642 (const_string "none")))
644 ;; Indicates if an instruction has both an immediate and a displacement.
646 (define_attr "imm_disp" "false,true,unknown"
647 (cond [(eq_attr "type" "other,multi")
648 (const_string "unknown")
649 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
650 (and (match_operand 0 "memory_displacement_operand" "")
651 (match_operand 1 "immediate_operand" "")))
652 (const_string "true")
653 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
654 (and (match_operand 0 "memory_displacement_operand" "")
655 (match_operand 2 "immediate_operand" "")))
656 (const_string "true")
658 (const_string "false")))
660 ;; Indicates if an FP operation has an integer source.
662 (define_attr "fp_int_src" "false,true"
663 (const_string "false"))
665 ;; Defines rounding mode of an FP operation.
667 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
668 (const_string "any"))
670 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
671 (define_attr "use_carry" "0,1" (const_string "0"))
673 ;; Define attribute to indicate unaligned ssemov insns
674 (define_attr "movu" "0,1" (const_string "0"))
676 ;; Describe a user's asm statement.
677 (define_asm_attributes
678 [(set_attr "length" "128")
679 (set_attr "type" "multi")])
681 ;; All integer comparison codes.
682 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
684 ;; All floating-point comparison codes.
685 (define_code_iterator fp_cond [unordered ordered
686 uneq unge ungt unle unlt ltgt])
688 (define_code_iterator plusminus [plus minus])
690 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
692 ;; Base name for define_insn
693 (define_code_attr plusminus_insn
694 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
695 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
697 ;; Base name for insn mnemonic.
698 (define_code_attr plusminus_mnemonic
699 [(plus "add") (ss_plus "adds") (us_plus "addus")
700 (minus "sub") (ss_minus "subs") (us_minus "subus")])
701 (define_code_attr plusminus_carry_mnemonic
702 [(plus "adc") (minus "sbb")])
704 ;; Mark commutative operators as such in constraints.
705 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
706 (minus "") (ss_minus "") (us_minus "")])
708 ;; Mapping of signed max and min
709 (define_code_iterator smaxmin [smax smin])
711 ;; Mapping of unsigned max and min
712 (define_code_iterator umaxmin [umax umin])
714 ;; Mapping of signed/unsigned max and min
715 (define_code_iterator maxmin [smax smin umax umin])
717 ;; Base name for integer and FP insn mnemonic
718 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
719 (umax "maxu") (umin "minu")])
720 (define_code_attr maxmin_float [(smax "max") (smin "min")])
722 ;; Mapping of logic operators
723 (define_code_iterator any_logic [and ior xor])
724 (define_code_iterator any_or [ior xor])
726 ;; Base name for insn mnemonic.
727 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
729 ;; Mapping of shift-right operators
730 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
732 ;; Base name for define_insn
733 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
735 ;; Base name for insn mnemonic.
736 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
738 ;; Mapping of rotate operators
739 (define_code_iterator any_rotate [rotate rotatert])
741 ;; Base name for define_insn
742 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
744 ;; Base name for insn mnemonic.
745 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
747 ;; Mapping of abs neg operators
748 (define_code_iterator absneg [abs neg])
750 ;; Base name for x87 insn mnemonic.
751 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
753 ;; Used in signed and unsigned widening multiplications.
754 (define_code_iterator any_extend [sign_extend zero_extend])
756 ;; Various insn prefixes for signed and unsigned operations.
757 (define_code_attr u [(sign_extend "") (zero_extend "u")
758 (div "") (udiv "u")])
759 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
761 ;; Used in signed and unsigned divisions.
762 (define_code_iterator any_div [div udiv])
763 (define_code_attr extract_code
764 [(div "SIGN_EXTRACT") (udiv "ZERO_EXTRACT")])
766 ;; Instruction prefix for signed and unsigned operations.
767 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
768 (div "i") (udiv "")])
770 ;; 64bit single word integer modes.
771 (define_mode_iterator SWI1248x [QI HI SI DI])
773 ;; 64bit single word integer modes without QImode and HImode.
774 (define_mode_iterator SWI48x [SI DI])
776 ;; Single word integer modes.
777 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
779 ;; Single word integer modes without SImode and DImode.
780 (define_mode_iterator SWI12 [QI HI])
782 ;; Single word integer modes without DImode.
783 (define_mode_iterator SWI124 [QI HI SI])
785 ;; Single word integer modes without QImode and DImode.
786 (define_mode_iterator SWI24 [HI SI])
788 ;; Single word integer modes without QImode.
789 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
791 ;; Single word integer modes without QImode and HImode.
792 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
794 ;; All math-dependant single and double word integer modes.
795 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
796 (HI "TARGET_HIMODE_MATH")
797 SI DI (TI "TARGET_64BIT")])
799 ;; Math-dependant single word integer modes.
800 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
801 (HI "TARGET_HIMODE_MATH")
802 SI (DI "TARGET_64BIT")])
804 ;; Math-dependant single word integer modes without DImode.
805 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
806 (HI "TARGET_HIMODE_MATH")
809 ;; Math-dependant single word integer modes without QImode.
810 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
811 SI (DI "TARGET_64BIT")])
813 ;; Double word integer modes.
814 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
815 (TI "TARGET_64BIT")])
817 ;; Double word integer modes as mode attribute.
818 (define_mode_attr DWI [(SI "DI") (DI "TI")])
819 (define_mode_attr dwi [(SI "di") (DI "ti")])
821 ;; Half mode for double word integer modes.
822 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
823 (DI "TARGET_64BIT")])
825 ;; Instruction suffix for integer modes.
826 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
828 ;; Register class for integer modes.
829 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
831 ;; Immediate operand constraint for integer modes.
832 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
834 ;; General operand constraint for word modes.
835 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
837 ;; Immediate operand constraint for double integer modes.
838 (define_mode_attr di [(SI "iF") (DI "e")])
840 ;; Immediate operand constraint for shifts.
841 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
843 ;; General operand predicate for integer modes.
844 (define_mode_attr general_operand
845 [(QI "general_operand")
846 (HI "general_operand")
847 (SI "general_operand")
848 (DI "x86_64_general_operand")
849 (TI "x86_64_general_operand")])
851 ;; General sign/zero extend operand predicate for integer modes.
852 (define_mode_attr general_szext_operand
853 [(QI "general_operand")
854 (HI "general_operand")
855 (SI "general_operand")
856 (DI "x86_64_szext_general_operand")])
858 ;; Operand predicate for shifts.
859 (define_mode_attr shift_operand
860 [(QI "nonimmediate_operand")
861 (HI "nonimmediate_operand")
862 (SI "nonimmediate_operand")
863 (DI "shiftdi_operand")
864 (TI "register_operand")])
866 ;; Operand predicate for shift argument.
867 (define_mode_attr shift_immediate_operand
868 [(QI "const_1_to_31_operand")
869 (HI "const_1_to_31_operand")
870 (SI "const_1_to_31_operand")
871 (DI "const_1_to_63_operand")])
873 ;; Input operand predicate for arithmetic left shifts.
874 (define_mode_attr ashl_input_operand
875 [(QI "nonimmediate_operand")
876 (HI "nonimmediate_operand")
877 (SI "nonimmediate_operand")
878 (DI "ashldi_input_operand")
879 (TI "reg_or_pm1_operand")])
881 ;; SSE and x87 SFmode and DFmode floating point modes
882 (define_mode_iterator MODEF [SF DF])
884 ;; All x87 floating point modes
885 (define_mode_iterator X87MODEF [SF DF XF])
887 ;; All integer modes handled by x87 fisttp operator.
888 (define_mode_iterator X87MODEI [HI SI DI])
890 ;; All integer modes handled by integer x87 operators.
891 (define_mode_iterator X87MODEI12 [HI SI])
893 ;; All integer modes handled by SSE cvtts?2si* operators.
894 (define_mode_iterator SSEMODEI24 [SI DI])
896 ;; SSE asm suffix for floating point modes
897 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
899 ;; SSE vector mode corresponding to a scalar mode
900 (define_mode_attr ssevecmode
901 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
903 ;; Instruction suffix for REX 64bit operators.
904 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
906 ;; This mode iterator allows :P to be used for patterns that operate on
907 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
908 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
910 ;; Scheduling descriptions
912 (include "pentium.md")
915 (include "athlon.md")
920 ;; Operand and operator predicates and constraints
922 (include "predicates.md")
923 (include "constraints.md")
926 ;; Compare and branch/compare and store instructions.
928 (define_expand "cbranch<mode>4"
929 [(set (reg:CC FLAGS_REG)
930 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
931 (match_operand:SDWIM 2 "<general_operand>" "")))
932 (set (pc) (if_then_else
933 (match_operator 0 "comparison_operator"
934 [(reg:CC FLAGS_REG) (const_int 0)])
935 (label_ref (match_operand 3 "" ""))
939 if (MEM_P (operands[1]) && MEM_P (operands[2]))
940 operands[1] = force_reg (<MODE>mode, operands[1]);
941 ix86_compare_op0 = operands[1];
942 ix86_compare_op1 = operands[2];
943 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
947 (define_expand "cstore<mode>4"
948 [(set (reg:CC FLAGS_REG)
949 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
950 (match_operand:SWIM 3 "<general_operand>" "")))
951 (set (match_operand:QI 0 "register_operand" "")
952 (match_operator 1 "comparison_operator"
953 [(reg:CC FLAGS_REG) (const_int 0)]))]
956 if (MEM_P (operands[2]) && MEM_P (operands[3]))
957 operands[2] = force_reg (<MODE>mode, operands[2]);
958 ix86_compare_op0 = operands[2];
959 ix86_compare_op1 = operands[3];
960 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
964 (define_expand "cmp<mode>_1"
965 [(set (reg:CC FLAGS_REG)
966 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
967 (match_operand:SWI48 1 "<general_operand>" "")))]
971 (define_insn "*cmp<mode>_ccno_1"
972 [(set (reg FLAGS_REG)
973 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
974 (match_operand:SWI 1 "const0_operand" "")))]
975 "ix86_match_ccmode (insn, CCNOmode)"
977 test{<imodesuffix>}\t%0, %0
978 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
979 [(set_attr "type" "test,icmp")
980 (set_attr "length_immediate" "0,1")
981 (set_attr "mode" "<MODE>")])
983 (define_insn "*cmp<mode>_1"
984 [(set (reg FLAGS_REG)
985 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
986 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
987 "ix86_match_ccmode (insn, CCmode)"
988 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
989 [(set_attr "type" "icmp")
990 (set_attr "mode" "<MODE>")])
992 (define_insn "*cmp<mode>_minus_1"
993 [(set (reg FLAGS_REG)
995 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
996 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
998 "ix86_match_ccmode (insn, CCGOCmode)"
999 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1000 [(set_attr "type" "icmp")
1001 (set_attr "mode" "<MODE>")])
1003 (define_insn "*cmpqi_ext_1"
1004 [(set (reg FLAGS_REG)
1006 (match_operand:QI 0 "general_operand" "Qm")
1009 (match_operand 1 "ext_register_operand" "Q")
1011 (const_int 8)) 0)))]
1012 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1013 "cmp{b}\t{%h1, %0|%0, %h1}"
1014 [(set_attr "type" "icmp")
1015 (set_attr "mode" "QI")])
1017 (define_insn "*cmpqi_ext_1_rex64"
1018 [(set (reg FLAGS_REG)
1020 (match_operand:QI 0 "register_operand" "Q")
1023 (match_operand 1 "ext_register_operand" "Q")
1025 (const_int 8)) 0)))]
1026 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1027 "cmp{b}\t{%h1, %0|%0, %h1}"
1028 [(set_attr "type" "icmp")
1029 (set_attr "mode" "QI")])
1031 (define_insn "*cmpqi_ext_2"
1032 [(set (reg FLAGS_REG)
1036 (match_operand 0 "ext_register_operand" "Q")
1039 (match_operand:QI 1 "const0_operand" "")))]
1040 "ix86_match_ccmode (insn, CCNOmode)"
1042 [(set_attr "type" "test")
1043 (set_attr "length_immediate" "0")
1044 (set_attr "mode" "QI")])
1046 (define_expand "cmpqi_ext_3"
1047 [(set (reg:CC FLAGS_REG)
1051 (match_operand 0 "ext_register_operand" "")
1054 (match_operand:QI 1 "immediate_operand" "")))]
1058 (define_insn "*cmpqi_ext_3_insn"
1059 [(set (reg FLAGS_REG)
1063 (match_operand 0 "ext_register_operand" "Q")
1066 (match_operand:QI 1 "general_operand" "Qmn")))]
1067 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1068 "cmp{b}\t{%1, %h0|%h0, %1}"
1069 [(set_attr "type" "icmp")
1070 (set_attr "modrm" "1")
1071 (set_attr "mode" "QI")])
1073 (define_insn "*cmpqi_ext_3_insn_rex64"
1074 [(set (reg FLAGS_REG)
1078 (match_operand 0 "ext_register_operand" "Q")
1081 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1082 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1083 "cmp{b}\t{%1, %h0|%h0, %1}"
1084 [(set_attr "type" "icmp")
1085 (set_attr "modrm" "1")
1086 (set_attr "mode" "QI")])
1088 (define_insn "*cmpqi_ext_4"
1089 [(set (reg FLAGS_REG)
1093 (match_operand 0 "ext_register_operand" "Q")
1098 (match_operand 1 "ext_register_operand" "Q")
1100 (const_int 8)) 0)))]
1101 "ix86_match_ccmode (insn, CCmode)"
1102 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1103 [(set_attr "type" "icmp")
1104 (set_attr "mode" "QI")])
1106 ;; These implement float point compares.
1107 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1108 ;; which would allow mix and match FP modes on the compares. Which is what
1109 ;; the old patterns did, but with many more of them.
1111 (define_expand "cbranchxf4"
1112 [(set (reg:CC FLAGS_REG)
1113 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1114 (match_operand:XF 2 "nonmemory_operand" "")))
1115 (set (pc) (if_then_else
1116 (match_operator 0 "ix86_fp_comparison_operator"
1119 (label_ref (match_operand 3 "" ""))
1123 ix86_compare_op0 = operands[1];
1124 ix86_compare_op1 = operands[2];
1125 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1129 (define_expand "cstorexf4"
1130 [(set (reg:CC FLAGS_REG)
1131 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1132 (match_operand:XF 3 "nonmemory_operand" "")))
1133 (set (match_operand:QI 0 "register_operand" "")
1134 (match_operator 1 "ix86_fp_comparison_operator"
1139 ix86_compare_op0 = operands[2];
1140 ix86_compare_op1 = operands[3];
1141 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1145 (define_expand "cbranch<mode>4"
1146 [(set (reg:CC FLAGS_REG)
1147 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1148 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1149 (set (pc) (if_then_else
1150 (match_operator 0 "ix86_fp_comparison_operator"
1153 (label_ref (match_operand 3 "" ""))
1155 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1157 ix86_compare_op0 = operands[1];
1158 ix86_compare_op1 = operands[2];
1159 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1163 (define_expand "cstore<mode>4"
1164 [(set (reg:CC FLAGS_REG)
1165 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1166 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1167 (set (match_operand:QI 0 "register_operand" "")
1168 (match_operator 1 "ix86_fp_comparison_operator"
1171 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1173 ix86_compare_op0 = operands[2];
1174 ix86_compare_op1 = operands[3];
1175 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1179 (define_expand "cbranchcc4"
1180 [(set (pc) (if_then_else
1181 (match_operator 0 "comparison_operator"
1182 [(match_operand 1 "flags_reg_operand" "")
1183 (match_operand 2 "const0_operand" "")])
1184 (label_ref (match_operand 3 "" ""))
1188 ix86_compare_op0 = operands[1];
1189 ix86_compare_op1 = operands[2];
1190 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1194 (define_expand "cstorecc4"
1195 [(set (match_operand:QI 0 "register_operand" "")
1196 (match_operator 1 "comparison_operator"
1197 [(match_operand 2 "flags_reg_operand" "")
1198 (match_operand 3 "const0_operand" "")]))]
1201 ix86_compare_op0 = operands[2];
1202 ix86_compare_op1 = operands[3];
1203 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1208 ;; FP compares, step 1:
1209 ;; Set the FP condition codes.
1211 ;; CCFPmode compare with exceptions
1212 ;; CCFPUmode compare with no exceptions
1214 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1215 ;; used to manage the reg stack popping would not be preserved.
1217 (define_insn "*cmpfp_0"
1218 [(set (match_operand:HI 0 "register_operand" "=a")
1221 (match_operand 1 "register_operand" "f")
1222 (match_operand 2 "const0_operand" ""))]
1224 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1225 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1226 "* return output_fp_compare (insn, operands, 0, 0);"
1227 [(set_attr "type" "multi")
1228 (set_attr "unit" "i387")
1230 (cond [(match_operand:SF 1 "" "")
1232 (match_operand:DF 1 "" "")
1235 (const_string "XF")))])
1237 (define_insn_and_split "*cmpfp_0_cc"
1238 [(set (reg:CCFP FLAGS_REG)
1240 (match_operand 1 "register_operand" "f")
1241 (match_operand 2 "const0_operand" "")))
1242 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1243 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1244 && TARGET_SAHF && !TARGET_CMOVE
1245 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1247 "&& reload_completed"
1250 [(compare:CCFP (match_dup 1)(match_dup 2))]
1252 (set (reg:CC FLAGS_REG)
1253 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1255 [(set_attr "type" "multi")
1256 (set_attr "unit" "i387")
1258 (cond [(match_operand:SF 1 "" "")
1260 (match_operand:DF 1 "" "")
1263 (const_string "XF")))])
1265 (define_insn "*cmpfp_xf"
1266 [(set (match_operand:HI 0 "register_operand" "=a")
1269 (match_operand:XF 1 "register_operand" "f")
1270 (match_operand:XF 2 "register_operand" "f"))]
1273 "* return output_fp_compare (insn, operands, 0, 0);"
1274 [(set_attr "type" "multi")
1275 (set_attr "unit" "i387")
1276 (set_attr "mode" "XF")])
1278 (define_insn_and_split "*cmpfp_xf_cc"
1279 [(set (reg:CCFP FLAGS_REG)
1281 (match_operand:XF 1 "register_operand" "f")
1282 (match_operand:XF 2 "register_operand" "f")))
1283 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1285 && TARGET_SAHF && !TARGET_CMOVE"
1287 "&& reload_completed"
1290 [(compare:CCFP (match_dup 1)(match_dup 2))]
1292 (set (reg:CC FLAGS_REG)
1293 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1295 [(set_attr "type" "multi")
1296 (set_attr "unit" "i387")
1297 (set_attr "mode" "XF")])
1299 (define_insn "*cmpfp_<mode>"
1300 [(set (match_operand:HI 0 "register_operand" "=a")
1303 (match_operand:MODEF 1 "register_operand" "f")
1304 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1307 "* return output_fp_compare (insn, operands, 0, 0);"
1308 [(set_attr "type" "multi")
1309 (set_attr "unit" "i387")
1310 (set_attr "mode" "<MODE>")])
1312 (define_insn_and_split "*cmpfp_<mode>_cc"
1313 [(set (reg:CCFP FLAGS_REG)
1315 (match_operand:MODEF 1 "register_operand" "f")
1316 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1317 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1319 && TARGET_SAHF && !TARGET_CMOVE"
1321 "&& reload_completed"
1324 [(compare:CCFP (match_dup 1)(match_dup 2))]
1326 (set (reg:CC FLAGS_REG)
1327 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1329 [(set_attr "type" "multi")
1330 (set_attr "unit" "i387")
1331 (set_attr "mode" "<MODE>")])
1333 (define_insn "*cmpfp_u"
1334 [(set (match_operand:HI 0 "register_operand" "=a")
1337 (match_operand 1 "register_operand" "f")
1338 (match_operand 2 "register_operand" "f"))]
1340 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1341 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1342 "* return output_fp_compare (insn, operands, 0, 1);"
1343 [(set_attr "type" "multi")
1344 (set_attr "unit" "i387")
1346 (cond [(match_operand:SF 1 "" "")
1348 (match_operand:DF 1 "" "")
1351 (const_string "XF")))])
1353 (define_insn_and_split "*cmpfp_u_cc"
1354 [(set (reg:CCFPU FLAGS_REG)
1356 (match_operand 1 "register_operand" "f")
1357 (match_operand 2 "register_operand" "f")))
1358 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1359 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1360 && TARGET_SAHF && !TARGET_CMOVE
1361 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1363 "&& reload_completed"
1366 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1368 (set (reg:CC FLAGS_REG)
1369 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1371 [(set_attr "type" "multi")
1372 (set_attr "unit" "i387")
1374 (cond [(match_operand:SF 1 "" "")
1376 (match_operand:DF 1 "" "")
1379 (const_string "XF")))])
1381 (define_insn "*cmpfp_<mode>"
1382 [(set (match_operand:HI 0 "register_operand" "=a")
1385 (match_operand 1 "register_operand" "f")
1386 (match_operator 3 "float_operator"
1387 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1389 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1390 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1391 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1392 "* return output_fp_compare (insn, operands, 0, 0);"
1393 [(set_attr "type" "multi")
1394 (set_attr "unit" "i387")
1395 (set_attr "fp_int_src" "true")
1396 (set_attr "mode" "<MODE>")])
1398 (define_insn_and_split "*cmpfp_<mode>_cc"
1399 [(set (reg:CCFP FLAGS_REG)
1401 (match_operand 1 "register_operand" "f")
1402 (match_operator 3 "float_operator"
1403 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1404 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1405 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1406 && TARGET_SAHF && !TARGET_CMOVE
1407 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1408 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1410 "&& reload_completed"
1415 (match_op_dup 3 [(match_dup 2)]))]
1417 (set (reg:CC FLAGS_REG)
1418 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1420 [(set_attr "type" "multi")
1421 (set_attr "unit" "i387")
1422 (set_attr "fp_int_src" "true")
1423 (set_attr "mode" "<MODE>")])
1425 ;; FP compares, step 2
1426 ;; Move the fpsw to ax.
1428 (define_insn "x86_fnstsw_1"
1429 [(set (match_operand:HI 0 "register_operand" "=a")
1430 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1433 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1434 (set_attr "mode" "SI")
1435 (set_attr "unit" "i387")])
1437 ;; FP compares, step 3
1438 ;; Get ax into flags, general case.
1440 (define_insn "x86_sahf_1"
1441 [(set (reg:CC FLAGS_REG)
1442 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1446 #ifndef HAVE_AS_IX86_SAHF
1448 return ASM_BYTE "0x9e";
1453 [(set_attr "length" "1")
1454 (set_attr "athlon_decode" "vector")
1455 (set_attr "amdfam10_decode" "direct")
1456 (set_attr "mode" "SI")])
1458 ;; Pentium Pro can do steps 1 through 3 in one go.
1459 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1460 (define_insn "*cmpfp_i_mixed"
1461 [(set (reg:CCFP FLAGS_REG)
1462 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1463 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1464 "TARGET_MIX_SSE_I387
1465 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1466 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1467 "* return output_fp_compare (insn, operands, 1, 0);"
1468 [(set_attr "type" "fcmp,ssecomi")
1469 (set_attr "prefix" "orig,maybe_vex")
1471 (if_then_else (match_operand:SF 1 "" "")
1473 (const_string "DF")))
1474 (set (attr "prefix_rep")
1475 (if_then_else (eq_attr "type" "ssecomi")
1477 (const_string "*")))
1478 (set (attr "prefix_data16")
1479 (cond [(eq_attr "type" "fcmp")
1481 (eq_attr "mode" "DF")
1484 (const_string "0")))
1485 (set_attr "athlon_decode" "vector")
1486 (set_attr "amdfam10_decode" "direct")])
1488 (define_insn "*cmpfp_i_sse"
1489 [(set (reg:CCFP FLAGS_REG)
1490 (compare:CCFP (match_operand 0 "register_operand" "x")
1491 (match_operand 1 "nonimmediate_operand" "xm")))]
1493 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1494 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1495 "* return output_fp_compare (insn, operands, 1, 0);"
1496 [(set_attr "type" "ssecomi")
1497 (set_attr "prefix" "maybe_vex")
1499 (if_then_else (match_operand:SF 1 "" "")
1501 (const_string "DF")))
1502 (set_attr "prefix_rep" "0")
1503 (set (attr "prefix_data16")
1504 (if_then_else (eq_attr "mode" "DF")
1506 (const_string "0")))
1507 (set_attr "athlon_decode" "vector")
1508 (set_attr "amdfam10_decode" "direct")])
1510 (define_insn "*cmpfp_i_i387"
1511 [(set (reg:CCFP FLAGS_REG)
1512 (compare:CCFP (match_operand 0 "register_operand" "f")
1513 (match_operand 1 "register_operand" "f")))]
1514 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1516 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1517 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1518 "* return output_fp_compare (insn, operands, 1, 0);"
1519 [(set_attr "type" "fcmp")
1521 (cond [(match_operand:SF 1 "" "")
1523 (match_operand:DF 1 "" "")
1526 (const_string "XF")))
1527 (set_attr "athlon_decode" "vector")
1528 (set_attr "amdfam10_decode" "direct")])
1530 (define_insn "*cmpfp_iu_mixed"
1531 [(set (reg:CCFPU FLAGS_REG)
1532 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1533 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1534 "TARGET_MIX_SSE_I387
1535 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1536 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1537 "* return output_fp_compare (insn, operands, 1, 1);"
1538 [(set_attr "type" "fcmp,ssecomi")
1539 (set_attr "prefix" "orig,maybe_vex")
1541 (if_then_else (match_operand:SF 1 "" "")
1543 (const_string "DF")))
1544 (set (attr "prefix_rep")
1545 (if_then_else (eq_attr "type" "ssecomi")
1547 (const_string "*")))
1548 (set (attr "prefix_data16")
1549 (cond [(eq_attr "type" "fcmp")
1551 (eq_attr "mode" "DF")
1554 (const_string "0")))
1555 (set_attr "athlon_decode" "vector")
1556 (set_attr "amdfam10_decode" "direct")])
1558 (define_insn "*cmpfp_iu_sse"
1559 [(set (reg:CCFPU FLAGS_REG)
1560 (compare:CCFPU (match_operand 0 "register_operand" "x")
1561 (match_operand 1 "nonimmediate_operand" "xm")))]
1563 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1564 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1565 "* return output_fp_compare (insn, operands, 1, 1);"
1566 [(set_attr "type" "ssecomi")
1567 (set_attr "prefix" "maybe_vex")
1569 (if_then_else (match_operand:SF 1 "" "")
1571 (const_string "DF")))
1572 (set_attr "prefix_rep" "0")
1573 (set (attr "prefix_data16")
1574 (if_then_else (eq_attr "mode" "DF")
1576 (const_string "0")))
1577 (set_attr "athlon_decode" "vector")
1578 (set_attr "amdfam10_decode" "direct")])
1580 (define_insn "*cmpfp_iu_387"
1581 [(set (reg:CCFPU FLAGS_REG)
1582 (compare:CCFPU (match_operand 0 "register_operand" "f")
1583 (match_operand 1 "register_operand" "f")))]
1584 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1586 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1587 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1588 "* return output_fp_compare (insn, operands, 1, 1);"
1589 [(set_attr "type" "fcmp")
1591 (cond [(match_operand:SF 1 "" "")
1593 (match_operand:DF 1 "" "")
1596 (const_string "XF")))
1597 (set_attr "athlon_decode" "vector")
1598 (set_attr "amdfam10_decode" "direct")])
1600 ;; Move instructions.
1602 (define_expand "movoi"
1603 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1604 (match_operand:OI 1 "general_operand" ""))]
1606 "ix86_expand_move (OImode, operands); DONE;")
1608 (define_expand "movti"
1609 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1610 (match_operand:TI 1 "nonimmediate_operand" ""))]
1611 "TARGET_64BIT || TARGET_SSE"
1614 ix86_expand_move (TImode, operands);
1615 else if (push_operand (operands[0], TImode))
1616 ix86_expand_push (TImode, operands[1]);
1618 ix86_expand_vector_move (TImode, operands);
1622 ;; This expands to what emit_move_complex would generate if we didn't
1623 ;; have a movti pattern. Having this avoids problems with reload on
1624 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1625 ;; to have around all the time.
1626 (define_expand "movcdi"
1627 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1628 (match_operand:CDI 1 "general_operand" ""))]
1631 if (push_operand (operands[0], CDImode))
1632 emit_move_complex_push (CDImode, operands[0], operands[1]);
1634 emit_move_complex_parts (operands[0], operands[1]);
1638 (define_expand "mov<mode>"
1639 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1640 (match_operand:SWI1248x 1 "general_operand" ""))]
1642 "ix86_expand_move (<MODE>mode, operands); DONE;")
1644 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1647 ;; %%% We don't use a post-inc memory reference because x86 is not a
1648 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1649 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1650 ;; targets without our curiosities, and it is just as easy to represent
1651 ;; this differently.
1653 (define_insn "*pushdi2_rex64"
1654 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1655 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1660 [(set_attr "type" "push,multi")
1661 (set_attr "mode" "DI")])
1663 ;; Convert impossible pushes of immediate to existing instructions.
1664 ;; First try to get scratch register and go through it. In case this
1665 ;; fails, push sign extended lower part first and then overwrite
1666 ;; upper part by 32bit move.
1668 [(match_scratch:DI 2 "r")
1669 (set (match_operand:DI 0 "push_operand" "")
1670 (match_operand:DI 1 "immediate_operand" ""))]
1671 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1672 && !x86_64_immediate_operand (operands[1], DImode)"
1673 [(set (match_dup 2) (match_dup 1))
1674 (set (match_dup 0) (match_dup 2))]
1677 ;; We need to define this as both peepholer and splitter for case
1678 ;; peephole2 pass is not run.
1679 ;; "&& 1" is needed to keep it from matching the previous pattern.
1681 [(set (match_operand:DI 0 "push_operand" "")
1682 (match_operand:DI 1 "immediate_operand" ""))]
1683 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1684 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1685 [(set (match_dup 0) (match_dup 1))
1686 (set (match_dup 2) (match_dup 3))]
1688 split_di (&operands[1], 1, &operands[2], &operands[3]);
1690 operands[1] = gen_lowpart (DImode, operands[2]);
1691 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1696 [(set (match_operand:DI 0 "push_operand" "")
1697 (match_operand:DI 1 "immediate_operand" ""))]
1698 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1699 ? epilogue_completed : reload_completed)
1700 && !symbolic_operand (operands[1], DImode)
1701 && !x86_64_immediate_operand (operands[1], DImode)"
1702 [(set (match_dup 0) (match_dup 1))
1703 (set (match_dup 2) (match_dup 3))]
1705 split_di (&operands[1], 1, &operands[2], &operands[3]);
1707 operands[1] = gen_lowpart (DImode, operands[2]);
1708 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1712 (define_insn "*pushdi2"
1713 [(set (match_operand:DI 0 "push_operand" "=<")
1714 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1719 [(set (match_operand:DI 0 "push_operand" "")
1720 (match_operand:DI 1 "general_operand" ""))]
1721 "!TARGET_64BIT && reload_completed
1722 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1724 "ix86_split_long_move (operands); DONE;")
1726 (define_insn "*pushsi2"
1727 [(set (match_operand:SI 0 "push_operand" "=<")
1728 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1731 [(set_attr "type" "push")
1732 (set_attr "mode" "SI")])
1734 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1735 ;; "push a byte/word". But actually we use pushl, which has the effect
1736 ;; of rounding the amount pushed up to a word.
1738 ;; For 64BIT abi we always round up to 8 bytes.
1739 (define_insn "*push<mode>2_rex64"
1740 [(set (match_operand:SWI124 0 "push_operand" "=X")
1741 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1744 [(set_attr "type" "push")
1745 (set_attr "mode" "DI")])
1747 (define_insn "*push<mode>2"
1748 [(set (match_operand:SWI12 0 "push_operand" "=X")
1749 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1752 [(set_attr "type" "push")
1753 (set_attr "mode" "SI")])
1755 (define_insn "*push<mode>2_prologue"
1756 [(set (match_operand:P 0 "push_operand" "=<")
1757 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1758 (clobber (mem:BLK (scratch)))]
1760 "push{<imodesuffix>}\t%1"
1761 [(set_attr "type" "push")
1762 (set_attr "mode" "<MODE>")])
1764 (define_insn "popdi1"
1765 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1766 (mem:DI (reg:DI SP_REG)))
1767 (set (reg:DI SP_REG)
1768 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1771 [(set_attr "type" "pop")
1772 (set_attr "mode" "DI")])
1774 (define_insn "popsi1"
1775 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1776 (mem:SI (reg:SI SP_REG)))
1777 (set (reg:SI SP_REG)
1778 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1781 [(set_attr "type" "pop")
1782 (set_attr "mode" "SI")])
1784 (define_insn "*popdi1_epilogue"
1785 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1786 (mem:DI (reg:DI SP_REG)))
1787 (set (reg:DI SP_REG)
1788 (plus:DI (reg:DI SP_REG) (const_int 8)))
1789 (clobber (mem:BLK (scratch)))]
1792 [(set_attr "type" "pop")
1793 (set_attr "mode" "DI")])
1795 (define_insn "*popsi1_epilogue"
1796 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1797 (mem:SI (reg:SI SP_REG)))
1798 (set (reg:SI SP_REG)
1799 (plus:SI (reg:SI SP_REG) (const_int 4)))
1800 (clobber (mem:BLK (scratch)))]
1803 [(set_attr "type" "pop")
1804 (set_attr "mode" "SI")])
1806 (define_insn "*mov<mode>_xor"
1807 [(set (match_operand:SWI48 0 "register_operand" "=r")
1808 (match_operand:SWI48 1 "const0_operand" ""))
1809 (clobber (reg:CC FLAGS_REG))]
1812 [(set_attr "type" "alu1")
1813 (set_attr "mode" "SI")
1814 (set_attr "length_immediate" "0")])
1816 (define_insn "*mov<mode>_or"
1817 [(set (match_operand:SWI48 0 "register_operand" "=r")
1818 (match_operand:SWI48 1 "const_int_operand" ""))
1819 (clobber (reg:CC FLAGS_REG))]
1821 && operands[1] == constm1_rtx"
1822 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1823 [(set_attr "type" "alu1")
1824 (set_attr "mode" "<MODE>")
1825 (set_attr "length_immediate" "1")])
1827 (define_insn "*movoi_internal_avx"
1828 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1829 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1830 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1832 switch (which_alternative)
1835 return "vxorps\t%0, %0, %0";
1838 if (misaligned_operand (operands[0], OImode)
1839 || misaligned_operand (operands[1], OImode))
1840 return "vmovdqu\t{%1, %0|%0, %1}";
1842 return "vmovdqa\t{%1, %0|%0, %1}";
1847 [(set_attr "type" "sselog1,ssemov,ssemov")
1848 (set_attr "prefix" "vex")
1849 (set_attr "mode" "OI")])
1851 (define_insn "*movti_internal_rex64"
1852 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1853 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1854 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1856 switch (which_alternative)
1862 if (get_attr_mode (insn) == MODE_V4SF)
1863 return "%vxorps\t%0, %d0";
1865 return "%vpxor\t%0, %d0";
1868 /* TDmode values are passed as TImode on the stack. Moving them
1869 to stack may result in unaligned memory access. */
1870 if (misaligned_operand (operands[0], TImode)
1871 || misaligned_operand (operands[1], TImode))
1873 if (get_attr_mode (insn) == MODE_V4SF)
1874 return "%vmovups\t{%1, %0|%0, %1}";
1876 return "%vmovdqu\t{%1, %0|%0, %1}";
1880 if (get_attr_mode (insn) == MODE_V4SF)
1881 return "%vmovaps\t{%1, %0|%0, %1}";
1883 return "%vmovdqa\t{%1, %0|%0, %1}";
1889 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1890 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1892 (cond [(eq_attr "alternative" "2,3")
1894 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1896 (const_string "V4SF")
1897 (const_string "TI"))
1898 (eq_attr "alternative" "4")
1900 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1902 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1904 (const_string "V4SF")
1905 (const_string "TI"))]
1906 (const_string "DI")))])
1909 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1910 (match_operand:TI 1 "general_operand" ""))]
1912 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1914 "ix86_split_long_move (operands); DONE;")
1916 (define_insn "*movti_internal_sse"
1917 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1918 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1919 "TARGET_SSE && !TARGET_64BIT
1920 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1922 switch (which_alternative)
1925 if (get_attr_mode (insn) == MODE_V4SF)
1926 return "%vxorps\t%0, %d0";
1928 return "%vpxor\t%0, %d0";
1931 /* TDmode values are passed as TImode on the stack. Moving them
1932 to stack may result in unaligned memory access. */
1933 if (misaligned_operand (operands[0], TImode)
1934 || misaligned_operand (operands[1], TImode))
1936 if (get_attr_mode (insn) == MODE_V4SF)
1937 return "%vmovups\t{%1, %0|%0, %1}";
1939 return "%vmovdqu\t{%1, %0|%0, %1}";
1943 if (get_attr_mode (insn) == MODE_V4SF)
1944 return "%vmovaps\t{%1, %0|%0, %1}";
1946 return "%vmovdqa\t{%1, %0|%0, %1}";
1952 [(set_attr "type" "sselog1,ssemov,ssemov")
1953 (set_attr "prefix" "maybe_vex")
1955 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1956 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1958 (const_string "V4SF")
1959 (and (eq_attr "alternative" "2")
1960 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1962 (const_string "V4SF")]
1963 (const_string "TI")))])
1965 (define_insn "*movdi_internal_rex64"
1966 [(set (match_operand:DI 0 "nonimmediate_operand"
1967 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1968 (match_operand:DI 1 "general_operand"
1969 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1970 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1972 switch (get_attr_type (insn))
1975 if (SSE_REG_P (operands[0]))
1976 return "movq2dq\t{%1, %0|%0, %1}";
1978 return "movdq2q\t{%1, %0|%0, %1}";
1983 if (get_attr_mode (insn) == MODE_TI)
1984 return "vmovdqa\t{%1, %0|%0, %1}";
1986 return "vmovq\t{%1, %0|%0, %1}";
1989 if (get_attr_mode (insn) == MODE_TI)
1990 return "movdqa\t{%1, %0|%0, %1}";
1994 /* Moves from and into integer register is done using movd
1995 opcode with REX prefix. */
1996 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1997 return "movd\t{%1, %0|%0, %1}";
1998 return "movq\t{%1, %0|%0, %1}";
2001 return "%vpxor\t%0, %d0";
2004 return "pxor\t%0, %0";
2010 return "lea{q}\t{%a1, %0|%0, %a1}";
2013 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2014 if (get_attr_mode (insn) == MODE_SI)
2015 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2016 else if (which_alternative == 2)
2017 return "movabs{q}\t{%1, %0|%0, %1}";
2019 return "mov{q}\t{%1, %0|%0, %1}";
2023 (cond [(eq_attr "alternative" "5")
2024 (const_string "mmx")
2025 (eq_attr "alternative" "6,7,8,9,10")
2026 (const_string "mmxmov")
2027 (eq_attr "alternative" "11")
2028 (const_string "sselog1")
2029 (eq_attr "alternative" "12,13,14,15,16")
2030 (const_string "ssemov")
2031 (eq_attr "alternative" "17,18")
2032 (const_string "ssecvt")
2033 (eq_attr "alternative" "4")
2034 (const_string "multi")
2035 (match_operand:DI 1 "pic_32bit_operand" "")
2036 (const_string "lea")
2038 (const_string "imov")))
2041 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2043 (const_string "*")))
2044 (set (attr "length_immediate")
2046 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2048 (const_string "*")))
2049 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2050 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2051 (set (attr "prefix")
2052 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2053 (const_string "maybe_vex")
2054 (const_string "orig")))
2055 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2057 ;; Convert impossible stores of immediate to existing instructions.
2058 ;; First try to get scratch register and go through it. In case this
2059 ;; fails, move by 32bit parts.
2061 [(match_scratch:DI 2 "r")
2062 (set (match_operand:DI 0 "memory_operand" "")
2063 (match_operand:DI 1 "immediate_operand" ""))]
2064 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2065 && !x86_64_immediate_operand (operands[1], DImode)"
2066 [(set (match_dup 2) (match_dup 1))
2067 (set (match_dup 0) (match_dup 2))]
2070 ;; We need to define this as both peepholer and splitter for case
2071 ;; peephole2 pass is not run.
2072 ;; "&& 1" is needed to keep it from matching the previous pattern.
2074 [(set (match_operand:DI 0 "memory_operand" "")
2075 (match_operand:DI 1 "immediate_operand" ""))]
2076 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2077 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2078 [(set (match_dup 2) (match_dup 3))
2079 (set (match_dup 4) (match_dup 5))]
2080 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2083 [(set (match_operand:DI 0 "memory_operand" "")
2084 (match_operand:DI 1 "immediate_operand" ""))]
2085 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2086 ? epilogue_completed : reload_completed)
2087 && !symbolic_operand (operands[1], DImode)
2088 && !x86_64_immediate_operand (operands[1], DImode)"
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]);")
2093 (define_insn "*movdi_internal"
2094 [(set (match_operand:DI 0 "nonimmediate_operand"
2095 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2096 (match_operand:DI 1 "general_operand"
2097 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2098 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2103 movq\t{%1, %0|%0, %1}
2104 movq\t{%1, %0|%0, %1}
2106 %vmovq\t{%1, %0|%0, %1}
2107 %vmovdqa\t{%1, %0|%0, %1}
2108 %vmovq\t{%1, %0|%0, %1}
2110 movlps\t{%1, %0|%0, %1}
2111 movaps\t{%1, %0|%0, %1}
2112 movlps\t{%1, %0|%0, %1}"
2113 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2114 (set (attr "prefix")
2115 (if_then_else (eq_attr "alternative" "5,6,7,8")
2116 (const_string "vex")
2117 (const_string "orig")))
2118 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2121 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2122 (match_operand:DI 1 "general_operand" ""))]
2123 "!TARGET_64BIT && reload_completed
2124 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2125 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2127 "ix86_split_long_move (operands); DONE;")
2129 (define_insn "*movsi_internal"
2130 [(set (match_operand:SI 0 "nonimmediate_operand"
2131 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2132 (match_operand:SI 1 "general_operand"
2133 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2134 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2136 switch (get_attr_type (insn))
2139 if (get_attr_mode (insn) == MODE_TI)
2140 return "%vpxor\t%0, %d0";
2141 return "%vxorps\t%0, %d0";
2144 switch (get_attr_mode (insn))
2147 return "%vmovdqa\t{%1, %0|%0, %1}";
2149 return "%vmovaps\t{%1, %0|%0, %1}";
2151 return "%vmovd\t{%1, %0|%0, %1}";
2153 return "%vmovss\t{%1, %0|%0, %1}";
2159 return "pxor\t%0, %0";
2162 if (get_attr_mode (insn) == MODE_DI)
2163 return "movq\t{%1, %0|%0, %1}";
2164 return "movd\t{%1, %0|%0, %1}";
2167 return "lea{l}\t{%a1, %0|%0, %a1}";
2170 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2171 return "mov{l}\t{%1, %0|%0, %1}";
2175 (cond [(eq_attr "alternative" "2")
2176 (const_string "mmx")
2177 (eq_attr "alternative" "3,4,5")
2178 (const_string "mmxmov")
2179 (eq_attr "alternative" "6")
2180 (const_string "sselog1")
2181 (eq_attr "alternative" "7,8,9,10,11")
2182 (const_string "ssemov")
2183 (match_operand:DI 1 "pic_32bit_operand" "")
2184 (const_string "lea")
2186 (const_string "imov")))
2187 (set (attr "prefix")
2188 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2189 (const_string "orig")
2190 (const_string "maybe_vex")))
2191 (set (attr "prefix_data16")
2192 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2194 (const_string "*")))
2196 (cond [(eq_attr "alternative" "2,3")
2198 (eq_attr "alternative" "6,7")
2200 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2201 (const_string "V4SF")
2202 (const_string "TI"))
2203 (and (eq_attr "alternative" "8,9,10,11")
2204 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2207 (const_string "SI")))])
2209 (define_insn "*movhi_internal"
2210 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2211 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2212 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2214 switch (get_attr_type (insn))
2217 /* movzwl is faster than movw on p2 due to partial word stalls,
2218 though not as fast as an aligned movl. */
2219 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2221 if (get_attr_mode (insn) == MODE_SI)
2222 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2224 return "mov{w}\t{%1, %0|%0, %1}";
2228 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2230 (const_string "imov")
2231 (and (eq_attr "alternative" "0")
2232 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2234 (eq (symbol_ref "TARGET_HIMODE_MATH")
2236 (const_string "imov")
2237 (and (eq_attr "alternative" "1,2")
2238 (match_operand:HI 1 "aligned_operand" ""))
2239 (const_string "imov")
2240 (and (ne (symbol_ref "TARGET_MOVX")
2242 (eq_attr "alternative" "0,2"))
2243 (const_string "imovx")
2245 (const_string "imov")))
2247 (cond [(eq_attr "type" "imovx")
2249 (and (eq_attr "alternative" "1,2")
2250 (match_operand:HI 1 "aligned_operand" ""))
2252 (and (eq_attr "alternative" "0")
2253 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2255 (eq (symbol_ref "TARGET_HIMODE_MATH")
2259 (const_string "HI")))])
2261 ;; Situation is quite tricky about when to choose full sized (SImode) move
2262 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2263 ;; partial register dependency machines (such as AMD Athlon), where QImode
2264 ;; moves issue extra dependency and for partial register stalls machines
2265 ;; that don't use QImode patterns (and QImode move cause stall on the next
2268 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2269 ;; register stall machines with, where we use QImode instructions, since
2270 ;; partial register stall can be caused there. Then we use movzx.
2271 (define_insn "*movqi_internal"
2272 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2273 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2274 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2276 switch (get_attr_type (insn))
2279 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2280 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2282 if (get_attr_mode (insn) == MODE_SI)
2283 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2285 return "mov{b}\t{%1, %0|%0, %1}";
2289 (cond [(and (eq_attr "alternative" "5")
2290 (not (match_operand:QI 1 "aligned_operand" "")))
2291 (const_string "imovx")
2292 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2294 (const_string "imov")
2295 (and (eq_attr "alternative" "3")
2296 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2298 (eq (symbol_ref "TARGET_QIMODE_MATH")
2300 (const_string "imov")
2301 (eq_attr "alternative" "3,5")
2302 (const_string "imovx")
2303 (and (ne (symbol_ref "TARGET_MOVX")
2305 (eq_attr "alternative" "2"))
2306 (const_string "imovx")
2308 (const_string "imov")))
2310 (cond [(eq_attr "alternative" "3,4,5")
2312 (eq_attr "alternative" "6")
2314 (eq_attr "type" "imovx")
2316 (and (eq_attr "type" "imov")
2317 (and (eq_attr "alternative" "0,1")
2318 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2320 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2322 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2325 ;; Avoid partial register stalls when not using QImode arithmetic
2326 (and (eq_attr "type" "imov")
2327 (and (eq_attr "alternative" "0,1")
2328 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2330 (eq (symbol_ref "TARGET_QIMODE_MATH")
2334 (const_string "QI")))])
2336 ;; Stores and loads of ax to arbitrary constant address.
2337 ;; We fake an second form of instruction to force reload to load address
2338 ;; into register when rax is not available
2339 (define_insn "*movabs<mode>_1"
2340 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2341 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2342 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2344 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2345 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2346 [(set_attr "type" "imov")
2347 (set_attr "modrm" "0,*")
2348 (set_attr "length_address" "8,0")
2349 (set_attr "length_immediate" "0,*")
2350 (set_attr "memory" "store")
2351 (set_attr "mode" "<MODE>")])
2353 (define_insn "*movabs<mode>_2"
2354 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2355 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2356 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2358 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2359 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2360 [(set_attr "type" "imov")
2361 (set_attr "modrm" "0,*")
2362 (set_attr "length_address" "8,0")
2363 (set_attr "length_immediate" "0")
2364 (set_attr "memory" "load")
2365 (set_attr "mode" "<MODE>")])
2367 (define_insn "*swap<mode>"
2368 [(set (match_operand:SWI48 0 "register_operand" "+r")
2369 (match_operand:SWI48 1 "register_operand" "+r"))
2373 "xchg{<imodesuffix>}\t%1, %0"
2374 [(set_attr "type" "imov")
2375 (set_attr "mode" "<MODE>")
2376 (set_attr "pent_pair" "np")
2377 (set_attr "athlon_decode" "vector")
2378 (set_attr "amdfam10_decode" "double")])
2380 (define_insn "*swap<mode>_1"
2381 [(set (match_operand:SWI12 0 "register_operand" "+r")
2382 (match_operand:SWI12 1 "register_operand" "+r"))
2385 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2387 [(set_attr "type" "imov")
2388 (set_attr "mode" "SI")
2389 (set_attr "pent_pair" "np")
2390 (set_attr "athlon_decode" "vector")
2391 (set_attr "amdfam10_decode" "double")])
2393 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2394 ;; is disabled for AMDFAM10
2395 (define_insn "*swap<mode>_2"
2396 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2397 (match_operand:SWI12 1 "register_operand" "+<r>"))
2400 "TARGET_PARTIAL_REG_STALL"
2401 "xchg{<imodesuffix>}\t%1, %0"
2402 [(set_attr "type" "imov")
2403 (set_attr "mode" "<MODE>")
2404 (set_attr "pent_pair" "np")
2405 (set_attr "athlon_decode" "vector")])
2407 (define_expand "movstrict<mode>"
2408 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2409 (match_operand:SWI12 1 "general_operand" ""))]
2412 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2414 /* Don't generate memory->memory moves, go through a register */
2415 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2416 operands[1] = force_reg (<MODE>mode, operands[1]);
2419 (define_insn "*movstrict<mode>_1"
2420 [(set (strict_low_part
2421 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2422 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2423 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2424 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2425 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2426 [(set_attr "type" "imov")
2427 (set_attr "mode" "<MODE>")])
2429 (define_insn "*movstrict<mode>_xor"
2430 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2431 (match_operand:SWI12 1 "const0_operand" ""))
2432 (clobber (reg:CC FLAGS_REG))]
2434 "xor{<imodesuffix>}\t%0, %0"
2435 [(set_attr "type" "alu1")
2436 (set_attr "mode" "<MODE>")
2437 (set_attr "length_immediate" "0")])
2439 (define_insn "*mov<mode>_extv_1"
2440 [(set (match_operand:SWI24 0 "register_operand" "=R")
2441 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2445 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2446 [(set_attr "type" "imovx")
2447 (set_attr "mode" "SI")])
2449 (define_insn "*movqi_extv_1_rex64"
2450 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2451 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2456 switch (get_attr_type (insn))
2459 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2461 return "mov{b}\t{%h1, %0|%0, %h1}";
2465 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2466 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2467 (ne (symbol_ref "TARGET_MOVX")
2469 (const_string "imovx")
2470 (const_string "imov")))
2472 (if_then_else (eq_attr "type" "imovx")
2474 (const_string "QI")))])
2476 (define_insn "*movqi_extv_1"
2477 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2478 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2483 switch (get_attr_type (insn))
2486 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2488 return "mov{b}\t{%h1, %0|%0, %h1}";
2492 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2493 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2494 (ne (symbol_ref "TARGET_MOVX")
2496 (const_string "imovx")
2497 (const_string "imov")))
2499 (if_then_else (eq_attr "type" "imovx")
2501 (const_string "QI")))])
2503 (define_insn "*mov<mode>_extzv_1"
2504 [(set (match_operand:SWI48 0 "register_operand" "=R")
2505 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2509 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2510 [(set_attr "type" "imovx")
2511 (set_attr "mode" "SI")])
2513 (define_insn "*movqi_extzv_2_rex64"
2514 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2516 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2521 switch (get_attr_type (insn))
2524 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2526 return "mov{b}\t{%h1, %0|%0, %h1}";
2530 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2531 (ne (symbol_ref "TARGET_MOVX")
2533 (const_string "imovx")
2534 (const_string "imov")))
2536 (if_then_else (eq_attr "type" "imovx")
2538 (const_string "QI")))])
2540 (define_insn "*movqi_extzv_2"
2541 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2543 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2548 switch (get_attr_type (insn))
2551 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2553 return "mov{b}\t{%h1, %0|%0, %h1}";
2557 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2558 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2559 (ne (symbol_ref "TARGET_MOVX")
2561 (const_string "imovx")
2562 (const_string "imov")))
2564 (if_then_else (eq_attr "type" "imovx")
2566 (const_string "QI")))])
2568 (define_expand "mov<mode>_insv_1"
2569 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2572 (match_operand:SWI48 1 "nonmemory_operand" ""))]
2576 (define_insn "*mov<mode>_insv_1_rex64"
2577 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2580 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2582 "mov{b}\t{%b1, %h0|%h0, %b1}"
2583 [(set_attr "type" "imov")
2584 (set_attr "mode" "QI")])
2586 (define_insn "*movsi_insv_1"
2587 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2590 (match_operand:SI 1 "general_operand" "Qmn"))]
2592 "mov{b}\t{%b1, %h0|%h0, %b1}"
2593 [(set_attr "type" "imov")
2594 (set_attr "mode" "QI")])
2596 (define_insn "*movqi_insv_2"
2597 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2600 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2603 "mov{b}\t{%h1, %h0|%h0, %h1}"
2604 [(set_attr "type" "imov")
2605 (set_attr "mode" "QI")])
2607 ;; Floating point move instructions.
2609 (define_expand "movtf"
2610 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2611 (match_operand:TF 1 "nonimmediate_operand" ""))]
2614 ix86_expand_move (TFmode, operands);
2618 (define_expand "mov<mode>"
2619 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2620 (match_operand:X87MODEF 1 "general_operand" ""))]
2622 "ix86_expand_move (<MODE>mode, operands); DONE;")
2624 (define_insn "*pushtf"
2625 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2626 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2629 /* This insn should be already split before reg-stack. */
2632 [(set_attr "type" "multi")
2633 (set_attr "unit" "sse,*,*")
2634 (set_attr "mode" "TF,SI,SI")])
2637 [(set (match_operand:TF 0 "push_operand" "")
2638 (match_operand:TF 1 "general_operand" ""))]
2639 "TARGET_SSE2 && reload_completed
2640 && !SSE_REG_P (operands[1])"
2642 "ix86_split_long_move (operands); DONE;")
2645 [(set (match_operand:TF 0 "push_operand" "")
2646 (match_operand:TF 1 "any_fp_register_operand" ""))]
2648 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2649 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
2652 (define_insn "*pushxf"
2653 [(set (match_operand:XF 0 "push_operand" "=<,<")
2654 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2655 "optimize_function_for_speed_p (cfun)"
2657 /* This insn should be already split before reg-stack. */
2660 [(set_attr "type" "multi")
2661 (set_attr "unit" "i387,*")
2662 (set_attr "mode" "XF,SI")])
2664 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2665 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2666 ;; Pushing using integer instructions is longer except for constants
2667 ;; and direct memory references (assuming that any given constant is pushed
2668 ;; only once, but this ought to be handled elsewhere).
2670 (define_insn "*pushxf_nointeger"
2671 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2672 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2673 "optimize_function_for_size_p (cfun)"
2675 /* This insn should be already split before reg-stack. */
2678 [(set_attr "type" "multi")
2679 (set_attr "unit" "i387,*,*")
2680 (set_attr "mode" "XF,SI,SI")])
2683 [(set (match_operand:XF 0 "push_operand" "")
2684 (match_operand:XF 1 "any_fp_register_operand" ""))]
2686 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2687 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2688 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2691 [(set (match_operand:XF 0 "push_operand" "")
2692 (match_operand:XF 1 "general_operand" ""))]
2694 && !ANY_FP_REG_P (operands[1])"
2696 "ix86_split_long_move (operands); DONE;")
2698 (define_insn "*pushdf"
2699 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2700 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2701 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2703 /* This insn should be already split before reg-stack. */
2706 [(set_attr "type" "multi")
2707 (set_attr "unit" "i387,*,*")
2708 (set_attr "mode" "DF,SI,DF")])
2710 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2711 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2712 ;; On the average, pushdf using integers can be still shorter. Allow this
2713 ;; pattern for optimize_size too.
2715 (define_insn "*pushdf_nointeger"
2716 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2717 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2718 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2720 /* This insn should be already split before reg-stack. */
2723 [(set_attr "type" "multi")
2724 (set_attr "unit" "i387,*,*,*")
2725 (set_attr "mode" "DF,SI,SI,DF")])
2727 ;; %%% Kill this when call knows how to work this out.
2729 [(set (match_operand:DF 0 "push_operand" "")
2730 (match_operand:DF 1 "any_fp_register_operand" ""))]
2732 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2733 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2737 [(set (match_operand:DF 0 "push_operand" "")
2738 (match_operand:DF 1 "general_operand" ""))]
2740 && !ANY_FP_REG_P (operands[1])"
2742 "ix86_split_long_move (operands); DONE;")
2744 (define_insn "*pushsf_rex64"
2745 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2746 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2749 /* Anything else should be already split before reg-stack. */
2750 gcc_assert (which_alternative == 1);
2751 return "push{q}\t%q1";
2753 [(set_attr "type" "multi,push,multi")
2754 (set_attr "unit" "i387,*,*")
2755 (set_attr "mode" "SF,DI,SF")])
2757 (define_insn "*pushsf"
2758 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2759 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2762 /* Anything else should be already split before reg-stack. */
2763 gcc_assert (which_alternative == 1);
2764 return "push{l}\t%1";
2766 [(set_attr "type" "multi,push,multi")
2767 (set_attr "unit" "i387,*,*")
2768 (set_attr "mode" "SF,SI,SF")])
2771 [(set (match_operand:SF 0 "push_operand" "")
2772 (match_operand:SF 1 "memory_operand" ""))]
2774 && MEM_P (operands[1])
2775 && (operands[2] = find_constant_src (insn))"
2779 ;; %%% Kill this when call knows how to work this out.
2781 [(set (match_operand:SF 0 "push_operand" "")
2782 (match_operand:SF 1 "any_fp_register_operand" ""))]
2784 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2785 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2786 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2788 (define_insn "*movtf_internal"
2789 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2790 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2792 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2794 switch (which_alternative)
2798 if (get_attr_mode (insn) == MODE_V4SF)
2799 return "%vmovaps\t{%1, %0|%0, %1}";
2801 return "%vmovdqa\t{%1, %0|%0, %1}";
2803 if (get_attr_mode (insn) == MODE_V4SF)
2804 return "%vxorps\t%0, %d0";
2806 return "%vpxor\t%0, %d0";
2814 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2815 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2817 (cond [(eq_attr "alternative" "0,2")
2819 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2821 (const_string "V4SF")
2822 (const_string "TI"))
2823 (eq_attr "alternative" "1")
2825 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2827 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2829 (const_string "V4SF")
2830 (const_string "TI"))]
2831 (const_string "DI")))])
2834 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2835 (match_operand:TF 1 "general_operand" ""))]
2837 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2839 "ix86_split_long_move (operands); DONE;")
2841 (define_insn "*movxf_internal"
2842 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2843 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2844 "optimize_function_for_speed_p (cfun)
2845 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2846 && (reload_in_progress || reload_completed
2847 || GET_CODE (operands[1]) != CONST_DOUBLE
2848 || memory_operand (operands[0], XFmode))"
2850 switch (which_alternative)
2854 return output_387_reg_move (insn, operands);
2857 return standard_80387_constant_opcode (operands[1]);
2866 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2867 (set_attr "mode" "XF,XF,XF,SI,SI")])
2869 ;; Do not use integer registers when optimizing for size
2870 (define_insn "*movxf_internal_nointeger"
2871 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2872 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2873 "optimize_function_for_size_p (cfun)
2874 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2875 && (reload_in_progress || reload_completed
2876 || standard_80387_constant_p (operands[1])
2877 || GET_CODE (operands[1]) != CONST_DOUBLE
2878 || memory_operand (operands[0], XFmode))"
2880 switch (which_alternative)
2884 return output_387_reg_move (insn, operands);
2887 return standard_80387_constant_opcode (operands[1]);
2895 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2896 (set_attr "mode" "XF,XF,XF,SI,SI")])
2899 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2900 (match_operand:XF 1 "general_operand" ""))]
2902 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2903 && ! (ANY_FP_REG_P (operands[0]) ||
2904 (GET_CODE (operands[0]) == SUBREG
2905 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2906 && ! (ANY_FP_REG_P (operands[1]) ||
2907 (GET_CODE (operands[1]) == SUBREG
2908 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2910 "ix86_split_long_move (operands); DONE;")
2912 (define_insn "*movdf_internal_rex64"
2913 [(set (match_operand:DF 0 "nonimmediate_operand"
2914 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2915 (match_operand:DF 1 "general_operand"
2916 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2917 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2918 && (reload_in_progress || reload_completed
2919 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2920 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2921 && optimize_function_for_size_p (cfun)
2922 && standard_80387_constant_p (operands[1]))
2923 || GET_CODE (operands[1]) != CONST_DOUBLE
2924 || memory_operand (operands[0], DFmode))"
2926 switch (which_alternative)
2930 return output_387_reg_move (insn, operands);
2933 return standard_80387_constant_opcode (operands[1]);
2940 switch (get_attr_mode (insn))
2943 return "%vxorps\t%0, %d0";
2945 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2946 return "%vxorps\t%0, %d0";
2948 return "%vxorpd\t%0, %d0";
2950 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2951 return "%vxorps\t%0, %d0";
2953 return "%vpxor\t%0, %d0";
2960 switch (get_attr_mode (insn))
2963 return "%vmovaps\t{%1, %0|%0, %1}";
2965 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2966 return "%vmovaps\t{%1, %0|%0, %1}";
2968 return "%vmovapd\t{%1, %0|%0, %1}";
2970 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2971 return "%vmovaps\t{%1, %0|%0, %1}";
2973 return "%vmovdqa\t{%1, %0|%0, %1}";
2975 return "%vmovq\t{%1, %0|%0, %1}";
2979 if (REG_P (operands[0]) && REG_P (operands[1]))
2980 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2982 return "vmovsd\t{%1, %0|%0, %1}";
2985 return "movsd\t{%1, %0|%0, %1}";
2987 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2989 return "%vmovlps\t{%1, %d0|%d0, %1}";
2996 return "%vmovd\t{%1, %0|%0, %1}";
3002 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3003 (set (attr "prefix")
3004 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3005 (const_string "orig")
3006 (const_string "maybe_vex")))
3007 (set (attr "prefix_data16")
3008 (if_then_else (eq_attr "mode" "V1DF")
3010 (const_string "*")))
3012 (cond [(eq_attr "alternative" "0,1,2")
3014 (eq_attr "alternative" "3,4,9,10")
3017 /* For SSE1, we have many fewer alternatives. */
3018 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3019 (cond [(eq_attr "alternative" "5,6")
3020 (const_string "V4SF")
3022 (const_string "V2SF"))
3024 /* xorps is one byte shorter. */
3025 (eq_attr "alternative" "5")
3026 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3028 (const_string "V4SF")
3029 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3033 (const_string "V2DF"))
3035 /* For architectures resolving dependencies on
3036 whole SSE registers use APD move to break dependency
3037 chains, otherwise use short move to avoid extra work.
3039 movaps encodes one byte shorter. */
3040 (eq_attr "alternative" "6")
3042 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3044 (const_string "V4SF")
3045 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3047 (const_string "V2DF")
3049 (const_string "DF"))
3050 /* For architectures resolving dependencies on register
3051 parts we may avoid extra work to zero out upper part
3053 (eq_attr "alternative" "7")
3055 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3057 (const_string "V1DF")
3058 (const_string "DF"))
3060 (const_string "DF")))])
3062 (define_insn "*movdf_internal"
3063 [(set (match_operand:DF 0 "nonimmediate_operand"
3064 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3065 (match_operand:DF 1 "general_operand"
3066 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3067 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3068 && optimize_function_for_speed_p (cfun)
3069 && TARGET_INTEGER_DFMODE_MOVES
3070 && (reload_in_progress || reload_completed
3071 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3072 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3073 && optimize_function_for_size_p (cfun)
3074 && standard_80387_constant_p (operands[1]))
3075 || GET_CODE (operands[1]) != CONST_DOUBLE
3076 || memory_operand (operands[0], DFmode))"
3078 switch (which_alternative)
3082 return output_387_reg_move (insn, operands);
3085 return standard_80387_constant_opcode (operands[1]);
3092 switch (get_attr_mode (insn))
3095 return "xorps\t%0, %0";
3097 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3098 return "xorps\t%0, %0";
3100 return "xorpd\t%0, %0";
3102 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3103 return "xorps\t%0, %0";
3105 return "pxor\t%0, %0";
3112 switch (get_attr_mode (insn))
3115 return "movaps\t{%1, %0|%0, %1}";
3117 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3118 return "movaps\t{%1, %0|%0, %1}";
3120 return "movapd\t{%1, %0|%0, %1}";
3122 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3123 return "movaps\t{%1, %0|%0, %1}";
3125 return "movdqa\t{%1, %0|%0, %1}";
3127 return "movq\t{%1, %0|%0, %1}";
3129 return "movsd\t{%1, %0|%0, %1}";
3131 return "movlpd\t{%1, %0|%0, %1}";
3133 return "movlps\t{%1, %0|%0, %1}";
3142 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3143 (set (attr "prefix_data16")
3144 (if_then_else (eq_attr "mode" "V1DF")
3146 (const_string "*")))
3148 (cond [(eq_attr "alternative" "0,1,2")
3150 (eq_attr "alternative" "3,4")
3153 /* For SSE1, we have many fewer alternatives. */
3154 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3155 (cond [(eq_attr "alternative" "5,6")
3156 (const_string "V4SF")
3158 (const_string "V2SF"))
3160 /* xorps is one byte shorter. */
3161 (eq_attr "alternative" "5")
3162 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3164 (const_string "V4SF")
3165 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3169 (const_string "V2DF"))
3171 /* For architectures resolving dependencies on
3172 whole SSE registers use APD move to break dependency
3173 chains, otherwise use short move to avoid extra work.
3175 movaps encodes one byte shorter. */
3176 (eq_attr "alternative" "6")
3178 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3180 (const_string "V4SF")
3181 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3183 (const_string "V2DF")
3185 (const_string "DF"))
3186 /* For architectures resolving dependencies on register
3187 parts we may avoid extra work to zero out upper part
3189 (eq_attr "alternative" "7")
3191 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3193 (const_string "V1DF")
3194 (const_string "DF"))
3196 (const_string "DF")))])
3198 ;; Moving is usually shorter when only FP registers are used. This separate
3199 ;; movdf pattern avoids the use of integer registers for FP operations
3200 ;; when optimizing for size.
3202 (define_insn "*movdf_internal_nointeger"
3203 [(set (match_operand:DF 0 "nonimmediate_operand"
3204 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3205 (match_operand:DF 1 "general_operand"
3206 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3207 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3208 && ((optimize_function_for_size_p (cfun)
3209 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3210 && (reload_in_progress || reload_completed
3211 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3212 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3213 && optimize_function_for_size_p (cfun)
3214 && !memory_operand (operands[0], DFmode)
3215 && standard_80387_constant_p (operands[1]))
3216 || GET_CODE (operands[1]) != CONST_DOUBLE
3217 || ((optimize_function_for_size_p (cfun)
3218 || !TARGET_MEMORY_MISMATCH_STALL
3219 || reload_in_progress || reload_completed)
3220 && memory_operand (operands[0], DFmode)))"
3222 switch (which_alternative)
3226 return output_387_reg_move (insn, operands);
3229 return standard_80387_constant_opcode (operands[1]);
3235 switch (get_attr_mode (insn))
3238 return "%vxorps\t%0, %d0";
3240 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3241 return "%vxorps\t%0, %d0";
3243 return "%vxorpd\t%0, %d0";
3245 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3246 return "%vxorps\t%0, %d0";
3248 return "%vpxor\t%0, %d0";
3255 switch (get_attr_mode (insn))
3258 return "%vmovaps\t{%1, %0|%0, %1}";
3260 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3261 return "%vmovaps\t{%1, %0|%0, %1}";
3263 return "%vmovapd\t{%1, %0|%0, %1}";
3265 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3266 return "%vmovaps\t{%1, %0|%0, %1}";
3268 return "%vmovdqa\t{%1, %0|%0, %1}";
3270 return "%vmovq\t{%1, %0|%0, %1}";
3274 if (REG_P (operands[0]) && REG_P (operands[1]))
3275 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3277 return "vmovsd\t{%1, %0|%0, %1}";
3280 return "movsd\t{%1, %0|%0, %1}";
3284 if (REG_P (operands[0]))
3285 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3287 return "vmovlpd\t{%1, %0|%0, %1}";
3290 return "movlpd\t{%1, %0|%0, %1}";
3294 if (REG_P (operands[0]))
3295 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3297 return "vmovlps\t{%1, %0|%0, %1}";
3300 return "movlps\t{%1, %0|%0, %1}";
3309 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3310 (set (attr "prefix")
3311 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3312 (const_string "orig")
3313 (const_string "maybe_vex")))
3314 (set (attr "prefix_data16")
3315 (if_then_else (eq_attr "mode" "V1DF")
3317 (const_string "*")))
3319 (cond [(eq_attr "alternative" "0,1,2")
3321 (eq_attr "alternative" "3,4")
3324 /* For SSE1, we have many fewer alternatives. */
3325 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3326 (cond [(eq_attr "alternative" "5,6")
3327 (const_string "V4SF")
3329 (const_string "V2SF"))
3331 /* xorps is one byte shorter. */
3332 (eq_attr "alternative" "5")
3333 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3335 (const_string "V4SF")
3336 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3340 (const_string "V2DF"))
3342 /* For architectures resolving dependencies on
3343 whole SSE registers use APD move to break dependency
3344 chains, otherwise use short move to avoid extra work.
3346 movaps encodes one byte shorter. */
3347 (eq_attr "alternative" "6")
3349 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3351 (const_string "V4SF")
3352 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3354 (const_string "V2DF")
3356 (const_string "DF"))
3357 /* For architectures resolving dependencies on register
3358 parts we may avoid extra work to zero out upper part
3360 (eq_attr "alternative" "7")
3362 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3364 (const_string "V1DF")
3365 (const_string "DF"))
3367 (const_string "DF")))])
3370 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3371 (match_operand:DF 1 "general_operand" ""))]
3373 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3374 && ! (ANY_FP_REG_P (operands[0]) ||
3375 (GET_CODE (operands[0]) == SUBREG
3376 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3377 && ! (ANY_FP_REG_P (operands[1]) ||
3378 (GET_CODE (operands[1]) == SUBREG
3379 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3381 "ix86_split_long_move (operands); DONE;")
3383 (define_insn "*movsf_internal"
3384 [(set (match_operand:SF 0 "nonimmediate_operand"
3385 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3386 (match_operand:SF 1 "general_operand"
3387 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3388 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3389 && (reload_in_progress || reload_completed
3390 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3391 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3392 && standard_80387_constant_p (operands[1]))
3393 || GET_CODE (operands[1]) != CONST_DOUBLE
3394 || memory_operand (operands[0], SFmode))"
3396 switch (which_alternative)
3400 return output_387_reg_move (insn, operands);
3403 return standard_80387_constant_opcode (operands[1]);
3407 return "mov{l}\t{%1, %0|%0, %1}";
3409 if (get_attr_mode (insn) == MODE_TI)
3410 return "%vpxor\t%0, %d0";
3412 return "%vxorps\t%0, %d0";
3414 if (get_attr_mode (insn) == MODE_V4SF)
3415 return "%vmovaps\t{%1, %0|%0, %1}";
3417 return "%vmovss\t{%1, %d0|%d0, %1}";
3420 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3421 : "vmovss\t{%1, %0|%0, %1}";
3423 return "movss\t{%1, %0|%0, %1}";
3425 return "%vmovss\t{%1, %0|%0, %1}";
3427 case 9: case 10: case 14: case 15:
3428 return "movd\t{%1, %0|%0, %1}";
3430 return "%vmovd\t{%1, %0|%0, %1}";
3433 return "movq\t{%1, %0|%0, %1}";
3439 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3440 (set (attr "prefix")
3441 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3442 (const_string "maybe_vex")
3443 (const_string "orig")))
3445 (cond [(eq_attr "alternative" "3,4,9,10")
3447 (eq_attr "alternative" "5")
3449 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3451 (ne (symbol_ref "TARGET_SSE2")
3453 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3456 (const_string "V4SF"))
3457 /* For architectures resolving dependencies on
3458 whole SSE registers use APS move to break dependency
3459 chains, otherwise use short move to avoid extra work.
3461 Do the same for architectures resolving dependencies on
3462 the parts. While in DF mode it is better to always handle
3463 just register parts, the SF mode is different due to lack
3464 of instructions to load just part of the register. It is
3465 better to maintain the whole registers in single format
3466 to avoid problems on using packed logical operations. */
3467 (eq_attr "alternative" "6")
3469 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3471 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3473 (const_string "V4SF")
3474 (const_string "SF"))
3475 (eq_attr "alternative" "11")
3476 (const_string "DI")]
3477 (const_string "SF")))])
3480 [(set (match_operand 0 "register_operand" "")
3481 (match_operand 1 "memory_operand" ""))]
3483 && MEM_P (operands[1])
3484 && (GET_MODE (operands[0]) == TFmode
3485 || GET_MODE (operands[0]) == XFmode
3486 || GET_MODE (operands[0]) == DFmode
3487 || GET_MODE (operands[0]) == SFmode)
3488 && (operands[2] = find_constant_src (insn))"
3489 [(set (match_dup 0) (match_dup 2))]
3491 rtx c = operands[2];
3492 rtx r = operands[0];
3494 if (GET_CODE (r) == SUBREG)
3499 if (!standard_sse_constant_p (c))
3502 else if (FP_REG_P (r))
3504 if (!standard_80387_constant_p (c))
3507 else if (MMX_REG_P (r))
3512 [(set (match_operand 0 "register_operand" "")
3513 (float_extend (match_operand 1 "memory_operand" "")))]
3515 && MEM_P (operands[1])
3516 && (GET_MODE (operands[0]) == TFmode
3517 || GET_MODE (operands[0]) == XFmode
3518 || GET_MODE (operands[0]) == DFmode
3519 || GET_MODE (operands[0]) == SFmode)
3520 && (operands[2] = find_constant_src (insn))"
3521 [(set (match_dup 0) (match_dup 2))]
3523 rtx c = operands[2];
3524 rtx r = operands[0];
3526 if (GET_CODE (r) == SUBREG)
3531 if (!standard_sse_constant_p (c))
3534 else if (FP_REG_P (r))
3536 if (!standard_80387_constant_p (c))
3539 else if (MMX_REG_P (r))
3543 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3545 [(set (match_operand:X87MODEF 0 "register_operand" "")
3546 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3547 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3548 && (standard_80387_constant_p (operands[1]) == 8
3549 || standard_80387_constant_p (operands[1]) == 9)"
3550 [(set (match_dup 0)(match_dup 1))
3552 (neg:X87MODEF (match_dup 0)))]
3556 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3557 if (real_isnegzero (&r))
3558 operands[1] = CONST0_RTX (<MODE>mode);
3560 operands[1] = CONST1_RTX (<MODE>mode);
3563 (define_insn "swapxf"
3564 [(set (match_operand:XF 0 "register_operand" "+f")
3565 (match_operand:XF 1 "register_operand" "+f"))
3570 if (STACK_TOP_P (operands[0]))
3575 [(set_attr "type" "fxch")
3576 (set_attr "mode" "XF")])
3578 (define_insn "*swap<mode>"
3579 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3580 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3583 "TARGET_80387 || reload_completed"
3585 if (STACK_TOP_P (operands[0]))
3590 [(set_attr "type" "fxch")
3591 (set_attr "mode" "<MODE>")])
3593 ;; Zero extension instructions
3595 (define_expand "zero_extendhisi2"
3596 [(set (match_operand:SI 0 "register_operand" "")
3597 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3600 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3602 operands[1] = force_reg (HImode, operands[1]);
3603 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3608 (define_insn "zero_extendhisi2_and"
3609 [(set (match_operand:SI 0 "register_operand" "=r")
3610 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3611 (clobber (reg:CC FLAGS_REG))]
3612 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3614 [(set_attr "type" "alu1")
3615 (set_attr "mode" "SI")])
3618 [(set (match_operand:SI 0 "register_operand" "")
3619 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3620 (clobber (reg:CC FLAGS_REG))]
3621 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3622 && optimize_function_for_speed_p (cfun)"
3623 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3624 (clobber (reg:CC FLAGS_REG))])]
3627 (define_insn "*zero_extendhisi2_movzwl"
3628 [(set (match_operand:SI 0 "register_operand" "=r")
3629 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3630 "!TARGET_ZERO_EXTEND_WITH_AND
3631 || optimize_function_for_size_p (cfun)"
3632 "movz{wl|x}\t{%1, %0|%0, %1}"
3633 [(set_attr "type" "imovx")
3634 (set_attr "mode" "SI")])
3636 (define_expand "zero_extendqihi2"
3638 [(set (match_operand:HI 0 "register_operand" "")
3639 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3640 (clobber (reg:CC FLAGS_REG))])]
3644 (define_insn "*zero_extendqihi2_and"
3645 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3646 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3647 (clobber (reg:CC FLAGS_REG))]
3648 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3650 [(set_attr "type" "alu1")
3651 (set_attr "mode" "HI")])
3653 (define_insn "*zero_extendqihi2_movzbw_and"
3654 [(set (match_operand:HI 0 "register_operand" "=r,r")
3655 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3656 (clobber (reg:CC FLAGS_REG))]
3657 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3659 [(set_attr "type" "imovx,alu1")
3660 (set_attr "mode" "HI")])
3662 ; zero extend to SImode here to avoid partial register stalls
3663 (define_insn "*zero_extendqihi2_movzbl"
3664 [(set (match_operand:HI 0 "register_operand" "=r")
3665 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3666 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3667 && reload_completed"
3668 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3669 [(set_attr "type" "imovx")
3670 (set_attr "mode" "SI")])
3672 ;; For the movzbw case strip only the clobber
3674 [(set (match_operand:HI 0 "register_operand" "")
3675 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3676 (clobber (reg:CC FLAGS_REG))]
3678 && (!TARGET_ZERO_EXTEND_WITH_AND
3679 || optimize_function_for_size_p (cfun))
3680 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3681 [(set (match_operand:HI 0 "register_operand" "")
3682 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3684 ;; When source and destination does not overlap, clear destination
3685 ;; first and then do the movb
3687 [(set (match_operand:HI 0 "register_operand" "")
3688 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3689 (clobber (reg:CC FLAGS_REG))]
3691 && ANY_QI_REG_P (operands[0])
3692 && (TARGET_ZERO_EXTEND_WITH_AND
3693 && optimize_function_for_speed_p (cfun))
3694 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3695 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3697 operands[2] = gen_lowpart (QImode, operands[0]);
3698 ix86_expand_clear (operands[0]);
3701 ;; Rest is handled by single and.
3703 [(set (match_operand:HI 0 "register_operand" "")
3704 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3705 (clobber (reg:CC FLAGS_REG))]
3707 && true_regnum (operands[0]) == true_regnum (operands[1])"
3708 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3709 (clobber (reg:CC FLAGS_REG))])]
3712 (define_expand "zero_extendqisi2"
3714 [(set (match_operand:SI 0 "register_operand" "")
3715 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3716 (clobber (reg:CC FLAGS_REG))])]
3720 (define_insn "*zero_extendqisi2_and"
3721 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3722 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3723 (clobber (reg:CC FLAGS_REG))]
3724 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3726 [(set_attr "type" "alu1")
3727 (set_attr "mode" "SI")])
3729 (define_insn "*zero_extendqisi2_movzbl_and"
3730 [(set (match_operand:SI 0 "register_operand" "=r,r")
3731 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3732 (clobber (reg:CC FLAGS_REG))]
3733 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3735 [(set_attr "type" "imovx,alu1")
3736 (set_attr "mode" "SI")])
3738 (define_insn "*zero_extendqisi2_movzbl"
3739 [(set (match_operand:SI 0 "register_operand" "=r")
3740 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3741 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3742 && reload_completed"
3743 "movz{bl|x}\t{%1, %0|%0, %1}"
3744 [(set_attr "type" "imovx")
3745 (set_attr "mode" "SI")])
3747 ;; For the movzbl case strip only the clobber
3749 [(set (match_operand:SI 0 "register_operand" "")
3750 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3751 (clobber (reg:CC FLAGS_REG))]
3753 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3754 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3756 (zero_extend:SI (match_dup 1)))])
3758 ;; When source and destination does not overlap, clear destination
3759 ;; first and then do the movb
3761 [(set (match_operand:SI 0 "register_operand" "")
3762 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3763 (clobber (reg:CC FLAGS_REG))]
3765 && ANY_QI_REG_P (operands[0])
3766 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3767 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3768 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3769 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3771 operands[2] = gen_lowpart (QImode, operands[0]);
3772 ix86_expand_clear (operands[0]);
3775 ;; Rest is handled by single and.
3777 [(set (match_operand:SI 0 "register_operand" "")
3778 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3779 (clobber (reg:CC FLAGS_REG))]
3781 && true_regnum (operands[0]) == true_regnum (operands[1])"
3782 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3783 (clobber (reg:CC FLAGS_REG))])]
3786 ;; %%% Kill me once multi-word ops are sane.
3787 (define_expand "zero_extendsidi2"
3788 [(set (match_operand:DI 0 "register_operand" "")
3789 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3794 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3799 (define_insn "zero_extendsidi2_32"
3800 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3802 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3803 (clobber (reg:CC FLAGS_REG))]
3809 movd\t{%1, %0|%0, %1}
3810 movd\t{%1, %0|%0, %1}
3811 %vmovd\t{%1, %0|%0, %1}
3812 %vmovd\t{%1, %0|%0, %1}"
3813 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3814 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3815 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3817 (define_insn "zero_extendsidi2_rex64"
3818 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3820 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3823 mov\t{%k1, %k0|%k0, %k1}
3825 movd\t{%1, %0|%0, %1}
3826 movd\t{%1, %0|%0, %1}
3827 %vmovd\t{%1, %0|%0, %1}
3828 %vmovd\t{%1, %0|%0, %1}"
3829 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3830 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3831 (set_attr "prefix_0f" "0,*,*,*,*,*")
3832 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3835 [(set (match_operand:DI 0 "memory_operand" "")
3836 (zero_extend:DI (match_dup 0)))]
3838 [(set (match_dup 4) (const_int 0))]
3839 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3842 [(set (match_operand:DI 0 "register_operand" "")
3843 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3844 (clobber (reg:CC FLAGS_REG))]
3845 "!TARGET_64BIT && reload_completed
3846 && true_regnum (operands[0]) == true_regnum (operands[1])"
3847 [(set (match_dup 4) (const_int 0))]
3848 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3851 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3852 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3853 (clobber (reg:CC FLAGS_REG))]
3854 "!TARGET_64BIT && reload_completed
3855 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3856 [(set (match_dup 3) (match_dup 1))
3857 (set (match_dup 4) (const_int 0))]
3858 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3860 (define_insn "zero_extendhidi2"
3861 [(set (match_operand:DI 0 "register_operand" "=r")
3862 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3864 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3865 [(set_attr "type" "imovx")
3866 (set_attr "mode" "SI")])
3868 (define_insn "zero_extendqidi2"
3869 [(set (match_operand:DI 0 "register_operand" "=r")
3870 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3872 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3873 [(set_attr "type" "imovx")
3874 (set_attr "mode" "SI")])
3876 ;; Sign extension instructions
3878 (define_expand "extendsidi2"
3879 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3880 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3881 (clobber (reg:CC FLAGS_REG))
3882 (clobber (match_scratch:SI 2 ""))])]
3887 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3892 (define_insn "*extendsidi2_1"
3893 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3894 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3895 (clobber (reg:CC FLAGS_REG))
3896 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3900 (define_insn "extendsidi2_rex64"
3901 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3902 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3906 movs{lq|x}\t{%1, %0|%0, %1}"
3907 [(set_attr "type" "imovx")
3908 (set_attr "mode" "DI")
3909 (set_attr "prefix_0f" "0")
3910 (set_attr "modrm" "0,1")])
3912 (define_insn "extendhidi2"
3913 [(set (match_operand:DI 0 "register_operand" "=r")
3914 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3916 "movs{wq|x}\t{%1, %0|%0, %1}"
3917 [(set_attr "type" "imovx")
3918 (set_attr "mode" "DI")])
3920 (define_insn "extendqidi2"
3921 [(set (match_operand:DI 0 "register_operand" "=r")
3922 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3924 "movs{bq|x}\t{%1, %0|%0, %1}"
3925 [(set_attr "type" "imovx")
3926 (set_attr "mode" "DI")])
3928 ;; Extend to memory case when source register does die.
3930 [(set (match_operand:DI 0 "memory_operand" "")
3931 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3932 (clobber (reg:CC FLAGS_REG))
3933 (clobber (match_operand:SI 2 "register_operand" ""))]
3935 && dead_or_set_p (insn, operands[1])
3936 && !reg_mentioned_p (operands[1], operands[0]))"
3937 [(set (match_dup 3) (match_dup 1))
3938 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3939 (clobber (reg:CC FLAGS_REG))])
3940 (set (match_dup 4) (match_dup 1))]
3941 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3943 ;; Extend to memory case when source register does not die.
3945 [(set (match_operand:DI 0 "memory_operand" "")
3946 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3947 (clobber (reg:CC FLAGS_REG))
3948 (clobber (match_operand:SI 2 "register_operand" ""))]
3952 split_di (&operands[0], 1, &operands[3], &operands[4]);
3954 emit_move_insn (operands[3], operands[1]);
3956 /* Generate a cltd if possible and doing so it profitable. */
3957 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3958 && true_regnum (operands[1]) == AX_REG
3959 && true_regnum (operands[2]) == DX_REG)
3961 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3965 emit_move_insn (operands[2], operands[1]);
3966 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3968 emit_move_insn (operands[4], operands[2]);
3972 ;; Extend to register case. Optimize case where source and destination
3973 ;; registers match and cases where we can use cltd.
3975 [(set (match_operand:DI 0 "register_operand" "")
3976 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3977 (clobber (reg:CC FLAGS_REG))
3978 (clobber (match_scratch:SI 2 ""))]
3982 split_di (&operands[0], 1, &operands[3], &operands[4]);
3984 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3985 emit_move_insn (operands[3], operands[1]);
3987 /* Generate a cltd if possible and doing so it profitable. */
3988 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3989 && true_regnum (operands[3]) == AX_REG
3990 && true_regnum (operands[4]) == DX_REG)
3992 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3996 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3997 emit_move_insn (operands[4], operands[1]);
3999 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4003 (define_insn "extendhisi2"
4004 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4005 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4008 switch (get_attr_prefix_0f (insn))
4011 return "{cwtl|cwde}";
4013 return "movs{wl|x}\t{%1, %0|%0, %1}";
4016 [(set_attr "type" "imovx")
4017 (set_attr "mode" "SI")
4018 (set (attr "prefix_0f")
4019 ;; movsx is short decodable while cwtl is vector decoded.
4020 (if_then_else (and (eq_attr "cpu" "!k6")
4021 (eq_attr "alternative" "0"))
4023 (const_string "1")))
4025 (if_then_else (eq_attr "prefix_0f" "0")
4027 (const_string "1")))])
4029 (define_insn "*extendhisi2_zext"
4030 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4032 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4035 switch (get_attr_prefix_0f (insn))
4038 return "{cwtl|cwde}";
4040 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4043 [(set_attr "type" "imovx")
4044 (set_attr "mode" "SI")
4045 (set (attr "prefix_0f")
4046 ;; movsx is short decodable while cwtl is vector decoded.
4047 (if_then_else (and (eq_attr "cpu" "!k6")
4048 (eq_attr "alternative" "0"))
4050 (const_string "1")))
4052 (if_then_else (eq_attr "prefix_0f" "0")
4054 (const_string "1")))])
4056 (define_insn "extendqihi2"
4057 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4058 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4061 switch (get_attr_prefix_0f (insn))
4064 return "{cbtw|cbw}";
4066 return "movs{bw|x}\t{%1, %0|%0, %1}";
4069 [(set_attr "type" "imovx")
4070 (set_attr "mode" "HI")
4071 (set (attr "prefix_0f")
4072 ;; movsx is short decodable while cwtl is vector decoded.
4073 (if_then_else (and (eq_attr "cpu" "!k6")
4074 (eq_attr "alternative" "0"))
4076 (const_string "1")))
4078 (if_then_else (eq_attr "prefix_0f" "0")
4080 (const_string "1")))])
4082 (define_insn "extendqisi2"
4083 [(set (match_operand:SI 0 "register_operand" "=r")
4084 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4086 "movs{bl|x}\t{%1, %0|%0, %1}"
4087 [(set_attr "type" "imovx")
4088 (set_attr "mode" "SI")])
4090 (define_insn "*extendqisi2_zext"
4091 [(set (match_operand:DI 0 "register_operand" "=r")
4093 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4095 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4096 [(set_attr "type" "imovx")
4097 (set_attr "mode" "SI")])
4099 ;; Conversions between float and double.
4101 ;; These are all no-ops in the model used for the 80387. So just
4104 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4105 (define_insn "*dummy_extendsfdf2"
4106 [(set (match_operand:DF 0 "push_operand" "=<")
4107 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4112 [(set (match_operand:DF 0 "push_operand" "")
4113 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4115 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4116 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4118 (define_insn "*dummy_extendsfxf2"
4119 [(set (match_operand:XF 0 "push_operand" "=<")
4120 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4125 [(set (match_operand:XF 0 "push_operand" "")
4126 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4128 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4129 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4130 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4133 [(set (match_operand:XF 0 "push_operand" "")
4134 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4136 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4137 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4138 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4140 (define_expand "extendsfdf2"
4141 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4142 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4143 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4145 /* ??? Needed for compress_float_constant since all fp constants
4146 are LEGITIMATE_CONSTANT_P. */
4147 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4149 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4150 && standard_80387_constant_p (operands[1]) > 0)
4152 operands[1] = simplify_const_unary_operation
4153 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4154 emit_move_insn_1 (operands[0], operands[1]);
4157 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4161 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4163 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4165 We do the conversion post reload to avoid producing of 128bit spills
4166 that might lead to ICE on 32bit target. The sequence unlikely combine
4169 [(set (match_operand:DF 0 "register_operand" "")
4171 (match_operand:SF 1 "nonimmediate_operand" "")))]
4172 "TARGET_USE_VECTOR_FP_CONVERTS
4173 && optimize_insn_for_speed_p ()
4174 && reload_completed && SSE_REG_P (operands[0])"
4179 (parallel [(const_int 0) (const_int 1)]))))]
4181 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4182 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4183 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4184 Try to avoid move when unpacking can be done in source. */
4185 if (REG_P (operands[1]))
4187 /* If it is unsafe to overwrite upper half of source, we need
4188 to move to destination and unpack there. */
4189 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4190 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4191 && true_regnum (operands[0]) != true_regnum (operands[1]))
4193 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4194 emit_move_insn (tmp, operands[1]);
4197 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4198 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4202 emit_insn (gen_vec_setv4sf_0 (operands[3],
4203 CONST0_RTX (V4SFmode), operands[1]));
4206 (define_insn "*extendsfdf2_mixed"
4207 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4209 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4210 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4212 switch (which_alternative)
4216 return output_387_reg_move (insn, operands);
4219 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4225 [(set_attr "type" "fmov,fmov,ssecvt")
4226 (set_attr "prefix" "orig,orig,maybe_vex")
4227 (set_attr "mode" "SF,XF,DF")])
4229 (define_insn "*extendsfdf2_sse"
4230 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4231 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4232 "TARGET_SSE2 && TARGET_SSE_MATH"
4233 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4234 [(set_attr "type" "ssecvt")
4235 (set_attr "prefix" "maybe_vex")
4236 (set_attr "mode" "DF")])
4238 (define_insn "*extendsfdf2_i387"
4239 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4240 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4242 "* return output_387_reg_move (insn, operands);"
4243 [(set_attr "type" "fmov")
4244 (set_attr "mode" "SF,XF")])
4246 (define_expand "extend<mode>xf2"
4247 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4248 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4251 /* ??? Needed for compress_float_constant since all fp constants
4252 are LEGITIMATE_CONSTANT_P. */
4253 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4255 if (standard_80387_constant_p (operands[1]) > 0)
4257 operands[1] = simplify_const_unary_operation
4258 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4259 emit_move_insn_1 (operands[0], operands[1]);
4262 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4266 (define_insn "*extend<mode>xf2_i387"
4267 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4269 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4271 "* return output_387_reg_move (insn, operands);"
4272 [(set_attr "type" "fmov")
4273 (set_attr "mode" "<MODE>,XF")])
4275 ;; %%% This seems bad bad news.
4276 ;; This cannot output into an f-reg because there is no way to be sure
4277 ;; of truncating in that case. Otherwise this is just like a simple move
4278 ;; insn. So we pretend we can output to a reg in order to get better
4279 ;; register preferencing, but we really use a stack slot.
4281 ;; Conversion from DFmode to SFmode.
4283 (define_expand "truncdfsf2"
4284 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4286 (match_operand:DF 1 "nonimmediate_operand" "")))]
4287 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4289 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4291 else if (flag_unsafe_math_optimizations)
4295 enum ix86_stack_slot slot = (virtuals_instantiated
4298 rtx temp = assign_386_stack_local (SFmode, slot);
4299 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4304 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4306 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4308 We do the conversion post reload to avoid producing of 128bit spills
4309 that might lead to ICE on 32bit target. The sequence unlikely combine
4312 [(set (match_operand:SF 0 "register_operand" "")
4314 (match_operand:DF 1 "nonimmediate_operand" "")))]
4315 "TARGET_USE_VECTOR_FP_CONVERTS
4316 && optimize_insn_for_speed_p ()
4317 && reload_completed && SSE_REG_P (operands[0])"
4320 (float_truncate:V2SF
4324 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4325 operands[3] = CONST0_RTX (V2SFmode);
4326 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4327 /* Use movsd for loading from memory, unpcklpd for registers.
4328 Try to avoid move when unpacking can be done in source, or SSE3
4329 movddup is available. */
4330 if (REG_P (operands[1]))
4333 && true_regnum (operands[0]) != true_regnum (operands[1])
4334 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4335 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4337 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4338 emit_move_insn (tmp, operands[1]);
4341 else if (!TARGET_SSE3)
4342 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4343 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4346 emit_insn (gen_sse2_loadlpd (operands[4],
4347 CONST0_RTX (V2DFmode), operands[1]));
4350 (define_expand "truncdfsf2_with_temp"
4351 [(parallel [(set (match_operand:SF 0 "" "")
4352 (float_truncate:SF (match_operand:DF 1 "" "")))
4353 (clobber (match_operand:SF 2 "" ""))])]
4356 (define_insn "*truncdfsf_fast_mixed"
4357 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4359 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4360 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4362 switch (which_alternative)
4365 return output_387_reg_move (insn, operands);
4367 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4372 [(set_attr "type" "fmov,ssecvt")
4373 (set_attr "prefix" "orig,maybe_vex")
4374 (set_attr "mode" "SF")])
4376 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4377 ;; because nothing we do here is unsafe.
4378 (define_insn "*truncdfsf_fast_sse"
4379 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4381 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4382 "TARGET_SSE2 && TARGET_SSE_MATH"
4383 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4384 [(set_attr "type" "ssecvt")
4385 (set_attr "prefix" "maybe_vex")
4386 (set_attr "mode" "SF")])
4388 (define_insn "*truncdfsf_fast_i387"
4389 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4391 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4392 "TARGET_80387 && flag_unsafe_math_optimizations"
4393 "* return output_387_reg_move (insn, operands);"
4394 [(set_attr "type" "fmov")
4395 (set_attr "mode" "SF")])
4397 (define_insn "*truncdfsf_mixed"
4398 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4400 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4401 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4402 "TARGET_MIX_SSE_I387"
4404 switch (which_alternative)
4407 return output_387_reg_move (insn, operands);
4409 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4415 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4416 (set_attr "unit" "*,*,i387,i387,i387")
4417 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4418 (set_attr "mode" "SF")])
4420 (define_insn "*truncdfsf_i387"
4421 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4423 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4424 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4427 switch (which_alternative)
4430 return output_387_reg_move (insn, operands);
4436 [(set_attr "type" "fmov,multi,multi,multi")
4437 (set_attr "unit" "*,i387,i387,i387")
4438 (set_attr "mode" "SF")])
4440 (define_insn "*truncdfsf2_i387_1"
4441 [(set (match_operand:SF 0 "memory_operand" "=m")
4443 (match_operand:DF 1 "register_operand" "f")))]
4445 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4446 && !TARGET_MIX_SSE_I387"
4447 "* return output_387_reg_move (insn, operands);"
4448 [(set_attr "type" "fmov")
4449 (set_attr "mode" "SF")])
4452 [(set (match_operand:SF 0 "register_operand" "")
4454 (match_operand:DF 1 "fp_register_operand" "")))
4455 (clobber (match_operand 2 "" ""))]
4457 [(set (match_dup 2) (match_dup 1))
4458 (set (match_dup 0) (match_dup 2))]
4460 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4463 ;; Conversion from XFmode to {SF,DF}mode
4465 (define_expand "truncxf<mode>2"
4466 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4467 (float_truncate:MODEF
4468 (match_operand:XF 1 "register_operand" "")))
4469 (clobber (match_dup 2))])]
4472 if (flag_unsafe_math_optimizations)
4474 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4475 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4476 if (reg != operands[0])
4477 emit_move_insn (operands[0], reg);
4482 enum ix86_stack_slot slot = (virtuals_instantiated
4485 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4489 (define_insn "*truncxfsf2_mixed"
4490 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4492 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4493 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4496 gcc_assert (!which_alternative);
4497 return output_387_reg_move (insn, operands);
4499 [(set_attr "type" "fmov,multi,multi,multi")
4500 (set_attr "unit" "*,i387,i387,i387")
4501 (set_attr "mode" "SF")])
4503 (define_insn "*truncxfdf2_mixed"
4504 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4506 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4507 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4510 gcc_assert (!which_alternative);
4511 return output_387_reg_move (insn, operands);
4513 [(set_attr "type" "fmov,multi,multi,multi")
4514 (set_attr "unit" "*,i387,i387,i387")
4515 (set_attr "mode" "DF")])
4517 (define_insn "truncxf<mode>2_i387_noop"
4518 [(set (match_operand:MODEF 0 "register_operand" "=f")
4519 (float_truncate:MODEF
4520 (match_operand:XF 1 "register_operand" "f")))]
4521 "TARGET_80387 && flag_unsafe_math_optimizations"
4522 "* return output_387_reg_move (insn, operands);"
4523 [(set_attr "type" "fmov")
4524 (set_attr "mode" "<MODE>")])
4526 (define_insn "*truncxf<mode>2_i387"
4527 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4528 (float_truncate:MODEF
4529 (match_operand:XF 1 "register_operand" "f")))]
4531 "* return output_387_reg_move (insn, operands);"
4532 [(set_attr "type" "fmov")
4533 (set_attr "mode" "<MODE>")])
4536 [(set (match_operand:MODEF 0 "register_operand" "")
4537 (float_truncate:MODEF
4538 (match_operand:XF 1 "register_operand" "")))
4539 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4540 "TARGET_80387 && reload_completed"
4541 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4542 (set (match_dup 0) (match_dup 2))]
4546 [(set (match_operand:MODEF 0 "memory_operand" "")
4547 (float_truncate:MODEF
4548 (match_operand:XF 1 "register_operand" "")))
4549 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4551 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4554 ;; Signed conversion to DImode.
4556 (define_expand "fix_truncxfdi2"
4557 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4558 (fix:DI (match_operand:XF 1 "register_operand" "")))
4559 (clobber (reg:CC FLAGS_REG))])]
4564 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4569 (define_expand "fix_trunc<mode>di2"
4570 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4571 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4572 (clobber (reg:CC FLAGS_REG))])]
4573 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4576 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4578 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4581 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4583 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4584 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4585 if (out != operands[0])
4586 emit_move_insn (operands[0], out);
4591 ;; Signed conversion to SImode.
4593 (define_expand "fix_truncxfsi2"
4594 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4595 (fix:SI (match_operand:XF 1 "register_operand" "")))
4596 (clobber (reg:CC FLAGS_REG))])]
4601 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4606 (define_expand "fix_trunc<mode>si2"
4607 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4608 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4609 (clobber (reg:CC FLAGS_REG))])]
4610 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4613 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4615 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4618 if (SSE_FLOAT_MODE_P (<MODE>mode))
4620 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4621 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4622 if (out != operands[0])
4623 emit_move_insn (operands[0], out);
4628 ;; Signed conversion to HImode.
4630 (define_expand "fix_trunc<mode>hi2"
4631 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4632 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4633 (clobber (reg:CC FLAGS_REG))])]
4635 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4639 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4644 ;; Unsigned conversion to SImode.
4646 (define_expand "fixuns_trunc<mode>si2"
4648 [(set (match_operand:SI 0 "register_operand" "")
4650 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4652 (clobber (match_scratch:<ssevecmode> 3 ""))
4653 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4654 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4656 enum machine_mode mode = <MODE>mode;
4657 enum machine_mode vecmode = <ssevecmode>mode;
4658 REAL_VALUE_TYPE TWO31r;
4661 if (optimize_insn_for_size_p ())
4664 real_ldexp (&TWO31r, &dconst1, 31);
4665 two31 = const_double_from_real_value (TWO31r, mode);
4666 two31 = ix86_build_const_vector (mode, true, two31);
4667 operands[2] = force_reg (vecmode, two31);
4670 (define_insn_and_split "*fixuns_trunc<mode>_1"
4671 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4673 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4674 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4675 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4676 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4677 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4678 && optimize_function_for_speed_p (cfun)"
4680 "&& reload_completed"
4683 ix86_split_convert_uns_si_sse (operands);
4687 ;; Unsigned conversion to HImode.
4688 ;; Without these patterns, we'll try the unsigned SI conversion which
4689 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4691 (define_expand "fixuns_trunc<mode>hi2"
4693 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4694 (set (match_operand:HI 0 "nonimmediate_operand" "")
4695 (subreg:HI (match_dup 2) 0))]
4696 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4697 "operands[2] = gen_reg_rtx (SImode);")
4699 ;; When SSE is available, it is always faster to use it!
4700 (define_insn "fix_trunc<mode>di_sse"
4701 [(set (match_operand:DI 0 "register_operand" "=r,r")
4702 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4703 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4704 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4705 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4706 [(set_attr "type" "sseicvt")
4707 (set_attr "prefix" "maybe_vex")
4708 (set_attr "prefix_rex" "1")
4709 (set_attr "mode" "<MODE>")
4710 (set_attr "athlon_decode" "double,vector")
4711 (set_attr "amdfam10_decode" "double,double")])
4713 (define_insn "fix_trunc<mode>si_sse"
4714 [(set (match_operand:SI 0 "register_operand" "=r,r")
4715 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4716 "SSE_FLOAT_MODE_P (<MODE>mode)
4717 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4718 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4719 [(set_attr "type" "sseicvt")
4720 (set_attr "prefix" "maybe_vex")
4721 (set_attr "mode" "<MODE>")
4722 (set_attr "athlon_decode" "double,vector")
4723 (set_attr "amdfam10_decode" "double,double")])
4725 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4727 [(set (match_operand:MODEF 0 "register_operand" "")
4728 (match_operand:MODEF 1 "memory_operand" ""))
4729 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4730 (fix:SSEMODEI24 (match_dup 0)))]
4731 "TARGET_SHORTEN_X87_SSE
4732 && peep2_reg_dead_p (2, operands[0])"
4733 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4736 ;; Avoid vector decoded forms of the instruction.
4738 [(match_scratch:DF 2 "Y2")
4739 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4740 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4741 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4742 [(set (match_dup 2) (match_dup 1))
4743 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4747 [(match_scratch:SF 2 "x")
4748 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4749 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4750 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4751 [(set (match_dup 2) (match_dup 1))
4752 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4755 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4756 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4757 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4758 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4760 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4761 && (TARGET_64BIT || <MODE>mode != DImode))
4763 && can_create_pseudo_p ()"
4768 if (memory_operand (operands[0], VOIDmode))
4769 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4772 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4773 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4779 [(set_attr "type" "fisttp")
4780 (set_attr "mode" "<MODE>")])
4782 (define_insn "fix_trunc<mode>_i387_fisttp"
4783 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4784 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4785 (clobber (match_scratch:XF 2 "=&1f"))]
4786 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4788 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4789 && (TARGET_64BIT || <MODE>mode != DImode))
4790 && TARGET_SSE_MATH)"
4791 "* return output_fix_trunc (insn, operands, 1);"
4792 [(set_attr "type" "fisttp")
4793 (set_attr "mode" "<MODE>")])
4795 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4796 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4797 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4798 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4799 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4800 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4802 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4803 && (TARGET_64BIT || <MODE>mode != DImode))
4804 && TARGET_SSE_MATH)"
4806 [(set_attr "type" "fisttp")
4807 (set_attr "mode" "<MODE>")])
4810 [(set (match_operand:X87MODEI 0 "register_operand" "")
4811 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4812 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4813 (clobber (match_scratch 3 ""))]
4815 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4816 (clobber (match_dup 3))])
4817 (set (match_dup 0) (match_dup 2))]
4821 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4822 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4823 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4824 (clobber (match_scratch 3 ""))]
4826 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4827 (clobber (match_dup 3))])]
4830 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4831 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4832 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4833 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4834 ;; function in i386.c.
4835 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4836 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4837 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4838 (clobber (reg:CC FLAGS_REG))]
4839 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4841 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4842 && (TARGET_64BIT || <MODE>mode != DImode))
4843 && can_create_pseudo_p ()"
4848 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4850 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4851 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4852 if (memory_operand (operands[0], VOIDmode))
4853 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4854 operands[2], operands[3]));
4857 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4858 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4859 operands[2], operands[3],
4864 [(set_attr "type" "fistp")
4865 (set_attr "i387_cw" "trunc")
4866 (set_attr "mode" "<MODE>")])
4868 (define_insn "fix_truncdi_i387"
4869 [(set (match_operand:DI 0 "memory_operand" "=m")
4870 (fix:DI (match_operand 1 "register_operand" "f")))
4871 (use (match_operand:HI 2 "memory_operand" "m"))
4872 (use (match_operand:HI 3 "memory_operand" "m"))
4873 (clobber (match_scratch:XF 4 "=&1f"))]
4874 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4876 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4877 "* return output_fix_trunc (insn, operands, 0);"
4878 [(set_attr "type" "fistp")
4879 (set_attr "i387_cw" "trunc")
4880 (set_attr "mode" "DI")])
4882 (define_insn "fix_truncdi_i387_with_temp"
4883 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4884 (fix:DI (match_operand 1 "register_operand" "f,f")))
4885 (use (match_operand:HI 2 "memory_operand" "m,m"))
4886 (use (match_operand:HI 3 "memory_operand" "m,m"))
4887 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4888 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4889 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4891 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4893 [(set_attr "type" "fistp")
4894 (set_attr "i387_cw" "trunc")
4895 (set_attr "mode" "DI")])
4898 [(set (match_operand:DI 0 "register_operand" "")
4899 (fix:DI (match_operand 1 "register_operand" "")))
4900 (use (match_operand:HI 2 "memory_operand" ""))
4901 (use (match_operand:HI 3 "memory_operand" ""))
4902 (clobber (match_operand:DI 4 "memory_operand" ""))
4903 (clobber (match_scratch 5 ""))]
4905 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4908 (clobber (match_dup 5))])
4909 (set (match_dup 0) (match_dup 4))]
4913 [(set (match_operand:DI 0 "memory_operand" "")
4914 (fix:DI (match_operand 1 "register_operand" "")))
4915 (use (match_operand:HI 2 "memory_operand" ""))
4916 (use (match_operand:HI 3 "memory_operand" ""))
4917 (clobber (match_operand:DI 4 "memory_operand" ""))
4918 (clobber (match_scratch 5 ""))]
4920 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4923 (clobber (match_dup 5))])]
4926 (define_insn "fix_trunc<mode>_i387"
4927 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4928 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4929 (use (match_operand:HI 2 "memory_operand" "m"))
4930 (use (match_operand:HI 3 "memory_operand" "m"))]
4931 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4933 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4934 "* return output_fix_trunc (insn, operands, 0);"
4935 [(set_attr "type" "fistp")
4936 (set_attr "i387_cw" "trunc")
4937 (set_attr "mode" "<MODE>")])
4939 (define_insn "fix_trunc<mode>_i387_with_temp"
4940 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4941 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4942 (use (match_operand:HI 2 "memory_operand" "m,m"))
4943 (use (match_operand:HI 3 "memory_operand" "m,m"))
4944 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4945 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4947 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4949 [(set_attr "type" "fistp")
4950 (set_attr "i387_cw" "trunc")
4951 (set_attr "mode" "<MODE>")])
4954 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4955 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4956 (use (match_operand:HI 2 "memory_operand" ""))
4957 (use (match_operand:HI 3 "memory_operand" ""))
4958 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4960 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4962 (use (match_dup 3))])
4963 (set (match_dup 0) (match_dup 4))]
4967 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4968 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4969 (use (match_operand:HI 2 "memory_operand" ""))
4970 (use (match_operand:HI 3 "memory_operand" ""))
4971 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4973 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4975 (use (match_dup 3))])]
4978 (define_insn "x86_fnstcw_1"
4979 [(set (match_operand:HI 0 "memory_operand" "=m")
4980 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4983 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4984 (set_attr "mode" "HI")
4985 (set_attr "unit" "i387")])
4987 (define_insn "x86_fldcw_1"
4988 [(set (reg:HI FPCR_REG)
4989 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4992 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4993 (set_attr "mode" "HI")
4994 (set_attr "unit" "i387")
4995 (set_attr "athlon_decode" "vector")
4996 (set_attr "amdfam10_decode" "vector")])
4998 ;; Conversion between fixed point and floating point.
5000 ;; Even though we only accept memory inputs, the backend _really_
5001 ;; wants to be able to do this between registers.
5003 (define_expand "floathi<mode>2"
5004 [(set (match_operand:X87MODEF 0 "register_operand" "")
5005 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5007 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5008 || TARGET_MIX_SSE_I387)"
5011 ;; Pre-reload splitter to add memory clobber to the pattern.
5012 (define_insn_and_split "*floathi<mode>2_1"
5013 [(set (match_operand:X87MODEF 0 "register_operand" "")
5014 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5016 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5017 || TARGET_MIX_SSE_I387)
5018 && can_create_pseudo_p ()"
5021 [(parallel [(set (match_dup 0)
5022 (float:X87MODEF (match_dup 1)))
5023 (clobber (match_dup 2))])]
5024 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5026 (define_insn "*floathi<mode>2_i387_with_temp"
5027 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5028 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5029 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5031 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5032 || TARGET_MIX_SSE_I387)"
5034 [(set_attr "type" "fmov,multi")
5035 (set_attr "mode" "<MODE>")
5036 (set_attr "unit" "*,i387")
5037 (set_attr "fp_int_src" "true")])
5039 (define_insn "*floathi<mode>2_i387"
5040 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5041 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5043 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5044 || TARGET_MIX_SSE_I387)"
5046 [(set_attr "type" "fmov")
5047 (set_attr "mode" "<MODE>")
5048 (set_attr "fp_int_src" "true")])
5051 [(set (match_operand:X87MODEF 0 "register_operand" "")
5052 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5053 (clobber (match_operand:HI 2 "memory_operand" ""))]
5055 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5056 || TARGET_MIX_SSE_I387)
5057 && reload_completed"
5058 [(set (match_dup 2) (match_dup 1))
5059 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5063 [(set (match_operand:X87MODEF 0 "register_operand" "")
5064 (float:X87MODEF (match_operand:HI 1 "memory_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 0) (float:X87MODEF (match_dup 1)))]
5073 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5074 [(set (match_operand:X87MODEF 0 "register_operand" "")
5076 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5078 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5079 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5081 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5082 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5083 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5085 rtx reg = gen_reg_rtx (XFmode);
5088 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5090 if (<X87MODEF:MODE>mode == SFmode)
5091 insn = gen_truncxfsf2 (operands[0], reg);
5092 else if (<X87MODEF:MODE>mode == DFmode)
5093 insn = gen_truncxfdf2 (operands[0], reg);
5102 ;; Pre-reload splitter to add memory clobber to the pattern.
5103 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5104 [(set (match_operand:X87MODEF 0 "register_operand" "")
5105 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5107 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5108 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5109 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5110 || TARGET_MIX_SSE_I387))
5111 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5112 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5113 && ((<SSEMODEI24:MODE>mode == SImode
5114 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5115 && optimize_function_for_speed_p (cfun)
5116 && flag_trapping_math)
5117 || !(TARGET_INTER_UNIT_CONVERSIONS
5118 || optimize_function_for_size_p (cfun)))))
5119 && can_create_pseudo_p ()"
5122 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5123 (clobber (match_dup 2))])]
5125 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5127 /* Avoid store forwarding (partial memory) stall penalty
5128 by passing DImode value through XMM registers. */
5129 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5130 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5131 && optimize_function_for_speed_p (cfun))
5133 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5140 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5141 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5143 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5144 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5145 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5146 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5148 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5149 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5150 (set_attr "unit" "*,i387,*,*,*")
5151 (set_attr "athlon_decode" "*,*,double,direct,double")
5152 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5153 (set_attr "fp_int_src" "true")])
5155 (define_insn "*floatsi<mode>2_vector_mixed"
5156 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5157 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5158 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5159 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5163 [(set_attr "type" "fmov,sseicvt")
5164 (set_attr "mode" "<MODE>,<ssevecmode>")
5165 (set_attr "unit" "i387,*")
5166 (set_attr "athlon_decode" "*,direct")
5167 (set_attr "amdfam10_decode" "*,double")
5168 (set_attr "fp_int_src" "true")])
5170 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5171 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5173 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5174 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5175 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5176 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5178 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5179 (set_attr "mode" "<MODEF:MODE>")
5180 (set_attr "unit" "*,i387,*,*")
5181 (set_attr "athlon_decode" "*,*,double,direct")
5182 (set_attr "amdfam10_decode" "*,*,vector,double")
5183 (set_attr "fp_int_src" "true")])
5186 [(set (match_operand:MODEF 0 "register_operand" "")
5187 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5188 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5189 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5190 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5191 && TARGET_INTER_UNIT_CONVERSIONS
5193 && (SSE_REG_P (operands[0])
5194 || (GET_CODE (operands[0]) == SUBREG
5195 && SSE_REG_P (operands[0])))"
5196 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5200 [(set (match_operand:MODEF 0 "register_operand" "")
5201 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5202 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5203 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5204 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5205 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5207 && (SSE_REG_P (operands[0])
5208 || (GET_CODE (operands[0]) == SUBREG
5209 && SSE_REG_P (operands[0])))"
5210 [(set (match_dup 2) (match_dup 1))
5211 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5214 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5215 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5217 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5218 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5219 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5220 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5223 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5224 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5225 [(set_attr "type" "fmov,sseicvt,sseicvt")
5226 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5227 (set_attr "mode" "<MODEF:MODE>")
5228 (set (attr "prefix_rex")
5230 (and (eq_attr "prefix" "maybe_vex")
5231 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5233 (const_string "*")))
5234 (set_attr "unit" "i387,*,*")
5235 (set_attr "athlon_decode" "*,double,direct")
5236 (set_attr "amdfam10_decode" "*,vector,double")
5237 (set_attr "fp_int_src" "true")])
5239 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5240 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5242 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5243 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5244 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5245 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5248 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5249 [(set_attr "type" "fmov,sseicvt")
5250 (set_attr "prefix" "orig,maybe_vex")
5251 (set_attr "mode" "<MODEF:MODE>")
5252 (set (attr "prefix_rex")
5254 (and (eq_attr "prefix" "maybe_vex")
5255 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5257 (const_string "*")))
5258 (set_attr "athlon_decode" "*,direct")
5259 (set_attr "amdfam10_decode" "*,double")
5260 (set_attr "fp_int_src" "true")])
5262 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5263 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5265 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5266 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5267 "TARGET_SSE2 && TARGET_SSE_MATH
5268 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5270 [(set_attr "type" "sseicvt")
5271 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5272 (set_attr "athlon_decode" "double,direct,double")
5273 (set_attr "amdfam10_decode" "vector,double,double")
5274 (set_attr "fp_int_src" "true")])
5276 (define_insn "*floatsi<mode>2_vector_sse"
5277 [(set (match_operand:MODEF 0 "register_operand" "=x")
5278 (float:MODEF (match_operand:SI 1 "memory_operand" "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>")
5284 (set_attr "athlon_decode" "direct")
5285 (set_attr "amdfam10_decode" "double")
5286 (set_attr "fp_int_src" "true")])
5289 [(set (match_operand:MODEF 0 "register_operand" "")
5290 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5291 (clobber (match_operand:SI 2 "memory_operand" ""))]
5292 "TARGET_SSE2 && TARGET_SSE_MATH
5293 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5295 && (SSE_REG_P (operands[0])
5296 || (GET_CODE (operands[0]) == SUBREG
5297 && SSE_REG_P (operands[0])))"
5300 rtx op1 = operands[1];
5302 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5304 if (GET_CODE (op1) == SUBREG)
5305 op1 = SUBREG_REG (op1);
5307 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5309 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5310 emit_insn (gen_sse2_loadld (operands[4],
5311 CONST0_RTX (V4SImode), operands[1]));
5313 /* We can ignore possible trapping value in the
5314 high part of SSE register for non-trapping math. */
5315 else if (SSE_REG_P (op1) && !flag_trapping_math)
5316 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5319 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5320 emit_move_insn (operands[2], operands[1]);
5321 emit_insn (gen_sse2_loadld (operands[4],
5322 CONST0_RTX (V4SImode), operands[2]));
5325 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5330 [(set (match_operand:MODEF 0 "register_operand" "")
5331 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5332 (clobber (match_operand:SI 2 "memory_operand" ""))]
5333 "TARGET_SSE2 && TARGET_SSE_MATH
5334 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5336 && (SSE_REG_P (operands[0])
5337 || (GET_CODE (operands[0]) == SUBREG
5338 && SSE_REG_P (operands[0])))"
5341 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5343 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5345 emit_insn (gen_sse2_loadld (operands[4],
5346 CONST0_RTX (V4SImode), operands[1]));
5348 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5353 [(set (match_operand:MODEF 0 "register_operand" "")
5354 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5355 "TARGET_SSE2 && TARGET_SSE_MATH
5356 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5358 && (SSE_REG_P (operands[0])
5359 || (GET_CODE (operands[0]) == SUBREG
5360 && SSE_REG_P (operands[0])))"
5363 rtx op1 = operands[1];
5365 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5367 if (GET_CODE (op1) == SUBREG)
5368 op1 = SUBREG_REG (op1);
5370 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5372 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5373 emit_insn (gen_sse2_loadld (operands[4],
5374 CONST0_RTX (V4SImode), operands[1]));
5376 /* We can ignore possible trapping value in the
5377 high part of SSE register for non-trapping math. */
5378 else if (SSE_REG_P (op1) && !flag_trapping_math)
5379 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5383 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5388 [(set (match_operand:MODEF 0 "register_operand" "")
5389 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5390 "TARGET_SSE2 && TARGET_SSE_MATH
5391 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5393 && (SSE_REG_P (operands[0])
5394 || (GET_CODE (operands[0]) == SUBREG
5395 && SSE_REG_P (operands[0])))"
5398 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5400 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5402 emit_insn (gen_sse2_loadld (operands[4],
5403 CONST0_RTX (V4SImode), operands[1]));
5405 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5409 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5410 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5412 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5413 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5414 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5415 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5417 [(set_attr "type" "sseicvt")
5418 (set_attr "mode" "<MODEF:MODE>")
5419 (set_attr "athlon_decode" "double,direct")
5420 (set_attr "amdfam10_decode" "vector,double")
5421 (set_attr "fp_int_src" "true")])
5423 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5424 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5426 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5427 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5428 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5429 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5430 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5431 [(set_attr "type" "sseicvt")
5432 (set_attr "prefix" "maybe_vex")
5433 (set_attr "mode" "<MODEF:MODE>")
5434 (set (attr "prefix_rex")
5436 (and (eq_attr "prefix" "maybe_vex")
5437 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5439 (const_string "*")))
5440 (set_attr "athlon_decode" "double,direct")
5441 (set_attr "amdfam10_decode" "vector,double")
5442 (set_attr "fp_int_src" "true")])
5445 [(set (match_operand:MODEF 0 "register_operand" "")
5446 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5447 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5448 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5449 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5450 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5452 && (SSE_REG_P (operands[0])
5453 || (GET_CODE (operands[0]) == SUBREG
5454 && SSE_REG_P (operands[0])))"
5455 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5458 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5459 [(set (match_operand:MODEF 0 "register_operand" "=x")
5461 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5462 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5463 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5464 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5465 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5466 [(set_attr "type" "sseicvt")
5467 (set_attr "prefix" "maybe_vex")
5468 (set_attr "mode" "<MODEF:MODE>")
5469 (set (attr "prefix_rex")
5471 (and (eq_attr "prefix" "maybe_vex")
5472 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5474 (const_string "*")))
5475 (set_attr "athlon_decode" "direct")
5476 (set_attr "amdfam10_decode" "double")
5477 (set_attr "fp_int_src" "true")])
5480 [(set (match_operand:MODEF 0 "register_operand" "")
5481 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5482 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5483 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5484 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5485 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5487 && (SSE_REG_P (operands[0])
5488 || (GET_CODE (operands[0]) == SUBREG
5489 && SSE_REG_P (operands[0])))"
5490 [(set (match_dup 2) (match_dup 1))
5491 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5495 [(set (match_operand:MODEF 0 "register_operand" "")
5496 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5497 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5498 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5499 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5501 && (SSE_REG_P (operands[0])
5502 || (GET_CODE (operands[0]) == SUBREG
5503 && SSE_REG_P (operands[0])))"
5504 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5507 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5508 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5510 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5511 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5513 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5517 [(set_attr "type" "fmov,multi")
5518 (set_attr "mode" "<X87MODEF:MODE>")
5519 (set_attr "unit" "*,i387")
5520 (set_attr "fp_int_src" "true")])
5522 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5523 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5525 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5527 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5529 [(set_attr "type" "fmov")
5530 (set_attr "mode" "<X87MODEF:MODE>")
5531 (set_attr "fp_int_src" "true")])
5534 [(set (match_operand:X87MODEF 0 "register_operand" "")
5535 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5536 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5538 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5540 && FP_REG_P (operands[0])"
5541 [(set (match_dup 2) (match_dup 1))
5542 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5546 [(set (match_operand:X87MODEF 0 "register_operand" "")
5547 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_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 0) (float:X87MODEF (match_dup 1)))]
5556 ;; Avoid store forwarding (partial memory) stall penalty
5557 ;; by passing DImode value through XMM registers. */
5559 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5560 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5562 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5563 (clobber (match_scratch:V4SI 3 "=X,x"))
5564 (clobber (match_scratch:V4SI 4 "=X,x"))
5565 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5566 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5567 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5568 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5570 [(set_attr "type" "multi")
5571 (set_attr "mode" "<X87MODEF:MODE>")
5572 (set_attr "unit" "i387")
5573 (set_attr "fp_int_src" "true")])
5576 [(set (match_operand:X87MODEF 0 "register_operand" "")
5577 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5578 (clobber (match_scratch:V4SI 3 ""))
5579 (clobber (match_scratch:V4SI 4 ""))
5580 (clobber (match_operand:DI 2 "memory_operand" ""))]
5581 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5582 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5583 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5585 && FP_REG_P (operands[0])"
5586 [(set (match_dup 2) (match_dup 3))
5587 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5589 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5590 Assemble the 64-bit DImode value in an xmm register. */
5591 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5592 gen_rtx_SUBREG (SImode, operands[1], 0)));
5593 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5594 gen_rtx_SUBREG (SImode, operands[1], 4)));
5595 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5598 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5602 [(set (match_operand:X87MODEF 0 "register_operand" "")
5603 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5604 (clobber (match_scratch:V4SI 3 ""))
5605 (clobber (match_scratch:V4SI 4 ""))
5606 (clobber (match_operand:DI 2 "memory_operand" ""))]
5607 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5608 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5609 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5611 && FP_REG_P (operands[0])"
5612 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5615 ;; Avoid store forwarding (partial memory) stall penalty by extending
5616 ;; SImode value to DImode through XMM register instead of pushing two
5617 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5618 ;; targets benefit from this optimization. Also note that fild
5619 ;; loads from memory only.
5621 (define_insn "*floatunssi<mode>2_1"
5622 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5623 (unsigned_float:X87MODEF
5624 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5625 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5626 (clobber (match_scratch:SI 3 "=X,x"))]
5628 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5631 [(set_attr "type" "multi")
5632 (set_attr "mode" "<MODE>")])
5635 [(set (match_operand:X87MODEF 0 "register_operand" "")
5636 (unsigned_float:X87MODEF
5637 (match_operand:SI 1 "register_operand" "")))
5638 (clobber (match_operand:DI 2 "memory_operand" ""))
5639 (clobber (match_scratch:SI 3 ""))]
5641 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5643 && reload_completed"
5644 [(set (match_dup 2) (match_dup 1))
5646 (float:X87MODEF (match_dup 2)))]
5647 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5650 [(set (match_operand:X87MODEF 0 "register_operand" "")
5651 (unsigned_float:X87MODEF
5652 (match_operand:SI 1 "memory_operand" "")))
5653 (clobber (match_operand:DI 2 "memory_operand" ""))
5654 (clobber (match_scratch:SI 3 ""))]
5656 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5658 && reload_completed"
5659 [(set (match_dup 2) (match_dup 3))
5661 (float:X87MODEF (match_dup 2)))]
5663 emit_move_insn (operands[3], operands[1]);
5664 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5667 (define_expand "floatunssi<mode>2"
5669 [(set (match_operand:X87MODEF 0 "register_operand" "")
5670 (unsigned_float:X87MODEF
5671 (match_operand:SI 1 "nonimmediate_operand" "")))
5672 (clobber (match_dup 2))
5673 (clobber (match_scratch:SI 3 ""))])]
5675 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5677 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5679 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5681 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5686 enum ix86_stack_slot slot = (virtuals_instantiated
5689 operands[2] = assign_386_stack_local (DImode, slot);
5693 (define_expand "floatunsdisf2"
5694 [(use (match_operand:SF 0 "register_operand" ""))
5695 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5696 "TARGET_64BIT && TARGET_SSE_MATH"
5697 "x86_emit_floatuns (operands); DONE;")
5699 (define_expand "floatunsdidf2"
5700 [(use (match_operand:DF 0 "register_operand" ""))
5701 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5702 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5703 && TARGET_SSE2 && TARGET_SSE_MATH"
5706 x86_emit_floatuns (operands);
5708 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5714 (define_expand "add<mode>3"
5715 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5716 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5717 (match_operand:SDWIM 2 "<general_operand>" "")))]
5719 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5721 (define_insn_and_split "*add<dwi>3_doubleword"
5722 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5724 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5725 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5726 (clobber (reg:CC FLAGS_REG))]
5727 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5730 [(parallel [(set (reg:CC FLAGS_REG)
5731 (unspec:CC [(match_dup 1) (match_dup 2)]
5734 (plus:DWIH (match_dup 1) (match_dup 2)))])
5735 (parallel [(set (match_dup 3)
5739 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5741 (clobber (reg:CC FLAGS_REG))])]
5742 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5744 (define_insn "*add<mode>3_cc"
5745 [(set (reg:CC FLAGS_REG)
5747 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5748 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5750 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5751 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5752 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5753 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5754 [(set_attr "type" "alu")
5755 (set_attr "mode" "<MODE>")])
5757 (define_insn "addqi3_cc"
5758 [(set (reg:CC FLAGS_REG)
5760 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5761 (match_operand:QI 2 "general_operand" "qn,qm")]
5763 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5764 (plus:QI (match_dup 1) (match_dup 2)))]
5765 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5766 "add{b}\t{%2, %0|%0, %2}"
5767 [(set_attr "type" "alu")
5768 (set_attr "mode" "QI")])
5770 (define_insn "*lea_1"
5771 [(set (match_operand:DWIH 0 "register_operand" "=r")
5772 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5774 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5775 [(set_attr "type" "lea")
5776 (set_attr "mode" "<MODE>")])
5778 (define_insn "*lea_2"
5779 [(set (match_operand:SI 0 "register_operand" "=r")
5780 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5782 "lea{l}\t{%a1, %0|%0, %a1}"
5783 [(set_attr "type" "lea")
5784 (set_attr "mode" "SI")])
5786 (define_insn "*lea_2_zext"
5787 [(set (match_operand:DI 0 "register_operand" "=r")
5789 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5791 "lea{l}\t{%a1, %k0|%k0, %a1}"
5792 [(set_attr "type" "lea")
5793 (set_attr "mode" "SI")])
5795 (define_insn "*add<mode>_1"
5796 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5798 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5799 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5800 (clobber (reg:CC FLAGS_REG))]
5801 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5803 switch (get_attr_type (insn))
5806 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5807 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
5810 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5811 if (operands[2] == const1_rtx)
5812 return "inc{<imodesuffix>}\t%0";
5815 gcc_assert (operands[2] == constm1_rtx);
5816 return "dec{<imodesuffix>}\t%0";
5820 /* Use add as much as possible to replace lea for AGU optimization. */
5821 if (which_alternative == 2 && TARGET_OPT_AGU)
5822 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
5824 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5825 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5826 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5828 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5832 (cond [(and (eq_attr "alternative" "2")
5833 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
5834 (const_string "lea")
5835 (eq_attr "alternative" "3")
5836 (const_string "lea")
5837 (match_operand:SWI48 2 "incdec_operand" "")
5838 (const_string "incdec")
5840 (const_string "alu")))
5841 (set (attr "length_immediate")
5843 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5845 (const_string "*")))
5846 (set_attr "mode" "<MODE>")])
5848 ;; It may seem that nonimmediate operand is proper one for operand 1.
5849 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5850 ;; we take care in ix86_binary_operator_ok to not allow two memory
5851 ;; operands so proper swapping will be done in reload. This allow
5852 ;; patterns constructed from addsi_1 to match.
5854 (define_insn "*addsi_1_zext"
5855 [(set (match_operand:DI 0 "register_operand" "=r,r")
5857 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5858 (match_operand:SI 2 "general_operand" "g,li"))))
5859 (clobber (reg:CC FLAGS_REG))]
5860 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5862 switch (get_attr_type (insn))
5865 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
5866 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5869 if (operands[2] == const1_rtx)
5870 return "inc{l}\t%k0";
5873 gcc_assert (operands[2] == constm1_rtx);
5874 return "dec{l}\t%k0";
5878 if (x86_maybe_negate_const_int (&operands[2], SImode))
5879 return "sub{l}\t{%2, %k0|%k0, %2}";
5881 return "add{l}\t{%2, %k0|%k0, %2}";
5885 (cond [(eq_attr "alternative" "1")
5886 (const_string "lea")
5887 (match_operand:SI 2 "incdec_operand" "")
5888 (const_string "incdec")
5890 (const_string "alu")))
5891 (set (attr "length_immediate")
5893 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5895 (const_string "*")))
5896 (set_attr "mode" "SI")])
5898 (define_insn "*addhi_1"
5899 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5900 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5901 (match_operand:HI 2 "general_operand" "rn,rm")))
5902 (clobber (reg:CC FLAGS_REG))]
5903 "TARGET_PARTIAL_REG_STALL
5904 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5906 switch (get_attr_type (insn))
5909 if (operands[2] == const1_rtx)
5910 return "inc{w}\t%0";
5913 gcc_assert (operands[2] == constm1_rtx);
5914 return "dec{w}\t%0";
5918 if (x86_maybe_negate_const_int (&operands[2], HImode))
5919 return "sub{w}\t{%2, %0|%0, %2}";
5921 return "add{w}\t{%2, %0|%0, %2}";
5925 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5926 (const_string "incdec")
5927 (const_string "alu")))
5928 (set (attr "length_immediate")
5930 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5932 (const_string "*")))
5933 (set_attr "mode" "HI")])
5935 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5936 ;; type optimizations enabled by define-splits. This is not important
5937 ;; for PII, and in fact harmful because of partial register stalls.
5939 (define_insn "*addhi_1_lea"
5940 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5941 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5942 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
5943 (clobber (reg:CC FLAGS_REG))]
5944 "!TARGET_PARTIAL_REG_STALL
5945 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5947 switch (get_attr_type (insn))
5953 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5954 if (operands[2] == const1_rtx)
5955 return "inc{w}\t%0";
5958 gcc_assert (operands[2] == constm1_rtx);
5959 return "dec{w}\t%0";
5963 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5964 if (x86_maybe_negate_const_int (&operands[2], HImode))
5965 return "sub{w}\t{%2, %0|%0, %2}";
5967 return "add{w}\t{%2, %0|%0, %2}";
5971 (if_then_else (eq_attr "alternative" "2")
5972 (const_string "lea")
5973 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5974 (const_string "incdec")
5975 (const_string "alu"))))
5976 (set (attr "length_immediate")
5978 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5980 (const_string "*")))
5981 (set_attr "mode" "HI,HI,SI")])
5983 (define_insn "*addqi_1"
5984 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5985 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5986 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5987 (clobber (reg:CC FLAGS_REG))]
5988 "TARGET_PARTIAL_REG_STALL
5989 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5991 int widen = (which_alternative == 2);
5992 switch (get_attr_type (insn))
5995 if (operands[2] == const1_rtx)
5996 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5999 gcc_assert (operands[2] == constm1_rtx);
6000 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6004 if (x86_maybe_negate_const_int (&operands[2], QImode))
6007 return "sub{l}\t{%2, %k0|%k0, %2}";
6009 return "sub{b}\t{%2, %0|%0, %2}";
6012 return "add{l}\t{%k2, %k0|%k0, %k2}";
6014 return "add{b}\t{%2, %0|%0, %2}";
6018 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6019 (const_string "incdec")
6020 (const_string "alu")))
6021 (set (attr "length_immediate")
6023 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6025 (const_string "*")))
6026 (set_attr "mode" "QI,QI,SI")])
6028 ;; %%% Potential partial reg stall on alternative 2. What to do?
6029 (define_insn "*addqi_1_lea"
6030 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6031 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6032 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6033 (clobber (reg:CC FLAGS_REG))]
6034 "!TARGET_PARTIAL_REG_STALL
6035 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6037 int widen = (which_alternative == 2);
6038 switch (get_attr_type (insn))
6044 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6045 if (operands[2] == const1_rtx)
6046 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6049 gcc_assert (operands[2] == constm1_rtx);
6050 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6054 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6055 if (x86_maybe_negate_const_int (&operands[2], QImode))
6058 return "sub{l}\t{%2, %k0|%k0, %2}";
6060 return "sub{b}\t{%2, %0|%0, %2}";
6063 return "add{l}\t{%k2, %k0|%k0, %k2}";
6065 return "add{b}\t{%2, %0|%0, %2}";
6069 (if_then_else (eq_attr "alternative" "3")
6070 (const_string "lea")
6071 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6072 (const_string "incdec")
6073 (const_string "alu"))))
6074 (set (attr "length_immediate")
6076 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6078 (const_string "*")))
6079 (set_attr "mode" "QI,QI,SI,SI")])
6081 (define_insn "*addqi_1_slp"
6082 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6083 (plus:QI (match_dup 0)
6084 (match_operand:QI 1 "general_operand" "qn,qnm")))
6085 (clobber (reg:CC FLAGS_REG))]
6086 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6087 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6089 switch (get_attr_type (insn))
6092 if (operands[1] == const1_rtx)
6093 return "inc{b}\t%0";
6096 gcc_assert (operands[1] == constm1_rtx);
6097 return "dec{b}\t%0";
6101 if (x86_maybe_negate_const_int (&operands[1], QImode))
6102 return "sub{b}\t{%1, %0|%0, %1}";
6104 return "add{b}\t{%1, %0|%0, %1}";
6108 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6109 (const_string "incdec")
6110 (const_string "alu1")))
6111 (set (attr "memory")
6112 (if_then_else (match_operand 1 "memory_operand" "")
6113 (const_string "load")
6114 (const_string "none")))
6115 (set_attr "mode" "QI")])
6117 (define_insn "*add<mode>_2"
6118 [(set (reg FLAGS_REG)
6121 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6122 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6124 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6125 (plus:SWI (match_dup 1) (match_dup 2)))]
6126 "ix86_match_ccmode (insn, CCGOCmode)
6127 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6129 switch (get_attr_type (insn))
6132 if (operands[2] == const1_rtx)
6133 return "inc{<imodesuffix>}\t%0";
6136 gcc_assert (operands[2] == constm1_rtx);
6137 return "dec{<imodesuffix>}\t%0";
6141 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6142 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6144 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6148 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6149 (const_string "incdec")
6150 (const_string "alu")))
6151 (set (attr "length_immediate")
6153 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6155 (const_string "*")))
6156 (set_attr "mode" "<MODE>")])
6158 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6159 (define_insn "*addsi_2_zext"
6160 [(set (reg FLAGS_REG)
6162 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6163 (match_operand:SI 2 "general_operand" "g"))
6165 (set (match_operand:DI 0 "register_operand" "=r")
6166 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6167 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6168 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6170 switch (get_attr_type (insn))
6173 if (operands[2] == const1_rtx)
6174 return "inc{l}\t%k0";
6177 gcc_assert (operands[2] == constm1_rtx);
6178 return "dec{l}\t%k0";
6182 if (x86_maybe_negate_const_int (&operands[2], SImode))
6183 return "sub{l}\t{%2, %k0|%k0, %2}";
6185 return "add{l}\t{%2, %k0|%k0, %2}";
6189 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6190 (const_string "incdec")
6191 (const_string "alu")))
6192 (set (attr "length_immediate")
6194 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6196 (const_string "*")))
6197 (set_attr "mode" "SI")])
6199 (define_insn "*add<mode>_3"
6200 [(set (reg FLAGS_REG)
6202 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6203 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6204 (clobber (match_scratch:SWI 0 "=<r>"))]
6205 "ix86_match_ccmode (insn, CCZmode)
6206 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6208 switch (get_attr_type (insn))
6211 if (operands[2] == const1_rtx)
6212 return "inc{<imodesuffix>}\t%0";
6215 gcc_assert (operands[2] == constm1_rtx);
6216 return "dec{<imodesuffix>}\t%0";
6220 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6221 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6223 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6227 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6228 (const_string "incdec")
6229 (const_string "alu")))
6230 (set (attr "length_immediate")
6232 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6234 (const_string "*")))
6235 (set_attr "mode" "<MODE>")])
6237 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6238 (define_insn "*addsi_3_zext"
6239 [(set (reg FLAGS_REG)
6241 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6242 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6243 (set (match_operand:DI 0 "register_operand" "=r")
6244 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6245 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6246 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6248 switch (get_attr_type (insn))
6251 if (operands[2] == const1_rtx)
6252 return "inc{l}\t%k0";
6255 gcc_assert (operands[2] == constm1_rtx);
6256 return "dec{l}\t%k0";
6260 if (x86_maybe_negate_const_int (&operands[2], SImode))
6261 return "sub{l}\t{%2, %k0|%k0, %2}";
6263 return "add{l}\t{%2, %k0|%k0, %2}";
6267 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6268 (const_string "incdec")
6269 (const_string "alu")))
6270 (set (attr "length_immediate")
6272 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6274 (const_string "*")))
6275 (set_attr "mode" "SI")])
6277 ; For comparisons against 1, -1 and 128, we may generate better code
6278 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6279 ; is matched then. We can't accept general immediate, because for
6280 ; case of overflows, the result is messed up.
6281 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6282 ; only for comparisons not depending on it.
6284 (define_insn "*adddi_4"
6285 [(set (reg FLAGS_REG)
6287 (match_operand:DI 1 "nonimmediate_operand" "0")
6288 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6289 (clobber (match_scratch:DI 0 "=rm"))]
6291 && ix86_match_ccmode (insn, CCGCmode)"
6293 switch (get_attr_type (insn))
6296 if (operands[2] == constm1_rtx)
6297 return "inc{q}\t%0";
6300 gcc_assert (operands[2] == const1_rtx);
6301 return "dec{q}\t%0";
6305 if (x86_maybe_negate_const_int (&operands[2], DImode))
6306 return "add{q}\t{%2, %0|%0, %2}";
6308 return "sub{q}\t{%2, %0|%0, %2}";
6312 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6313 (const_string "incdec")
6314 (const_string "alu")))
6315 (set (attr "length_immediate")
6317 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6319 (const_string "*")))
6320 (set_attr "mode" "DI")])
6322 ; For comparisons against 1, -1 and 128, we may generate better code
6323 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6324 ; is matched then. We can't accept general immediate, because for
6325 ; case of overflows, the result is messed up.
6326 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6327 ; only for comparisons not depending on it.
6329 (define_insn "*add<mode>_4"
6330 [(set (reg FLAGS_REG)
6332 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6333 (match_operand:SWI124 2 "const_int_operand" "n")))
6334 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6335 "ix86_match_ccmode (insn, CCGCmode)"
6337 switch (get_attr_type (insn))
6340 if (operands[2] == constm1_rtx)
6341 return "inc{<imodesuffix>}\t%0";
6344 gcc_assert (operands[2] == const1_rtx);
6345 return "dec{<imodesuffix>}\t%0";
6349 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6350 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6352 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6356 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6357 (const_string "incdec")
6358 (const_string "alu")))
6359 (set (attr "length_immediate")
6361 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6363 (const_string "*")))
6364 (set_attr "mode" "<MODE>")])
6366 (define_insn "*add<mode>_5"
6367 [(set (reg FLAGS_REG)
6370 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6371 (match_operand:SWI 2 "<general_operand>" "<g>"))
6373 (clobber (match_scratch:SWI 0 "=<r>"))]
6374 "ix86_match_ccmode (insn, CCGOCmode)
6375 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6377 switch (get_attr_type (insn))
6380 if (operands[2] == const1_rtx)
6381 return "inc{<imodesuffix>}\t%0";
6384 gcc_assert (operands[2] == constm1_rtx);
6385 return "dec{<imodesuffix>}\t%0";
6389 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6390 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6392 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6396 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6397 (const_string "incdec")
6398 (const_string "alu")))
6399 (set (attr "length_immediate")
6401 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6403 (const_string "*")))
6404 (set_attr "mode" "<MODE>")])
6406 (define_insn "*addqi_ext_1_rex64"
6407 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6412 (match_operand 1 "ext_register_operand" "0")
6415 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6416 (clobber (reg:CC FLAGS_REG))]
6419 switch (get_attr_type (insn))
6422 if (operands[2] == const1_rtx)
6423 return "inc{b}\t%h0";
6426 gcc_assert (operands[2] == constm1_rtx);
6427 return "dec{b}\t%h0";
6431 return "add{b}\t{%2, %h0|%h0, %2}";
6435 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6436 (const_string "incdec")
6437 (const_string "alu")))
6438 (set_attr "modrm" "1")
6439 (set_attr "mode" "QI")])
6441 (define_insn "addqi_ext_1"
6442 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6447 (match_operand 1 "ext_register_operand" "0")
6450 (match_operand:QI 2 "general_operand" "Qmn")))
6451 (clobber (reg:CC FLAGS_REG))]
6454 switch (get_attr_type (insn))
6457 if (operands[2] == const1_rtx)
6458 return "inc{b}\t%h0";
6461 gcc_assert (operands[2] == constm1_rtx);
6462 return "dec{b}\t%h0";
6466 return "add{b}\t{%2, %h0|%h0, %2}";
6470 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6471 (const_string "incdec")
6472 (const_string "alu")))
6473 (set_attr "modrm" "1")
6474 (set_attr "mode" "QI")])
6476 (define_insn "*addqi_ext_2"
6477 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6482 (match_operand 1 "ext_register_operand" "%0")
6486 (match_operand 2 "ext_register_operand" "Q")
6489 (clobber (reg:CC FLAGS_REG))]
6491 "add{b}\t{%h2, %h0|%h0, %h2}"
6492 [(set_attr "type" "alu")
6493 (set_attr "mode" "QI")])
6495 ;; The lea patterns for non-Pmodes needs to be matched by
6496 ;; several insns converted to real lea by splitters.
6498 (define_insn_and_split "*lea_general_1"
6499 [(set (match_operand 0 "register_operand" "=r")
6500 (plus (plus (match_operand 1 "index_register_operand" "l")
6501 (match_operand 2 "register_operand" "r"))
6502 (match_operand 3 "immediate_operand" "i")))]
6503 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6504 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6505 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6506 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6507 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6508 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6509 || GET_MODE (operands[3]) == VOIDmode)"
6511 "&& reload_completed"
6515 operands[0] = gen_lowpart (SImode, operands[0]);
6516 operands[1] = gen_lowpart (Pmode, operands[1]);
6517 operands[2] = gen_lowpart (Pmode, operands[2]);
6518 operands[3] = gen_lowpart (Pmode, operands[3]);
6519 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6521 if (Pmode != SImode)
6522 pat = gen_rtx_SUBREG (SImode, pat, 0);
6523 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6526 [(set_attr "type" "lea")
6527 (set_attr "mode" "SI")])
6529 (define_insn_and_split "*lea_general_1_zext"
6530 [(set (match_operand:DI 0 "register_operand" "=r")
6533 (match_operand:SI 1 "index_register_operand" "l")
6534 (match_operand:SI 2 "register_operand" "r"))
6535 (match_operand:SI 3 "immediate_operand" "i"))))]
6538 "&& reload_completed"
6540 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6542 (match_dup 3)) 0)))]
6544 operands[1] = gen_lowpart (Pmode, operands[1]);
6545 operands[2] = gen_lowpart (Pmode, operands[2]);
6546 operands[3] = gen_lowpart (Pmode, operands[3]);
6548 [(set_attr "type" "lea")
6549 (set_attr "mode" "SI")])
6551 (define_insn_and_split "*lea_general_2"
6552 [(set (match_operand 0 "register_operand" "=r")
6553 (plus (mult (match_operand 1 "index_register_operand" "l")
6554 (match_operand 2 "const248_operand" "i"))
6555 (match_operand 3 "nonmemory_operand" "ri")))]
6556 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6557 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6558 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6559 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6560 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6561 || GET_MODE (operands[3]) == VOIDmode)"
6563 "&& reload_completed"
6567 operands[0] = gen_lowpart (SImode, operands[0]);
6568 operands[1] = gen_lowpart (Pmode, operands[1]);
6569 operands[3] = gen_lowpart (Pmode, operands[3]);
6570 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6572 if (Pmode != SImode)
6573 pat = gen_rtx_SUBREG (SImode, pat, 0);
6574 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6577 [(set_attr "type" "lea")
6578 (set_attr "mode" "SI")])
6580 (define_insn_and_split "*lea_general_2_zext"
6581 [(set (match_operand:DI 0 "register_operand" "=r")
6584 (match_operand:SI 1 "index_register_operand" "l")
6585 (match_operand:SI 2 "const248_operand" "n"))
6586 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6589 "&& reload_completed"
6591 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6593 (match_dup 3)) 0)))]
6595 operands[1] = gen_lowpart (Pmode, operands[1]);
6596 operands[3] = gen_lowpart (Pmode, operands[3]);
6598 [(set_attr "type" "lea")
6599 (set_attr "mode" "SI")])
6601 (define_insn_and_split "*lea_general_3"
6602 [(set (match_operand 0 "register_operand" "=r")
6603 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6604 (match_operand 2 "const248_operand" "i"))
6605 (match_operand 3 "register_operand" "r"))
6606 (match_operand 4 "immediate_operand" "i")))]
6607 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6608 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6609 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6610 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6611 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6613 "&& reload_completed"
6617 operands[0] = gen_lowpart (SImode, operands[0]);
6618 operands[1] = gen_lowpart (Pmode, operands[1]);
6619 operands[3] = gen_lowpart (Pmode, operands[3]);
6620 operands[4] = gen_lowpart (Pmode, operands[4]);
6621 pat = gen_rtx_PLUS (Pmode,
6622 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6626 if (Pmode != SImode)
6627 pat = gen_rtx_SUBREG (SImode, pat, 0);
6628 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6631 [(set_attr "type" "lea")
6632 (set_attr "mode" "SI")])
6634 (define_insn_and_split "*lea_general_3_zext"
6635 [(set (match_operand:DI 0 "register_operand" "=r")
6639 (match_operand:SI 1 "index_register_operand" "l")
6640 (match_operand:SI 2 "const248_operand" "n"))
6641 (match_operand:SI 3 "register_operand" "r"))
6642 (match_operand:SI 4 "immediate_operand" "i"))))]
6645 "&& reload_completed"
6647 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6650 (match_dup 4)) 0)))]
6652 operands[1] = gen_lowpart (Pmode, operands[1]);
6653 operands[3] = gen_lowpart (Pmode, operands[3]);
6654 operands[4] = gen_lowpart (Pmode, operands[4]);
6656 [(set_attr "type" "lea")
6657 (set_attr "mode" "SI")])
6659 ;; Convert lea to the lea pattern to avoid flags dependency.
6661 [(set (match_operand:DI 0 "register_operand" "")
6662 (plus:DI (match_operand:DI 1 "register_operand" "")
6663 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6664 (clobber (reg:CC FLAGS_REG))]
6665 "TARGET_64BIT && reload_completed
6666 && ix86_lea_for_add_ok (PLUS, insn, operands)"
6668 (plus:DI (match_dup 1)
6672 ;; Convert lea to the lea pattern to avoid flags dependency.
6674 [(set (match_operand 0 "register_operand" "")
6675 (plus (match_operand 1 "register_operand" "")
6676 (match_operand 2 "nonmemory_operand" "")))
6677 (clobber (reg:CC FLAGS_REG))]
6678 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
6682 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6683 may confuse gen_lowpart. */
6684 if (GET_MODE (operands[0]) != Pmode)
6686 operands[1] = gen_lowpart (Pmode, operands[1]);
6687 operands[2] = gen_lowpart (Pmode, operands[2]);
6689 operands[0] = gen_lowpart (SImode, operands[0]);
6690 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6691 if (Pmode != SImode)
6692 pat = gen_rtx_SUBREG (SImode, pat, 0);
6693 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6697 ;; Convert lea to the lea pattern to avoid flags dependency.
6699 [(set (match_operand:DI 0 "register_operand" "")
6701 (plus:SI (match_operand:SI 1 "register_operand" "")
6702 (match_operand:SI 2 "nonmemory_operand" ""))))
6703 (clobber (reg:CC FLAGS_REG))]
6704 "TARGET_64BIT && reload_completed
6705 && true_regnum (operands[0]) != true_regnum (operands[1])"
6707 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6709 operands[1] = gen_lowpart (Pmode, operands[1]);
6710 operands[2] = gen_lowpart (Pmode, operands[2]);
6713 ;; Subtract instructions
6715 (define_expand "sub<mode>3"
6716 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6717 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6718 (match_operand:SDWIM 2 "<general_operand>" "")))]
6720 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6722 (define_insn_and_split "*sub<dwi>3_doubleword"
6723 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6725 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6726 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6727 (clobber (reg:CC FLAGS_REG))]
6728 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6731 [(parallel [(set (reg:CC FLAGS_REG)
6732 (compare:CC (match_dup 1) (match_dup 2)))
6734 (minus:DWIH (match_dup 1) (match_dup 2)))])
6735 (parallel [(set (match_dup 3)
6739 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6741 (clobber (reg:CC FLAGS_REG))])]
6742 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6744 (define_insn "*sub<mode>_1"
6745 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6747 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6748 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6749 (clobber (reg:CC FLAGS_REG))]
6750 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6751 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6752 [(set_attr "type" "alu")
6753 (set_attr "mode" "<MODE>")])
6755 (define_insn "*subsi_1_zext"
6756 [(set (match_operand:DI 0 "register_operand" "=r")
6758 (minus:SI (match_operand:SI 1 "register_operand" "0")
6759 (match_operand:SI 2 "general_operand" "g"))))
6760 (clobber (reg:CC FLAGS_REG))]
6761 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6762 "sub{l}\t{%2, %k0|%k0, %2}"
6763 [(set_attr "type" "alu")
6764 (set_attr "mode" "SI")])
6766 (define_insn "*subqi_1_slp"
6767 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6768 (minus:QI (match_dup 0)
6769 (match_operand:QI 1 "general_operand" "qn,qm")))
6770 (clobber (reg:CC FLAGS_REG))]
6771 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6772 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6773 "sub{b}\t{%1, %0|%0, %1}"
6774 [(set_attr "type" "alu1")
6775 (set_attr "mode" "QI")])
6777 (define_insn "*sub<mode>_2"
6778 [(set (reg FLAGS_REG)
6781 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6782 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6784 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6785 (minus:SWI (match_dup 1) (match_dup 2)))]
6786 "ix86_match_ccmode (insn, CCGOCmode)
6787 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6788 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6789 [(set_attr "type" "alu")
6790 (set_attr "mode" "<MODE>")])
6792 (define_insn "*subsi_2_zext"
6793 [(set (reg FLAGS_REG)
6795 (minus:SI (match_operand:SI 1 "register_operand" "0")
6796 (match_operand:SI 2 "general_operand" "g"))
6798 (set (match_operand:DI 0 "register_operand" "=r")
6800 (minus:SI (match_dup 1)
6802 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6803 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6804 "sub{l}\t{%2, %k0|%k0, %2}"
6805 [(set_attr "type" "alu")
6806 (set_attr "mode" "SI")])
6808 (define_insn "*sub<mode>_3"
6809 [(set (reg FLAGS_REG)
6810 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6811 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6812 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6813 (minus:SWI (match_dup 1) (match_dup 2)))]
6814 "ix86_match_ccmode (insn, CCmode)
6815 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6816 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6817 [(set_attr "type" "alu")
6818 (set_attr "mode" "<MODE>")])
6820 (define_insn "*subsi_3_zext"
6821 [(set (reg FLAGS_REG)
6822 (compare (match_operand:SI 1 "register_operand" "0")
6823 (match_operand:SI 2 "general_operand" "g")))
6824 (set (match_operand:DI 0 "register_operand" "=r")
6826 (minus:SI (match_dup 1)
6828 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6829 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6830 "sub{l}\t{%2, %1|%1, %2}"
6831 [(set_attr "type" "alu")
6832 (set_attr "mode" "SI")])
6834 ;; Add with carry and subtract with borrow
6836 (define_expand "<plusminus_insn><mode>3_carry"
6838 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6840 (match_operand:SWI 1 "nonimmediate_operand" "")
6841 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6842 [(match_operand 3 "flags_reg_operand" "")
6844 (match_operand:SWI 2 "<general_operand>" ""))))
6845 (clobber (reg:CC FLAGS_REG))])]
6846 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6849 (define_insn "*<plusminus_insn><mode>3_carry"
6850 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6852 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6854 (match_operator 3 "ix86_carry_flag_operator"
6855 [(reg FLAGS_REG) (const_int 0)])
6856 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6857 (clobber (reg:CC FLAGS_REG))]
6858 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6859 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6860 [(set_attr "type" "alu")
6861 (set_attr "use_carry" "1")
6862 (set_attr "pent_pair" "pu")
6863 (set_attr "mode" "<MODE>")])
6865 (define_insn "*addsi3_carry_zext"
6866 [(set (match_operand:DI 0 "register_operand" "=r")
6868 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6869 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6870 [(reg FLAGS_REG) (const_int 0)])
6871 (match_operand:SI 2 "general_operand" "g")))))
6872 (clobber (reg:CC FLAGS_REG))]
6873 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6874 "adc{l}\t{%2, %k0|%k0, %2}"
6875 [(set_attr "type" "alu")
6876 (set_attr "use_carry" "1")
6877 (set_attr "pent_pair" "pu")
6878 (set_attr "mode" "SI")])
6880 (define_insn "*subsi3_carry_zext"
6881 [(set (match_operand:DI 0 "register_operand" "=r")
6883 (minus:SI (match_operand:SI 1 "register_operand" "0")
6884 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6885 [(reg FLAGS_REG) (const_int 0)])
6886 (match_operand:SI 2 "general_operand" "g")))))
6887 (clobber (reg:CC FLAGS_REG))]
6888 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6889 "sbb{l}\t{%2, %k0|%k0, %2}"
6890 [(set_attr "type" "alu")
6891 (set_attr "pent_pair" "pu")
6892 (set_attr "mode" "SI")])
6894 ;; Overflow setting add and subtract instructions
6896 (define_insn "*add<mode>3_cconly_overflow"
6897 [(set (reg:CCC FLAGS_REG)
6900 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6901 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
6903 (clobber (match_scratch:SWI 0 "=<r>"))]
6904 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6905 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6906 [(set_attr "type" "alu")
6907 (set_attr "mode" "<MODE>")])
6909 (define_insn "*sub<mode>3_cconly_overflow"
6910 [(set (reg:CCC FLAGS_REG)
6913 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6914 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6917 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6918 [(set_attr "type" "icmp")
6919 (set_attr "mode" "<MODE>")])
6921 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6922 [(set (reg:CCC FLAGS_REG)
6925 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6926 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6928 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6929 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6930 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6931 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6932 [(set_attr "type" "alu")
6933 (set_attr "mode" "<MODE>")])
6935 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6936 [(set (reg:CCC FLAGS_REG)
6939 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6940 (match_operand:SI 2 "general_operand" "g"))
6942 (set (match_operand:DI 0 "register_operand" "=r")
6943 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6944 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6945 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6946 [(set_attr "type" "alu")
6947 (set_attr "mode" "SI")])
6949 ;; The patterns that match these are at the end of this file.
6951 (define_expand "<plusminus_insn>xf3"
6952 [(set (match_operand:XF 0 "register_operand" "")
6954 (match_operand:XF 1 "register_operand" "")
6955 (match_operand:XF 2 "register_operand" "")))]
6959 (define_expand "<plusminus_insn><mode>3"
6960 [(set (match_operand:MODEF 0 "register_operand" "")
6962 (match_operand:MODEF 1 "register_operand" "")
6963 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6964 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6965 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6968 ;; Multiply instructions
6970 (define_expand "mul<mode>3"
6971 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6973 (match_operand:SWIM248 1 "register_operand" "")
6974 (match_operand:SWIM248 2 "<general_operand>" "")))
6975 (clobber (reg:CC FLAGS_REG))])]
6979 (define_expand "mulqi3"
6980 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6982 (match_operand:QI 1 "register_operand" "")
6983 (match_operand:QI 2 "nonimmediate_operand" "")))
6984 (clobber (reg:CC FLAGS_REG))])]
6985 "TARGET_QIMODE_MATH"
6989 ;; IMUL reg32/64, reg32/64, imm8 Direct
6990 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6991 ;; IMUL reg32/64, reg32/64, imm32 Direct
6992 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6993 ;; IMUL reg32/64, reg32/64 Direct
6994 ;; IMUL reg32/64, mem32/64 Direct
6996 (define_insn "*mul<mode>3_1"
6997 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6999 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7000 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7001 (clobber (reg:CC FLAGS_REG))]
7002 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7004 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7005 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7006 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7007 [(set_attr "type" "imul")
7008 (set_attr "prefix_0f" "0,0,1")
7009 (set (attr "athlon_decode")
7010 (cond [(eq_attr "cpu" "athlon")
7011 (const_string "vector")
7012 (eq_attr "alternative" "1")
7013 (const_string "vector")
7014 (and (eq_attr "alternative" "2")
7015 (match_operand 1 "memory_operand" ""))
7016 (const_string "vector")]
7017 (const_string "direct")))
7018 (set (attr "amdfam10_decode")
7019 (cond [(and (eq_attr "alternative" "0,1")
7020 (match_operand 1 "memory_operand" ""))
7021 (const_string "vector")]
7022 (const_string "direct")))
7023 (set_attr "mode" "<MODE>")])
7025 (define_insn "*mulsi3_1_zext"
7026 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7028 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7029 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7030 (clobber (reg:CC FLAGS_REG))]
7032 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7034 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7035 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7036 imul{l}\t{%2, %k0|%k0, %2}"
7037 [(set_attr "type" "imul")
7038 (set_attr "prefix_0f" "0,0,1")
7039 (set (attr "athlon_decode")
7040 (cond [(eq_attr "cpu" "athlon")
7041 (const_string "vector")
7042 (eq_attr "alternative" "1")
7043 (const_string "vector")
7044 (and (eq_attr "alternative" "2")
7045 (match_operand 1 "memory_operand" ""))
7046 (const_string "vector")]
7047 (const_string "direct")))
7048 (set (attr "amdfam10_decode")
7049 (cond [(and (eq_attr "alternative" "0,1")
7050 (match_operand 1 "memory_operand" ""))
7051 (const_string "vector")]
7052 (const_string "direct")))
7053 (set_attr "mode" "SI")])
7056 ;; IMUL reg16, reg16, imm8 VectorPath
7057 ;; IMUL reg16, mem16, imm8 VectorPath
7058 ;; IMUL reg16, reg16, imm16 VectorPath
7059 ;; IMUL reg16, mem16, imm16 VectorPath
7060 ;; IMUL reg16, reg16 Direct
7061 ;; IMUL reg16, mem16 Direct
7063 (define_insn "*mulhi3_1"
7064 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7065 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7066 (match_operand:HI 2 "general_operand" "K,n,mr")))
7067 (clobber (reg:CC FLAGS_REG))]
7069 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7071 imul{w}\t{%2, %1, %0|%0, %1, %2}
7072 imul{w}\t{%2, %1, %0|%0, %1, %2}
7073 imul{w}\t{%2, %0|%0, %2}"
7074 [(set_attr "type" "imul")
7075 (set_attr "prefix_0f" "0,0,1")
7076 (set (attr "athlon_decode")
7077 (cond [(eq_attr "cpu" "athlon")
7078 (const_string "vector")
7079 (eq_attr "alternative" "1,2")
7080 (const_string "vector")]
7081 (const_string "direct")))
7082 (set (attr "amdfam10_decode")
7083 (cond [(eq_attr "alternative" "0,1")
7084 (const_string "vector")]
7085 (const_string "direct")))
7086 (set_attr "mode" "HI")])
7092 (define_insn "*mulqi3_1"
7093 [(set (match_operand:QI 0 "register_operand" "=a")
7094 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7095 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7096 (clobber (reg:CC FLAGS_REG))]
7098 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7100 [(set_attr "type" "imul")
7101 (set_attr "length_immediate" "0")
7102 (set (attr "athlon_decode")
7103 (if_then_else (eq_attr "cpu" "athlon")
7104 (const_string "vector")
7105 (const_string "direct")))
7106 (set_attr "amdfam10_decode" "direct")
7107 (set_attr "mode" "QI")])
7109 (define_expand "<u>mul<mode><dwi>3"
7110 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7113 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7115 (match_operand:DWIH 2 "register_operand" ""))))
7116 (clobber (reg:CC FLAGS_REG))])]
7120 (define_expand "<u>mulqihi3"
7121 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7124 (match_operand:QI 1 "nonimmediate_operand" ""))
7126 (match_operand:QI 2 "register_operand" ""))))
7127 (clobber (reg:CC FLAGS_REG))])]
7128 "TARGET_QIMODE_MATH"
7131 (define_insn "*<u>mul<mode><dwi>3_1"
7132 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7135 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7137 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7138 (clobber (reg:CC FLAGS_REG))]
7139 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7140 "<sgnprefix>mul{<imodesuffix>}\t%2"
7141 [(set_attr "type" "imul")
7142 (set_attr "length_immediate" "0")
7143 (set (attr "athlon_decode")
7144 (if_then_else (eq_attr "cpu" "athlon")
7145 (const_string "vector")
7146 (const_string "double")))
7147 (set_attr "amdfam10_decode" "double")
7148 (set_attr "mode" "<MODE>")])
7150 (define_insn "*<u>mulqihi3_1"
7151 [(set (match_operand:HI 0 "register_operand" "=a")
7154 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7156 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7157 (clobber (reg:CC FLAGS_REG))]
7159 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7160 "<sgnprefix>mul{b}\t%2"
7161 [(set_attr "type" "imul")
7162 (set_attr "length_immediate" "0")
7163 (set (attr "athlon_decode")
7164 (if_then_else (eq_attr "cpu" "athlon")
7165 (const_string "vector")
7166 (const_string "direct")))
7167 (set_attr "amdfam10_decode" "direct")
7168 (set_attr "mode" "QI")])
7170 (define_expand "<s>mul<mode>3_highpart"
7171 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7176 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7178 (match_operand:SWI48 2 "register_operand" "")))
7180 (clobber (match_scratch:SWI48 3 ""))
7181 (clobber (reg:CC FLAGS_REG))])]
7183 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7185 (define_insn "*<s>muldi3_highpart_1"
7186 [(set (match_operand:DI 0 "register_operand" "=d")
7191 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7193 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7195 (clobber (match_scratch:DI 3 "=1"))
7196 (clobber (reg:CC FLAGS_REG))]
7198 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7199 "<sgnprefix>mul{q}\t%2"
7200 [(set_attr "type" "imul")
7201 (set_attr "length_immediate" "0")
7202 (set (attr "athlon_decode")
7203 (if_then_else (eq_attr "cpu" "athlon")
7204 (const_string "vector")
7205 (const_string "double")))
7206 (set_attr "amdfam10_decode" "double")
7207 (set_attr "mode" "DI")])
7209 (define_insn "*<s>mulsi3_highpart_1"
7210 [(set (match_operand:SI 0 "register_operand" "=d")
7215 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7217 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7219 (clobber (match_scratch:SI 3 "=1"))
7220 (clobber (reg:CC FLAGS_REG))]
7221 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7222 "<sgnprefix>mul{l}\t%2"
7223 [(set_attr "type" "imul")
7224 (set_attr "length_immediate" "0")
7225 (set (attr "athlon_decode")
7226 (if_then_else (eq_attr "cpu" "athlon")
7227 (const_string "vector")
7228 (const_string "double")))
7229 (set_attr "amdfam10_decode" "double")
7230 (set_attr "mode" "SI")])
7232 (define_insn "*<s>mulsi3_highpart_zext"
7233 [(set (match_operand:DI 0 "register_operand" "=d")
7234 (zero_extend:DI (truncate:SI
7236 (mult:DI (any_extend:DI
7237 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7239 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7241 (clobber (match_scratch:SI 3 "=1"))
7242 (clobber (reg:CC FLAGS_REG))]
7244 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7245 "<sgnprefix>mul{l}\t%2"
7246 [(set_attr "type" "imul")
7247 (set_attr "length_immediate" "0")
7248 (set (attr "athlon_decode")
7249 (if_then_else (eq_attr "cpu" "athlon")
7250 (const_string "vector")
7251 (const_string "double")))
7252 (set_attr "amdfam10_decode" "double")
7253 (set_attr "mode" "SI")])
7255 ;; The patterns that match these are at the end of this file.
7257 (define_expand "mulxf3"
7258 [(set (match_operand:XF 0 "register_operand" "")
7259 (mult:XF (match_operand:XF 1 "register_operand" "")
7260 (match_operand:XF 2 "register_operand" "")))]
7264 (define_expand "mul<mode>3"
7265 [(set (match_operand:MODEF 0 "register_operand" "")
7266 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7267 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7268 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7269 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7272 ;; Divide instructions
7274 ;; The patterns that match these are at the end of this file.
7276 (define_expand "divxf3"
7277 [(set (match_operand:XF 0 "register_operand" "")
7278 (div:XF (match_operand:XF 1 "register_operand" "")
7279 (match_operand:XF 2 "register_operand" "")))]
7283 (define_expand "divdf3"
7284 [(set (match_operand:DF 0 "register_operand" "")
7285 (div:DF (match_operand:DF 1 "register_operand" "")
7286 (match_operand:DF 2 "nonimmediate_operand" "")))]
7287 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7288 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7291 (define_expand "divsf3"
7292 [(set (match_operand:SF 0 "register_operand" "")
7293 (div:SF (match_operand:SF 1 "register_operand" "")
7294 (match_operand:SF 2 "nonimmediate_operand" "")))]
7295 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7298 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7299 && flag_finite_math_only && !flag_trapping_math
7300 && flag_unsafe_math_optimizations)
7302 ix86_emit_swdivsf (operands[0], operands[1],
7303 operands[2], SFmode);
7308 ;; Divmod instructions.
7310 (define_expand "<u>divmodqi4"
7311 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7313 (match_operand:QI 1 "register_operand" "")
7314 (match_operand:QI 2 "nonimmediate_operand" "")))
7315 (set (match_operand:QI 3 "register_operand" "")
7316 (mod:QI (match_dup 1) (match_dup 2)))
7317 (clobber (reg:CC FLAGS_REG))])]
7318 "TARGET_QIMODE_MATH"
7323 tmp0 = gen_reg_rtx (HImode);
7324 tmp1 = gen_reg_rtx (HImode);
7326 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7328 if (<extract_code> == SIGN_EXTRACT)
7330 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7331 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7333 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7334 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7336 tmp1 = gen_rtx_<extract_code> (QImode, tmp0,
7337 GEN_INT (8), GEN_INT (8));
7341 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7342 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7344 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7345 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7347 tmp1 = gen_rtx_<extract_code> (SImode, tmp0,
7348 GEN_INT (8), GEN_INT (8));
7349 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7352 /* Extract remainder from AH. */
7353 insn = emit_move_insn (operands[3], tmp1);
7354 set_unique_reg_note (insn, REG_EQUAL, mod);
7356 /* Extract quotient from AL. */
7357 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7358 set_unique_reg_note (insn, REG_EQUAL, div);
7363 ;; Divide AX by r/m8, with result stored in
7366 (define_insn "divmodhiqi3"
7367 [(set (match_operand:HI 0 "register_operand" "=a")
7371 (mod:QI (match_operand:HI 1 "register_operand" "0")
7372 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7374 (zero_extend:HI (div:QI (match_dup 1) (match_dup 2)))))
7375 (clobber (reg:CC FLAGS_REG))]
7376 "TARGET_QIMODE_MATH"
7378 [(set_attr "type" "idiv")
7379 (set_attr "mode" "QI")])
7381 (define_insn "udivmodhiqi3"
7382 [(set (match_operand:HI 0 "register_operand" "=a")
7386 (umod:QI (match_operand:HI 1 "register_operand" "0")
7387 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7389 (zero_extend:HI (udiv:QI (match_dup 1) (match_dup 2)))))
7390 (clobber (reg:CC FLAGS_REG))]
7391 "TARGET_QIMODE_MATH"
7393 [(set_attr "type" "idiv")
7394 (set_attr "mode" "QI")])
7396 (define_expand "divmod<mode>4"
7397 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7399 (match_operand:SWIM248 1 "register_operand" "")
7400 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7401 (set (match_operand:SWIM248 3 "register_operand" "")
7402 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7403 (clobber (reg:CC FLAGS_REG))])]
7407 (define_insn_and_split "*divmod<mode>4"
7408 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7409 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7410 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7411 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7412 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7413 (clobber (reg:CC FLAGS_REG))]
7417 [(parallel [(set (match_dup 1)
7418 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7419 (clobber (reg:CC FLAGS_REG))])
7420 (parallel [(set (match_dup 0)
7421 (div:SWIM248 (match_dup 2) (match_dup 3)))
7423 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7425 (clobber (reg:CC FLAGS_REG))])]
7427 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7429 if (<MODE>mode != HImode
7430 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7431 operands[4] = operands[2];
7434 /* Avoid use of cltd in favor of a mov+shift. */
7435 emit_move_insn (operands[1], operands[2]);
7436 operands[4] = operands[1];
7439 [(set_attr "type" "multi")
7440 (set_attr "mode" "<MODE>")])
7442 (define_insn "*divmod<mode>4_noext"
7443 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7444 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7445 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7446 (set (match_operand:SWIM248 1 "register_operand" "=d")
7447 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7448 (use (match_operand:SWIM248 4 "register_operand" "1"))
7449 (clobber (reg:CC FLAGS_REG))]
7451 "idiv{<imodesuffix>}\t%3"
7452 [(set_attr "type" "idiv")
7453 (set_attr "mode" "<MODE>")])
7455 (define_expand "udivmod<mode>4"
7456 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7458 (match_operand:SWIM248 1 "register_operand" "")
7459 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7460 (set (match_operand:SWIM248 3 "register_operand" "")
7461 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7462 (clobber (reg:CC FLAGS_REG))])]
7466 (define_insn_and_split "*udivmod<mode>4"
7467 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7468 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7469 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7470 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7471 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7472 (clobber (reg:CC FLAGS_REG))]
7476 [(set (match_dup 1) (const_int 0))
7477 (parallel [(set (match_dup 0)
7478 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7480 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7482 (clobber (reg:CC FLAGS_REG))])]
7484 [(set_attr "type" "multi")
7485 (set_attr "mode" "<MODE>")])
7487 (define_insn "*udivmod<mode>4_noext"
7488 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7489 (udiv: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 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7493 (use (match_operand:SWIM248 4 "register_operand" "1"))
7494 (clobber (reg:CC FLAGS_REG))]
7496 "div{<imodesuffix>}\t%3"
7497 [(set_attr "type" "idiv")
7498 (set_attr "mode" "<MODE>")])
7500 ;; We cannot use div/idiv for double division, because it causes
7501 ;; "division by zero" on the overflow and that's not what we expect
7502 ;; from truncate. Because true (non truncating) double division is
7503 ;; never generated, we can't create this insn anyway.
7506 ; [(set (match_operand:SI 0 "register_operand" "=a")
7508 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7510 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7511 ; (set (match_operand:SI 3 "register_operand" "=d")
7513 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7514 ; (clobber (reg:CC FLAGS_REG))]
7516 ; "div{l}\t{%2, %0|%0, %2}"
7517 ; [(set_attr "type" "idiv")])
7519 ;;- Logical AND instructions
7521 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7522 ;; Note that this excludes ah.
7524 (define_expand "testsi_ccno_1"
7525 [(set (reg:CCNO FLAGS_REG)
7527 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7528 (match_operand:SI 1 "nonmemory_operand" ""))
7533 (define_expand "testqi_ccz_1"
7534 [(set (reg:CCZ FLAGS_REG)
7535 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7536 (match_operand:QI 1 "nonmemory_operand" ""))
7541 (define_insn "*testdi_1"
7542 [(set (reg FLAGS_REG)
7545 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7546 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7548 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7549 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7551 test{l}\t{%k1, %k0|%k0, %k1}
7552 test{l}\t{%k1, %k0|%k0, %k1}
7553 test{q}\t{%1, %0|%0, %1}
7554 test{q}\t{%1, %0|%0, %1}
7555 test{q}\t{%1, %0|%0, %1}"
7556 [(set_attr "type" "test")
7557 (set_attr "modrm" "0,1,0,1,1")
7558 (set_attr "mode" "SI,SI,DI,DI,DI")])
7560 (define_insn "*testqi_1_maybe_si"
7561 [(set (reg FLAGS_REG)
7564 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7565 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7567 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7568 && ix86_match_ccmode (insn,
7569 CONST_INT_P (operands[1])
7570 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7572 if (which_alternative == 3)
7574 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7575 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7576 return "test{l}\t{%1, %k0|%k0, %1}";
7578 return "test{b}\t{%1, %0|%0, %1}";
7580 [(set_attr "type" "test")
7581 (set_attr "modrm" "0,1,1,1")
7582 (set_attr "mode" "QI,QI,QI,SI")
7583 (set_attr "pent_pair" "uv,np,uv,np")])
7585 (define_insn "*test<mode>_1"
7586 [(set (reg FLAGS_REG)
7589 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7590 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7592 "ix86_match_ccmode (insn, CCNOmode)
7593 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7594 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7595 [(set_attr "type" "test")
7596 (set_attr "modrm" "0,1,1")
7597 (set_attr "mode" "<MODE>")
7598 (set_attr "pent_pair" "uv,np,uv")])
7600 (define_expand "testqi_ext_ccno_0"
7601 [(set (reg:CCNO FLAGS_REG)
7605 (match_operand 0 "ext_register_operand" "")
7608 (match_operand 1 "const_int_operand" ""))
7613 (define_insn "*testqi_ext_0"
7614 [(set (reg FLAGS_REG)
7618 (match_operand 0 "ext_register_operand" "Q")
7621 (match_operand 1 "const_int_operand" "n"))
7623 "ix86_match_ccmode (insn, CCNOmode)"
7624 "test{b}\t{%1, %h0|%h0, %1}"
7625 [(set_attr "type" "test")
7626 (set_attr "mode" "QI")
7627 (set_attr "length_immediate" "1")
7628 (set_attr "modrm" "1")
7629 (set_attr "pent_pair" "np")])
7631 (define_insn "*testqi_ext_1_rex64"
7632 [(set (reg FLAGS_REG)
7636 (match_operand 0 "ext_register_operand" "Q")
7640 (match_operand:QI 1 "register_operand" "Q")))
7642 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7643 "test{b}\t{%1, %h0|%h0, %1}"
7644 [(set_attr "type" "test")
7645 (set_attr "mode" "QI")])
7647 (define_insn "*testqi_ext_1"
7648 [(set (reg FLAGS_REG)
7652 (match_operand 0 "ext_register_operand" "Q")
7656 (match_operand:QI 1 "general_operand" "Qm")))
7658 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7659 "test{b}\t{%1, %h0|%h0, %1}"
7660 [(set_attr "type" "test")
7661 (set_attr "mode" "QI")])
7663 (define_insn "*testqi_ext_2"
7664 [(set (reg FLAGS_REG)
7668 (match_operand 0 "ext_register_operand" "Q")
7672 (match_operand 1 "ext_register_operand" "Q")
7676 "ix86_match_ccmode (insn, CCNOmode)"
7677 "test{b}\t{%h1, %h0|%h0, %h1}"
7678 [(set_attr "type" "test")
7679 (set_attr "mode" "QI")])
7681 (define_insn "*testqi_ext_3_rex64"
7682 [(set (reg FLAGS_REG)
7683 (compare (zero_extract:DI
7684 (match_operand 0 "nonimmediate_operand" "rm")
7685 (match_operand:DI 1 "const_int_operand" "")
7686 (match_operand:DI 2 "const_int_operand" ""))
7689 && ix86_match_ccmode (insn, CCNOmode)
7690 && INTVAL (operands[1]) > 0
7691 && INTVAL (operands[2]) >= 0
7692 /* Ensure that resulting mask is zero or sign extended operand. */
7693 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7694 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7695 && INTVAL (operands[1]) > 32))
7696 && (GET_MODE (operands[0]) == SImode
7697 || GET_MODE (operands[0]) == DImode
7698 || GET_MODE (operands[0]) == HImode
7699 || GET_MODE (operands[0]) == QImode)"
7702 ;; Combine likes to form bit extractions for some tests. Humor it.
7703 (define_insn "*testqi_ext_3"
7704 [(set (reg FLAGS_REG)
7705 (compare (zero_extract:SI
7706 (match_operand 0 "nonimmediate_operand" "rm")
7707 (match_operand:SI 1 "const_int_operand" "")
7708 (match_operand:SI 2 "const_int_operand" ""))
7710 "ix86_match_ccmode (insn, CCNOmode)
7711 && INTVAL (operands[1]) > 0
7712 && INTVAL (operands[2]) >= 0
7713 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7714 && (GET_MODE (operands[0]) == SImode
7715 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7716 || GET_MODE (operands[0]) == HImode
7717 || GET_MODE (operands[0]) == QImode)"
7721 [(set (match_operand 0 "flags_reg_operand" "")
7722 (match_operator 1 "compare_operator"
7724 (match_operand 2 "nonimmediate_operand" "")
7725 (match_operand 3 "const_int_operand" "")
7726 (match_operand 4 "const_int_operand" ""))
7728 "ix86_match_ccmode (insn, CCNOmode)"
7729 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7731 rtx val = operands[2];
7732 HOST_WIDE_INT len = INTVAL (operands[3]);
7733 HOST_WIDE_INT pos = INTVAL (operands[4]);
7735 enum machine_mode mode, submode;
7737 mode = GET_MODE (val);
7740 /* ??? Combine likes to put non-volatile mem extractions in QImode
7741 no matter the size of the test. So find a mode that works. */
7742 if (! MEM_VOLATILE_P (val))
7744 mode = smallest_mode_for_size (pos + len, MODE_INT);
7745 val = adjust_address (val, mode, 0);
7748 else if (GET_CODE (val) == SUBREG
7749 && (submode = GET_MODE (SUBREG_REG (val)),
7750 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7751 && pos + len <= GET_MODE_BITSIZE (submode)
7752 && GET_MODE_CLASS (submode) == MODE_INT)
7754 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7756 val = SUBREG_REG (val);
7758 else if (mode == HImode && pos + len <= 8)
7760 /* Small HImode tests can be converted to QImode. */
7762 val = gen_lowpart (QImode, val);
7765 if (len == HOST_BITS_PER_WIDE_INT)
7768 mask = ((HOST_WIDE_INT)1 << len) - 1;
7771 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7774 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7775 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7776 ;; this is relatively important trick.
7777 ;; Do the conversion only post-reload to avoid limiting of the register class
7780 [(set (match_operand 0 "flags_reg_operand" "")
7781 (match_operator 1 "compare_operator"
7782 [(and (match_operand 2 "register_operand" "")
7783 (match_operand 3 "const_int_operand" ""))
7786 && QI_REG_P (operands[2])
7787 && GET_MODE (operands[2]) != QImode
7788 && ((ix86_match_ccmode (insn, CCZmode)
7789 && !(INTVAL (operands[3]) & ~(255 << 8)))
7790 || (ix86_match_ccmode (insn, CCNOmode)
7791 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7794 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7797 "operands[2] = gen_lowpart (SImode, operands[2]);
7798 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7801 [(set (match_operand 0 "flags_reg_operand" "")
7802 (match_operator 1 "compare_operator"
7803 [(and (match_operand 2 "nonimmediate_operand" "")
7804 (match_operand 3 "const_int_operand" ""))
7807 && GET_MODE (operands[2]) != QImode
7808 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7809 && ((ix86_match_ccmode (insn, CCZmode)
7810 && !(INTVAL (operands[3]) & ~255))
7811 || (ix86_match_ccmode (insn, CCNOmode)
7812 && !(INTVAL (operands[3]) & ~127)))"
7814 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7816 "operands[2] = gen_lowpart (QImode, operands[2]);
7817 operands[3] = gen_lowpart (QImode, operands[3]);")
7819 ;; %%% This used to optimize known byte-wide and operations to memory,
7820 ;; and sometimes to QImode registers. If this is considered useful,
7821 ;; it should be done with splitters.
7823 (define_expand "and<mode>3"
7824 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7825 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7826 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7828 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7830 (define_insn "*anddi_1"
7831 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7833 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7834 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7835 (clobber (reg:CC FLAGS_REG))]
7836 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7838 switch (get_attr_type (insn))
7842 enum machine_mode mode;
7844 gcc_assert (CONST_INT_P (operands[2]));
7845 if (INTVAL (operands[2]) == 0xff)
7849 gcc_assert (INTVAL (operands[2]) == 0xffff);
7853 operands[1] = gen_lowpart (mode, operands[1]);
7855 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7857 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7861 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7862 if (get_attr_mode (insn) == MODE_SI)
7863 return "and{l}\t{%k2, %k0|%k0, %k2}";
7865 return "and{q}\t{%2, %0|%0, %2}";
7868 [(set_attr "type" "alu,alu,alu,imovx")
7869 (set_attr "length_immediate" "*,*,*,0")
7870 (set (attr "prefix_rex")
7872 (and (eq_attr "type" "imovx")
7873 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7874 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7876 (const_string "*")))
7877 (set_attr "mode" "SI,DI,DI,SI")])
7879 (define_insn "*andsi_1"
7880 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7881 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7882 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7883 (clobber (reg:CC FLAGS_REG))]
7884 "ix86_binary_operator_ok (AND, SImode, operands)"
7886 switch (get_attr_type (insn))
7890 enum machine_mode mode;
7892 gcc_assert (CONST_INT_P (operands[2]));
7893 if (INTVAL (operands[2]) == 0xff)
7897 gcc_assert (INTVAL (operands[2]) == 0xffff);
7901 operands[1] = gen_lowpart (mode, operands[1]);
7903 return "movz{bl|x}\t{%1, %0|%0, %1}";
7905 return "movz{wl|x}\t{%1, %0|%0, %1}";
7909 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7910 return "and{l}\t{%2, %0|%0, %2}";
7913 [(set_attr "type" "alu,alu,imovx")
7914 (set (attr "prefix_rex")
7916 (and (eq_attr "type" "imovx")
7917 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7918 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7920 (const_string "*")))
7921 (set_attr "length_immediate" "*,*,0")
7922 (set_attr "mode" "SI")])
7924 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7925 (define_insn "*andsi_1_zext"
7926 [(set (match_operand:DI 0 "register_operand" "=r")
7928 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7929 (match_operand:SI 2 "general_operand" "g"))))
7930 (clobber (reg:CC FLAGS_REG))]
7931 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7932 "and{l}\t{%2, %k0|%k0, %2}"
7933 [(set_attr "type" "alu")
7934 (set_attr "mode" "SI")])
7936 (define_insn "*andhi_1"
7937 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7938 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7939 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7940 (clobber (reg:CC FLAGS_REG))]
7941 "ix86_binary_operator_ok (AND, HImode, operands)"
7943 switch (get_attr_type (insn))
7946 gcc_assert (CONST_INT_P (operands[2]));
7947 gcc_assert (INTVAL (operands[2]) == 0xff);
7948 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7951 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7953 return "and{w}\t{%2, %0|%0, %2}";
7956 [(set_attr "type" "alu,alu,imovx")
7957 (set_attr "length_immediate" "*,*,0")
7958 (set (attr "prefix_rex")
7960 (and (eq_attr "type" "imovx")
7961 (match_operand 1 "ext_QIreg_nomode_operand" ""))
7963 (const_string "*")))
7964 (set_attr "mode" "HI,HI,SI")])
7966 ;; %%% Potential partial reg stall on alternative 2. What to do?
7967 (define_insn "*andqi_1"
7968 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7969 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7970 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7971 (clobber (reg:CC FLAGS_REG))]
7972 "ix86_binary_operator_ok (AND, QImode, operands)"
7974 and{b}\t{%2, %0|%0, %2}
7975 and{b}\t{%2, %0|%0, %2}
7976 and{l}\t{%k2, %k0|%k0, %k2}"
7977 [(set_attr "type" "alu")
7978 (set_attr "mode" "QI,QI,SI")])
7980 (define_insn "*andqi_1_slp"
7981 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7982 (and:QI (match_dup 0)
7983 (match_operand:QI 1 "general_operand" "qn,qmn")))
7984 (clobber (reg:CC FLAGS_REG))]
7985 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7986 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7987 "and{b}\t{%1, %0|%0, %1}"
7988 [(set_attr "type" "alu1")
7989 (set_attr "mode" "QI")])
7992 [(set (match_operand 0 "register_operand" "")
7994 (const_int -65536)))
7995 (clobber (reg:CC FLAGS_REG))]
7996 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7997 || optimize_function_for_size_p (cfun)"
7998 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7999 "operands[1] = gen_lowpart (HImode, operands[0]);")
8002 [(set (match_operand 0 "ext_register_operand" "")
8005 (clobber (reg:CC FLAGS_REG))]
8006 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8007 && reload_completed"
8008 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8009 "operands[1] = gen_lowpart (QImode, operands[0]);")
8012 [(set (match_operand 0 "ext_register_operand" "")
8014 (const_int -65281)))
8015 (clobber (reg:CC FLAGS_REG))]
8016 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8017 && reload_completed"
8018 [(parallel [(set (zero_extract:SI (match_dup 0)
8022 (zero_extract:SI (match_dup 0)
8025 (zero_extract:SI (match_dup 0)
8028 (clobber (reg:CC FLAGS_REG))])]
8029 "operands[0] = gen_lowpart (SImode, operands[0]);")
8031 (define_insn "*anddi_2"
8032 [(set (reg FLAGS_REG)
8035 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8036 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8038 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8039 (and:DI (match_dup 1) (match_dup 2)))]
8040 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8041 && ix86_binary_operator_ok (AND, DImode, operands)"
8043 and{l}\t{%k2, %k0|%k0, %k2}
8044 and{q}\t{%2, %0|%0, %2}
8045 and{q}\t{%2, %0|%0, %2}"
8046 [(set_attr "type" "alu")
8047 (set_attr "mode" "SI,DI,DI")])
8049 (define_insn "*andqi_2_maybe_si"
8050 [(set (reg FLAGS_REG)
8052 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8053 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8055 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8056 (and:QI (match_dup 1) (match_dup 2)))]
8057 "ix86_binary_operator_ok (AND, QImode, operands)
8058 && ix86_match_ccmode (insn,
8059 CONST_INT_P (operands[2])
8060 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8062 if (which_alternative == 2)
8064 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8065 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8066 return "and{l}\t{%2, %k0|%k0, %2}";
8068 return "and{b}\t{%2, %0|%0, %2}";
8070 [(set_attr "type" "alu")
8071 (set_attr "mode" "QI,QI,SI")])
8073 (define_insn "*and<mode>_2"
8074 [(set (reg FLAGS_REG)
8075 (compare (and:SWI124
8076 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8077 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8079 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8080 (and:SWI124 (match_dup 1) (match_dup 2)))]
8081 "ix86_match_ccmode (insn, CCNOmode)
8082 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8083 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8084 [(set_attr "type" "alu")
8085 (set_attr "mode" "<MODE>")])
8087 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8088 (define_insn "*andsi_2_zext"
8089 [(set (reg FLAGS_REG)
8091 (match_operand:SI 1 "nonimmediate_operand" "%0")
8092 (match_operand:SI 2 "general_operand" "g"))
8094 (set (match_operand:DI 0 "register_operand" "=r")
8095 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8096 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8097 && ix86_binary_operator_ok (AND, SImode, operands)"
8098 "and{l}\t{%2, %k0|%k0, %2}"
8099 [(set_attr "type" "alu")
8100 (set_attr "mode" "SI")])
8102 (define_insn "*andqi_2_slp"
8103 [(set (reg FLAGS_REG)
8105 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8106 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8108 (set (strict_low_part (match_dup 0))
8109 (and:QI (match_dup 0) (match_dup 1)))]
8110 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8111 && ix86_match_ccmode (insn, CCNOmode)
8112 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8113 "and{b}\t{%1, %0|%0, %1}"
8114 [(set_attr "type" "alu1")
8115 (set_attr "mode" "QI")])
8117 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8118 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8119 ;; for a QImode operand, which of course failed.
8120 (define_insn "andqi_ext_0"
8121 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8126 (match_operand 1 "ext_register_operand" "0")
8129 (match_operand 2 "const_int_operand" "n")))
8130 (clobber (reg:CC FLAGS_REG))]
8132 "and{b}\t{%2, %h0|%h0, %2}"
8133 [(set_attr "type" "alu")
8134 (set_attr "length_immediate" "1")
8135 (set_attr "modrm" "1")
8136 (set_attr "mode" "QI")])
8138 ;; Generated by peephole translating test to and. This shows up
8139 ;; often in fp comparisons.
8140 (define_insn "*andqi_ext_0_cc"
8141 [(set (reg FLAGS_REG)
8145 (match_operand 1 "ext_register_operand" "0")
8148 (match_operand 2 "const_int_operand" "n"))
8150 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8159 "ix86_match_ccmode (insn, CCNOmode)"
8160 "and{b}\t{%2, %h0|%h0, %2}"
8161 [(set_attr "type" "alu")
8162 (set_attr "length_immediate" "1")
8163 (set_attr "modrm" "1")
8164 (set_attr "mode" "QI")])
8166 (define_insn "*andqi_ext_1_rex64"
8167 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8172 (match_operand 1 "ext_register_operand" "0")
8176 (match_operand 2 "ext_register_operand" "Q"))))
8177 (clobber (reg:CC FLAGS_REG))]
8179 "and{b}\t{%2, %h0|%h0, %2}"
8180 [(set_attr "type" "alu")
8181 (set_attr "length_immediate" "0")
8182 (set_attr "mode" "QI")])
8184 (define_insn "*andqi_ext_1"
8185 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8190 (match_operand 1 "ext_register_operand" "0")
8194 (match_operand:QI 2 "general_operand" "Qm"))))
8195 (clobber (reg:CC FLAGS_REG))]
8197 "and{b}\t{%2, %h0|%h0, %2}"
8198 [(set_attr "type" "alu")
8199 (set_attr "length_immediate" "0")
8200 (set_attr "mode" "QI")])
8202 (define_insn "*andqi_ext_2"
8203 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8208 (match_operand 1 "ext_register_operand" "%0")
8212 (match_operand 2 "ext_register_operand" "Q")
8215 (clobber (reg:CC FLAGS_REG))]
8217 "and{b}\t{%h2, %h0|%h0, %h2}"
8218 [(set_attr "type" "alu")
8219 (set_attr "length_immediate" "0")
8220 (set_attr "mode" "QI")])
8222 ;; Convert wide AND instructions with immediate operand to shorter QImode
8223 ;; equivalents when possible.
8224 ;; Don't do the splitting with memory operands, since it introduces risk
8225 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8226 ;; for size, but that can (should?) be handled by generic code instead.
8228 [(set (match_operand 0 "register_operand" "")
8229 (and (match_operand 1 "register_operand" "")
8230 (match_operand 2 "const_int_operand" "")))
8231 (clobber (reg:CC FLAGS_REG))]
8233 && QI_REG_P (operands[0])
8234 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8235 && !(~INTVAL (operands[2]) & ~(255 << 8))
8236 && GET_MODE (operands[0]) != QImode"
8237 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8238 (and:SI (zero_extract:SI (match_dup 1)
8239 (const_int 8) (const_int 8))
8241 (clobber (reg:CC FLAGS_REG))])]
8242 "operands[0] = gen_lowpart (SImode, operands[0]);
8243 operands[1] = gen_lowpart (SImode, operands[1]);
8244 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8246 ;; Since AND can be encoded with sign extended immediate, this is only
8247 ;; profitable when 7th bit is not set.
8249 [(set (match_operand 0 "register_operand" "")
8250 (and (match_operand 1 "general_operand" "")
8251 (match_operand 2 "const_int_operand" "")))
8252 (clobber (reg:CC FLAGS_REG))]
8254 && ANY_QI_REG_P (operands[0])
8255 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8256 && !(~INTVAL (operands[2]) & ~255)
8257 && !(INTVAL (operands[2]) & 128)
8258 && GET_MODE (operands[0]) != QImode"
8259 [(parallel [(set (strict_low_part (match_dup 0))
8260 (and:QI (match_dup 1)
8262 (clobber (reg:CC FLAGS_REG))])]
8263 "operands[0] = gen_lowpart (QImode, operands[0]);
8264 operands[1] = gen_lowpart (QImode, operands[1]);
8265 operands[2] = gen_lowpart (QImode, operands[2]);")
8267 ;; Logical inclusive and exclusive OR instructions
8269 ;; %%% This used to optimize known byte-wide and operations to memory.
8270 ;; If this is considered useful, it should be done with splitters.
8272 (define_expand "<code><mode>3"
8273 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8274 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8275 (match_operand:SWIM 2 "<general_operand>" "")))]
8277 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8279 (define_insn "*<code><mode>_1"
8280 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8282 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8283 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8284 (clobber (reg:CC FLAGS_REG))]
8285 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8286 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8287 [(set_attr "type" "alu")
8288 (set_attr "mode" "<MODE>")])
8290 ;; %%% Potential partial reg stall on alternative 2. What to do?
8291 (define_insn "*<code>qi_1"
8292 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8293 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8294 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8295 (clobber (reg:CC FLAGS_REG))]
8296 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8298 <logic>{b}\t{%2, %0|%0, %2}
8299 <logic>{b}\t{%2, %0|%0, %2}
8300 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8301 [(set_attr "type" "alu")
8302 (set_attr "mode" "QI,QI,SI")])
8304 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8305 (define_insn "*<code>si_1_zext"
8306 [(set (match_operand:DI 0 "register_operand" "=r")
8308 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8309 (match_operand:SI 2 "general_operand" "g"))))
8310 (clobber (reg:CC FLAGS_REG))]
8311 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8312 "<logic>{l}\t{%2, %k0|%k0, %2}"
8313 [(set_attr "type" "alu")
8314 (set_attr "mode" "SI")])
8316 (define_insn "*<code>si_1_zext_imm"
8317 [(set (match_operand:DI 0 "register_operand" "=r")
8319 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8320 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8321 (clobber (reg:CC FLAGS_REG))]
8322 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8323 "<logic>{l}\t{%2, %k0|%k0, %2}"
8324 [(set_attr "type" "alu")
8325 (set_attr "mode" "SI")])
8327 (define_insn "*<code>qi_1_slp"
8328 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8329 (any_or:QI (match_dup 0)
8330 (match_operand:QI 1 "general_operand" "qmn,qn")))
8331 (clobber (reg:CC FLAGS_REG))]
8332 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8333 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8334 "<logic>{b}\t{%1, %0|%0, %1}"
8335 [(set_attr "type" "alu1")
8336 (set_attr "mode" "QI")])
8338 (define_insn "*<code><mode>_2"
8339 [(set (reg FLAGS_REG)
8340 (compare (any_or:SWI
8341 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8342 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8344 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8345 (any_or:SWI (match_dup 1) (match_dup 2)))]
8346 "ix86_match_ccmode (insn, CCNOmode)
8347 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8348 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8349 [(set_attr "type" "alu")
8350 (set_attr "mode" "<MODE>")])
8352 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8353 ;; ??? Special case for immediate operand is missing - it is tricky.
8354 (define_insn "*<code>si_2_zext"
8355 [(set (reg FLAGS_REG)
8356 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8357 (match_operand:SI 2 "general_operand" "g"))
8359 (set (match_operand:DI 0 "register_operand" "=r")
8360 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8361 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8362 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8363 "<logic>{l}\t{%2, %k0|%k0, %2}"
8364 [(set_attr "type" "alu")
8365 (set_attr "mode" "SI")])
8367 (define_insn "*<code>si_2_zext_imm"
8368 [(set (reg FLAGS_REG)
8370 (match_operand:SI 1 "nonimmediate_operand" "%0")
8371 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8373 (set (match_operand:DI 0 "register_operand" "=r")
8374 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8375 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8376 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8377 "<logic>{l}\t{%2, %k0|%k0, %2}"
8378 [(set_attr "type" "alu")
8379 (set_attr "mode" "SI")])
8381 (define_insn "*<code>qi_2_slp"
8382 [(set (reg FLAGS_REG)
8383 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8384 (match_operand:QI 1 "general_operand" "qmn,qn"))
8386 (set (strict_low_part (match_dup 0))
8387 (any_or:QI (match_dup 0) (match_dup 1)))]
8388 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8389 && ix86_match_ccmode (insn, CCNOmode)
8390 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8391 "<logic>{b}\t{%1, %0|%0, %1}"
8392 [(set_attr "type" "alu1")
8393 (set_attr "mode" "QI")])
8395 (define_insn "*<code><mode>_3"
8396 [(set (reg FLAGS_REG)
8397 (compare (any_or:SWI
8398 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8399 (match_operand:SWI 2 "<general_operand>" "<g>"))
8401 (clobber (match_scratch:SWI 0 "=<r>"))]
8402 "ix86_match_ccmode (insn, CCNOmode)
8403 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8404 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8405 [(set_attr "type" "alu")
8406 (set_attr "mode" "<MODE>")])
8408 (define_insn "*<code>qi_ext_0"
8409 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8414 (match_operand 1 "ext_register_operand" "0")
8417 (match_operand 2 "const_int_operand" "n")))
8418 (clobber (reg:CC FLAGS_REG))]
8419 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8420 "<logic>{b}\t{%2, %h0|%h0, %2}"
8421 [(set_attr "type" "alu")
8422 (set_attr "length_immediate" "1")
8423 (set_attr "modrm" "1")
8424 (set_attr "mode" "QI")])
8426 (define_insn "*<code>qi_ext_1_rex64"
8427 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8432 (match_operand 1 "ext_register_operand" "0")
8436 (match_operand 2 "ext_register_operand" "Q"))))
8437 (clobber (reg:CC FLAGS_REG))]
8439 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8440 "<logic>{b}\t{%2, %h0|%h0, %2}"
8441 [(set_attr "type" "alu")
8442 (set_attr "length_immediate" "0")
8443 (set_attr "mode" "QI")])
8445 (define_insn "*<code>qi_ext_1"
8446 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8451 (match_operand 1 "ext_register_operand" "0")
8455 (match_operand:QI 2 "general_operand" "Qm"))))
8456 (clobber (reg:CC FLAGS_REG))]
8458 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8459 "<logic>{b}\t{%2, %h0|%h0, %2}"
8460 [(set_attr "type" "alu")
8461 (set_attr "length_immediate" "0")
8462 (set_attr "mode" "QI")])
8464 (define_insn "*<code>qi_ext_2"
8465 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8469 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8472 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8475 (clobber (reg:CC FLAGS_REG))]
8476 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8477 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8478 [(set_attr "type" "alu")
8479 (set_attr "length_immediate" "0")
8480 (set_attr "mode" "QI")])
8483 [(set (match_operand 0 "register_operand" "")
8484 (any_or (match_operand 1 "register_operand" "")
8485 (match_operand 2 "const_int_operand" "")))
8486 (clobber (reg:CC FLAGS_REG))]
8488 && QI_REG_P (operands[0])
8489 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8490 && !(INTVAL (operands[2]) & ~(255 << 8))
8491 && GET_MODE (operands[0]) != QImode"
8492 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8493 (any_or:SI (zero_extract:SI (match_dup 1)
8494 (const_int 8) (const_int 8))
8496 (clobber (reg:CC FLAGS_REG))])]
8497 "operands[0] = gen_lowpart (SImode, operands[0]);
8498 operands[1] = gen_lowpart (SImode, operands[1]);
8499 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8501 ;; Since OR can be encoded with sign extended immediate, this is only
8502 ;; profitable when 7th bit is set.
8504 [(set (match_operand 0 "register_operand" "")
8505 (any_or (match_operand 1 "general_operand" "")
8506 (match_operand 2 "const_int_operand" "")))
8507 (clobber (reg:CC FLAGS_REG))]
8509 && ANY_QI_REG_P (operands[0])
8510 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8511 && !(INTVAL (operands[2]) & ~255)
8512 && (INTVAL (operands[2]) & 128)
8513 && GET_MODE (operands[0]) != QImode"
8514 [(parallel [(set (strict_low_part (match_dup 0))
8515 (any_or:QI (match_dup 1)
8517 (clobber (reg:CC FLAGS_REG))])]
8518 "operands[0] = gen_lowpart (QImode, operands[0]);
8519 operands[1] = gen_lowpart (QImode, operands[1]);
8520 operands[2] = gen_lowpart (QImode, operands[2]);")
8522 (define_expand "xorqi_cc_ext_1"
8524 (set (reg:CCNO FLAGS_REG)
8528 (match_operand 1 "ext_register_operand" "")
8531 (match_operand:QI 2 "general_operand" ""))
8533 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8545 (define_insn "*xorqi_cc_ext_1_rex64"
8546 [(set (reg FLAGS_REG)
8550 (match_operand 1 "ext_register_operand" "0")
8553 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8555 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8564 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8565 "xor{b}\t{%2, %h0|%h0, %2}"
8566 [(set_attr "type" "alu")
8567 (set_attr "modrm" "1")
8568 (set_attr "mode" "QI")])
8570 (define_insn "*xorqi_cc_ext_1"
8571 [(set (reg FLAGS_REG)
8575 (match_operand 1 "ext_register_operand" "0")
8578 (match_operand:QI 2 "general_operand" "qmn"))
8580 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8589 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8590 "xor{b}\t{%2, %h0|%h0, %2}"
8591 [(set_attr "type" "alu")
8592 (set_attr "modrm" "1")
8593 (set_attr "mode" "QI")])
8595 ;; Negation instructions
8597 (define_expand "neg<mode>2"
8598 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8599 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8601 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8603 (define_insn_and_split "*neg<dwi>2_doubleword"
8604 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8605 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8606 (clobber (reg:CC FLAGS_REG))]
8607 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8611 [(set (reg:CCZ FLAGS_REG)
8612 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8613 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8616 (plus:DWIH (match_dup 3)
8617 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8619 (clobber (reg:CC FLAGS_REG))])
8622 (neg:DWIH (match_dup 2)))
8623 (clobber (reg:CC FLAGS_REG))])]
8624 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
8626 (define_insn "*neg<mode>2_1"
8627 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8628 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8629 (clobber (reg:CC FLAGS_REG))]
8630 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8631 "neg{<imodesuffix>}\t%0"
8632 [(set_attr "type" "negnot")
8633 (set_attr "mode" "<MODE>")])
8635 ;; Combine is quite creative about this pattern.
8636 (define_insn "*negsi2_1_zext"
8637 [(set (match_operand:DI 0 "register_operand" "=r")
8639 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8642 (clobber (reg:CC FLAGS_REG))]
8643 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8645 [(set_attr "type" "negnot")
8646 (set_attr "mode" "SI")])
8648 ;; The problem with neg is that it does not perform (compare x 0),
8649 ;; it really performs (compare 0 x), which leaves us with the zero
8650 ;; flag being the only useful item.
8652 (define_insn "*neg<mode>2_cmpz"
8653 [(set (reg:CCZ FLAGS_REG)
8655 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8657 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8658 (neg:SWI (match_dup 1)))]
8659 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8660 "neg{<imodesuffix>}\t%0"
8661 [(set_attr "type" "negnot")
8662 (set_attr "mode" "<MODE>")])
8664 (define_insn "*negsi2_cmpz_zext"
8665 [(set (reg:CCZ FLAGS_REG)
8669 (match_operand:DI 1 "register_operand" "0")
8673 (set (match_operand:DI 0 "register_operand" "=r")
8674 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8677 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8679 [(set_attr "type" "negnot")
8680 (set_attr "mode" "SI")])
8682 ;; Changing of sign for FP values is doable using integer unit too.
8684 (define_expand "<code><mode>2"
8685 [(set (match_operand:X87MODEF 0 "register_operand" "")
8686 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8687 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8688 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8690 (define_insn "*absneg<mode>2_mixed"
8691 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8692 (match_operator:MODEF 3 "absneg_operator"
8693 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8694 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8695 (clobber (reg:CC FLAGS_REG))]
8696 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8699 (define_insn "*absneg<mode>2_sse"
8700 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8701 (match_operator:MODEF 3 "absneg_operator"
8702 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8703 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8704 (clobber (reg:CC FLAGS_REG))]
8705 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8708 (define_insn "*absneg<mode>2_i387"
8709 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8710 (match_operator:X87MODEF 3 "absneg_operator"
8711 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8712 (use (match_operand 2 "" ""))
8713 (clobber (reg:CC FLAGS_REG))]
8714 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8717 (define_expand "<code>tf2"
8718 [(set (match_operand:TF 0 "register_operand" "")
8719 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8721 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8723 (define_insn "*absnegtf2_sse"
8724 [(set (match_operand:TF 0 "register_operand" "=x,x")
8725 (match_operator:TF 3 "absneg_operator"
8726 [(match_operand:TF 1 "register_operand" "0,x")]))
8727 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8728 (clobber (reg:CC FLAGS_REG))]
8732 ;; Splitters for fp abs and neg.
8735 [(set (match_operand 0 "fp_register_operand" "")
8736 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8737 (use (match_operand 2 "" ""))
8738 (clobber (reg:CC FLAGS_REG))]
8740 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8743 [(set (match_operand 0 "register_operand" "")
8744 (match_operator 3 "absneg_operator"
8745 [(match_operand 1 "register_operand" "")]))
8746 (use (match_operand 2 "nonimmediate_operand" ""))
8747 (clobber (reg:CC FLAGS_REG))]
8748 "reload_completed && SSE_REG_P (operands[0])"
8749 [(set (match_dup 0) (match_dup 3))]
8751 enum machine_mode mode = GET_MODE (operands[0]);
8752 enum machine_mode vmode = GET_MODE (operands[2]);
8755 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8756 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8757 if (operands_match_p (operands[0], operands[2]))
8760 operands[1] = operands[2];
8763 if (GET_CODE (operands[3]) == ABS)
8764 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8766 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8771 [(set (match_operand:SF 0 "register_operand" "")
8772 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8773 (use (match_operand:V4SF 2 "" ""))
8774 (clobber (reg:CC FLAGS_REG))]
8776 [(parallel [(set (match_dup 0) (match_dup 1))
8777 (clobber (reg:CC FLAGS_REG))])]
8780 operands[0] = gen_lowpart (SImode, operands[0]);
8781 if (GET_CODE (operands[1]) == ABS)
8783 tmp = gen_int_mode (0x7fffffff, SImode);
8784 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8788 tmp = gen_int_mode (0x80000000, SImode);
8789 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8795 [(set (match_operand:DF 0 "register_operand" "")
8796 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8797 (use (match_operand 2 "" ""))
8798 (clobber (reg:CC FLAGS_REG))]
8800 [(parallel [(set (match_dup 0) (match_dup 1))
8801 (clobber (reg:CC FLAGS_REG))])]
8806 tmp = gen_lowpart (DImode, operands[0]);
8807 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8810 if (GET_CODE (operands[1]) == ABS)
8813 tmp = gen_rtx_NOT (DImode, tmp);
8817 operands[0] = gen_highpart (SImode, operands[0]);
8818 if (GET_CODE (operands[1]) == ABS)
8820 tmp = gen_int_mode (0x7fffffff, SImode);
8821 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8825 tmp = gen_int_mode (0x80000000, SImode);
8826 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8833 [(set (match_operand:XF 0 "register_operand" "")
8834 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8835 (use (match_operand 2 "" ""))
8836 (clobber (reg:CC FLAGS_REG))]
8838 [(parallel [(set (match_dup 0) (match_dup 1))
8839 (clobber (reg:CC FLAGS_REG))])]
8842 operands[0] = gen_rtx_REG (SImode,
8843 true_regnum (operands[0])
8844 + (TARGET_64BIT ? 1 : 2));
8845 if (GET_CODE (operands[1]) == ABS)
8847 tmp = GEN_INT (0x7fff);
8848 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8852 tmp = GEN_INT (0x8000);
8853 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8858 ;; Conditionalize these after reload. If they match before reload, we
8859 ;; lose the clobber and ability to use integer instructions.
8861 (define_insn "*<code><mode>2_1"
8862 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8863 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8865 && (reload_completed
8866 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8867 "f<absneg_mnemonic>"
8868 [(set_attr "type" "fsgn")
8869 (set_attr "mode" "<MODE>")])
8871 (define_insn "*<code>extendsfdf2"
8872 [(set (match_operand:DF 0 "register_operand" "=f")
8873 (absneg:DF (float_extend:DF
8874 (match_operand:SF 1 "register_operand" "0"))))]
8875 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8876 "f<absneg_mnemonic>"
8877 [(set_attr "type" "fsgn")
8878 (set_attr "mode" "DF")])
8880 (define_insn "*<code>extendsfxf2"
8881 [(set (match_operand:XF 0 "register_operand" "=f")
8882 (absneg:XF (float_extend:XF
8883 (match_operand:SF 1 "register_operand" "0"))))]
8885 "f<absneg_mnemonic>"
8886 [(set_attr "type" "fsgn")
8887 (set_attr "mode" "XF")])
8889 (define_insn "*<code>extenddfxf2"
8890 [(set (match_operand:XF 0 "register_operand" "=f")
8891 (absneg:XF (float_extend:XF
8892 (match_operand:DF 1 "register_operand" "0"))))]
8894 "f<absneg_mnemonic>"
8895 [(set_attr "type" "fsgn")
8896 (set_attr "mode" "XF")])
8898 ;; Copysign instructions
8900 (define_mode_iterator CSGNMODE [SF DF TF])
8901 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8903 (define_expand "copysign<mode>3"
8904 [(match_operand:CSGNMODE 0 "register_operand" "")
8905 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8906 (match_operand:CSGNMODE 2 "register_operand" "")]
8907 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8908 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8910 ix86_expand_copysign (operands);
8914 (define_insn_and_split "copysign<mode>3_const"
8915 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8917 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8918 (match_operand:CSGNMODE 2 "register_operand" "0")
8919 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8921 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8922 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8924 "&& reload_completed"
8927 ix86_split_copysign_const (operands);
8931 (define_insn "copysign<mode>3_var"
8932 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8934 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8935 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8936 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8937 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8939 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8940 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8941 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8945 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8947 [(match_operand:CSGNMODE 2 "register_operand" "")
8948 (match_operand:CSGNMODE 3 "register_operand" "")
8949 (match_operand:<CSGNVMODE> 4 "" "")
8950 (match_operand:<CSGNVMODE> 5 "" "")]
8952 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8953 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8954 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8955 && reload_completed"
8958 ix86_split_copysign_var (operands);
8962 ;; One complement instructions
8964 (define_expand "one_cmpl<mode>2"
8965 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8966 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8968 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8970 (define_insn "*one_cmpl<mode>2_1"
8971 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8972 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8973 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8974 "not{<imodesuffix>}\t%0"
8975 [(set_attr "type" "negnot")
8976 (set_attr "mode" "<MODE>")])
8978 ;; %%% Potential partial reg stall on alternative 1. What to do?
8979 (define_insn "*one_cmplqi2_1"
8980 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8981 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8982 "ix86_unary_operator_ok (NOT, QImode, operands)"
8986 [(set_attr "type" "negnot")
8987 (set_attr "mode" "QI,SI")])
8989 ;; ??? Currently never generated - xor is used instead.
8990 (define_insn "*one_cmplsi2_1_zext"
8991 [(set (match_operand:DI 0 "register_operand" "=r")
8993 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8994 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8996 [(set_attr "type" "negnot")
8997 (set_attr "mode" "SI")])
8999 (define_insn "*one_cmpl<mode>2_2"
9000 [(set (reg FLAGS_REG)
9001 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9003 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9004 (not:SWI (match_dup 1)))]
9005 "ix86_match_ccmode (insn, CCNOmode)
9006 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9008 [(set_attr "type" "alu1")
9009 (set_attr "mode" "<MODE>")])
9012 [(set (match_operand 0 "flags_reg_operand" "")
9013 (match_operator 2 "compare_operator"
9014 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9016 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9017 (not:SWI (match_dup 3)))]
9018 "ix86_match_ccmode (insn, CCNOmode)"
9019 [(parallel [(set (match_dup 0)
9020 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9023 (xor:SWI (match_dup 3) (const_int -1)))])]
9026 ;; ??? Currently never generated - xor is used instead.
9027 (define_insn "*one_cmplsi2_2_zext"
9028 [(set (reg FLAGS_REG)
9029 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9031 (set (match_operand:DI 0 "register_operand" "=r")
9032 (zero_extend:DI (not:SI (match_dup 1))))]
9033 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9034 && ix86_unary_operator_ok (NOT, SImode, operands)"
9036 [(set_attr "type" "alu1")
9037 (set_attr "mode" "SI")])
9040 [(set (match_operand 0 "flags_reg_operand" "")
9041 (match_operator 2 "compare_operator"
9042 [(not:SI (match_operand:SI 3 "register_operand" ""))
9044 (set (match_operand:DI 1 "register_operand" "")
9045 (zero_extend:DI (not:SI (match_dup 3))))]
9046 "ix86_match_ccmode (insn, CCNOmode)"
9047 [(parallel [(set (match_dup 0)
9048 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9051 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9054 ;; Shift instructions
9056 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9057 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9058 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9059 ;; from the assembler input.
9061 ;; This instruction shifts the target reg/mem as usual, but instead of
9062 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9063 ;; is a left shift double, bits are taken from the high order bits of
9064 ;; reg, else if the insn is a shift right double, bits are taken from the
9065 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9066 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9068 ;; Since sh[lr]d does not change the `reg' operand, that is done
9069 ;; separately, making all shifts emit pairs of shift double and normal
9070 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9071 ;; support a 63 bit shift, each shift where the count is in a reg expands
9072 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9074 ;; If the shift count is a constant, we need never emit more than one
9075 ;; shift pair, instead using moves and sign extension for counts greater
9078 (define_expand "ashl<mode>3"
9079 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9080 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9081 (match_operand:QI 2 "nonmemory_operand" "")))]
9083 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9085 (define_insn "*ashl<mode>3_doubleword"
9086 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9087 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9088 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9089 (clobber (reg:CC FLAGS_REG))]
9092 [(set_attr "type" "multi")])
9095 [(set (match_operand:DWI 0 "register_operand" "")
9096 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9097 (match_operand:QI 2 "nonmemory_operand" "")))
9098 (clobber (reg:CC FLAGS_REG))]
9099 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9101 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9103 ;; By default we don't ask for a scratch register, because when DWImode
9104 ;; values are manipulated, registers are already at a premium. But if
9105 ;; we have one handy, we won't turn it away.
9108 [(match_scratch:DWIH 3 "r")
9109 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9111 (match_operand:<DWI> 1 "nonmemory_operand" "")
9112 (match_operand:QI 2 "nonmemory_operand" "")))
9113 (clobber (reg:CC FLAGS_REG))])
9117 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9119 (define_insn "x86_64_shld"
9120 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9121 (ior:DI (ashift:DI (match_dup 0)
9122 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9123 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9124 (minus:QI (const_int 64) (match_dup 2)))))
9125 (clobber (reg:CC FLAGS_REG))]
9127 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9128 [(set_attr "type" "ishift")
9129 (set_attr "prefix_0f" "1")
9130 (set_attr "mode" "DI")
9131 (set_attr "athlon_decode" "vector")
9132 (set_attr "amdfam10_decode" "vector")])
9134 (define_insn "x86_shld"
9135 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9136 (ior:SI (ashift:SI (match_dup 0)
9137 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9138 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9139 (minus:QI (const_int 32) (match_dup 2)))))
9140 (clobber (reg:CC FLAGS_REG))]
9142 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9143 [(set_attr "type" "ishift")
9144 (set_attr "prefix_0f" "1")
9145 (set_attr "mode" "SI")
9146 (set_attr "pent_pair" "np")
9147 (set_attr "athlon_decode" "vector")
9148 (set_attr "amdfam10_decode" "vector")])
9150 (define_expand "x86_shift<mode>_adj_1"
9151 [(set (reg:CCZ FLAGS_REG)
9152 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9155 (set (match_operand:SWI48 0 "register_operand" "")
9156 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9157 (match_operand:SWI48 1 "register_operand" "")
9160 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9161 (match_operand:SWI48 3 "register_operand" "r")
9164 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9166 (define_expand "x86_shift<mode>_adj_2"
9167 [(use (match_operand:SWI48 0 "register_operand" ""))
9168 (use (match_operand:SWI48 1 "register_operand" ""))
9169 (use (match_operand:QI 2 "register_operand" ""))]
9172 rtx label = gen_label_rtx ();
9175 emit_insn (gen_testqi_ccz_1 (operands[2],
9176 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9178 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9179 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9180 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9181 gen_rtx_LABEL_REF (VOIDmode, label),
9183 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9184 JUMP_LABEL (tmp) = label;
9186 emit_move_insn (operands[0], operands[1]);
9187 ix86_expand_clear (operands[1]);
9190 LABEL_NUSES (label) = 1;
9195 (define_insn "*ashl<mode>3_1"
9196 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9197 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9198 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9199 (clobber (reg:CC FLAGS_REG))]
9200 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9202 switch (get_attr_type (insn))
9208 gcc_assert (operands[2] == const1_rtx);
9209 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9210 return "add{<imodesuffix>}\t%0, %0";
9213 if (operands[2] == const1_rtx
9214 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9215 return "sal{<imodesuffix>}\t%0";
9217 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9221 (cond [(eq_attr "alternative" "1")
9222 (const_string "lea")
9223 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9225 (match_operand 0 "register_operand" ""))
9226 (match_operand 2 "const1_operand" ""))
9227 (const_string "alu")
9229 (const_string "ishift")))
9230 (set (attr "length_immediate")
9232 (ior (eq_attr "type" "alu")
9233 (and (eq_attr "type" "ishift")
9234 (and (match_operand 2 "const1_operand" "")
9235 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9238 (const_string "*")))
9239 (set_attr "mode" "<MODE>")])
9241 (define_insn "*ashlsi3_1_zext"
9242 [(set (match_operand:DI 0 "register_operand" "=r,r")
9244 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9245 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9246 (clobber (reg:CC FLAGS_REG))]
9247 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9249 switch (get_attr_type (insn))
9255 gcc_assert (operands[2] == const1_rtx);
9256 return "add{l}\t%k0, %k0";
9259 if (operands[2] == const1_rtx
9260 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9261 return "sal{l}\t%k0";
9263 return "sal{l}\t{%2, %k0|%k0, %2}";
9267 (cond [(eq_attr "alternative" "1")
9268 (const_string "lea")
9269 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
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" "SI")])
9286 (define_insn "*ashlhi3_1"
9287 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9288 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9289 (match_operand:QI 2 "nonmemory_operand" "cI")))
9290 (clobber (reg:CC FLAGS_REG))]
9291 "TARGET_PARTIAL_REG_STALL
9292 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9294 switch (get_attr_type (insn))
9297 gcc_assert (operands[2] == const1_rtx);
9298 return "add{w}\t%0, %0";
9301 if (operands[2] == const1_rtx
9302 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9303 return "sal{w}\t%0";
9305 return "sal{w}\t{%2, %0|%0, %2}";
9309 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9311 (match_operand 0 "register_operand" ""))
9312 (match_operand 2 "const1_operand" ""))
9313 (const_string "alu")
9315 (const_string "ishift")))
9316 (set (attr "length_immediate")
9318 (ior (eq_attr "type" "alu")
9319 (and (eq_attr "type" "ishift")
9320 (and (match_operand 2 "const1_operand" "")
9321 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9324 (const_string "*")))
9325 (set_attr "mode" "HI")])
9327 (define_insn "*ashlhi3_1_lea"
9328 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9329 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9330 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9331 (clobber (reg:CC FLAGS_REG))]
9332 "!TARGET_PARTIAL_REG_STALL
9333 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9335 switch (get_attr_type (insn))
9341 gcc_assert (operands[2] == const1_rtx);
9342 return "add{w}\t%0, %0";
9345 if (operands[2] == const1_rtx
9346 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9347 return "sal{w}\t%0";
9349 return "sal{w}\t{%2, %0|%0, %2}";
9353 (cond [(eq_attr "alternative" "1")
9354 (const_string "lea")
9355 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9357 (match_operand 0 "register_operand" ""))
9358 (match_operand 2 "const1_operand" ""))
9359 (const_string "alu")
9361 (const_string "ishift")))
9362 (set (attr "length_immediate")
9364 (ior (eq_attr "type" "alu")
9365 (and (eq_attr "type" "ishift")
9366 (and (match_operand 2 "const1_operand" "")
9367 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9370 (const_string "*")))
9371 (set_attr "mode" "HI,SI")])
9373 (define_insn "*ashlqi3_1"
9374 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9375 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9376 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9377 (clobber (reg:CC FLAGS_REG))]
9378 "TARGET_PARTIAL_REG_STALL
9379 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9381 switch (get_attr_type (insn))
9384 gcc_assert (operands[2] == const1_rtx);
9385 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9386 return "add{l}\t%k0, %k0";
9388 return "add{b}\t%0, %0";
9391 if (operands[2] == const1_rtx
9392 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9394 if (get_attr_mode (insn) == MODE_SI)
9395 return "sal{l}\t%k0";
9397 return "sal{b}\t%0";
9401 if (get_attr_mode (insn) == MODE_SI)
9402 return "sal{l}\t{%2, %k0|%k0, %2}";
9404 return "sal{b}\t{%2, %0|%0, %2}";
9409 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9411 (match_operand 0 "register_operand" ""))
9412 (match_operand 2 "const1_operand" ""))
9413 (const_string "alu")
9415 (const_string "ishift")))
9416 (set (attr "length_immediate")
9418 (ior (eq_attr "type" "alu")
9419 (and (eq_attr "type" "ishift")
9420 (and (match_operand 2 "const1_operand" "")
9421 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9424 (const_string "*")))
9425 (set_attr "mode" "QI,SI")])
9427 ;; %%% Potential partial reg stall on alternative 2. What to do?
9428 (define_insn "*ashlqi3_1_lea"
9429 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9430 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9431 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9432 (clobber (reg:CC FLAGS_REG))]
9433 "!TARGET_PARTIAL_REG_STALL
9434 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9436 switch (get_attr_type (insn))
9442 gcc_assert (operands[2] == const1_rtx);
9443 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9444 return "add{l}\t%k0, %k0";
9446 return "add{b}\t%0, %0";
9449 if (operands[2] == const1_rtx
9450 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9452 if (get_attr_mode (insn) == MODE_SI)
9453 return "sal{l}\t%k0";
9455 return "sal{b}\t%0";
9459 if (get_attr_mode (insn) == MODE_SI)
9460 return "sal{l}\t{%2, %k0|%k0, %2}";
9462 return "sal{b}\t{%2, %0|%0, %2}";
9467 (cond [(eq_attr "alternative" "2")
9468 (const_string "lea")
9469 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9471 (match_operand 0 "register_operand" ""))
9472 (match_operand 2 "const1_operand" ""))
9473 (const_string "alu")
9475 (const_string "ishift")))
9476 (set (attr "length_immediate")
9478 (ior (eq_attr "type" "alu")
9479 (and (eq_attr "type" "ishift")
9480 (and (match_operand 2 "const1_operand" "")
9481 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9484 (const_string "*")))
9485 (set_attr "mode" "QI,SI,SI")])
9487 (define_insn "*ashlqi3_1_slp"
9488 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9489 (ashift:QI (match_dup 0)
9490 (match_operand:QI 1 "nonmemory_operand" "cI")))
9491 (clobber (reg:CC FLAGS_REG))]
9492 "(optimize_function_for_size_p (cfun)
9493 || !TARGET_PARTIAL_FLAG_REG_STALL
9494 || (operands[1] == const1_rtx
9496 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9498 switch (get_attr_type (insn))
9501 gcc_assert (operands[1] == const1_rtx);
9502 return "add{b}\t%0, %0";
9505 if (operands[1] == const1_rtx
9506 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9507 return "sal{b}\t%0";
9509 return "sal{b}\t{%1, %0|%0, %1}";
9513 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9515 (match_operand 0 "register_operand" ""))
9516 (match_operand 1 "const1_operand" ""))
9517 (const_string "alu")
9519 (const_string "ishift1")))
9520 (set (attr "length_immediate")
9522 (ior (eq_attr "type" "alu")
9523 (and (eq_attr "type" "ishift1")
9524 (and (match_operand 1 "const1_operand" "")
9525 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9528 (const_string "*")))
9529 (set_attr "mode" "QI")])
9531 ;; Convert lea to the lea pattern to avoid flags dependency.
9533 [(set (match_operand:DI 0 "register_operand" "")
9534 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9535 (match_operand:QI 2 "const_int_operand" "")))
9536 (clobber (reg:CC FLAGS_REG))]
9537 "TARGET_64BIT && reload_completed
9538 && true_regnum (operands[0]) != true_regnum (operands[1])"
9540 (mult:DI (match_dup 1)
9542 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9544 ;; Convert lea to the lea pattern to avoid flags dependency.
9546 [(set (match_operand 0 "register_operand" "")
9547 (ashift (match_operand 1 "index_register_operand" "")
9548 (match_operand:QI 2 "const_int_operand" "")))
9549 (clobber (reg:CC FLAGS_REG))]
9551 && true_regnum (operands[0]) != true_regnum (operands[1])
9552 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
9556 enum machine_mode mode = GET_MODE (operands[0]);
9558 if (GET_MODE_SIZE (mode) < 4)
9559 operands[0] = gen_lowpart (SImode, operands[0]);
9561 operands[1] = gen_lowpart (Pmode, operands[1]);
9562 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9564 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9565 if (Pmode != SImode)
9566 pat = gen_rtx_SUBREG (SImode, pat, 0);
9567 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9571 ;; Rare case of shifting RSP is handled by generating move and shift
9573 [(set (match_operand 0 "register_operand" "")
9574 (ashift (match_operand 1 "register_operand" "")
9575 (match_operand:QI 2 "const_int_operand" "")))
9576 (clobber (reg:CC FLAGS_REG))]
9578 && true_regnum (operands[0]) != true_regnum (operands[1])"
9582 emit_move_insn (operands[0], operands[1]);
9583 pat = gen_rtx_SET (VOIDmode, operands[0],
9584 gen_rtx_ASHIFT (GET_MODE (operands[0]),
9585 operands[0], operands[2]));
9586 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
9587 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
9591 ;; Convert lea to the lea pattern to avoid flags dependency.
9593 [(set (match_operand:DI 0 "register_operand" "")
9595 (ashift:SI (match_operand:SI 1 "register_operand" "")
9596 (match_operand:QI 2 "const_int_operand" ""))))
9597 (clobber (reg:CC FLAGS_REG))]
9598 "TARGET_64BIT && reload_completed
9599 && true_regnum (operands[0]) != true_regnum (operands[1])"
9601 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9603 operands[1] = gen_lowpart (Pmode, operands[1]);
9604 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9607 ;; This pattern can't accept a variable shift count, since shifts by
9608 ;; zero don't affect the flags. We assume that shifts by constant
9609 ;; zero are optimized away.
9610 (define_insn "*ashl<mode>3_cmp"
9611 [(set (reg FLAGS_REG)
9613 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9614 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9616 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9617 (ashift:SWI (match_dup 1) (match_dup 2)))]
9618 "(optimize_function_for_size_p (cfun)
9619 || !TARGET_PARTIAL_FLAG_REG_STALL
9620 || (operands[2] == const1_rtx
9622 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9623 && ix86_match_ccmode (insn, CCGOCmode)
9624 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9626 switch (get_attr_type (insn))
9629 gcc_assert (operands[2] == const1_rtx);
9630 return "add{<imodesuffix>}\t%0, %0";
9633 if (operands[2] == const1_rtx
9634 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9635 return "sal{<imodesuffix>}\t%0";
9637 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9641 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9643 (match_operand 0 "register_operand" ""))
9644 (match_operand 2 "const1_operand" ""))
9645 (const_string "alu")
9647 (const_string "ishift")))
9648 (set (attr "length_immediate")
9650 (ior (eq_attr "type" "alu")
9651 (and (eq_attr "type" "ishift")
9652 (and (match_operand 2 "const1_operand" "")
9653 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9656 (const_string "*")))
9657 (set_attr "mode" "<MODE>")])
9659 (define_insn "*ashlsi3_cmp_zext"
9660 [(set (reg FLAGS_REG)
9662 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9663 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9665 (set (match_operand:DI 0 "register_operand" "=r")
9666 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9668 && (optimize_function_for_size_p (cfun)
9669 || !TARGET_PARTIAL_FLAG_REG_STALL
9670 || (operands[2] == const1_rtx
9672 || TARGET_DOUBLE_WITH_ADD)))
9673 && ix86_match_ccmode (insn, CCGOCmode)
9674 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9676 switch (get_attr_type (insn))
9679 gcc_assert (operands[2] == const1_rtx);
9680 return "add{l}\t%k0, %k0";
9683 if (operands[2] == const1_rtx
9684 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9685 return "sal{l}\t%k0";
9687 return "sal{l}\t{%2, %k0|%k0, %2}";
9691 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9693 (match_operand 2 "const1_operand" ""))
9694 (const_string "alu")
9696 (const_string "ishift")))
9697 (set (attr "length_immediate")
9699 (ior (eq_attr "type" "alu")
9700 (and (eq_attr "type" "ishift")
9701 (and (match_operand 2 "const1_operand" "")
9702 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9705 (const_string "*")))
9706 (set_attr "mode" "SI")])
9708 (define_insn "*ashl<mode>3_cconly"
9709 [(set (reg FLAGS_REG)
9711 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9712 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9714 (clobber (match_scratch:SWI 0 "=<r>"))]
9715 "(optimize_function_for_size_p (cfun)
9716 || !TARGET_PARTIAL_FLAG_REG_STALL
9717 || (operands[2] == const1_rtx
9719 || TARGET_DOUBLE_WITH_ADD)))
9720 && ix86_match_ccmode (insn, CCGOCmode)
9721 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9723 switch (get_attr_type (insn))
9726 gcc_assert (operands[2] == const1_rtx);
9727 return "add{<imodesuffix>}\t%0, %0";
9730 if (operands[2] == const1_rtx
9731 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9732 return "sal{<imodesuffix>}\t%0";
9734 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9738 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9740 (match_operand 0 "register_operand" ""))
9741 (match_operand 2 "const1_operand" ""))
9742 (const_string "alu")
9744 (const_string "ishift")))
9745 (set (attr "length_immediate")
9747 (ior (eq_attr "type" "alu")
9748 (and (eq_attr "type" "ishift")
9749 (and (match_operand 2 "const1_operand" "")
9750 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9753 (const_string "*")))
9754 (set_attr "mode" "<MODE>")])
9756 ;; See comment above `ashl<mode>3' about how this works.
9758 (define_expand "<shiftrt_insn><mode>3"
9759 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9760 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9761 (match_operand:QI 2 "nonmemory_operand" "")))]
9763 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9765 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9766 [(set (match_operand:DWI 0 "register_operand" "=r")
9767 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9768 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9769 (clobber (reg:CC FLAGS_REG))]
9772 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9774 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9775 [(set_attr "type" "multi")])
9777 ;; By default we don't ask for a scratch register, because when DWImode
9778 ;; values are manipulated, registers are already at a premium. But if
9779 ;; we have one handy, we won't turn it away.
9782 [(match_scratch:DWIH 3 "r")
9783 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9785 (match_operand:<DWI> 1 "register_operand" "")
9786 (match_operand:QI 2 "nonmemory_operand" "")))
9787 (clobber (reg:CC FLAGS_REG))])
9791 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9793 (define_insn "x86_64_shrd"
9794 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9795 (ior:DI (ashiftrt:DI (match_dup 0)
9796 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9797 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9798 (minus:QI (const_int 64) (match_dup 2)))))
9799 (clobber (reg:CC FLAGS_REG))]
9801 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9802 [(set_attr "type" "ishift")
9803 (set_attr "prefix_0f" "1")
9804 (set_attr "mode" "DI")
9805 (set_attr "athlon_decode" "vector")
9806 (set_attr "amdfam10_decode" "vector")])
9808 (define_insn "x86_shrd"
9809 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9810 (ior:SI (ashiftrt:SI (match_dup 0)
9811 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9812 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9813 (minus:QI (const_int 32) (match_dup 2)))))
9814 (clobber (reg:CC FLAGS_REG))]
9816 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9817 [(set_attr "type" "ishift")
9818 (set_attr "prefix_0f" "1")
9819 (set_attr "mode" "SI")
9820 (set_attr "pent_pair" "np")
9821 (set_attr "athlon_decode" "vector")
9822 (set_attr "amdfam10_decode" "vector")])
9824 (define_insn "ashrdi3_cvt"
9825 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9826 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9827 (match_operand:QI 2 "const_int_operand" "")))
9828 (clobber (reg:CC FLAGS_REG))]
9829 "TARGET_64BIT && INTVAL (operands[2]) == 63
9830 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9831 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9834 sar{q}\t{%2, %0|%0, %2}"
9835 [(set_attr "type" "imovx,ishift")
9836 (set_attr "prefix_0f" "0,*")
9837 (set_attr "length_immediate" "0,*")
9838 (set_attr "modrm" "0,1")
9839 (set_attr "mode" "DI")])
9841 (define_insn "ashrsi3_cvt"
9842 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9843 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9844 (match_operand:QI 2 "const_int_operand" "")))
9845 (clobber (reg:CC FLAGS_REG))]
9846 "INTVAL (operands[2]) == 31
9847 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9848 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9851 sar{l}\t{%2, %0|%0, %2}"
9852 [(set_attr "type" "imovx,ishift")
9853 (set_attr "prefix_0f" "0,*")
9854 (set_attr "length_immediate" "0,*")
9855 (set_attr "modrm" "0,1")
9856 (set_attr "mode" "SI")])
9858 (define_insn "*ashrsi3_cvt_zext"
9859 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9861 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9862 (match_operand:QI 2 "const_int_operand" ""))))
9863 (clobber (reg:CC FLAGS_REG))]
9864 "TARGET_64BIT && INTVAL (operands[2]) == 31
9865 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9866 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9869 sar{l}\t{%2, %k0|%k0, %2}"
9870 [(set_attr "type" "imovx,ishift")
9871 (set_attr "prefix_0f" "0,*")
9872 (set_attr "length_immediate" "0,*")
9873 (set_attr "modrm" "0,1")
9874 (set_attr "mode" "SI")])
9876 (define_expand "x86_shift<mode>_adj_3"
9877 [(use (match_operand:SWI48 0 "register_operand" ""))
9878 (use (match_operand:SWI48 1 "register_operand" ""))
9879 (use (match_operand:QI 2 "register_operand" ""))]
9882 rtx label = gen_label_rtx ();
9885 emit_insn (gen_testqi_ccz_1 (operands[2],
9886 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9888 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9889 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9890 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9891 gen_rtx_LABEL_REF (VOIDmode, label),
9893 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9894 JUMP_LABEL (tmp) = label;
9896 emit_move_insn (operands[0], operands[1]);
9897 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9898 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9900 LABEL_NUSES (label) = 1;
9905 (define_insn "*<shiftrt_insn><mode>3_1"
9906 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9907 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9908 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9909 (clobber (reg:CC FLAGS_REG))]
9910 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9912 if (operands[2] == const1_rtx
9913 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9914 return "<shiftrt>{<imodesuffix>}\t%0";
9916 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9918 [(set_attr "type" "ishift")
9919 (set (attr "length_immediate")
9921 (and (match_operand 2 "const1_operand" "")
9922 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9925 (const_string "*")))
9926 (set_attr "mode" "<MODE>")])
9928 (define_insn "*<shiftrt_insn>si3_1_zext"
9929 [(set (match_operand:DI 0 "register_operand" "=r")
9931 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9932 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9933 (clobber (reg:CC FLAGS_REG))]
9934 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9936 if (operands[2] == const1_rtx
9937 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9938 return "<shiftrt>{l}\t%k0";
9940 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9942 [(set_attr "type" "ishift")
9943 (set (attr "length_immediate")
9945 (and (match_operand 2 "const1_operand" "")
9946 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9949 (const_string "*")))
9950 (set_attr "mode" "SI")])
9952 (define_insn "*<shiftrt_insn>qi3_1_slp"
9953 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9954 (any_shiftrt:QI (match_dup 0)
9955 (match_operand:QI 1 "nonmemory_operand" "cI")))
9956 (clobber (reg:CC FLAGS_REG))]
9957 "(optimize_function_for_size_p (cfun)
9958 || !TARGET_PARTIAL_REG_STALL
9959 || (operands[1] == const1_rtx
9962 if (operands[1] == const1_rtx
9963 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9964 return "<shiftrt>{b}\t%0";
9966 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9968 [(set_attr "type" "ishift1")
9969 (set (attr "length_immediate")
9971 (and (match_operand 1 "const1_operand" "")
9972 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9975 (const_string "*")))
9976 (set_attr "mode" "QI")])
9978 ;; This pattern can't accept a variable shift count, since shifts by
9979 ;; zero don't affect the flags. We assume that shifts by constant
9980 ;; zero are optimized away.
9981 (define_insn "*<shiftrt_insn><mode>3_cmp"
9982 [(set (reg FLAGS_REG)
9985 (match_operand:SWI 1 "nonimmediate_operand" "0")
9986 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9988 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9989 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9990 "(optimize_function_for_size_p (cfun)
9991 || !TARGET_PARTIAL_FLAG_REG_STALL
9992 || (operands[2] == const1_rtx
9994 && ix86_match_ccmode (insn, CCGOCmode)
9995 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9997 if (operands[2] == const1_rtx
9998 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9999 return "<shiftrt>{<imodesuffix>}\t%0";
10001 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10003 [(set_attr "type" "ishift")
10004 (set (attr "length_immediate")
10006 (and (match_operand 2 "const1_operand" "")
10007 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10010 (const_string "*")))
10011 (set_attr "mode" "<MODE>")])
10013 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10014 [(set (reg FLAGS_REG)
10016 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10017 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10019 (set (match_operand:DI 0 "register_operand" "=r")
10020 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10022 && (optimize_function_for_size_p (cfun)
10023 || !TARGET_PARTIAL_FLAG_REG_STALL
10024 || (operands[2] == const1_rtx
10026 && ix86_match_ccmode (insn, CCGOCmode)
10027 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10029 if (operands[2] == const1_rtx
10030 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10031 return "<shiftrt>{l}\t%k0";
10033 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10035 [(set_attr "type" "ishift")
10036 (set (attr "length_immediate")
10038 (and (match_operand 2 "const1_operand" "")
10039 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10042 (const_string "*")))
10043 (set_attr "mode" "SI")])
10045 (define_insn "*<shiftrt_insn><mode>3_cconly"
10046 [(set (reg FLAGS_REG)
10049 (match_operand:SWI 1 "nonimmediate_operand" "0")
10050 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10052 (clobber (match_scratch:SWI 0 "=<r>"))]
10053 "(optimize_function_for_size_p (cfun)
10054 || !TARGET_PARTIAL_FLAG_REG_STALL
10055 || (operands[2] == const1_rtx
10057 && ix86_match_ccmode (insn, CCGOCmode)
10058 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10060 if (operands[2] == const1_rtx
10061 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10062 return "<shiftrt>{<imodesuffix>}\t%0";
10064 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10066 [(set_attr "type" "ishift")
10067 (set (attr "length_immediate")
10069 (and (match_operand 2 "const1_operand" "")
10070 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10073 (const_string "*")))
10074 (set_attr "mode" "<MODE>")])
10076 ;; Rotate instructions
10078 (define_expand "<rotate_insn>ti3"
10079 [(set (match_operand:TI 0 "register_operand" "")
10080 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10081 (match_operand:QI 2 "nonmemory_operand" "")))]
10084 if (const_1_to_63_operand (operands[2], VOIDmode))
10085 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10086 (operands[0], operands[1], operands[2]));
10093 (define_expand "<rotate_insn>di3"
10094 [(set (match_operand:DI 0 "shiftdi_operand" "")
10095 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10096 (match_operand:QI 2 "nonmemory_operand" "")))]
10100 ix86_expand_binary_operator (<CODE>, DImode, operands);
10101 else if (const_1_to_31_operand (operands[2], VOIDmode))
10102 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10103 (operands[0], operands[1], operands[2]));
10110 (define_expand "<rotate_insn><mode>3"
10111 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10112 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10113 (match_operand:QI 2 "nonmemory_operand" "")))]
10115 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10117 ;; Implement rotation using two double-precision
10118 ;; shift instructions and a scratch register.
10120 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10121 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10122 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10123 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10124 (clobber (reg:CC FLAGS_REG))
10125 (clobber (match_scratch:DWIH 3 "=&r"))]
10129 [(set (match_dup 3) (match_dup 4))
10131 [(set (match_dup 4)
10132 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10133 (lshiftrt:DWIH (match_dup 5)
10134 (minus:QI (match_dup 6) (match_dup 2)))))
10135 (clobber (reg:CC FLAGS_REG))])
10137 [(set (match_dup 5)
10138 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10139 (lshiftrt:DWIH (match_dup 3)
10140 (minus:QI (match_dup 6) (match_dup 2)))))
10141 (clobber (reg:CC FLAGS_REG))])]
10143 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10145 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10148 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10149 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10150 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10151 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10152 (clobber (reg:CC FLAGS_REG))
10153 (clobber (match_scratch:DWIH 3 "=&r"))]
10157 [(set (match_dup 3) (match_dup 4))
10159 [(set (match_dup 4)
10160 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10161 (ashift:DWIH (match_dup 5)
10162 (minus:QI (match_dup 6) (match_dup 2)))))
10163 (clobber (reg:CC FLAGS_REG))])
10165 [(set (match_dup 5)
10166 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10167 (ashift:DWIH (match_dup 3)
10168 (minus:QI (match_dup 6) (match_dup 2)))))
10169 (clobber (reg:CC FLAGS_REG))])]
10171 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10173 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10176 (define_insn "*<rotate_insn><mode>3_1"
10177 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10178 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10179 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10180 (clobber (reg:CC FLAGS_REG))]
10181 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10183 if (operands[2] == const1_rtx
10184 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10185 return "<rotate>{<imodesuffix>}\t%0";
10187 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10189 [(set_attr "type" "rotate")
10190 (set (attr "length_immediate")
10192 (and (match_operand 2 "const1_operand" "")
10193 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10196 (const_string "*")))
10197 (set_attr "mode" "<MODE>")])
10199 (define_insn "*<rotate_insn>si3_1_zext"
10200 [(set (match_operand:DI 0 "register_operand" "=r")
10202 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10203 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10204 (clobber (reg:CC FLAGS_REG))]
10205 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10207 if (operands[2] == const1_rtx
10208 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10209 return "<rotate>{l}\t%k0";
10211 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10213 [(set_attr "type" "rotate")
10214 (set (attr "length_immediate")
10216 (and (match_operand 2 "const1_operand" "")
10217 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10220 (const_string "*")))
10221 (set_attr "mode" "SI")])
10223 (define_insn "*<rotate_insn>qi3_1_slp"
10224 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10225 (any_rotate:QI (match_dup 0)
10226 (match_operand:QI 1 "nonmemory_operand" "cI")))
10227 (clobber (reg:CC FLAGS_REG))]
10228 "(optimize_function_for_size_p (cfun)
10229 || !TARGET_PARTIAL_REG_STALL
10230 || (operands[1] == const1_rtx
10231 && TARGET_SHIFT1))"
10233 if (operands[1] == const1_rtx
10234 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10235 return "<rotate>{b}\t%0";
10237 return "<rotate>{b}\t{%1, %0|%0, %1}";
10239 [(set_attr "type" "rotate1")
10240 (set (attr "length_immediate")
10242 (and (match_operand 1 "const1_operand" "")
10243 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10246 (const_string "*")))
10247 (set_attr "mode" "QI")])
10250 [(set (match_operand:HI 0 "register_operand" "")
10251 (any_rotate:HI (match_dup 0) (const_int 8)))
10252 (clobber (reg:CC FLAGS_REG))]
10254 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10255 [(parallel [(set (strict_low_part (match_dup 0))
10256 (bswap:HI (match_dup 0)))
10257 (clobber (reg:CC FLAGS_REG))])]
10260 ;; Bit set / bit test instructions
10262 (define_expand "extv"
10263 [(set (match_operand:SI 0 "register_operand" "")
10264 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10265 (match_operand:SI 2 "const8_operand" "")
10266 (match_operand:SI 3 "const8_operand" "")))]
10269 /* Handle extractions from %ah et al. */
10270 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10273 /* From mips.md: extract_bit_field doesn't verify that our source
10274 matches the predicate, so check it again here. */
10275 if (! ext_register_operand (operands[1], VOIDmode))
10279 (define_expand "extzv"
10280 [(set (match_operand:SI 0 "register_operand" "")
10281 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10282 (match_operand:SI 2 "const8_operand" "")
10283 (match_operand:SI 3 "const8_operand" "")))]
10286 /* Handle extractions from %ah et al. */
10287 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10290 /* From mips.md: extract_bit_field doesn't verify that our source
10291 matches the predicate, so check it again here. */
10292 if (! ext_register_operand (operands[1], VOIDmode))
10296 (define_expand "insv"
10297 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10298 (match_operand 1 "const8_operand" "")
10299 (match_operand 2 "const8_operand" ""))
10300 (match_operand 3 "register_operand" ""))]
10303 /* Handle insertions to %ah et al. */
10304 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10307 /* From mips.md: insert_bit_field doesn't verify that our source
10308 matches the predicate, so check it again here. */
10309 if (! ext_register_operand (operands[0], VOIDmode))
10313 emit_insn (gen_movdi_insv_1 (operands[0], operands[3]));
10315 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
10320 ;; %%% bts, btr, btc, bt.
10321 ;; In general these instructions are *slow* when applied to memory,
10322 ;; since they enforce atomic operation. When applied to registers,
10323 ;; it depends on the cpu implementation. They're never faster than
10324 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10325 ;; no point. But in 64-bit, we can't hold the relevant immediates
10326 ;; within the instruction itself, so operating on bits in the high
10327 ;; 32-bits of a register becomes easier.
10329 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10330 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10331 ;; negdf respectively, so they can never be disabled entirely.
10333 (define_insn "*btsq"
10334 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10336 (match_operand:DI 1 "const_0_to_63_operand" ""))
10338 (clobber (reg:CC FLAGS_REG))]
10339 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10340 "bts{q}\t{%1, %0|%0, %1}"
10341 [(set_attr "type" "alu1")
10342 (set_attr "prefix_0f" "1")
10343 (set_attr "mode" "DI")])
10345 (define_insn "*btrq"
10346 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10348 (match_operand:DI 1 "const_0_to_63_operand" ""))
10350 (clobber (reg:CC FLAGS_REG))]
10351 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10352 "btr{q}\t{%1, %0|%0, %1}"
10353 [(set_attr "type" "alu1")
10354 (set_attr "prefix_0f" "1")
10355 (set_attr "mode" "DI")])
10357 (define_insn "*btcq"
10358 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10360 (match_operand:DI 1 "const_0_to_63_operand" ""))
10361 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10362 (clobber (reg:CC FLAGS_REG))]
10363 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10364 "btc{q}\t{%1, %0|%0, %1}"
10365 [(set_attr "type" "alu1")
10366 (set_attr "prefix_0f" "1")
10367 (set_attr "mode" "DI")])
10369 ;; Allow Nocona to avoid these instructions if a register is available.
10372 [(match_scratch:DI 2 "r")
10373 (parallel [(set (zero_extract:DI
10374 (match_operand:DI 0 "register_operand" "")
10376 (match_operand:DI 1 "const_0_to_63_operand" ""))
10378 (clobber (reg:CC FLAGS_REG))])]
10379 "TARGET_64BIT && !TARGET_USE_BT"
10382 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10385 if (HOST_BITS_PER_WIDE_INT >= 64)
10386 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10387 else if (i < HOST_BITS_PER_WIDE_INT)
10388 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10390 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10392 op1 = immed_double_const (lo, hi, DImode);
10395 emit_move_insn (operands[2], op1);
10399 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10404 [(match_scratch:DI 2 "r")
10405 (parallel [(set (zero_extract:DI
10406 (match_operand:DI 0 "register_operand" "")
10408 (match_operand:DI 1 "const_0_to_63_operand" ""))
10410 (clobber (reg:CC FLAGS_REG))])]
10411 "TARGET_64BIT && !TARGET_USE_BT"
10414 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10417 if (HOST_BITS_PER_WIDE_INT >= 64)
10418 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10419 else if (i < HOST_BITS_PER_WIDE_INT)
10420 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10422 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10424 op1 = immed_double_const (~lo, ~hi, DImode);
10427 emit_move_insn (operands[2], op1);
10431 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10436 [(match_scratch:DI 2 "r")
10437 (parallel [(set (zero_extract:DI
10438 (match_operand:DI 0 "register_operand" "")
10440 (match_operand:DI 1 "const_0_to_63_operand" ""))
10441 (not:DI (zero_extract:DI
10442 (match_dup 0) (const_int 1) (match_dup 1))))
10443 (clobber (reg:CC FLAGS_REG))])]
10444 "TARGET_64BIT && !TARGET_USE_BT"
10447 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10450 if (HOST_BITS_PER_WIDE_INT >= 64)
10451 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10452 else if (i < HOST_BITS_PER_WIDE_INT)
10453 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10455 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10457 op1 = immed_double_const (lo, hi, DImode);
10460 emit_move_insn (operands[2], op1);
10464 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10468 (define_insn "*bt<mode>"
10469 [(set (reg:CCC FLAGS_REG)
10471 (zero_extract:SWI48
10472 (match_operand:SWI48 0 "register_operand" "r")
10474 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10476 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10477 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10478 [(set_attr "type" "alu1")
10479 (set_attr "prefix_0f" "1")
10480 (set_attr "mode" "<MODE>")])
10482 ;; Store-flag instructions.
10484 ;; For all sCOND expanders, also expand the compare or test insn that
10485 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10487 (define_insn_and_split "*setcc_di_1"
10488 [(set (match_operand:DI 0 "register_operand" "=q")
10489 (match_operator:DI 1 "ix86_comparison_operator"
10490 [(reg FLAGS_REG) (const_int 0)]))]
10491 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10493 "&& reload_completed"
10494 [(set (match_dup 2) (match_dup 1))
10495 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10497 PUT_MODE (operands[1], QImode);
10498 operands[2] = gen_lowpart (QImode, operands[0]);
10501 (define_insn_and_split "*setcc_si_1_and"
10502 [(set (match_operand:SI 0 "register_operand" "=q")
10503 (match_operator:SI 1 "ix86_comparison_operator"
10504 [(reg FLAGS_REG) (const_int 0)]))
10505 (clobber (reg:CC FLAGS_REG))]
10506 "!TARGET_PARTIAL_REG_STALL
10507 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10509 "&& reload_completed"
10510 [(set (match_dup 2) (match_dup 1))
10511 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10512 (clobber (reg:CC FLAGS_REG))])]
10514 PUT_MODE (operands[1], QImode);
10515 operands[2] = gen_lowpart (QImode, operands[0]);
10518 (define_insn_and_split "*setcc_si_1_movzbl"
10519 [(set (match_operand:SI 0 "register_operand" "=q")
10520 (match_operator:SI 1 "ix86_comparison_operator"
10521 [(reg FLAGS_REG) (const_int 0)]))]
10522 "!TARGET_PARTIAL_REG_STALL
10523 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10525 "&& reload_completed"
10526 [(set (match_dup 2) (match_dup 1))
10527 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10529 PUT_MODE (operands[1], QImode);
10530 operands[2] = gen_lowpart (QImode, operands[0]);
10533 (define_insn "*setcc_qi"
10534 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10535 (match_operator:QI 1 "ix86_comparison_operator"
10536 [(reg FLAGS_REG) (const_int 0)]))]
10539 [(set_attr "type" "setcc")
10540 (set_attr "mode" "QI")])
10542 (define_insn "*setcc_qi_slp"
10543 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10544 (match_operator:QI 1 "ix86_comparison_operator"
10545 [(reg FLAGS_REG) (const_int 0)]))]
10548 [(set_attr "type" "setcc")
10549 (set_attr "mode" "QI")])
10551 ;; In general it is not safe to assume too much about CCmode registers,
10552 ;; so simplify-rtx stops when it sees a second one. Under certain
10553 ;; conditions this is safe on x86, so help combine not create
10560 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10561 (ne:QI (match_operator 1 "ix86_comparison_operator"
10562 [(reg FLAGS_REG) (const_int 0)])
10565 [(set (match_dup 0) (match_dup 1))]
10567 PUT_MODE (operands[1], QImode);
10571 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10572 (ne:QI (match_operator 1 "ix86_comparison_operator"
10573 [(reg FLAGS_REG) (const_int 0)])
10576 [(set (match_dup 0) (match_dup 1))]
10578 PUT_MODE (operands[1], QImode);
10582 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10583 (eq:QI (match_operator 1 "ix86_comparison_operator"
10584 [(reg FLAGS_REG) (const_int 0)])
10587 [(set (match_dup 0) (match_dup 1))]
10589 rtx new_op1 = copy_rtx (operands[1]);
10590 operands[1] = new_op1;
10591 PUT_MODE (new_op1, QImode);
10592 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10593 GET_MODE (XEXP (new_op1, 0))));
10595 /* Make sure that (a) the CCmode we have for the flags is strong
10596 enough for the reversed compare or (b) we have a valid FP compare. */
10597 if (! ix86_comparison_operator (new_op1, VOIDmode))
10602 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10603 (eq:QI (match_operator 1 "ix86_comparison_operator"
10604 [(reg FLAGS_REG) (const_int 0)])
10607 [(set (match_dup 0) (match_dup 1))]
10609 rtx new_op1 = copy_rtx (operands[1]);
10610 operands[1] = new_op1;
10611 PUT_MODE (new_op1, QImode);
10612 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10613 GET_MODE (XEXP (new_op1, 0))));
10615 /* Make sure that (a) the CCmode we have for the flags is strong
10616 enough for the reversed compare or (b) we have a valid FP compare. */
10617 if (! ix86_comparison_operator (new_op1, VOIDmode))
10621 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10622 ;; subsequent logical operations are used to imitate conditional moves.
10623 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10626 (define_insn "*avx_setcc<mode>"
10627 [(set (match_operand:MODEF 0 "register_operand" "=x")
10628 (match_operator:MODEF 1 "avx_comparison_float_operator"
10629 [(match_operand:MODEF 2 "register_operand" "x")
10630 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10632 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10633 [(set_attr "type" "ssecmp")
10634 (set_attr "prefix" "vex")
10635 (set_attr "length_immediate" "1")
10636 (set_attr "mode" "<MODE>")])
10638 (define_insn "*sse_setcc<mode>"
10639 [(set (match_operand:MODEF 0 "register_operand" "=x")
10640 (match_operator:MODEF 1 "sse_comparison_operator"
10641 [(match_operand:MODEF 2 "register_operand" "0")
10642 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10643 "SSE_FLOAT_MODE_P (<MODE>mode)"
10644 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10645 [(set_attr "type" "ssecmp")
10646 (set_attr "length_immediate" "1")
10647 (set_attr "mode" "<MODE>")])
10649 ;; Basic conditional jump instructions.
10650 ;; We ignore the overflow flag for signed branch instructions.
10652 (define_insn "*jcc_1"
10654 (if_then_else (match_operator 1 "ix86_comparison_operator"
10655 [(reg FLAGS_REG) (const_int 0)])
10656 (label_ref (match_operand 0 "" ""))
10660 [(set_attr "type" "ibr")
10661 (set_attr "modrm" "0")
10662 (set (attr "length")
10663 (if_then_else (and (ge (minus (match_dup 0) (pc))
10665 (lt (minus (match_dup 0) (pc))
10670 (define_insn "*jcc_2"
10672 (if_then_else (match_operator 1 "ix86_comparison_operator"
10673 [(reg FLAGS_REG) (const_int 0)])
10675 (label_ref (match_operand 0 "" ""))))]
10678 [(set_attr "type" "ibr")
10679 (set_attr "modrm" "0")
10680 (set (attr "length")
10681 (if_then_else (and (ge (minus (match_dup 0) (pc))
10683 (lt (minus (match_dup 0) (pc))
10688 ;; In general it is not safe to assume too much about CCmode registers,
10689 ;; so simplify-rtx stops when it sees a second one. Under certain
10690 ;; conditions this is safe on x86, so help combine not create
10698 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10699 [(reg FLAGS_REG) (const_int 0)])
10701 (label_ref (match_operand 1 "" ""))
10705 (if_then_else (match_dup 0)
10706 (label_ref (match_dup 1))
10709 PUT_MODE (operands[0], VOIDmode);
10714 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10715 [(reg FLAGS_REG) (const_int 0)])
10717 (label_ref (match_operand 1 "" ""))
10721 (if_then_else (match_dup 0)
10722 (label_ref (match_dup 1))
10725 rtx new_op0 = copy_rtx (operands[0]);
10726 operands[0] = new_op0;
10727 PUT_MODE (new_op0, VOIDmode);
10728 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10729 GET_MODE (XEXP (new_op0, 0))));
10731 /* Make sure that (a) the CCmode we have for the flags is strong
10732 enough for the reversed compare or (b) we have a valid FP compare. */
10733 if (! ix86_comparison_operator (new_op0, VOIDmode))
10737 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10738 ;; pass generates from shift insn with QImode operand. Actually, the mode
10739 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10740 ;; appropriate modulo of the bit offset value.
10742 (define_insn_and_split "*jcc_bt<mode>"
10744 (if_then_else (match_operator 0 "bt_comparison_operator"
10745 [(zero_extract:SWI48
10746 (match_operand:SWI48 1 "register_operand" "r")
10749 (match_operand:QI 2 "register_operand" "r")))
10751 (label_ref (match_operand 3 "" ""))
10753 (clobber (reg:CC FLAGS_REG))]
10754 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10757 [(set (reg:CCC FLAGS_REG)
10759 (zero_extract:SWI48
10765 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10766 (label_ref (match_dup 3))
10769 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10771 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10774 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10775 ;; also for DImode, this is what combine produces.
10776 (define_insn_and_split "*jcc_bt<mode>_mask"
10778 (if_then_else (match_operator 0 "bt_comparison_operator"
10779 [(zero_extract:SWI48
10780 (match_operand:SWI48 1 "register_operand" "r")
10783 (match_operand:SI 2 "register_operand" "r")
10784 (match_operand:SI 3 "const_int_operand" "n")))])
10785 (label_ref (match_operand 4 "" ""))
10787 (clobber (reg:CC FLAGS_REG))]
10788 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10789 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10790 == GET_MODE_BITSIZE (<MODE>mode)-1"
10793 [(set (reg:CCC FLAGS_REG)
10795 (zero_extract:SWI48
10801 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10802 (label_ref (match_dup 4))
10805 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10807 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10810 (define_insn_and_split "*jcc_btsi_1"
10812 (if_then_else (match_operator 0 "bt_comparison_operator"
10815 (match_operand:SI 1 "register_operand" "r")
10816 (match_operand:QI 2 "register_operand" "r"))
10819 (label_ref (match_operand 3 "" ""))
10821 (clobber (reg:CC FLAGS_REG))]
10822 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10825 [(set (reg:CCC FLAGS_REG)
10833 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10834 (label_ref (match_dup 3))
10837 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10839 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10842 ;; avoid useless masking of bit offset operand
10843 (define_insn_and_split "*jcc_btsi_mask_1"
10846 (match_operator 0 "bt_comparison_operator"
10849 (match_operand:SI 1 "register_operand" "r")
10852 (match_operand:SI 2 "register_operand" "r")
10853 (match_operand:SI 3 "const_int_operand" "n")) 0))
10856 (label_ref (match_operand 4 "" ""))
10858 (clobber (reg:CC FLAGS_REG))]
10859 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10860 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10863 [(set (reg:CCC FLAGS_REG)
10871 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10872 (label_ref (match_dup 4))
10874 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10876 ;; Define combination compare-and-branch fp compare instructions to help
10879 (define_insn "*fp_jcc_1_387"
10881 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10882 [(match_operand 1 "register_operand" "f")
10883 (match_operand 2 "nonimmediate_operand" "fm")])
10884 (label_ref (match_operand 3 "" ""))
10886 (clobber (reg:CCFP FPSR_REG))
10887 (clobber (reg:CCFP FLAGS_REG))
10888 (clobber (match_scratch:HI 4 "=a"))]
10890 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10891 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10892 && SELECT_CC_MODE (GET_CODE (operands[0]),
10893 operands[1], operands[2]) == CCFPmode
10897 (define_insn "*fp_jcc_1r_387"
10899 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10900 [(match_operand 1 "register_operand" "f")
10901 (match_operand 2 "nonimmediate_operand" "fm")])
10903 (label_ref (match_operand 3 "" ""))))
10904 (clobber (reg:CCFP FPSR_REG))
10905 (clobber (reg:CCFP FLAGS_REG))
10906 (clobber (match_scratch:HI 4 "=a"))]
10908 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10909 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10910 && SELECT_CC_MODE (GET_CODE (operands[0]),
10911 operands[1], operands[2]) == CCFPmode
10915 (define_insn "*fp_jcc_2_387"
10917 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10918 [(match_operand 1 "register_operand" "f")
10919 (match_operand 2 "register_operand" "f")])
10920 (label_ref (match_operand 3 "" ""))
10922 (clobber (reg:CCFP FPSR_REG))
10923 (clobber (reg:CCFP FLAGS_REG))
10924 (clobber (match_scratch:HI 4 "=a"))]
10925 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10926 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10930 (define_insn "*fp_jcc_2r_387"
10932 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10933 [(match_operand 1 "register_operand" "f")
10934 (match_operand 2 "register_operand" "f")])
10936 (label_ref (match_operand 3 "" ""))))
10937 (clobber (reg:CCFP FPSR_REG))
10938 (clobber (reg:CCFP FLAGS_REG))
10939 (clobber (match_scratch:HI 4 "=a"))]
10940 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10941 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10945 (define_insn "*fp_jcc_3_387"
10947 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10948 [(match_operand 1 "register_operand" "f")
10949 (match_operand 2 "const0_operand" "")])
10950 (label_ref (match_operand 3 "" ""))
10952 (clobber (reg:CCFP FPSR_REG))
10953 (clobber (reg:CCFP FLAGS_REG))
10954 (clobber (match_scratch:HI 4 "=a"))]
10955 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10956 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10957 && SELECT_CC_MODE (GET_CODE (operands[0]),
10958 operands[1], operands[2]) == CCFPmode
10964 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10965 [(match_operand 1 "register_operand" "")
10966 (match_operand 2 "nonimmediate_operand" "")])
10967 (match_operand 3 "" "")
10968 (match_operand 4 "" "")))
10969 (clobber (reg:CCFP FPSR_REG))
10970 (clobber (reg:CCFP FLAGS_REG))]
10974 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10975 operands[3], operands[4], NULL_RTX, NULL_RTX);
10981 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10982 [(match_operand 1 "register_operand" "")
10983 (match_operand 2 "general_operand" "")])
10984 (match_operand 3 "" "")
10985 (match_operand 4 "" "")))
10986 (clobber (reg:CCFP FPSR_REG))
10987 (clobber (reg:CCFP FLAGS_REG))
10988 (clobber (match_scratch:HI 5 "=a"))]
10992 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10993 operands[3], operands[4], operands[5], NULL_RTX);
10997 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10998 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10999 ;; with a precedence over other operators and is always put in the first
11000 ;; place. Swap condition and operands to match ficom instruction.
11002 (define_insn "*fp_jcc_4_<mode>_387"
11005 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11006 [(match_operator 1 "float_operator"
11007 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11008 (match_operand 3 "register_operand" "f,f")])
11009 (label_ref (match_operand 4 "" ""))
11011 (clobber (reg:CCFP FPSR_REG))
11012 (clobber (reg:CCFP FLAGS_REG))
11013 (clobber (match_scratch:HI 5 "=a,a"))]
11014 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11015 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11016 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11017 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11024 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11025 [(match_operator 1 "float_operator"
11026 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11027 (match_operand 3 "register_operand" "")])
11028 (match_operand 4 "" "")
11029 (match_operand 5 "" "")))
11030 (clobber (reg:CCFP FPSR_REG))
11031 (clobber (reg:CCFP FLAGS_REG))
11032 (clobber (match_scratch:HI 6 "=a"))]
11036 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11038 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11039 operands[3], operands[7],
11040 operands[4], operands[5], operands[6], NULL_RTX);
11044 ;; %%% Kill this when reload knows how to do it.
11048 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11049 [(match_operator 1 "float_operator"
11050 [(match_operand:X87MODEI12 2 "register_operand" "")])
11051 (match_operand 3 "register_operand" "")])
11052 (match_operand 4 "" "")
11053 (match_operand 5 "" "")))
11054 (clobber (reg:CCFP FPSR_REG))
11055 (clobber (reg:CCFP FLAGS_REG))
11056 (clobber (match_scratch:HI 6 "=a"))]
11060 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11061 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11063 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11064 operands[3], operands[7],
11065 operands[4], operands[5], operands[6], operands[2]);
11069 ;; Unconditional and other jump instructions
11071 (define_insn "jump"
11073 (label_ref (match_operand 0 "" "")))]
11076 [(set_attr "type" "ibr")
11077 (set (attr "length")
11078 (if_then_else (and (ge (minus (match_dup 0) (pc))
11080 (lt (minus (match_dup 0) (pc))
11084 (set_attr "modrm" "0")])
11086 (define_expand "indirect_jump"
11087 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11091 (define_insn "*indirect_jump"
11092 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11095 [(set_attr "type" "ibr")
11096 (set_attr "length_immediate" "0")])
11098 (define_expand "tablejump"
11099 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11100 (use (label_ref (match_operand 1 "" "")))])]
11103 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11104 relative. Convert the relative address to an absolute address. */
11108 enum rtx_code code;
11110 /* We can't use @GOTOFF for text labels on VxWorks;
11111 see gotoff_operand. */
11112 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11116 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11118 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11122 op1 = pic_offset_table_rtx;
11127 op0 = pic_offset_table_rtx;
11131 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11136 (define_insn "*tablejump_1"
11137 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11138 (use (label_ref (match_operand 1 "" "")))]
11141 [(set_attr "type" "ibr")
11142 (set_attr "length_immediate" "0")])
11144 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11147 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11148 (set (match_operand:QI 1 "register_operand" "")
11149 (match_operator:QI 2 "ix86_comparison_operator"
11150 [(reg FLAGS_REG) (const_int 0)]))
11151 (set (match_operand 3 "q_regs_operand" "")
11152 (zero_extend (match_dup 1)))]
11153 "(peep2_reg_dead_p (3, operands[1])
11154 || operands_match_p (operands[1], operands[3]))
11155 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11156 [(set (match_dup 4) (match_dup 0))
11157 (set (strict_low_part (match_dup 5))
11160 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11161 operands[5] = gen_lowpart (QImode, operands[3]);
11162 ix86_expand_clear (operands[3]);
11165 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11168 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11169 (set (match_operand:QI 1 "register_operand" "")
11170 (match_operator:QI 2 "ix86_comparison_operator"
11171 [(reg FLAGS_REG) (const_int 0)]))
11172 (parallel [(set (match_operand 3 "q_regs_operand" "")
11173 (zero_extend (match_dup 1)))
11174 (clobber (reg:CC FLAGS_REG))])]
11175 "(peep2_reg_dead_p (3, operands[1])
11176 || operands_match_p (operands[1], operands[3]))
11177 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11178 [(set (match_dup 4) (match_dup 0))
11179 (set (strict_low_part (match_dup 5))
11182 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11183 operands[5] = gen_lowpart (QImode, operands[3]);
11184 ix86_expand_clear (operands[3]);
11187 ;; Call instructions.
11189 ;; The predicates normally associated with named expanders are not properly
11190 ;; checked for calls. This is a bug in the generic code, but it isn't that
11191 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11193 ;; P6 processors will jump to the address after the decrement when %esp
11194 ;; is used as a call operand, so they will execute return address as a code.
11195 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11197 ;; Call subroutine returning no value.
11199 (define_expand "call_pop"
11200 [(parallel [(call (match_operand:QI 0 "" "")
11201 (match_operand:SI 1 "" ""))
11202 (set (reg:SI SP_REG)
11203 (plus:SI (reg:SI SP_REG)
11204 (match_operand:SI 3 "" "")))])]
11207 ix86_expand_call (NULL, operands[0], operands[1],
11208 operands[2], operands[3], 0);
11212 (define_insn "*call_pop_0"
11213 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11214 (match_operand:SI 1 "" ""))
11215 (set (reg:SI SP_REG)
11216 (plus:SI (reg:SI SP_REG)
11217 (match_operand:SI 2 "immediate_operand" "")))]
11220 if (SIBLING_CALL_P (insn))
11223 return "call\t%P0";
11225 [(set_attr "type" "call")])
11227 (define_insn "*call_pop_1"
11228 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11229 (match_operand:SI 1 "" ""))
11230 (set (reg:SI SP_REG)
11231 (plus:SI (reg:SI SP_REG)
11232 (match_operand:SI 2 "immediate_operand" "i")))]
11233 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11235 if (constant_call_address_operand (operands[0], Pmode))
11236 return "call\t%P0";
11237 return "call\t%A0";
11239 [(set_attr "type" "call")])
11241 (define_insn "*sibcall_pop_1"
11242 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11243 (match_operand:SI 1 "" ""))
11244 (set (reg:SI SP_REG)
11245 (plus:SI (reg:SI SP_REG)
11246 (match_operand:SI 2 "immediate_operand" "i,i")))]
11247 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11251 [(set_attr "type" "call")])
11253 (define_expand "call"
11254 [(call (match_operand:QI 0 "" "")
11255 (match_operand 1 "" ""))
11256 (use (match_operand 2 "" ""))]
11259 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11263 (define_expand "sibcall"
11264 [(call (match_operand:QI 0 "" "")
11265 (match_operand 1 "" ""))
11266 (use (match_operand 2 "" ""))]
11269 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11273 (define_insn "*call_0"
11274 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11275 (match_operand 1 "" ""))]
11278 if (SIBLING_CALL_P (insn))
11281 return "call\t%P0";
11283 [(set_attr "type" "call")])
11285 (define_insn "*call_1"
11286 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11287 (match_operand 1 "" ""))]
11288 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11290 if (constant_call_address_operand (operands[0], Pmode))
11291 return "call\t%P0";
11292 return "call\t%A0";
11294 [(set_attr "type" "call")])
11296 (define_insn "*sibcall_1"
11297 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11298 (match_operand 1 "" ""))]
11299 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11303 [(set_attr "type" "call")])
11305 (define_insn "*call_1_rex64"
11306 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11307 (match_operand 1 "" ""))]
11308 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11309 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11311 if (constant_call_address_operand (operands[0], Pmode))
11312 return "call\t%P0";
11313 return "call\t%A0";
11315 [(set_attr "type" "call")])
11317 (define_insn "*call_1_rex64_ms_sysv"
11318 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11319 (match_operand 1 "" ""))
11320 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11321 (clobber (reg:TI XMM6_REG))
11322 (clobber (reg:TI XMM7_REG))
11323 (clobber (reg:TI XMM8_REG))
11324 (clobber (reg:TI XMM9_REG))
11325 (clobber (reg:TI XMM10_REG))
11326 (clobber (reg:TI XMM11_REG))
11327 (clobber (reg:TI XMM12_REG))
11328 (clobber (reg:TI XMM13_REG))
11329 (clobber (reg:TI XMM14_REG))
11330 (clobber (reg:TI XMM15_REG))
11331 (clobber (reg:DI SI_REG))
11332 (clobber (reg:DI DI_REG))]
11333 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11335 if (constant_call_address_operand (operands[0], Pmode))
11336 return "call\t%P0";
11337 return "call\t%A0";
11339 [(set_attr "type" "call")])
11341 (define_insn "*call_1_rex64_large"
11342 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11343 (match_operand 1 "" ""))]
11344 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11346 [(set_attr "type" "call")])
11348 (define_insn "*sibcall_1_rex64"
11349 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11350 (match_operand 1 "" ""))]
11351 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11355 [(set_attr "type" "call")])
11357 ;; Call subroutine, returning value in operand 0
11358 (define_expand "call_value_pop"
11359 [(parallel [(set (match_operand 0 "" "")
11360 (call (match_operand:QI 1 "" "")
11361 (match_operand:SI 2 "" "")))
11362 (set (reg:SI SP_REG)
11363 (plus:SI (reg:SI SP_REG)
11364 (match_operand:SI 4 "" "")))])]
11367 ix86_expand_call (operands[0], operands[1], operands[2],
11368 operands[3], operands[4], 0);
11372 (define_expand "call_value"
11373 [(set (match_operand 0 "" "")
11374 (call (match_operand:QI 1 "" "")
11375 (match_operand:SI 2 "" "")))
11376 (use (match_operand:SI 3 "" ""))]
11377 ;; Operand 3 is not used on the i386.
11380 ix86_expand_call (operands[0], operands[1], operands[2],
11381 operands[3], NULL, 0);
11385 (define_expand "sibcall_value"
11386 [(set (match_operand 0 "" "")
11387 (call (match_operand:QI 1 "" "")
11388 (match_operand:SI 2 "" "")))
11389 (use (match_operand:SI 3 "" ""))]
11390 ;; Operand 3 is not used on the i386.
11393 ix86_expand_call (operands[0], operands[1], operands[2],
11394 operands[3], NULL, 1);
11398 ;; Call subroutine returning any type.
11400 (define_expand "untyped_call"
11401 [(parallel [(call (match_operand 0 "" "")
11403 (match_operand 1 "" "")
11404 (match_operand 2 "" "")])]
11409 /* In order to give reg-stack an easier job in validating two
11410 coprocessor registers as containing a possible return value,
11411 simply pretend the untyped call returns a complex long double
11414 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11415 and should have the default ABI. */
11417 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11418 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11419 operands[0], const0_rtx,
11420 GEN_INT ((TARGET_64BIT
11421 ? (ix86_abi == SYSV_ABI
11422 ? X86_64_SSE_REGPARM_MAX
11423 : X86_64_MS_SSE_REGPARM_MAX)
11424 : X86_32_SSE_REGPARM_MAX)
11428 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11430 rtx set = XVECEXP (operands[2], 0, i);
11431 emit_move_insn (SET_DEST (set), SET_SRC (set));
11434 /* The optimizer does not know that the call sets the function value
11435 registers we stored in the result block. We avoid problems by
11436 claiming that all hard registers are used and clobbered at this
11438 emit_insn (gen_blockage ());
11443 ;; Prologue and epilogue instructions
11445 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11446 ;; all of memory. This blocks insns from being moved across this point.
11448 (define_insn "blockage"
11449 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11452 [(set_attr "length" "0")])
11454 ;; Do not schedule instructions accessing memory across this point.
11456 (define_expand "memory_blockage"
11457 [(set (match_dup 0)
11458 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11461 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11462 MEM_VOLATILE_P (operands[0]) = 1;
11465 (define_insn "*memory_blockage"
11466 [(set (match_operand:BLK 0 "" "")
11467 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11470 [(set_attr "length" "0")])
11472 ;; As USE insns aren't meaningful after reload, this is used instead
11473 ;; to prevent deleting instructions setting registers for PIC code
11474 (define_insn "prologue_use"
11475 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11478 [(set_attr "length" "0")])
11480 ;; Insn emitted into the body of a function to return from a function.
11481 ;; This is only done if the function's epilogue is known to be simple.
11482 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11484 (define_expand "return"
11486 "ix86_can_use_return_insn_p ()"
11488 if (crtl->args.pops_args)
11490 rtx popc = GEN_INT (crtl->args.pops_args);
11491 emit_jump_insn (gen_return_pop_internal (popc));
11496 (define_insn "return_internal"
11500 [(set_attr "length" "1")
11501 (set_attr "atom_unit" "jeu")
11502 (set_attr "length_immediate" "0")
11503 (set_attr "modrm" "0")])
11505 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11506 ;; instruction Athlon and K8 have.
11508 (define_insn "return_internal_long"
11510 (unspec [(const_int 0)] UNSPEC_REP)]
11513 [(set_attr "length" "2")
11514 (set_attr "atom_unit" "jeu")
11515 (set_attr "length_immediate" "0")
11516 (set_attr "prefix_rep" "1")
11517 (set_attr "modrm" "0")])
11519 (define_insn "return_pop_internal"
11521 (use (match_operand:SI 0 "const_int_operand" ""))]
11524 [(set_attr "length" "3")
11525 (set_attr "atom_unit" "jeu")
11526 (set_attr "length_immediate" "2")
11527 (set_attr "modrm" "0")])
11529 (define_insn "return_indirect_internal"
11531 (use (match_operand:SI 0 "register_operand" "r"))]
11534 [(set_attr "type" "ibr")
11535 (set_attr "length_immediate" "0")])
11541 [(set_attr "length" "1")
11542 (set_attr "length_immediate" "0")
11543 (set_attr "modrm" "0")])
11545 (define_insn "vswapmov"
11546 [(set (match_operand:SI 0 "register_operand" "=r")
11547 (match_operand:SI 1 "register_operand" "r"))
11548 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
11550 "movl.s\t{%1, %0|%0, %1}"
11551 [(set_attr "length" "2")
11552 (set_attr "length_immediate" "0")
11553 (set_attr "modrm" "0")])
11555 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11556 ;; branch prediction penalty for the third jump in a 16-byte
11560 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11563 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11564 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11566 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11567 The align insn is used to avoid 3 jump instructions in the row to improve
11568 branch prediction and the benefits hardly outweigh the cost of extra 8
11569 nops on the average inserted by full alignment pseudo operation. */
11573 [(set_attr "length" "16")])
11575 (define_expand "prologue"
11578 "ix86_expand_prologue (); DONE;")
11580 (define_insn "set_got"
11581 [(set (match_operand:SI 0 "register_operand" "=r")
11582 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11583 (clobber (reg:CC FLAGS_REG))]
11585 { return output_set_got (operands[0], NULL_RTX); }
11586 [(set_attr "type" "multi")
11587 (set_attr "length" "12")])
11589 (define_insn "set_got_labelled"
11590 [(set (match_operand:SI 0 "register_operand" "=r")
11591 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11593 (clobber (reg:CC FLAGS_REG))]
11595 { return output_set_got (operands[0], operands[1]); }
11596 [(set_attr "type" "multi")
11597 (set_attr "length" "12")])
11599 (define_insn "set_got_rex64"
11600 [(set (match_operand:DI 0 "register_operand" "=r")
11601 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11603 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11604 [(set_attr "type" "lea")
11605 (set_attr "length_address" "4")
11606 (set_attr "mode" "DI")])
11608 (define_insn "set_rip_rex64"
11609 [(set (match_operand:DI 0 "register_operand" "=r")
11610 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11612 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11613 [(set_attr "type" "lea")
11614 (set_attr "length_address" "4")
11615 (set_attr "mode" "DI")])
11617 (define_insn "set_got_offset_rex64"
11618 [(set (match_operand:DI 0 "register_operand" "=r")
11620 [(label_ref (match_operand 1 "" ""))]
11621 UNSPEC_SET_GOT_OFFSET))]
11623 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11624 [(set_attr "type" "imov")
11625 (set_attr "length_immediate" "0")
11626 (set_attr "length_address" "8")
11627 (set_attr "mode" "DI")])
11629 (define_expand "epilogue"
11632 "ix86_expand_epilogue (1); DONE;")
11634 (define_expand "sibcall_epilogue"
11637 "ix86_expand_epilogue (0); DONE;")
11639 (define_expand "eh_return"
11640 [(use (match_operand 0 "register_operand" ""))]
11643 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11645 /* Tricky bit: we write the address of the handler to which we will
11646 be returning into someone else's stack frame, one word below the
11647 stack address we wish to restore. */
11648 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11649 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11650 tmp = gen_rtx_MEM (Pmode, tmp);
11651 emit_move_insn (tmp, ra);
11653 emit_jump_insn (gen_eh_return_internal ());
11658 (define_insn_and_split "eh_return_internal"
11662 "epilogue_completed"
11664 "ix86_expand_epilogue (2); DONE;")
11666 (define_insn "leave"
11667 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11668 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11669 (clobber (mem:BLK (scratch)))]
11672 [(set_attr "type" "leave")])
11674 (define_insn "leave_rex64"
11675 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11676 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11677 (clobber (mem:BLK (scratch)))]
11680 [(set_attr "type" "leave")])
11682 ;; Bit manipulation instructions.
11684 (define_expand "ffs<mode>2"
11685 [(set (match_dup 2) (const_int -1))
11686 (parallel [(set (reg:CCZ FLAGS_REG)
11688 (match_operand:SWI48 1 "nonimmediate_operand" "")
11690 (set (match_operand:SWI48 0 "register_operand" "")
11691 (ctz:SWI48 (match_dup 1)))])
11692 (set (match_dup 0) (if_then_else:SWI48
11693 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11696 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11697 (clobber (reg:CC FLAGS_REG))])]
11700 if (<MODE>mode == SImode && !TARGET_CMOVE)
11702 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11705 operands[2] = gen_reg_rtx (<MODE>mode);
11708 (define_insn_and_split "ffssi2_no_cmove"
11709 [(set (match_operand:SI 0 "register_operand" "=r")
11710 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11711 (clobber (match_scratch:SI 2 "=&q"))
11712 (clobber (reg:CC FLAGS_REG))]
11715 "&& reload_completed"
11716 [(parallel [(set (reg:CCZ FLAGS_REG)
11717 (compare:CCZ (match_dup 1) (const_int 0)))
11718 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11719 (set (strict_low_part (match_dup 3))
11720 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11721 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11722 (clobber (reg:CC FLAGS_REG))])
11723 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11724 (clobber (reg:CC FLAGS_REG))])
11725 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11726 (clobber (reg:CC FLAGS_REG))])]
11728 operands[3] = gen_lowpart (QImode, operands[2]);
11729 ix86_expand_clear (operands[2]);
11732 (define_insn "*ffs<mode>_1"
11733 [(set (reg:CCZ FLAGS_REG)
11734 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11736 (set (match_operand:SWI48 0 "register_operand" "=r")
11737 (ctz:SWI48 (match_dup 1)))]
11739 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11740 [(set_attr "type" "alu1")
11741 (set_attr "prefix_0f" "1")
11742 (set_attr "mode" "<MODE>")])
11744 (define_insn "ctz<mode>2"
11745 [(set (match_operand:SWI48 0 "register_operand" "=r")
11746 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11747 (clobber (reg:CC FLAGS_REG))]
11749 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11750 [(set_attr "type" "alu1")
11751 (set_attr "prefix_0f" "1")
11752 (set_attr "mode" "<MODE>")])
11754 (define_expand "clz<mode>2"
11756 [(set (match_operand:SWI248 0 "register_operand" "")
11759 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11760 (clobber (reg:CC FLAGS_REG))])
11762 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11763 (clobber (reg:CC FLAGS_REG))])]
11768 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11771 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11774 (define_insn "clz<mode>2_abm"
11775 [(set (match_operand:SWI248 0 "register_operand" "=r")
11776 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11777 (clobber (reg:CC FLAGS_REG))]
11779 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11780 [(set_attr "prefix_rep" "1")
11781 (set_attr "type" "bitmanip")
11782 (set_attr "mode" "<MODE>")])
11784 (define_insn "bsr_rex64"
11785 [(set (match_operand:DI 0 "register_operand" "=r")
11786 (minus:DI (const_int 63)
11787 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11788 (clobber (reg:CC FLAGS_REG))]
11790 "bsr{q}\t{%1, %0|%0, %1}"
11791 [(set_attr "type" "alu1")
11792 (set_attr "prefix_0f" "1")
11793 (set_attr "mode" "DI")])
11796 [(set (match_operand:SI 0 "register_operand" "=r")
11797 (minus:SI (const_int 31)
11798 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11799 (clobber (reg:CC FLAGS_REG))]
11801 "bsr{l}\t{%1, %0|%0, %1}"
11802 [(set_attr "type" "alu1")
11803 (set_attr "prefix_0f" "1")
11804 (set_attr "mode" "SI")])
11806 (define_insn "*bsrhi"
11807 [(set (match_operand:HI 0 "register_operand" "=r")
11808 (minus:HI (const_int 15)
11809 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11810 (clobber (reg:CC FLAGS_REG))]
11812 "bsr{w}\t{%1, %0|%0, %1}"
11813 [(set_attr "type" "alu1")
11814 (set_attr "prefix_0f" "1")
11815 (set_attr "mode" "HI")])
11817 (define_insn "popcount<mode>2"
11818 [(set (match_operand:SWI248 0 "register_operand" "=r")
11820 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11821 (clobber (reg:CC FLAGS_REG))]
11825 return "popcnt\t{%1, %0|%0, %1}";
11827 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11830 [(set_attr "prefix_rep" "1")
11831 (set_attr "type" "bitmanip")
11832 (set_attr "mode" "<MODE>")])
11834 (define_insn "*popcount<mode>2_cmp"
11835 [(set (reg FLAGS_REG)
11838 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11840 (set (match_operand:SWI248 0 "register_operand" "=r")
11841 (popcount:SWI248 (match_dup 1)))]
11842 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11845 return "popcnt\t{%1, %0|%0, %1}";
11847 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11850 [(set_attr "prefix_rep" "1")
11851 (set_attr "type" "bitmanip")
11852 (set_attr "mode" "<MODE>")])
11854 (define_insn "*popcountsi2_cmp_zext"
11855 [(set (reg FLAGS_REG)
11857 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11859 (set (match_operand:DI 0 "register_operand" "=r")
11860 (zero_extend:DI(popcount:SI (match_dup 1))))]
11861 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11864 return "popcnt\t{%1, %0|%0, %1}";
11866 return "popcnt{l}\t{%1, %0|%0, %1}";
11869 [(set_attr "prefix_rep" "1")
11870 (set_attr "type" "bitmanip")
11871 (set_attr "mode" "SI")])
11873 (define_expand "bswap<mode>2"
11874 [(set (match_operand:SWI48 0 "register_operand" "")
11875 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11878 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11880 rtx x = operands[0];
11882 emit_move_insn (x, operands[1]);
11883 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11884 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11885 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11890 (define_insn "*bswap<mode>2_movbe"
11891 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11892 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11894 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11897 movbe\t{%1, %0|%0, %1}
11898 movbe\t{%1, %0|%0, %1}"
11899 [(set_attr "type" "bitmanip,imov,imov")
11900 (set_attr "modrm" "0,1,1")
11901 (set_attr "prefix_0f" "*,1,1")
11902 (set_attr "prefix_extra" "*,1,1")
11903 (set_attr "mode" "<MODE>")])
11905 (define_insn "*bswap<mode>2_1"
11906 [(set (match_operand:SWI48 0 "register_operand" "=r")
11907 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11910 [(set_attr "type" "bitmanip")
11911 (set_attr "modrm" "0")
11912 (set_attr "mode" "<MODE>")])
11914 (define_insn "*bswaphi_lowpart_1"
11915 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11916 (bswap:HI (match_dup 0)))
11917 (clobber (reg:CC FLAGS_REG))]
11918 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11920 xchg{b}\t{%h0, %b0|%b0, %h0}
11921 rol{w}\t{$8, %0|%0, 8}"
11922 [(set_attr "length" "2,4")
11923 (set_attr "mode" "QI,HI")])
11925 (define_insn "bswaphi_lowpart"
11926 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11927 (bswap:HI (match_dup 0)))
11928 (clobber (reg:CC FLAGS_REG))]
11930 "rol{w}\t{$8, %0|%0, 8}"
11931 [(set_attr "length" "4")
11932 (set_attr "mode" "HI")])
11934 (define_expand "paritydi2"
11935 [(set (match_operand:DI 0 "register_operand" "")
11936 (parity:DI (match_operand:DI 1 "register_operand" "")))]
11939 rtx scratch = gen_reg_rtx (QImode);
11942 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
11943 NULL_RTX, operands[1]));
11945 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11946 gen_rtx_REG (CCmode, FLAGS_REG),
11948 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11951 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
11954 rtx tmp = gen_reg_rtx (SImode);
11956 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
11957 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
11962 (define_expand "paritysi2"
11963 [(set (match_operand:SI 0 "register_operand" "")
11964 (parity:SI (match_operand:SI 1 "register_operand" "")))]
11967 rtx scratch = gen_reg_rtx (QImode);
11970 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
11972 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11973 gen_rtx_REG (CCmode, FLAGS_REG),
11975 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11977 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
11981 (define_insn_and_split "paritydi2_cmp"
11982 [(set (reg:CC FLAGS_REG)
11983 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
11985 (clobber (match_scratch:DI 0 "=r"))
11986 (clobber (match_scratch:SI 1 "=&r"))
11987 (clobber (match_scratch:HI 2 "=Q"))]
11990 "&& reload_completed"
11992 [(set (match_dup 1)
11993 (xor:SI (match_dup 1) (match_dup 4)))
11994 (clobber (reg:CC FLAGS_REG))])
11996 [(set (reg:CC FLAGS_REG)
11997 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11998 (clobber (match_dup 1))
11999 (clobber (match_dup 2))])]
12001 operands[4] = gen_lowpart (SImode, operands[3]);
12005 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12006 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12009 operands[1] = gen_highpart (SImode, operands[3]);
12012 (define_insn_and_split "paritysi2_cmp"
12013 [(set (reg:CC FLAGS_REG)
12014 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12016 (clobber (match_scratch:SI 0 "=r"))
12017 (clobber (match_scratch:HI 1 "=&Q"))]
12020 "&& reload_completed"
12022 [(set (match_dup 1)
12023 (xor:HI (match_dup 1) (match_dup 3)))
12024 (clobber (reg:CC FLAGS_REG))])
12026 [(set (reg:CC FLAGS_REG)
12027 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12028 (clobber (match_dup 1))])]
12030 operands[3] = gen_lowpart (HImode, operands[2]);
12032 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12033 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12036 (define_insn "*parityhi2_cmp"
12037 [(set (reg:CC FLAGS_REG)
12038 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12040 (clobber (match_scratch:HI 0 "=Q"))]
12042 "xor{b}\t{%h0, %b0|%b0, %h0}"
12043 [(set_attr "length" "2")
12044 (set_attr "mode" "HI")])
12046 ;; Thread-local storage patterns for ELF.
12048 ;; Note that these code sequences must appear exactly as shown
12049 ;; in order to allow linker relaxation.
12051 (define_insn "*tls_global_dynamic_32_gnu"
12052 [(set (match_operand:SI 0 "register_operand" "=a")
12053 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12054 (match_operand:SI 2 "tls_symbolic_operand" "")
12055 (match_operand:SI 3 "call_insn_operand" "")]
12057 (clobber (match_scratch:SI 4 "=d"))
12058 (clobber (match_scratch:SI 5 "=c"))
12059 (clobber (reg:CC FLAGS_REG))]
12060 "!TARGET_64BIT && TARGET_GNU_TLS"
12061 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12062 [(set_attr "type" "multi")
12063 (set_attr "length" "12")])
12065 (define_expand "tls_global_dynamic_32"
12066 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12069 (match_operand:SI 1 "tls_symbolic_operand" "")
12072 (clobber (match_scratch:SI 4 ""))
12073 (clobber (match_scratch:SI 5 ""))
12074 (clobber (reg:CC FLAGS_REG))])]
12078 operands[2] = pic_offset_table_rtx;
12081 operands[2] = gen_reg_rtx (Pmode);
12082 emit_insn (gen_set_got (operands[2]));
12084 if (TARGET_GNU2_TLS)
12086 emit_insn (gen_tls_dynamic_gnu2_32
12087 (operands[0], operands[1], operands[2]));
12090 operands[3] = ix86_tls_get_addr ();
12093 (define_insn "*tls_global_dynamic_64"
12094 [(set (match_operand:DI 0 "register_operand" "=a")
12095 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12096 (match_operand:DI 3 "" "")))
12097 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12100 { 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"; }
12101 [(set_attr "type" "multi")
12102 (set_attr "length" "16")])
12104 (define_expand "tls_global_dynamic_64"
12105 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12106 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12107 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12111 if (TARGET_GNU2_TLS)
12113 emit_insn (gen_tls_dynamic_gnu2_64
12114 (operands[0], operands[1]));
12117 operands[2] = ix86_tls_get_addr ();
12120 (define_insn "*tls_local_dynamic_base_32_gnu"
12121 [(set (match_operand:SI 0 "register_operand" "=a")
12122 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12123 (match_operand:SI 2 "call_insn_operand" "")]
12124 UNSPEC_TLS_LD_BASE))
12125 (clobber (match_scratch:SI 3 "=d"))
12126 (clobber (match_scratch:SI 4 "=c"))
12127 (clobber (reg:CC FLAGS_REG))]
12128 "!TARGET_64BIT && TARGET_GNU_TLS"
12129 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12130 [(set_attr "type" "multi")
12131 (set_attr "length" "11")])
12133 (define_expand "tls_local_dynamic_base_32"
12134 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12135 (unspec:SI [(match_dup 1) (match_dup 2)]
12136 UNSPEC_TLS_LD_BASE))
12137 (clobber (match_scratch:SI 3 ""))
12138 (clobber (match_scratch:SI 4 ""))
12139 (clobber (reg:CC FLAGS_REG))])]
12143 operands[1] = pic_offset_table_rtx;
12146 operands[1] = gen_reg_rtx (Pmode);
12147 emit_insn (gen_set_got (operands[1]));
12149 if (TARGET_GNU2_TLS)
12151 emit_insn (gen_tls_dynamic_gnu2_32
12152 (operands[0], ix86_tls_module_base (), operands[1]));
12155 operands[2] = ix86_tls_get_addr ();
12158 (define_insn "*tls_local_dynamic_base_64"
12159 [(set (match_operand:DI 0 "register_operand" "=a")
12160 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12161 (match_operand:DI 2 "" "")))
12162 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12164 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12165 [(set_attr "type" "multi")
12166 (set_attr "length" "12")])
12168 (define_expand "tls_local_dynamic_base_64"
12169 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12170 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12171 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12174 if (TARGET_GNU2_TLS)
12176 emit_insn (gen_tls_dynamic_gnu2_64
12177 (operands[0], ix86_tls_module_base ()));
12180 operands[1] = ix86_tls_get_addr ();
12183 ;; Local dynamic of a single variable is a lose. Show combine how
12184 ;; to convert that back to global dynamic.
12186 (define_insn_and_split "*tls_local_dynamic_32_once"
12187 [(set (match_operand:SI 0 "register_operand" "=a")
12188 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12189 (match_operand:SI 2 "call_insn_operand" "")]
12190 UNSPEC_TLS_LD_BASE)
12191 (const:SI (unspec:SI
12192 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12194 (clobber (match_scratch:SI 4 "=d"))
12195 (clobber (match_scratch:SI 5 "=c"))
12196 (clobber (reg:CC FLAGS_REG))]
12200 [(parallel [(set (match_dup 0)
12201 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12203 (clobber (match_dup 4))
12204 (clobber (match_dup 5))
12205 (clobber (reg:CC FLAGS_REG))])]
12208 ;; Load and add the thread base pointer from %gs:0.
12210 (define_insn "*load_tp_si"
12211 [(set (match_operand:SI 0 "register_operand" "=r")
12212 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12214 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12215 [(set_attr "type" "imov")
12216 (set_attr "modrm" "0")
12217 (set_attr "length" "7")
12218 (set_attr "memory" "load")
12219 (set_attr "imm_disp" "false")])
12221 (define_insn "*add_tp_si"
12222 [(set (match_operand:SI 0 "register_operand" "=r")
12223 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12224 (match_operand:SI 1 "register_operand" "0")))
12225 (clobber (reg:CC FLAGS_REG))]
12227 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12228 [(set_attr "type" "alu")
12229 (set_attr "modrm" "0")
12230 (set_attr "length" "7")
12231 (set_attr "memory" "load")
12232 (set_attr "imm_disp" "false")])
12234 (define_insn "*load_tp_di"
12235 [(set (match_operand:DI 0 "register_operand" "=r")
12236 (unspec:DI [(const_int 0)] UNSPEC_TP))]
12238 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12239 [(set_attr "type" "imov")
12240 (set_attr "modrm" "0")
12241 (set_attr "length" "7")
12242 (set_attr "memory" "load")
12243 (set_attr "imm_disp" "false")])
12245 (define_insn "*add_tp_di"
12246 [(set (match_operand:DI 0 "register_operand" "=r")
12247 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12248 (match_operand:DI 1 "register_operand" "0")))
12249 (clobber (reg:CC FLAGS_REG))]
12251 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12252 [(set_attr "type" "alu")
12253 (set_attr "modrm" "0")
12254 (set_attr "length" "7")
12255 (set_attr "memory" "load")
12256 (set_attr "imm_disp" "false")])
12258 ;; GNU2 TLS patterns can be split.
12260 (define_expand "tls_dynamic_gnu2_32"
12261 [(set (match_dup 3)
12262 (plus:SI (match_operand:SI 2 "register_operand" "")
12264 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12267 [(set (match_operand:SI 0 "register_operand" "")
12268 (unspec:SI [(match_dup 1) (match_dup 3)
12269 (match_dup 2) (reg:SI SP_REG)]
12271 (clobber (reg:CC FLAGS_REG))])]
12272 "!TARGET_64BIT && TARGET_GNU2_TLS"
12274 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12275 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12278 (define_insn "*tls_dynamic_lea_32"
12279 [(set (match_operand:SI 0 "register_operand" "=r")
12280 (plus:SI (match_operand:SI 1 "register_operand" "b")
12282 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12283 UNSPEC_TLSDESC))))]
12284 "!TARGET_64BIT && TARGET_GNU2_TLS"
12285 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12286 [(set_attr "type" "lea")
12287 (set_attr "mode" "SI")
12288 (set_attr "length" "6")
12289 (set_attr "length_address" "4")])
12291 (define_insn "*tls_dynamic_call_32"
12292 [(set (match_operand:SI 0 "register_operand" "=a")
12293 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12294 (match_operand:SI 2 "register_operand" "0")
12295 ;; we have to make sure %ebx still points to the GOT
12296 (match_operand:SI 3 "register_operand" "b")
12299 (clobber (reg:CC FLAGS_REG))]
12300 "!TARGET_64BIT && TARGET_GNU2_TLS"
12301 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12302 [(set_attr "type" "call")
12303 (set_attr "length" "2")
12304 (set_attr "length_address" "0")])
12306 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12307 [(set (match_operand:SI 0 "register_operand" "=&a")
12309 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12310 (match_operand:SI 4 "" "")
12311 (match_operand:SI 2 "register_operand" "b")
12314 (const:SI (unspec:SI
12315 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12317 (clobber (reg:CC FLAGS_REG))]
12318 "!TARGET_64BIT && TARGET_GNU2_TLS"
12321 [(set (match_dup 0) (match_dup 5))]
12323 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12324 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12327 (define_expand "tls_dynamic_gnu2_64"
12328 [(set (match_dup 2)
12329 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12332 [(set (match_operand:DI 0 "register_operand" "")
12333 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12335 (clobber (reg:CC FLAGS_REG))])]
12336 "TARGET_64BIT && TARGET_GNU2_TLS"
12338 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12339 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12342 (define_insn "*tls_dynamic_lea_64"
12343 [(set (match_operand:DI 0 "register_operand" "=r")
12344 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12346 "TARGET_64BIT && TARGET_GNU2_TLS"
12347 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12348 [(set_attr "type" "lea")
12349 (set_attr "mode" "DI")
12350 (set_attr "length" "7")
12351 (set_attr "length_address" "4")])
12353 (define_insn "*tls_dynamic_call_64"
12354 [(set (match_operand:DI 0 "register_operand" "=a")
12355 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12356 (match_operand:DI 2 "register_operand" "0")
12359 (clobber (reg:CC FLAGS_REG))]
12360 "TARGET_64BIT && TARGET_GNU2_TLS"
12361 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12362 [(set_attr "type" "call")
12363 (set_attr "length" "2")
12364 (set_attr "length_address" "0")])
12366 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12367 [(set (match_operand:DI 0 "register_operand" "=&a")
12369 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12370 (match_operand:DI 3 "" "")
12373 (const:DI (unspec:DI
12374 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12376 (clobber (reg:CC FLAGS_REG))]
12377 "TARGET_64BIT && TARGET_GNU2_TLS"
12380 [(set (match_dup 0) (match_dup 4))]
12382 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12383 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12388 ;; These patterns match the binary 387 instructions for addM3, subM3,
12389 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12390 ;; SFmode. The first is the normal insn, the second the same insn but
12391 ;; with one operand a conversion, and the third the same insn but with
12392 ;; the other operand a conversion. The conversion may be SFmode or
12393 ;; SImode if the target mode DFmode, but only SImode if the target mode
12396 ;; Gcc is slightly more smart about handling normal two address instructions
12397 ;; so use special patterns for add and mull.
12399 (define_insn "*fop_<mode>_comm_mixed_avx"
12400 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12401 (match_operator:MODEF 3 "binary_fp_operator"
12402 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12403 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12404 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12405 && COMMUTATIVE_ARITH_P (operands[3])
12406 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12407 "* return output_387_binary_op (insn, operands);"
12408 [(set (attr "type")
12409 (if_then_else (eq_attr "alternative" "1")
12410 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12411 (const_string "ssemul")
12412 (const_string "sseadd"))
12413 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12414 (const_string "fmul")
12415 (const_string "fop"))))
12416 (set_attr "prefix" "orig,maybe_vex")
12417 (set_attr "mode" "<MODE>")])
12419 (define_insn "*fop_<mode>_comm_mixed"
12420 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12421 (match_operator:MODEF 3 "binary_fp_operator"
12422 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12423 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12424 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12425 && COMMUTATIVE_ARITH_P (operands[3])
12426 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12427 "* return output_387_binary_op (insn, operands);"
12428 [(set (attr "type")
12429 (if_then_else (eq_attr "alternative" "1")
12430 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12431 (const_string "ssemul")
12432 (const_string "sseadd"))
12433 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12434 (const_string "fmul")
12435 (const_string "fop"))))
12436 (set_attr "mode" "<MODE>")])
12438 (define_insn "*fop_<mode>_comm_avx"
12439 [(set (match_operand:MODEF 0 "register_operand" "=x")
12440 (match_operator:MODEF 3 "binary_fp_operator"
12441 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12442 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12443 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12444 && COMMUTATIVE_ARITH_P (operands[3])
12445 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12446 "* return output_387_binary_op (insn, operands);"
12447 [(set (attr "type")
12448 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12449 (const_string "ssemul")
12450 (const_string "sseadd")))
12451 (set_attr "prefix" "vex")
12452 (set_attr "mode" "<MODE>")])
12454 (define_insn "*fop_<mode>_comm_sse"
12455 [(set (match_operand:MODEF 0 "register_operand" "=x")
12456 (match_operator:MODEF 3 "binary_fp_operator"
12457 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12458 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12459 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12460 && COMMUTATIVE_ARITH_P (operands[3])
12461 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12462 "* return output_387_binary_op (insn, operands);"
12463 [(set (attr "type")
12464 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12465 (const_string "ssemul")
12466 (const_string "sseadd")))
12467 (set_attr "mode" "<MODE>")])
12469 (define_insn "*fop_<mode>_comm_i387"
12470 [(set (match_operand:MODEF 0 "register_operand" "=f")
12471 (match_operator:MODEF 3 "binary_fp_operator"
12472 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12473 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12474 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12475 && COMMUTATIVE_ARITH_P (operands[3])
12476 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12477 "* return output_387_binary_op (insn, operands);"
12478 [(set (attr "type")
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>_1_mixed_avx"
12485 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12486 (match_operator:MODEF 3 "binary_fp_operator"
12487 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12488 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12489 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
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 (cond [(and (eq_attr "alternative" "2")
12495 (match_operand:MODEF 3 "mult_operator" ""))
12496 (const_string "ssemul")
12497 (and (eq_attr "alternative" "2")
12498 (match_operand:MODEF 3 "div_operator" ""))
12499 (const_string "ssediv")
12500 (eq_attr "alternative" "2")
12501 (const_string "sseadd")
12502 (match_operand:MODEF 3 "mult_operator" "")
12503 (const_string "fmul")
12504 (match_operand:MODEF 3 "div_operator" "")
12505 (const_string "fdiv")
12507 (const_string "fop")))
12508 (set_attr "prefix" "orig,orig,maybe_vex")
12509 (set_attr "mode" "<MODE>")])
12511 (define_insn "*fop_<mode>_1_mixed"
12512 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12513 (match_operator:MODEF 3 "binary_fp_operator"
12514 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12515 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12516 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12517 && !COMMUTATIVE_ARITH_P (operands[3])
12518 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12519 "* return output_387_binary_op (insn, operands);"
12520 [(set (attr "type")
12521 (cond [(and (eq_attr "alternative" "2")
12522 (match_operand:MODEF 3 "mult_operator" ""))
12523 (const_string "ssemul")
12524 (and (eq_attr "alternative" "2")
12525 (match_operand:MODEF 3 "div_operator" ""))
12526 (const_string "ssediv")
12527 (eq_attr "alternative" "2")
12528 (const_string "sseadd")
12529 (match_operand:MODEF 3 "mult_operator" "")
12530 (const_string "fmul")
12531 (match_operand:MODEF 3 "div_operator" "")
12532 (const_string "fdiv")
12534 (const_string "fop")))
12535 (set_attr "mode" "<MODE>")])
12537 (define_insn "*rcpsf2_sse"
12538 [(set (match_operand:SF 0 "register_operand" "=x")
12539 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12542 "%vrcpss\t{%1, %d0|%d0, %1}"
12543 [(set_attr "type" "sse")
12544 (set_attr "atom_sse_attr" "rcp")
12545 (set_attr "prefix" "maybe_vex")
12546 (set_attr "mode" "SF")])
12548 (define_insn "*fop_<mode>_1_avx"
12549 [(set (match_operand:MODEF 0 "register_operand" "=x")
12550 (match_operator:MODEF 3 "binary_fp_operator"
12551 [(match_operand:MODEF 1 "register_operand" "x")
12552 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12553 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12554 && !COMMUTATIVE_ARITH_P (operands[3])"
12555 "* return output_387_binary_op (insn, operands);"
12556 [(set (attr "type")
12557 (cond [(match_operand:MODEF 3 "mult_operator" "")
12558 (const_string "ssemul")
12559 (match_operand:MODEF 3 "div_operator" "")
12560 (const_string "ssediv")
12562 (const_string "sseadd")))
12563 (set_attr "prefix" "vex")
12564 (set_attr "mode" "<MODE>")])
12566 (define_insn "*fop_<mode>_1_sse"
12567 [(set (match_operand:MODEF 0 "register_operand" "=x")
12568 (match_operator:MODEF 3 "binary_fp_operator"
12569 [(match_operand:MODEF 1 "register_operand" "0")
12570 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12571 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12572 && !COMMUTATIVE_ARITH_P (operands[3])"
12573 "* return output_387_binary_op (insn, operands);"
12574 [(set (attr "type")
12575 (cond [(match_operand:MODEF 3 "mult_operator" "")
12576 (const_string "ssemul")
12577 (match_operand:MODEF 3 "div_operator" "")
12578 (const_string "ssediv")
12580 (const_string "sseadd")))
12581 (set_attr "mode" "<MODE>")])
12583 ;; This pattern is not fully shadowed by the pattern above.
12584 (define_insn "*fop_<mode>_1_i387"
12585 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12586 (match_operator:MODEF 3 "binary_fp_operator"
12587 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12588 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12589 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12590 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12591 && !COMMUTATIVE_ARITH_P (operands[3])
12592 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12593 "* return output_387_binary_op (insn, operands);"
12594 [(set (attr "type")
12595 (cond [(match_operand:MODEF 3 "mult_operator" "")
12596 (const_string "fmul")
12597 (match_operand:MODEF 3 "div_operator" "")
12598 (const_string "fdiv")
12600 (const_string "fop")))
12601 (set_attr "mode" "<MODE>")])
12603 ;; ??? Add SSE splitters for these!
12604 (define_insn "*fop_<MODEF:mode>_2_i387"
12605 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12606 (match_operator:MODEF 3 "binary_fp_operator"
12608 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12609 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12610 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12611 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12612 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12613 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12614 [(set (attr "type")
12615 (cond [(match_operand:MODEF 3 "mult_operator" "")
12616 (const_string "fmul")
12617 (match_operand:MODEF 3 "div_operator" "")
12618 (const_string "fdiv")
12620 (const_string "fop")))
12621 (set_attr "fp_int_src" "true")
12622 (set_attr "mode" "<X87MODEI12:MODE>")])
12624 (define_insn "*fop_<MODEF:mode>_3_i387"
12625 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12626 (match_operator:MODEF 3 "binary_fp_operator"
12627 [(match_operand:MODEF 1 "register_operand" "0,0")
12629 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12630 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12631 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12632 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12633 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12634 [(set (attr "type")
12635 (cond [(match_operand:MODEF 3 "mult_operator" "")
12636 (const_string "fmul")
12637 (match_operand:MODEF 3 "div_operator" "")
12638 (const_string "fdiv")
12640 (const_string "fop")))
12641 (set_attr "fp_int_src" "true")
12642 (set_attr "mode" "<MODE>")])
12644 (define_insn "*fop_df_4_i387"
12645 [(set (match_operand:DF 0 "register_operand" "=f,f")
12646 (match_operator:DF 3 "binary_fp_operator"
12648 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12649 (match_operand:DF 2 "register_operand" "0,f")]))]
12650 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12651 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12652 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12653 "* return output_387_binary_op (insn, operands);"
12654 [(set (attr "type")
12655 (cond [(match_operand:DF 3 "mult_operator" "")
12656 (const_string "fmul")
12657 (match_operand:DF 3 "div_operator" "")
12658 (const_string "fdiv")
12660 (const_string "fop")))
12661 (set_attr "mode" "SF")])
12663 (define_insn "*fop_df_5_i387"
12664 [(set (match_operand:DF 0 "register_operand" "=f,f")
12665 (match_operator:DF 3 "binary_fp_operator"
12666 [(match_operand:DF 1 "register_operand" "0,f")
12668 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12669 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12670 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12671 "* return output_387_binary_op (insn, operands);"
12672 [(set (attr "type")
12673 (cond [(match_operand:DF 3 "mult_operator" "")
12674 (const_string "fmul")
12675 (match_operand:DF 3 "div_operator" "")
12676 (const_string "fdiv")
12678 (const_string "fop")))
12679 (set_attr "mode" "SF")])
12681 (define_insn "*fop_df_6_i387"
12682 [(set (match_operand:DF 0 "register_operand" "=f,f")
12683 (match_operator:DF 3 "binary_fp_operator"
12685 (match_operand:SF 1 "register_operand" "0,f"))
12687 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12688 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12689 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12690 "* return output_387_binary_op (insn, operands);"
12691 [(set (attr "type")
12692 (cond [(match_operand:DF 3 "mult_operator" "")
12693 (const_string "fmul")
12694 (match_operand:DF 3 "div_operator" "")
12695 (const_string "fdiv")
12697 (const_string "fop")))
12698 (set_attr "mode" "SF")])
12700 (define_insn "*fop_xf_comm_i387"
12701 [(set (match_operand:XF 0 "register_operand" "=f")
12702 (match_operator:XF 3 "binary_fp_operator"
12703 [(match_operand:XF 1 "register_operand" "%0")
12704 (match_operand:XF 2 "register_operand" "f")]))]
12706 && COMMUTATIVE_ARITH_P (operands[3])"
12707 "* return output_387_binary_op (insn, operands);"
12708 [(set (attr "type")
12709 (if_then_else (match_operand:XF 3 "mult_operator" "")
12710 (const_string "fmul")
12711 (const_string "fop")))
12712 (set_attr "mode" "XF")])
12714 (define_insn "*fop_xf_1_i387"
12715 [(set (match_operand:XF 0 "register_operand" "=f,f")
12716 (match_operator:XF 3 "binary_fp_operator"
12717 [(match_operand:XF 1 "register_operand" "0,f")
12718 (match_operand:XF 2 "register_operand" "f,0")]))]
12720 && !COMMUTATIVE_ARITH_P (operands[3])"
12721 "* return output_387_binary_op (insn, operands);"
12722 [(set (attr "type")
12723 (cond [(match_operand:XF 3 "mult_operator" "")
12724 (const_string "fmul")
12725 (match_operand:XF 3 "div_operator" "")
12726 (const_string "fdiv")
12728 (const_string "fop")))
12729 (set_attr "mode" "XF")])
12731 (define_insn "*fop_xf_2_i387"
12732 [(set (match_operand:XF 0 "register_operand" "=f,f")
12733 (match_operator:XF 3 "binary_fp_operator"
12735 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12736 (match_operand:XF 2 "register_operand" "0,0")]))]
12737 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12738 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12739 [(set (attr "type")
12740 (cond [(match_operand:XF 3 "mult_operator" "")
12741 (const_string "fmul")
12742 (match_operand:XF 3 "div_operator" "")
12743 (const_string "fdiv")
12745 (const_string "fop")))
12746 (set_attr "fp_int_src" "true")
12747 (set_attr "mode" "<MODE>")])
12749 (define_insn "*fop_xf_3_i387"
12750 [(set (match_operand:XF 0 "register_operand" "=f,f")
12751 (match_operator:XF 3 "binary_fp_operator"
12752 [(match_operand:XF 1 "register_operand" "0,0")
12754 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12755 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12756 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12757 [(set (attr "type")
12758 (cond [(match_operand:XF 3 "mult_operator" "")
12759 (const_string "fmul")
12760 (match_operand:XF 3 "div_operator" "")
12761 (const_string "fdiv")
12763 (const_string "fop")))
12764 (set_attr "fp_int_src" "true")
12765 (set_attr "mode" "<MODE>")])
12767 (define_insn "*fop_xf_4_i387"
12768 [(set (match_operand:XF 0 "register_operand" "=f,f")
12769 (match_operator:XF 3 "binary_fp_operator"
12771 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12772 (match_operand:XF 2 "register_operand" "0,f")]))]
12774 "* return output_387_binary_op (insn, operands);"
12775 [(set (attr "type")
12776 (cond [(match_operand:XF 3 "mult_operator" "")
12777 (const_string "fmul")
12778 (match_operand:XF 3 "div_operator" "")
12779 (const_string "fdiv")
12781 (const_string "fop")))
12782 (set_attr "mode" "<MODE>")])
12784 (define_insn "*fop_xf_5_i387"
12785 [(set (match_operand:XF 0 "register_operand" "=f,f")
12786 (match_operator:XF 3 "binary_fp_operator"
12787 [(match_operand:XF 1 "register_operand" "0,f")
12789 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12791 "* return output_387_binary_op (insn, operands);"
12792 [(set (attr "type")
12793 (cond [(match_operand:XF 3 "mult_operator" "")
12794 (const_string "fmul")
12795 (match_operand:XF 3 "div_operator" "")
12796 (const_string "fdiv")
12798 (const_string "fop")))
12799 (set_attr "mode" "<MODE>")])
12801 (define_insn "*fop_xf_6_i387"
12802 [(set (match_operand:XF 0 "register_operand" "=f,f")
12803 (match_operator:XF 3 "binary_fp_operator"
12805 (match_operand:MODEF 1 "register_operand" "0,f"))
12807 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12809 "* return output_387_binary_op (insn, operands);"
12810 [(set (attr "type")
12811 (cond [(match_operand:XF 3 "mult_operator" "")
12812 (const_string "fmul")
12813 (match_operand:XF 3 "div_operator" "")
12814 (const_string "fdiv")
12816 (const_string "fop")))
12817 (set_attr "mode" "<MODE>")])
12820 [(set (match_operand 0 "register_operand" "")
12821 (match_operator 3 "binary_fp_operator"
12822 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12823 (match_operand 2 "register_operand" "")]))]
12825 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12826 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12829 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12830 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12831 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12832 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12833 GET_MODE (operands[3]),
12836 ix86_free_from_memory (GET_MODE (operands[1]));
12841 [(set (match_operand 0 "register_operand" "")
12842 (match_operator 3 "binary_fp_operator"
12843 [(match_operand 1 "register_operand" "")
12844 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12846 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12847 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12850 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12851 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12852 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12853 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12854 GET_MODE (operands[3]),
12857 ix86_free_from_memory (GET_MODE (operands[2]));
12861 ;; FPU special functions.
12863 ;; This pattern implements a no-op XFmode truncation for
12864 ;; all fancy i386 XFmode math functions.
12866 (define_insn "truncxf<mode>2_i387_noop_unspec"
12867 [(set (match_operand:MODEF 0 "register_operand" "=f")
12868 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12869 UNSPEC_TRUNC_NOOP))]
12870 "TARGET_USE_FANCY_MATH_387"
12871 "* return output_387_reg_move (insn, operands);"
12872 [(set_attr "type" "fmov")
12873 (set_attr "mode" "<MODE>")])
12875 (define_insn "sqrtxf2"
12876 [(set (match_operand:XF 0 "register_operand" "=f")
12877 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12878 "TARGET_USE_FANCY_MATH_387"
12880 [(set_attr "type" "fpspc")
12881 (set_attr "mode" "XF")
12882 (set_attr "athlon_decode" "direct")
12883 (set_attr "amdfam10_decode" "direct")])
12885 (define_insn "sqrt_extend<mode>xf2_i387"
12886 [(set (match_operand:XF 0 "register_operand" "=f")
12889 (match_operand:MODEF 1 "register_operand" "0"))))]
12890 "TARGET_USE_FANCY_MATH_387"
12892 [(set_attr "type" "fpspc")
12893 (set_attr "mode" "XF")
12894 (set_attr "athlon_decode" "direct")
12895 (set_attr "amdfam10_decode" "direct")])
12897 (define_insn "*rsqrtsf2_sse"
12898 [(set (match_operand:SF 0 "register_operand" "=x")
12899 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12902 "%vrsqrtss\t{%1, %d0|%d0, %1}"
12903 [(set_attr "type" "sse")
12904 (set_attr "atom_sse_attr" "rcp")
12905 (set_attr "prefix" "maybe_vex")
12906 (set_attr "mode" "SF")])
12908 (define_expand "rsqrtsf2"
12909 [(set (match_operand:SF 0 "register_operand" "")
12910 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
12914 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12918 (define_insn "*sqrt<mode>2_sse"
12919 [(set (match_operand:MODEF 0 "register_operand" "=x")
12921 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12922 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12923 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
12924 [(set_attr "type" "sse")
12925 (set_attr "atom_sse_attr" "sqrt")
12926 (set_attr "prefix" "maybe_vex")
12927 (set_attr "mode" "<MODE>")
12928 (set_attr "athlon_decode" "*")
12929 (set_attr "amdfam10_decode" "*")])
12931 (define_expand "sqrt<mode>2"
12932 [(set (match_operand:MODEF 0 "register_operand" "")
12934 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
12935 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12936 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12938 if (<MODE>mode == SFmode
12939 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
12940 && flag_finite_math_only && !flag_trapping_math
12941 && flag_unsafe_math_optimizations)
12943 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12947 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12949 rtx op0 = gen_reg_rtx (XFmode);
12950 rtx op1 = force_reg (<MODE>mode, operands[1]);
12952 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
12953 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
12958 (define_insn "fpremxf4_i387"
12959 [(set (match_operand:XF 0 "register_operand" "=f")
12960 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12961 (match_operand:XF 3 "register_operand" "1")]
12963 (set (match_operand:XF 1 "register_operand" "=u")
12964 (unspec:XF [(match_dup 2) (match_dup 3)]
12966 (set (reg:CCFP FPSR_REG)
12967 (unspec:CCFP [(match_dup 2) (match_dup 3)]
12969 "TARGET_USE_FANCY_MATH_387"
12971 [(set_attr "type" "fpspc")
12972 (set_attr "mode" "XF")])
12974 (define_expand "fmodxf3"
12975 [(use (match_operand:XF 0 "register_operand" ""))
12976 (use (match_operand:XF 1 "general_operand" ""))
12977 (use (match_operand:XF 2 "general_operand" ""))]
12978 "TARGET_USE_FANCY_MATH_387"
12980 rtx label = gen_label_rtx ();
12982 rtx op1 = gen_reg_rtx (XFmode);
12983 rtx op2 = gen_reg_rtx (XFmode);
12985 emit_move_insn (op2, operands[2]);
12986 emit_move_insn (op1, operands[1]);
12988 emit_label (label);
12989 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12990 ix86_emit_fp_unordered_jump (label);
12991 LABEL_NUSES (label) = 1;
12993 emit_move_insn (operands[0], op1);
12997 (define_expand "fmod<mode>3"
12998 [(use (match_operand:MODEF 0 "register_operand" ""))
12999 (use (match_operand:MODEF 1 "general_operand" ""))
13000 (use (match_operand:MODEF 2 "general_operand" ""))]
13001 "TARGET_USE_FANCY_MATH_387"
13003 rtx label = gen_label_rtx ();
13005 rtx op1 = gen_reg_rtx (XFmode);
13006 rtx op2 = gen_reg_rtx (XFmode);
13008 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13009 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13011 emit_label (label);
13012 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13013 ix86_emit_fp_unordered_jump (label);
13014 LABEL_NUSES (label) = 1;
13016 /* Truncate the result properly for strict SSE math. */
13017 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13018 && !TARGET_MIX_SSE_I387)
13019 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13021 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13026 (define_insn "fprem1xf4_i387"
13027 [(set (match_operand:XF 0 "register_operand" "=f")
13028 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13029 (match_operand:XF 3 "register_operand" "1")]
13031 (set (match_operand:XF 1 "register_operand" "=u")
13032 (unspec:XF [(match_dup 2) (match_dup 3)]
13034 (set (reg:CCFP FPSR_REG)
13035 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13037 "TARGET_USE_FANCY_MATH_387"
13039 [(set_attr "type" "fpspc")
13040 (set_attr "mode" "XF")])
13042 (define_expand "remainderxf3"
13043 [(use (match_operand:XF 0 "register_operand" ""))
13044 (use (match_operand:XF 1 "general_operand" ""))
13045 (use (match_operand:XF 2 "general_operand" ""))]
13046 "TARGET_USE_FANCY_MATH_387"
13048 rtx label = gen_label_rtx ();
13050 rtx op1 = gen_reg_rtx (XFmode);
13051 rtx op2 = gen_reg_rtx (XFmode);
13053 emit_move_insn (op2, operands[2]);
13054 emit_move_insn (op1, operands[1]);
13056 emit_label (label);
13057 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13058 ix86_emit_fp_unordered_jump (label);
13059 LABEL_NUSES (label) = 1;
13061 emit_move_insn (operands[0], op1);
13065 (define_expand "remainder<mode>3"
13066 [(use (match_operand:MODEF 0 "register_operand" ""))
13067 (use (match_operand:MODEF 1 "general_operand" ""))
13068 (use (match_operand:MODEF 2 "general_operand" ""))]
13069 "TARGET_USE_FANCY_MATH_387"
13071 rtx label = gen_label_rtx ();
13073 rtx op1 = gen_reg_rtx (XFmode);
13074 rtx op2 = gen_reg_rtx (XFmode);
13076 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13077 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13079 emit_label (label);
13081 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13082 ix86_emit_fp_unordered_jump (label);
13083 LABEL_NUSES (label) = 1;
13085 /* Truncate the result properly for strict SSE math. */
13086 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13087 && !TARGET_MIX_SSE_I387)
13088 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13090 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13095 (define_insn "*sinxf2_i387"
13096 [(set (match_operand:XF 0 "register_operand" "=f")
13097 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13098 "TARGET_USE_FANCY_MATH_387
13099 && flag_unsafe_math_optimizations"
13101 [(set_attr "type" "fpspc")
13102 (set_attr "mode" "XF")])
13104 (define_insn "*sin_extend<mode>xf2_i387"
13105 [(set (match_operand:XF 0 "register_operand" "=f")
13106 (unspec:XF [(float_extend:XF
13107 (match_operand:MODEF 1 "register_operand" "0"))]
13109 "TARGET_USE_FANCY_MATH_387
13110 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13111 || TARGET_MIX_SSE_I387)
13112 && flag_unsafe_math_optimizations"
13114 [(set_attr "type" "fpspc")
13115 (set_attr "mode" "XF")])
13117 (define_insn "*cosxf2_i387"
13118 [(set (match_operand:XF 0 "register_operand" "=f")
13119 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13120 "TARGET_USE_FANCY_MATH_387
13121 && flag_unsafe_math_optimizations"
13123 [(set_attr "type" "fpspc")
13124 (set_attr "mode" "XF")])
13126 (define_insn "*cos_extend<mode>xf2_i387"
13127 [(set (match_operand:XF 0 "register_operand" "=f")
13128 (unspec:XF [(float_extend:XF
13129 (match_operand:MODEF 1 "register_operand" "0"))]
13131 "TARGET_USE_FANCY_MATH_387
13132 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13133 || TARGET_MIX_SSE_I387)
13134 && flag_unsafe_math_optimizations"
13136 [(set_attr "type" "fpspc")
13137 (set_attr "mode" "XF")])
13139 ;; When sincos pattern is defined, sin and cos builtin functions will be
13140 ;; expanded to sincos pattern with one of its outputs left unused.
13141 ;; CSE pass will figure out if two sincos patterns can be combined,
13142 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13143 ;; depending on the unused output.
13145 (define_insn "sincosxf3"
13146 [(set (match_operand:XF 0 "register_operand" "=f")
13147 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13148 UNSPEC_SINCOS_COS))
13149 (set (match_operand:XF 1 "register_operand" "=u")
13150 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13151 "TARGET_USE_FANCY_MATH_387
13152 && flag_unsafe_math_optimizations"
13154 [(set_attr "type" "fpspc")
13155 (set_attr "mode" "XF")])
13158 [(set (match_operand:XF 0 "register_operand" "")
13159 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13160 UNSPEC_SINCOS_COS))
13161 (set (match_operand:XF 1 "register_operand" "")
13162 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13163 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13164 && !(reload_completed || reload_in_progress)"
13165 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13169 [(set (match_operand:XF 0 "register_operand" "")
13170 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13171 UNSPEC_SINCOS_COS))
13172 (set (match_operand:XF 1 "register_operand" "")
13173 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13174 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13175 && !(reload_completed || reload_in_progress)"
13176 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13179 (define_insn "sincos_extend<mode>xf3_i387"
13180 [(set (match_operand:XF 0 "register_operand" "=f")
13181 (unspec:XF [(float_extend:XF
13182 (match_operand:MODEF 2 "register_operand" "0"))]
13183 UNSPEC_SINCOS_COS))
13184 (set (match_operand:XF 1 "register_operand" "=u")
13185 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13186 "TARGET_USE_FANCY_MATH_387
13187 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13188 || TARGET_MIX_SSE_I387)
13189 && flag_unsafe_math_optimizations"
13191 [(set_attr "type" "fpspc")
13192 (set_attr "mode" "XF")])
13195 [(set (match_operand:XF 0 "register_operand" "")
13196 (unspec:XF [(float_extend:XF
13197 (match_operand:MODEF 2 "register_operand" ""))]
13198 UNSPEC_SINCOS_COS))
13199 (set (match_operand:XF 1 "register_operand" "")
13200 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13201 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13202 && !(reload_completed || reload_in_progress)"
13203 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13207 [(set (match_operand:XF 0 "register_operand" "")
13208 (unspec:XF [(float_extend:XF
13209 (match_operand:MODEF 2 "register_operand" ""))]
13210 UNSPEC_SINCOS_COS))
13211 (set (match_operand:XF 1 "register_operand" "")
13212 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13213 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13214 && !(reload_completed || reload_in_progress)"
13215 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13218 (define_expand "sincos<mode>3"
13219 [(use (match_operand:MODEF 0 "register_operand" ""))
13220 (use (match_operand:MODEF 1 "register_operand" ""))
13221 (use (match_operand:MODEF 2 "register_operand" ""))]
13222 "TARGET_USE_FANCY_MATH_387
13223 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13224 || TARGET_MIX_SSE_I387)
13225 && flag_unsafe_math_optimizations"
13227 rtx op0 = gen_reg_rtx (XFmode);
13228 rtx op1 = gen_reg_rtx (XFmode);
13230 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13231 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13232 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13236 (define_insn "fptanxf4_i387"
13237 [(set (match_operand:XF 0 "register_operand" "=f")
13238 (match_operand:XF 3 "const_double_operand" "F"))
13239 (set (match_operand:XF 1 "register_operand" "=u")
13240 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13242 "TARGET_USE_FANCY_MATH_387
13243 && flag_unsafe_math_optimizations
13244 && standard_80387_constant_p (operands[3]) == 2"
13246 [(set_attr "type" "fpspc")
13247 (set_attr "mode" "XF")])
13249 (define_insn "fptan_extend<mode>xf4_i387"
13250 [(set (match_operand:MODEF 0 "register_operand" "=f")
13251 (match_operand:MODEF 3 "const_double_operand" "F"))
13252 (set (match_operand:XF 1 "register_operand" "=u")
13253 (unspec:XF [(float_extend:XF
13254 (match_operand:MODEF 2 "register_operand" "0"))]
13256 "TARGET_USE_FANCY_MATH_387
13257 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13258 || TARGET_MIX_SSE_I387)
13259 && flag_unsafe_math_optimizations
13260 && standard_80387_constant_p (operands[3]) == 2"
13262 [(set_attr "type" "fpspc")
13263 (set_attr "mode" "XF")])
13265 (define_expand "tanxf2"
13266 [(use (match_operand:XF 0 "register_operand" ""))
13267 (use (match_operand:XF 1 "register_operand" ""))]
13268 "TARGET_USE_FANCY_MATH_387
13269 && flag_unsafe_math_optimizations"
13271 rtx one = gen_reg_rtx (XFmode);
13272 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13274 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13278 (define_expand "tan<mode>2"
13279 [(use (match_operand:MODEF 0 "register_operand" ""))
13280 (use (match_operand:MODEF 1 "register_operand" ""))]
13281 "TARGET_USE_FANCY_MATH_387
13282 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13283 || TARGET_MIX_SSE_I387)
13284 && flag_unsafe_math_optimizations"
13286 rtx op0 = gen_reg_rtx (XFmode);
13288 rtx one = gen_reg_rtx (<MODE>mode);
13289 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13291 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13292 operands[1], op2));
13293 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13297 (define_insn "*fpatanxf3_i387"
13298 [(set (match_operand:XF 0 "register_operand" "=f")
13299 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13300 (match_operand:XF 2 "register_operand" "u")]
13302 (clobber (match_scratch:XF 3 "=2"))]
13303 "TARGET_USE_FANCY_MATH_387
13304 && flag_unsafe_math_optimizations"
13306 [(set_attr "type" "fpspc")
13307 (set_attr "mode" "XF")])
13309 (define_insn "fpatan_extend<mode>xf3_i387"
13310 [(set (match_operand:XF 0 "register_operand" "=f")
13311 (unspec:XF [(float_extend:XF
13312 (match_operand:MODEF 1 "register_operand" "0"))
13314 (match_operand:MODEF 2 "register_operand" "u"))]
13316 (clobber (match_scratch:XF 3 "=2"))]
13317 "TARGET_USE_FANCY_MATH_387
13318 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13319 || TARGET_MIX_SSE_I387)
13320 && flag_unsafe_math_optimizations"
13322 [(set_attr "type" "fpspc")
13323 (set_attr "mode" "XF")])
13325 (define_expand "atan2xf3"
13326 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13327 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13328 (match_operand:XF 1 "register_operand" "")]
13330 (clobber (match_scratch:XF 3 ""))])]
13331 "TARGET_USE_FANCY_MATH_387
13332 && flag_unsafe_math_optimizations"
13335 (define_expand "atan2<mode>3"
13336 [(use (match_operand:MODEF 0 "register_operand" ""))
13337 (use (match_operand:MODEF 1 "register_operand" ""))
13338 (use (match_operand:MODEF 2 "register_operand" ""))]
13339 "TARGET_USE_FANCY_MATH_387
13340 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13341 || TARGET_MIX_SSE_I387)
13342 && flag_unsafe_math_optimizations"
13344 rtx op0 = gen_reg_rtx (XFmode);
13346 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13347 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13351 (define_expand "atanxf2"
13352 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13353 (unspec:XF [(match_dup 2)
13354 (match_operand:XF 1 "register_operand" "")]
13356 (clobber (match_scratch:XF 3 ""))])]
13357 "TARGET_USE_FANCY_MATH_387
13358 && flag_unsafe_math_optimizations"
13360 operands[2] = gen_reg_rtx (XFmode);
13361 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13364 (define_expand "atan<mode>2"
13365 [(use (match_operand:MODEF 0 "register_operand" ""))
13366 (use (match_operand:MODEF 1 "register_operand" ""))]
13367 "TARGET_USE_FANCY_MATH_387
13368 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13369 || TARGET_MIX_SSE_I387)
13370 && flag_unsafe_math_optimizations"
13372 rtx op0 = gen_reg_rtx (XFmode);
13374 rtx op2 = gen_reg_rtx (<MODE>mode);
13375 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13377 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13378 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13382 (define_expand "asinxf2"
13383 [(set (match_dup 2)
13384 (mult:XF (match_operand:XF 1 "register_operand" "")
13386 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13387 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13388 (parallel [(set (match_operand:XF 0 "register_operand" "")
13389 (unspec:XF [(match_dup 5) (match_dup 1)]
13391 (clobber (match_scratch:XF 6 ""))])]
13392 "TARGET_USE_FANCY_MATH_387
13393 && flag_unsafe_math_optimizations"
13397 if (optimize_insn_for_size_p ())
13400 for (i = 2; i < 6; i++)
13401 operands[i] = gen_reg_rtx (XFmode);
13403 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13406 (define_expand "asin<mode>2"
13407 [(use (match_operand:MODEF 0 "register_operand" ""))
13408 (use (match_operand:MODEF 1 "general_operand" ""))]
13409 "TARGET_USE_FANCY_MATH_387
13410 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13411 || TARGET_MIX_SSE_I387)
13412 && flag_unsafe_math_optimizations"
13414 rtx op0 = gen_reg_rtx (XFmode);
13415 rtx op1 = gen_reg_rtx (XFmode);
13417 if (optimize_insn_for_size_p ())
13420 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13421 emit_insn (gen_asinxf2 (op0, op1));
13422 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13426 (define_expand "acosxf2"
13427 [(set (match_dup 2)
13428 (mult:XF (match_operand:XF 1 "register_operand" "")
13430 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13431 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13432 (parallel [(set (match_operand:XF 0 "register_operand" "")
13433 (unspec:XF [(match_dup 1) (match_dup 5)]
13435 (clobber (match_scratch:XF 6 ""))])]
13436 "TARGET_USE_FANCY_MATH_387
13437 && flag_unsafe_math_optimizations"
13441 if (optimize_insn_for_size_p ())
13444 for (i = 2; i < 6; i++)
13445 operands[i] = gen_reg_rtx (XFmode);
13447 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13450 (define_expand "acos<mode>2"
13451 [(use (match_operand:MODEF 0 "register_operand" ""))
13452 (use (match_operand:MODEF 1 "general_operand" ""))]
13453 "TARGET_USE_FANCY_MATH_387
13454 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13455 || TARGET_MIX_SSE_I387)
13456 && flag_unsafe_math_optimizations"
13458 rtx op0 = gen_reg_rtx (XFmode);
13459 rtx op1 = gen_reg_rtx (XFmode);
13461 if (optimize_insn_for_size_p ())
13464 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13465 emit_insn (gen_acosxf2 (op0, op1));
13466 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13470 (define_insn "fyl2xxf3_i387"
13471 [(set (match_operand:XF 0 "register_operand" "=f")
13472 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13473 (match_operand:XF 2 "register_operand" "u")]
13475 (clobber (match_scratch:XF 3 "=2"))]
13476 "TARGET_USE_FANCY_MATH_387
13477 && flag_unsafe_math_optimizations"
13479 [(set_attr "type" "fpspc")
13480 (set_attr "mode" "XF")])
13482 (define_insn "fyl2x_extend<mode>xf3_i387"
13483 [(set (match_operand:XF 0 "register_operand" "=f")
13484 (unspec:XF [(float_extend:XF
13485 (match_operand:MODEF 1 "register_operand" "0"))
13486 (match_operand:XF 2 "register_operand" "u")]
13488 (clobber (match_scratch:XF 3 "=2"))]
13489 "TARGET_USE_FANCY_MATH_387
13490 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13491 || TARGET_MIX_SSE_I387)
13492 && flag_unsafe_math_optimizations"
13494 [(set_attr "type" "fpspc")
13495 (set_attr "mode" "XF")])
13497 (define_expand "logxf2"
13498 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13499 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13500 (match_dup 2)] UNSPEC_FYL2X))
13501 (clobber (match_scratch:XF 3 ""))])]
13502 "TARGET_USE_FANCY_MATH_387
13503 && flag_unsafe_math_optimizations"
13505 operands[2] = gen_reg_rtx (XFmode);
13506 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13509 (define_expand "log<mode>2"
13510 [(use (match_operand:MODEF 0 "register_operand" ""))
13511 (use (match_operand:MODEF 1 "register_operand" ""))]
13512 "TARGET_USE_FANCY_MATH_387
13513 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13514 || TARGET_MIX_SSE_I387)
13515 && flag_unsafe_math_optimizations"
13517 rtx op0 = gen_reg_rtx (XFmode);
13519 rtx op2 = gen_reg_rtx (XFmode);
13520 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13522 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13523 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13527 (define_expand "log10xf2"
13528 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13529 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13530 (match_dup 2)] UNSPEC_FYL2X))
13531 (clobber (match_scratch:XF 3 ""))])]
13532 "TARGET_USE_FANCY_MATH_387
13533 && flag_unsafe_math_optimizations"
13535 operands[2] = gen_reg_rtx (XFmode);
13536 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13539 (define_expand "log10<mode>2"
13540 [(use (match_operand:MODEF 0 "register_operand" ""))
13541 (use (match_operand:MODEF 1 "register_operand" ""))]
13542 "TARGET_USE_FANCY_MATH_387
13543 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13544 || TARGET_MIX_SSE_I387)
13545 && flag_unsafe_math_optimizations"
13547 rtx op0 = gen_reg_rtx (XFmode);
13549 rtx op2 = gen_reg_rtx (XFmode);
13550 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13552 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13553 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13557 (define_expand "log2xf2"
13558 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13559 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13560 (match_dup 2)] UNSPEC_FYL2X))
13561 (clobber (match_scratch:XF 3 ""))])]
13562 "TARGET_USE_FANCY_MATH_387
13563 && flag_unsafe_math_optimizations"
13565 operands[2] = gen_reg_rtx (XFmode);
13566 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13569 (define_expand "log2<mode>2"
13570 [(use (match_operand:MODEF 0 "register_operand" ""))
13571 (use (match_operand:MODEF 1 "register_operand" ""))]
13572 "TARGET_USE_FANCY_MATH_387
13573 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13574 || TARGET_MIX_SSE_I387)
13575 && flag_unsafe_math_optimizations"
13577 rtx op0 = gen_reg_rtx (XFmode);
13579 rtx op2 = gen_reg_rtx (XFmode);
13580 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13582 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13583 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13587 (define_insn "fyl2xp1xf3_i387"
13588 [(set (match_operand:XF 0 "register_operand" "=f")
13589 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13590 (match_operand:XF 2 "register_operand" "u")]
13592 (clobber (match_scratch:XF 3 "=2"))]
13593 "TARGET_USE_FANCY_MATH_387
13594 && flag_unsafe_math_optimizations"
13596 [(set_attr "type" "fpspc")
13597 (set_attr "mode" "XF")])
13599 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13600 [(set (match_operand:XF 0 "register_operand" "=f")
13601 (unspec:XF [(float_extend:XF
13602 (match_operand:MODEF 1 "register_operand" "0"))
13603 (match_operand:XF 2 "register_operand" "u")]
13605 (clobber (match_scratch:XF 3 "=2"))]
13606 "TARGET_USE_FANCY_MATH_387
13607 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13608 || TARGET_MIX_SSE_I387)
13609 && flag_unsafe_math_optimizations"
13611 [(set_attr "type" "fpspc")
13612 (set_attr "mode" "XF")])
13614 (define_expand "log1pxf2"
13615 [(use (match_operand:XF 0 "register_operand" ""))
13616 (use (match_operand:XF 1 "register_operand" ""))]
13617 "TARGET_USE_FANCY_MATH_387
13618 && flag_unsafe_math_optimizations"
13620 if (optimize_insn_for_size_p ())
13623 ix86_emit_i387_log1p (operands[0], operands[1]);
13627 (define_expand "log1p<mode>2"
13628 [(use (match_operand:MODEF 0 "register_operand" ""))
13629 (use (match_operand:MODEF 1 "register_operand" ""))]
13630 "TARGET_USE_FANCY_MATH_387
13631 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13632 || TARGET_MIX_SSE_I387)
13633 && flag_unsafe_math_optimizations"
13637 if (optimize_insn_for_size_p ())
13640 op0 = gen_reg_rtx (XFmode);
13642 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13644 ix86_emit_i387_log1p (op0, operands[1]);
13645 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13649 (define_insn "fxtractxf3_i387"
13650 [(set (match_operand:XF 0 "register_operand" "=f")
13651 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13652 UNSPEC_XTRACT_FRACT))
13653 (set (match_operand:XF 1 "register_operand" "=u")
13654 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13655 "TARGET_USE_FANCY_MATH_387
13656 && flag_unsafe_math_optimizations"
13658 [(set_attr "type" "fpspc")
13659 (set_attr "mode" "XF")])
13661 (define_insn "fxtract_extend<mode>xf3_i387"
13662 [(set (match_operand:XF 0 "register_operand" "=f")
13663 (unspec:XF [(float_extend:XF
13664 (match_operand:MODEF 2 "register_operand" "0"))]
13665 UNSPEC_XTRACT_FRACT))
13666 (set (match_operand:XF 1 "register_operand" "=u")
13667 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13668 "TARGET_USE_FANCY_MATH_387
13669 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13670 || TARGET_MIX_SSE_I387)
13671 && flag_unsafe_math_optimizations"
13673 [(set_attr "type" "fpspc")
13674 (set_attr "mode" "XF")])
13676 (define_expand "logbxf2"
13677 [(parallel [(set (match_dup 2)
13678 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13679 UNSPEC_XTRACT_FRACT))
13680 (set (match_operand:XF 0 "register_operand" "")
13681 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13682 "TARGET_USE_FANCY_MATH_387
13683 && flag_unsafe_math_optimizations"
13685 operands[2] = gen_reg_rtx (XFmode);
13688 (define_expand "logb<mode>2"
13689 [(use (match_operand:MODEF 0 "register_operand" ""))
13690 (use (match_operand:MODEF 1 "register_operand" ""))]
13691 "TARGET_USE_FANCY_MATH_387
13692 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13693 || TARGET_MIX_SSE_I387)
13694 && flag_unsafe_math_optimizations"
13696 rtx op0 = gen_reg_rtx (XFmode);
13697 rtx op1 = gen_reg_rtx (XFmode);
13699 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13700 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13704 (define_expand "ilogbxf2"
13705 [(use (match_operand:SI 0 "register_operand" ""))
13706 (use (match_operand:XF 1 "register_operand" ""))]
13707 "TARGET_USE_FANCY_MATH_387
13708 && flag_unsafe_math_optimizations"
13712 if (optimize_insn_for_size_p ())
13715 op0 = gen_reg_rtx (XFmode);
13716 op1 = gen_reg_rtx (XFmode);
13718 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13719 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13723 (define_expand "ilogb<mode>2"
13724 [(use (match_operand:SI 0 "register_operand" ""))
13725 (use (match_operand:MODEF 1 "register_operand" ""))]
13726 "TARGET_USE_FANCY_MATH_387
13727 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13728 || TARGET_MIX_SSE_I387)
13729 && flag_unsafe_math_optimizations"
13733 if (optimize_insn_for_size_p ())
13736 op0 = gen_reg_rtx (XFmode);
13737 op1 = gen_reg_rtx (XFmode);
13739 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13740 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13744 (define_insn "*f2xm1xf2_i387"
13745 [(set (match_operand:XF 0 "register_operand" "=f")
13746 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13748 "TARGET_USE_FANCY_MATH_387
13749 && flag_unsafe_math_optimizations"
13751 [(set_attr "type" "fpspc")
13752 (set_attr "mode" "XF")])
13754 (define_insn "*fscalexf4_i387"
13755 [(set (match_operand:XF 0 "register_operand" "=f")
13756 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13757 (match_operand:XF 3 "register_operand" "1")]
13758 UNSPEC_FSCALE_FRACT))
13759 (set (match_operand:XF 1 "register_operand" "=u")
13760 (unspec:XF [(match_dup 2) (match_dup 3)]
13761 UNSPEC_FSCALE_EXP))]
13762 "TARGET_USE_FANCY_MATH_387
13763 && flag_unsafe_math_optimizations"
13765 [(set_attr "type" "fpspc")
13766 (set_attr "mode" "XF")])
13768 (define_expand "expNcorexf3"
13769 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13770 (match_operand:XF 2 "register_operand" "")))
13771 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13772 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13773 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13774 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13775 (parallel [(set (match_operand:XF 0 "register_operand" "")
13776 (unspec:XF [(match_dup 8) (match_dup 4)]
13777 UNSPEC_FSCALE_FRACT))
13779 (unspec:XF [(match_dup 8) (match_dup 4)]
13780 UNSPEC_FSCALE_EXP))])]
13781 "TARGET_USE_FANCY_MATH_387
13782 && flag_unsafe_math_optimizations"
13786 if (optimize_insn_for_size_p ())
13789 for (i = 3; i < 10; i++)
13790 operands[i] = gen_reg_rtx (XFmode);
13792 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13795 (define_expand "expxf2"
13796 [(use (match_operand:XF 0 "register_operand" ""))
13797 (use (match_operand:XF 1 "register_operand" ""))]
13798 "TARGET_USE_FANCY_MATH_387
13799 && flag_unsafe_math_optimizations"
13803 if (optimize_insn_for_size_p ())
13806 op2 = gen_reg_rtx (XFmode);
13807 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13809 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13813 (define_expand "exp<mode>2"
13814 [(use (match_operand:MODEF 0 "register_operand" ""))
13815 (use (match_operand:MODEF 1 "general_operand" ""))]
13816 "TARGET_USE_FANCY_MATH_387
13817 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13818 || TARGET_MIX_SSE_I387)
13819 && flag_unsafe_math_optimizations"
13823 if (optimize_insn_for_size_p ())
13826 op0 = gen_reg_rtx (XFmode);
13827 op1 = gen_reg_rtx (XFmode);
13829 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13830 emit_insn (gen_expxf2 (op0, op1));
13831 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13835 (define_expand "exp10xf2"
13836 [(use (match_operand:XF 0 "register_operand" ""))
13837 (use (match_operand:XF 1 "register_operand" ""))]
13838 "TARGET_USE_FANCY_MATH_387
13839 && flag_unsafe_math_optimizations"
13843 if (optimize_insn_for_size_p ())
13846 op2 = gen_reg_rtx (XFmode);
13847 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13849 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13853 (define_expand "exp10<mode>2"
13854 [(use (match_operand:MODEF 0 "register_operand" ""))
13855 (use (match_operand:MODEF 1 "general_operand" ""))]
13856 "TARGET_USE_FANCY_MATH_387
13857 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13858 || TARGET_MIX_SSE_I387)
13859 && flag_unsafe_math_optimizations"
13863 if (optimize_insn_for_size_p ())
13866 op0 = gen_reg_rtx (XFmode);
13867 op1 = gen_reg_rtx (XFmode);
13869 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13870 emit_insn (gen_exp10xf2 (op0, op1));
13871 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13875 (define_expand "exp2xf2"
13876 [(use (match_operand:XF 0 "register_operand" ""))
13877 (use (match_operand:XF 1 "register_operand" ""))]
13878 "TARGET_USE_FANCY_MATH_387
13879 && flag_unsafe_math_optimizations"
13883 if (optimize_insn_for_size_p ())
13886 op2 = gen_reg_rtx (XFmode);
13887 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13889 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13893 (define_expand "exp2<mode>2"
13894 [(use (match_operand:MODEF 0 "register_operand" ""))
13895 (use (match_operand:MODEF 1 "general_operand" ""))]
13896 "TARGET_USE_FANCY_MATH_387
13897 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13898 || TARGET_MIX_SSE_I387)
13899 && flag_unsafe_math_optimizations"
13903 if (optimize_insn_for_size_p ())
13906 op0 = gen_reg_rtx (XFmode);
13907 op1 = gen_reg_rtx (XFmode);
13909 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13910 emit_insn (gen_exp2xf2 (op0, op1));
13911 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13915 (define_expand "expm1xf2"
13916 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13918 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13919 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13920 (set (match_dup 9) (float_extend:XF (match_dup 13)))
13921 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13922 (parallel [(set (match_dup 7)
13923 (unspec:XF [(match_dup 6) (match_dup 4)]
13924 UNSPEC_FSCALE_FRACT))
13926 (unspec:XF [(match_dup 6) (match_dup 4)]
13927 UNSPEC_FSCALE_EXP))])
13928 (parallel [(set (match_dup 10)
13929 (unspec:XF [(match_dup 9) (match_dup 8)]
13930 UNSPEC_FSCALE_FRACT))
13931 (set (match_dup 11)
13932 (unspec:XF [(match_dup 9) (match_dup 8)]
13933 UNSPEC_FSCALE_EXP))])
13934 (set (match_dup 12) (minus:XF (match_dup 10)
13935 (float_extend:XF (match_dup 13))))
13936 (set (match_operand:XF 0 "register_operand" "")
13937 (plus:XF (match_dup 12) (match_dup 7)))]
13938 "TARGET_USE_FANCY_MATH_387
13939 && flag_unsafe_math_optimizations"
13943 if (optimize_insn_for_size_p ())
13946 for (i = 2; i < 13; i++)
13947 operands[i] = gen_reg_rtx (XFmode);
13950 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
13952 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
13955 (define_expand "expm1<mode>2"
13956 [(use (match_operand:MODEF 0 "register_operand" ""))
13957 (use (match_operand:MODEF 1 "general_operand" ""))]
13958 "TARGET_USE_FANCY_MATH_387
13959 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13960 || TARGET_MIX_SSE_I387)
13961 && flag_unsafe_math_optimizations"
13965 if (optimize_insn_for_size_p ())
13968 op0 = gen_reg_rtx (XFmode);
13969 op1 = gen_reg_rtx (XFmode);
13971 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13972 emit_insn (gen_expm1xf2 (op0, op1));
13973 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13977 (define_expand "ldexpxf3"
13978 [(set (match_dup 3)
13979 (float:XF (match_operand:SI 2 "register_operand" "")))
13980 (parallel [(set (match_operand:XF 0 " register_operand" "")
13981 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13983 UNSPEC_FSCALE_FRACT))
13985 (unspec:XF [(match_dup 1) (match_dup 3)]
13986 UNSPEC_FSCALE_EXP))])]
13987 "TARGET_USE_FANCY_MATH_387
13988 && flag_unsafe_math_optimizations"
13990 if (optimize_insn_for_size_p ())
13993 operands[3] = gen_reg_rtx (XFmode);
13994 operands[4] = gen_reg_rtx (XFmode);
13997 (define_expand "ldexp<mode>3"
13998 [(use (match_operand:MODEF 0 "register_operand" ""))
13999 (use (match_operand:MODEF 1 "general_operand" ""))
14000 (use (match_operand:SI 2 "register_operand" ""))]
14001 "TARGET_USE_FANCY_MATH_387
14002 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14003 || TARGET_MIX_SSE_I387)
14004 && flag_unsafe_math_optimizations"
14008 if (optimize_insn_for_size_p ())
14011 op0 = gen_reg_rtx (XFmode);
14012 op1 = gen_reg_rtx (XFmode);
14014 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14015 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14016 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14020 (define_expand "scalbxf3"
14021 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14022 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14023 (match_operand:XF 2 "register_operand" "")]
14024 UNSPEC_FSCALE_FRACT))
14026 (unspec:XF [(match_dup 1) (match_dup 2)]
14027 UNSPEC_FSCALE_EXP))])]
14028 "TARGET_USE_FANCY_MATH_387
14029 && flag_unsafe_math_optimizations"
14031 if (optimize_insn_for_size_p ())
14034 operands[3] = gen_reg_rtx (XFmode);
14037 (define_expand "scalb<mode>3"
14038 [(use (match_operand:MODEF 0 "register_operand" ""))
14039 (use (match_operand:MODEF 1 "general_operand" ""))
14040 (use (match_operand:MODEF 2 "general_operand" ""))]
14041 "TARGET_USE_FANCY_MATH_387
14042 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14043 || TARGET_MIX_SSE_I387)
14044 && flag_unsafe_math_optimizations"
14048 if (optimize_insn_for_size_p ())
14051 op0 = gen_reg_rtx (XFmode);
14052 op1 = gen_reg_rtx (XFmode);
14053 op2 = gen_reg_rtx (XFmode);
14055 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14056 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14057 emit_insn (gen_scalbxf3 (op0, op1, op2));
14058 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14062 (define_expand "significandxf2"
14063 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14064 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14065 UNSPEC_XTRACT_FRACT))
14067 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14068 "TARGET_USE_FANCY_MATH_387
14069 && flag_unsafe_math_optimizations"
14071 operands[2] = gen_reg_rtx (XFmode);
14074 (define_expand "significand<mode>2"
14075 [(use (match_operand:MODEF 0 "register_operand" ""))
14076 (use (match_operand:MODEF 1 "register_operand" ""))]
14077 "TARGET_USE_FANCY_MATH_387
14078 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14079 || TARGET_MIX_SSE_I387)
14080 && flag_unsafe_math_optimizations"
14082 rtx op0 = gen_reg_rtx (XFmode);
14083 rtx op1 = gen_reg_rtx (XFmode);
14085 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14086 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14091 (define_insn "sse4_1_round<mode>2"
14092 [(set (match_operand:MODEF 0 "register_operand" "=x")
14093 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14094 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14097 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14098 [(set_attr "type" "ssecvt")
14099 (set_attr "prefix_extra" "1")
14100 (set_attr "prefix" "maybe_vex")
14101 (set_attr "mode" "<MODE>")])
14103 (define_insn "rintxf2"
14104 [(set (match_operand:XF 0 "register_operand" "=f")
14105 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14107 "TARGET_USE_FANCY_MATH_387
14108 && flag_unsafe_math_optimizations"
14110 [(set_attr "type" "fpspc")
14111 (set_attr "mode" "XF")])
14113 (define_expand "rint<mode>2"
14114 [(use (match_operand:MODEF 0 "register_operand" ""))
14115 (use (match_operand:MODEF 1 "register_operand" ""))]
14116 "(TARGET_USE_FANCY_MATH_387
14117 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14118 || TARGET_MIX_SSE_I387)
14119 && flag_unsafe_math_optimizations)
14120 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14121 && !flag_trapping_math)"
14123 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14124 && !flag_trapping_math)
14126 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14129 emit_insn (gen_sse4_1_round<mode>2
14130 (operands[0], operands[1], GEN_INT (0x04)));
14132 ix86_expand_rint (operand0, operand1);
14136 rtx op0 = gen_reg_rtx (XFmode);
14137 rtx op1 = gen_reg_rtx (XFmode);
14139 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14140 emit_insn (gen_rintxf2 (op0, op1));
14142 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14147 (define_expand "round<mode>2"
14148 [(match_operand:MODEF 0 "register_operand" "")
14149 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14150 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14151 && !flag_trapping_math && !flag_rounding_math"
14153 if (optimize_insn_for_size_p ())
14155 if (TARGET_64BIT || (<MODE>mode != DFmode))
14156 ix86_expand_round (operand0, operand1);
14158 ix86_expand_rounddf_32 (operand0, operand1);
14162 (define_insn_and_split "*fistdi2_1"
14163 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14164 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14166 "TARGET_USE_FANCY_MATH_387
14167 && can_create_pseudo_p ()"
14172 if (memory_operand (operands[0], VOIDmode))
14173 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14176 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14177 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14182 [(set_attr "type" "fpspc")
14183 (set_attr "mode" "DI")])
14185 (define_insn "fistdi2"
14186 [(set (match_operand:DI 0 "memory_operand" "=m")
14187 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14189 (clobber (match_scratch:XF 2 "=&1f"))]
14190 "TARGET_USE_FANCY_MATH_387"
14191 "* return output_fix_trunc (insn, operands, 0);"
14192 [(set_attr "type" "fpspc")
14193 (set_attr "mode" "DI")])
14195 (define_insn "fistdi2_with_temp"
14196 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14197 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14199 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14200 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14201 "TARGET_USE_FANCY_MATH_387"
14203 [(set_attr "type" "fpspc")
14204 (set_attr "mode" "DI")])
14207 [(set (match_operand:DI 0 "register_operand" "")
14208 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14210 (clobber (match_operand:DI 2 "memory_operand" ""))
14211 (clobber (match_scratch 3 ""))]
14213 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14214 (clobber (match_dup 3))])
14215 (set (match_dup 0) (match_dup 2))]
14219 [(set (match_operand:DI 0 "memory_operand" "")
14220 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14222 (clobber (match_operand:DI 2 "memory_operand" ""))
14223 (clobber (match_scratch 3 ""))]
14225 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14226 (clobber (match_dup 3))])]
14229 (define_insn_and_split "*fist<mode>2_1"
14230 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14231 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14233 "TARGET_USE_FANCY_MATH_387
14234 && can_create_pseudo_p ()"
14239 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14240 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14244 [(set_attr "type" "fpspc")
14245 (set_attr "mode" "<MODE>")])
14247 (define_insn "fist<mode>2"
14248 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14249 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14251 "TARGET_USE_FANCY_MATH_387"
14252 "* return output_fix_trunc (insn, operands, 0);"
14253 [(set_attr "type" "fpspc")
14254 (set_attr "mode" "<MODE>")])
14256 (define_insn "fist<mode>2_with_temp"
14257 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14258 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14260 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14261 "TARGET_USE_FANCY_MATH_387"
14263 [(set_attr "type" "fpspc")
14264 (set_attr "mode" "<MODE>")])
14267 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14268 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14270 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14272 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14273 (set (match_dup 0) (match_dup 2))]
14277 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14278 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14280 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14282 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14285 (define_expand "lrintxf<mode>2"
14286 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14287 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14289 "TARGET_USE_FANCY_MATH_387"
14292 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14293 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14294 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14295 UNSPEC_FIX_NOTRUNC))]
14296 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14297 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14300 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14301 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14302 (match_operand:MODEF 1 "register_operand" "")]
14303 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14304 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14305 && !flag_trapping_math && !flag_rounding_math"
14307 if (optimize_insn_for_size_p ())
14309 ix86_expand_lround (operand0, operand1);
14313 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14314 (define_insn_and_split "frndintxf2_floor"
14315 [(set (match_operand:XF 0 "register_operand" "")
14316 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14317 UNSPEC_FRNDINT_FLOOR))
14318 (clobber (reg:CC FLAGS_REG))]
14319 "TARGET_USE_FANCY_MATH_387
14320 && flag_unsafe_math_optimizations
14321 && can_create_pseudo_p ()"
14326 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14328 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14329 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14331 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14332 operands[2], operands[3]));
14335 [(set_attr "type" "frndint")
14336 (set_attr "i387_cw" "floor")
14337 (set_attr "mode" "XF")])
14339 (define_insn "frndintxf2_floor_i387"
14340 [(set (match_operand:XF 0 "register_operand" "=f")
14341 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14342 UNSPEC_FRNDINT_FLOOR))
14343 (use (match_operand:HI 2 "memory_operand" "m"))
14344 (use (match_operand:HI 3 "memory_operand" "m"))]
14345 "TARGET_USE_FANCY_MATH_387
14346 && flag_unsafe_math_optimizations"
14347 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14348 [(set_attr "type" "frndint")
14349 (set_attr "i387_cw" "floor")
14350 (set_attr "mode" "XF")])
14352 (define_expand "floorxf2"
14353 [(use (match_operand:XF 0 "register_operand" ""))
14354 (use (match_operand:XF 1 "register_operand" ""))]
14355 "TARGET_USE_FANCY_MATH_387
14356 && flag_unsafe_math_optimizations"
14358 if (optimize_insn_for_size_p ())
14360 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14364 (define_expand "floor<mode>2"
14365 [(use (match_operand:MODEF 0 "register_operand" ""))
14366 (use (match_operand:MODEF 1 "register_operand" ""))]
14367 "(TARGET_USE_FANCY_MATH_387
14368 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14369 || TARGET_MIX_SSE_I387)
14370 && flag_unsafe_math_optimizations)
14371 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14372 && !flag_trapping_math)"
14374 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14375 && !flag_trapping_math
14376 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14378 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14381 emit_insn (gen_sse4_1_round<mode>2
14382 (operands[0], operands[1], GEN_INT (0x01)));
14383 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14384 ix86_expand_floorceil (operand0, operand1, true);
14386 ix86_expand_floorceildf_32 (operand0, operand1, true);
14392 if (optimize_insn_for_size_p ())
14395 op0 = gen_reg_rtx (XFmode);
14396 op1 = gen_reg_rtx (XFmode);
14397 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14398 emit_insn (gen_frndintxf2_floor (op0, op1));
14400 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14405 (define_insn_and_split "*fist<mode>2_floor_1"
14406 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14407 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14408 UNSPEC_FIST_FLOOR))
14409 (clobber (reg:CC FLAGS_REG))]
14410 "TARGET_USE_FANCY_MATH_387
14411 && flag_unsafe_math_optimizations
14412 && can_create_pseudo_p ()"
14417 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14419 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14420 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14421 if (memory_operand (operands[0], VOIDmode))
14422 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14423 operands[2], operands[3]));
14426 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14427 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14428 operands[2], operands[3],
14433 [(set_attr "type" "fistp")
14434 (set_attr "i387_cw" "floor")
14435 (set_attr "mode" "<MODE>")])
14437 (define_insn "fistdi2_floor"
14438 [(set (match_operand:DI 0 "memory_operand" "=m")
14439 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14440 UNSPEC_FIST_FLOOR))
14441 (use (match_operand:HI 2 "memory_operand" "m"))
14442 (use (match_operand:HI 3 "memory_operand" "m"))
14443 (clobber (match_scratch:XF 4 "=&1f"))]
14444 "TARGET_USE_FANCY_MATH_387
14445 && flag_unsafe_math_optimizations"
14446 "* return output_fix_trunc (insn, operands, 0);"
14447 [(set_attr "type" "fistp")
14448 (set_attr "i387_cw" "floor")
14449 (set_attr "mode" "DI")])
14451 (define_insn "fistdi2_floor_with_temp"
14452 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14453 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14454 UNSPEC_FIST_FLOOR))
14455 (use (match_operand:HI 2 "memory_operand" "m,m"))
14456 (use (match_operand:HI 3 "memory_operand" "m,m"))
14457 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14458 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14459 "TARGET_USE_FANCY_MATH_387
14460 && flag_unsafe_math_optimizations"
14462 [(set_attr "type" "fistp")
14463 (set_attr "i387_cw" "floor")
14464 (set_attr "mode" "DI")])
14467 [(set (match_operand:DI 0 "register_operand" "")
14468 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14469 UNSPEC_FIST_FLOOR))
14470 (use (match_operand:HI 2 "memory_operand" ""))
14471 (use (match_operand:HI 3 "memory_operand" ""))
14472 (clobber (match_operand:DI 4 "memory_operand" ""))
14473 (clobber (match_scratch 5 ""))]
14475 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14476 (use (match_dup 2))
14477 (use (match_dup 3))
14478 (clobber (match_dup 5))])
14479 (set (match_dup 0) (match_dup 4))]
14483 [(set (match_operand:DI 0 "memory_operand" "")
14484 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14485 UNSPEC_FIST_FLOOR))
14486 (use (match_operand:HI 2 "memory_operand" ""))
14487 (use (match_operand:HI 3 "memory_operand" ""))
14488 (clobber (match_operand:DI 4 "memory_operand" ""))
14489 (clobber (match_scratch 5 ""))]
14491 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14492 (use (match_dup 2))
14493 (use (match_dup 3))
14494 (clobber (match_dup 5))])]
14497 (define_insn "fist<mode>2_floor"
14498 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14499 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14500 UNSPEC_FIST_FLOOR))
14501 (use (match_operand:HI 2 "memory_operand" "m"))
14502 (use (match_operand:HI 3 "memory_operand" "m"))]
14503 "TARGET_USE_FANCY_MATH_387
14504 && flag_unsafe_math_optimizations"
14505 "* return output_fix_trunc (insn, operands, 0);"
14506 [(set_attr "type" "fistp")
14507 (set_attr "i387_cw" "floor")
14508 (set_attr "mode" "<MODE>")])
14510 (define_insn "fist<mode>2_floor_with_temp"
14511 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14512 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14513 UNSPEC_FIST_FLOOR))
14514 (use (match_operand:HI 2 "memory_operand" "m,m"))
14515 (use (match_operand:HI 3 "memory_operand" "m,m"))
14516 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14517 "TARGET_USE_FANCY_MATH_387
14518 && flag_unsafe_math_optimizations"
14520 [(set_attr "type" "fistp")
14521 (set_attr "i387_cw" "floor")
14522 (set_attr "mode" "<MODE>")])
14525 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14526 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14527 UNSPEC_FIST_FLOOR))
14528 (use (match_operand:HI 2 "memory_operand" ""))
14529 (use (match_operand:HI 3 "memory_operand" ""))
14530 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14532 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14533 UNSPEC_FIST_FLOOR))
14534 (use (match_dup 2))
14535 (use (match_dup 3))])
14536 (set (match_dup 0) (match_dup 4))]
14540 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14541 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14542 UNSPEC_FIST_FLOOR))
14543 (use (match_operand:HI 2 "memory_operand" ""))
14544 (use (match_operand:HI 3 "memory_operand" ""))
14545 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14547 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14548 UNSPEC_FIST_FLOOR))
14549 (use (match_dup 2))
14550 (use (match_dup 3))])]
14553 (define_expand "lfloorxf<mode>2"
14554 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14555 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14556 UNSPEC_FIST_FLOOR))
14557 (clobber (reg:CC FLAGS_REG))])]
14558 "TARGET_USE_FANCY_MATH_387
14559 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14560 && flag_unsafe_math_optimizations"
14563 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14564 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14565 (match_operand:MODEF 1 "register_operand" "")]
14566 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14567 && !flag_trapping_math"
14569 if (TARGET_64BIT && optimize_insn_for_size_p ())
14571 ix86_expand_lfloorceil (operand0, operand1, true);
14575 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14576 (define_insn_and_split "frndintxf2_ceil"
14577 [(set (match_operand:XF 0 "register_operand" "")
14578 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14579 UNSPEC_FRNDINT_CEIL))
14580 (clobber (reg:CC FLAGS_REG))]
14581 "TARGET_USE_FANCY_MATH_387
14582 && flag_unsafe_math_optimizations
14583 && can_create_pseudo_p ()"
14588 ix86_optimize_mode_switching[I387_CEIL] = 1;
14590 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14591 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14593 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14594 operands[2], operands[3]));
14597 [(set_attr "type" "frndint")
14598 (set_attr "i387_cw" "ceil")
14599 (set_attr "mode" "XF")])
14601 (define_insn "frndintxf2_ceil_i387"
14602 [(set (match_operand:XF 0 "register_operand" "=f")
14603 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14604 UNSPEC_FRNDINT_CEIL))
14605 (use (match_operand:HI 2 "memory_operand" "m"))
14606 (use (match_operand:HI 3 "memory_operand" "m"))]
14607 "TARGET_USE_FANCY_MATH_387
14608 && flag_unsafe_math_optimizations"
14609 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14610 [(set_attr "type" "frndint")
14611 (set_attr "i387_cw" "ceil")
14612 (set_attr "mode" "XF")])
14614 (define_expand "ceilxf2"
14615 [(use (match_operand:XF 0 "register_operand" ""))
14616 (use (match_operand:XF 1 "register_operand" ""))]
14617 "TARGET_USE_FANCY_MATH_387
14618 && flag_unsafe_math_optimizations"
14620 if (optimize_insn_for_size_p ())
14622 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14626 (define_expand "ceil<mode>2"
14627 [(use (match_operand:MODEF 0 "register_operand" ""))
14628 (use (match_operand:MODEF 1 "register_operand" ""))]
14629 "(TARGET_USE_FANCY_MATH_387
14630 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14631 || TARGET_MIX_SSE_I387)
14632 && flag_unsafe_math_optimizations)
14633 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14634 && !flag_trapping_math)"
14636 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14637 && !flag_trapping_math
14638 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14641 emit_insn (gen_sse4_1_round<mode>2
14642 (operands[0], operands[1], GEN_INT (0x02)));
14643 else if (optimize_insn_for_size_p ())
14645 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14646 ix86_expand_floorceil (operand0, operand1, false);
14648 ix86_expand_floorceildf_32 (operand0, operand1, false);
14654 if (optimize_insn_for_size_p ())
14657 op0 = gen_reg_rtx (XFmode);
14658 op1 = gen_reg_rtx (XFmode);
14659 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14660 emit_insn (gen_frndintxf2_ceil (op0, op1));
14662 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14667 (define_insn_and_split "*fist<mode>2_ceil_1"
14668 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14669 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14671 (clobber (reg:CC FLAGS_REG))]
14672 "TARGET_USE_FANCY_MATH_387
14673 && flag_unsafe_math_optimizations
14674 && can_create_pseudo_p ()"
14679 ix86_optimize_mode_switching[I387_CEIL] = 1;
14681 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14682 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14683 if (memory_operand (operands[0], VOIDmode))
14684 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14685 operands[2], operands[3]));
14688 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14689 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14690 operands[2], operands[3],
14695 [(set_attr "type" "fistp")
14696 (set_attr "i387_cw" "ceil")
14697 (set_attr "mode" "<MODE>")])
14699 (define_insn "fistdi2_ceil"
14700 [(set (match_operand:DI 0 "memory_operand" "=m")
14701 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14703 (use (match_operand:HI 2 "memory_operand" "m"))
14704 (use (match_operand:HI 3 "memory_operand" "m"))
14705 (clobber (match_scratch:XF 4 "=&1f"))]
14706 "TARGET_USE_FANCY_MATH_387
14707 && flag_unsafe_math_optimizations"
14708 "* return output_fix_trunc (insn, operands, 0);"
14709 [(set_attr "type" "fistp")
14710 (set_attr "i387_cw" "ceil")
14711 (set_attr "mode" "DI")])
14713 (define_insn "fistdi2_ceil_with_temp"
14714 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14715 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14717 (use (match_operand:HI 2 "memory_operand" "m,m"))
14718 (use (match_operand:HI 3 "memory_operand" "m,m"))
14719 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14720 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14721 "TARGET_USE_FANCY_MATH_387
14722 && flag_unsafe_math_optimizations"
14724 [(set_attr "type" "fistp")
14725 (set_attr "i387_cw" "ceil")
14726 (set_attr "mode" "DI")])
14729 [(set (match_operand:DI 0 "register_operand" "")
14730 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14732 (use (match_operand:HI 2 "memory_operand" ""))
14733 (use (match_operand:HI 3 "memory_operand" ""))
14734 (clobber (match_operand:DI 4 "memory_operand" ""))
14735 (clobber (match_scratch 5 ""))]
14737 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14738 (use (match_dup 2))
14739 (use (match_dup 3))
14740 (clobber (match_dup 5))])
14741 (set (match_dup 0) (match_dup 4))]
14745 [(set (match_operand:DI 0 "memory_operand" "")
14746 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14748 (use (match_operand:HI 2 "memory_operand" ""))
14749 (use (match_operand:HI 3 "memory_operand" ""))
14750 (clobber (match_operand:DI 4 "memory_operand" ""))
14751 (clobber (match_scratch 5 ""))]
14753 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14754 (use (match_dup 2))
14755 (use (match_dup 3))
14756 (clobber (match_dup 5))])]
14759 (define_insn "fist<mode>2_ceil"
14760 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14761 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14763 (use (match_operand:HI 2 "memory_operand" "m"))
14764 (use (match_operand:HI 3 "memory_operand" "m"))]
14765 "TARGET_USE_FANCY_MATH_387
14766 && flag_unsafe_math_optimizations"
14767 "* return output_fix_trunc (insn, operands, 0);"
14768 [(set_attr "type" "fistp")
14769 (set_attr "i387_cw" "ceil")
14770 (set_attr "mode" "<MODE>")])
14772 (define_insn "fist<mode>2_ceil_with_temp"
14773 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14774 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14776 (use (match_operand:HI 2 "memory_operand" "m,m"))
14777 (use (match_operand:HI 3 "memory_operand" "m,m"))
14778 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14779 "TARGET_USE_FANCY_MATH_387
14780 && flag_unsafe_math_optimizations"
14782 [(set_attr "type" "fistp")
14783 (set_attr "i387_cw" "ceil")
14784 (set_attr "mode" "<MODE>")])
14787 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14788 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14790 (use (match_operand:HI 2 "memory_operand" ""))
14791 (use (match_operand:HI 3 "memory_operand" ""))
14792 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14794 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14796 (use (match_dup 2))
14797 (use (match_dup 3))])
14798 (set (match_dup 0) (match_dup 4))]
14802 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14803 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14805 (use (match_operand:HI 2 "memory_operand" ""))
14806 (use (match_operand:HI 3 "memory_operand" ""))
14807 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14809 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14811 (use (match_dup 2))
14812 (use (match_dup 3))])]
14815 (define_expand "lceilxf<mode>2"
14816 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14817 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14819 (clobber (reg:CC FLAGS_REG))])]
14820 "TARGET_USE_FANCY_MATH_387
14821 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14822 && flag_unsafe_math_optimizations"
14825 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14826 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14827 (match_operand:MODEF 1 "register_operand" "")]
14828 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14829 && !flag_trapping_math"
14831 ix86_expand_lfloorceil (operand0, operand1, false);
14835 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14836 (define_insn_and_split "frndintxf2_trunc"
14837 [(set (match_operand:XF 0 "register_operand" "")
14838 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14839 UNSPEC_FRNDINT_TRUNC))
14840 (clobber (reg:CC FLAGS_REG))]
14841 "TARGET_USE_FANCY_MATH_387
14842 && flag_unsafe_math_optimizations
14843 && can_create_pseudo_p ()"
14848 ix86_optimize_mode_switching[I387_TRUNC] = 1;
14850 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14851 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14853 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14854 operands[2], operands[3]));
14857 [(set_attr "type" "frndint")
14858 (set_attr "i387_cw" "trunc")
14859 (set_attr "mode" "XF")])
14861 (define_insn "frndintxf2_trunc_i387"
14862 [(set (match_operand:XF 0 "register_operand" "=f")
14863 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14864 UNSPEC_FRNDINT_TRUNC))
14865 (use (match_operand:HI 2 "memory_operand" "m"))
14866 (use (match_operand:HI 3 "memory_operand" "m"))]
14867 "TARGET_USE_FANCY_MATH_387
14868 && flag_unsafe_math_optimizations"
14869 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14870 [(set_attr "type" "frndint")
14871 (set_attr "i387_cw" "trunc")
14872 (set_attr "mode" "XF")])
14874 (define_expand "btruncxf2"
14875 [(use (match_operand:XF 0 "register_operand" ""))
14876 (use (match_operand:XF 1 "register_operand" ""))]
14877 "TARGET_USE_FANCY_MATH_387
14878 && flag_unsafe_math_optimizations"
14880 if (optimize_insn_for_size_p ())
14882 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14886 (define_expand "btrunc<mode>2"
14887 [(use (match_operand:MODEF 0 "register_operand" ""))
14888 (use (match_operand:MODEF 1 "register_operand" ""))]
14889 "(TARGET_USE_FANCY_MATH_387
14890 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14891 || TARGET_MIX_SSE_I387)
14892 && flag_unsafe_math_optimizations)
14893 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14894 && !flag_trapping_math)"
14896 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14897 && !flag_trapping_math
14898 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14901 emit_insn (gen_sse4_1_round<mode>2
14902 (operands[0], operands[1], GEN_INT (0x03)));
14903 else if (optimize_insn_for_size_p ())
14905 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14906 ix86_expand_trunc (operand0, operand1);
14908 ix86_expand_truncdf_32 (operand0, operand1);
14914 if (optimize_insn_for_size_p ())
14917 op0 = gen_reg_rtx (XFmode);
14918 op1 = gen_reg_rtx (XFmode);
14919 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14920 emit_insn (gen_frndintxf2_trunc (op0, op1));
14922 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14927 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14928 (define_insn_and_split "frndintxf2_mask_pm"
14929 [(set (match_operand:XF 0 "register_operand" "")
14930 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14931 UNSPEC_FRNDINT_MASK_PM))
14932 (clobber (reg:CC FLAGS_REG))]
14933 "TARGET_USE_FANCY_MATH_387
14934 && flag_unsafe_math_optimizations
14935 && can_create_pseudo_p ()"
14940 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14942 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14943 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14945 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14946 operands[2], operands[3]));
14949 [(set_attr "type" "frndint")
14950 (set_attr "i387_cw" "mask_pm")
14951 (set_attr "mode" "XF")])
14953 (define_insn "frndintxf2_mask_pm_i387"
14954 [(set (match_operand:XF 0 "register_operand" "=f")
14955 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14956 UNSPEC_FRNDINT_MASK_PM))
14957 (use (match_operand:HI 2 "memory_operand" "m"))
14958 (use (match_operand:HI 3 "memory_operand" "m"))]
14959 "TARGET_USE_FANCY_MATH_387
14960 && flag_unsafe_math_optimizations"
14961 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14962 [(set_attr "type" "frndint")
14963 (set_attr "i387_cw" "mask_pm")
14964 (set_attr "mode" "XF")])
14966 (define_expand "nearbyintxf2"
14967 [(use (match_operand:XF 0 "register_operand" ""))
14968 (use (match_operand:XF 1 "register_operand" ""))]
14969 "TARGET_USE_FANCY_MATH_387
14970 && flag_unsafe_math_optimizations"
14972 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
14977 (define_expand "nearbyint<mode>2"
14978 [(use (match_operand:MODEF 0 "register_operand" ""))
14979 (use (match_operand:MODEF 1 "register_operand" ""))]
14980 "TARGET_USE_FANCY_MATH_387
14981 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14982 || TARGET_MIX_SSE_I387)
14983 && flag_unsafe_math_optimizations"
14985 rtx op0 = gen_reg_rtx (XFmode);
14986 rtx op1 = gen_reg_rtx (XFmode);
14988 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14989 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14991 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14995 (define_insn "fxam<mode>2_i387"
14996 [(set (match_operand:HI 0 "register_operand" "=a")
14998 [(match_operand:X87MODEF 1 "register_operand" "f")]
15000 "TARGET_USE_FANCY_MATH_387"
15001 "fxam\n\tfnstsw\t%0"
15002 [(set_attr "type" "multi")
15003 (set_attr "length" "4")
15004 (set_attr "unit" "i387")
15005 (set_attr "mode" "<MODE>")])
15007 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15008 [(set (match_operand:HI 0 "register_operand" "")
15010 [(match_operand:MODEF 1 "memory_operand" "")]
15012 "TARGET_USE_FANCY_MATH_387
15013 && can_create_pseudo_p ()"
15016 [(set (match_dup 2)(match_dup 1))
15018 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15020 operands[2] = gen_reg_rtx (<MODE>mode);
15022 MEM_VOLATILE_P (operands[1]) = 1;
15024 [(set_attr "type" "multi")
15025 (set_attr "unit" "i387")
15026 (set_attr "mode" "<MODE>")])
15028 (define_expand "isinfxf2"
15029 [(use (match_operand:SI 0 "register_operand" ""))
15030 (use (match_operand:XF 1 "register_operand" ""))]
15031 "TARGET_USE_FANCY_MATH_387
15032 && TARGET_C99_FUNCTIONS"
15034 rtx mask = GEN_INT (0x45);
15035 rtx val = GEN_INT (0x05);
15039 rtx scratch = gen_reg_rtx (HImode);
15040 rtx res = gen_reg_rtx (QImode);
15042 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15044 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15045 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15046 cond = gen_rtx_fmt_ee (EQ, QImode,
15047 gen_rtx_REG (CCmode, FLAGS_REG),
15049 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15050 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15054 (define_expand "isinf<mode>2"
15055 [(use (match_operand:SI 0 "register_operand" ""))
15056 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15057 "TARGET_USE_FANCY_MATH_387
15058 && TARGET_C99_FUNCTIONS
15059 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15061 rtx mask = GEN_INT (0x45);
15062 rtx val = GEN_INT (0x05);
15066 rtx scratch = gen_reg_rtx (HImode);
15067 rtx res = gen_reg_rtx (QImode);
15069 /* Remove excess precision by forcing value through memory. */
15070 if (memory_operand (operands[1], VOIDmode))
15071 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15074 enum ix86_stack_slot slot = (virtuals_instantiated
15077 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15079 emit_move_insn (temp, operands[1]);
15080 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15083 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15084 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15085 cond = gen_rtx_fmt_ee (EQ, QImode,
15086 gen_rtx_REG (CCmode, FLAGS_REG),
15088 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15089 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15093 (define_expand "signbit<mode>2"
15094 [(use (match_operand:SI 0 "register_operand" ""))
15095 (use (match_operand:X87MODEF 1 "register_operand" ""))]
15096 "TARGET_USE_FANCY_MATH_387
15097 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15099 rtx mask = GEN_INT (0x0200);
15101 rtx scratch = gen_reg_rtx (HImode);
15103 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15104 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15108 ;; Block operation instructions
15111 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15114 [(set_attr "length" "1")
15115 (set_attr "length_immediate" "0")
15116 (set_attr "modrm" "0")])
15118 (define_expand "movmemsi"
15119 [(use (match_operand:BLK 0 "memory_operand" ""))
15120 (use (match_operand:BLK 1 "memory_operand" ""))
15121 (use (match_operand:SI 2 "nonmemory_operand" ""))
15122 (use (match_operand:SI 3 "const_int_operand" ""))
15123 (use (match_operand:SI 4 "const_int_operand" ""))
15124 (use (match_operand:SI 5 "const_int_operand" ""))]
15127 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15128 operands[4], operands[5]))
15134 (define_expand "movmemdi"
15135 [(use (match_operand:BLK 0 "memory_operand" ""))
15136 (use (match_operand:BLK 1 "memory_operand" ""))
15137 (use (match_operand:DI 2 "nonmemory_operand" ""))
15138 (use (match_operand:DI 3 "const_int_operand" ""))
15139 (use (match_operand:SI 4 "const_int_operand" ""))
15140 (use (match_operand:SI 5 "const_int_operand" ""))]
15143 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15144 operands[4], operands[5]))
15150 ;; Most CPUs don't like single string operations
15151 ;; Handle this case here to simplify previous expander.
15153 (define_expand "strmov"
15154 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15155 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15156 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15157 (clobber (reg:CC FLAGS_REG))])
15158 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15159 (clobber (reg:CC FLAGS_REG))])]
15162 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15164 /* If .md ever supports :P for Pmode, these can be directly
15165 in the pattern above. */
15166 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15167 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15169 /* Can't use this if the user has appropriated esi or edi. */
15170 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15171 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15173 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15174 operands[2], operands[3],
15175 operands[5], operands[6]));
15179 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15182 (define_expand "strmov_singleop"
15183 [(parallel [(set (match_operand 1 "memory_operand" "")
15184 (match_operand 3 "memory_operand" ""))
15185 (set (match_operand 0 "register_operand" "")
15186 (match_operand 4 "" ""))
15187 (set (match_operand 2 "register_operand" "")
15188 (match_operand 5 "" ""))])]
15190 "ix86_current_function_needs_cld = 1;")
15192 (define_insn "*strmovdi_rex_1"
15193 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15194 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15195 (set (match_operand:DI 0 "register_operand" "=D")
15196 (plus:DI (match_dup 2)
15198 (set (match_operand:DI 1 "register_operand" "=S")
15199 (plus:DI (match_dup 3)
15203 [(set_attr "type" "str")
15204 (set_attr "mode" "DI")
15205 (set_attr "memory" "both")])
15207 (define_insn "*strmovsi_1"
15208 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15209 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15210 (set (match_operand:SI 0 "register_operand" "=D")
15211 (plus:SI (match_dup 2)
15213 (set (match_operand:SI 1 "register_operand" "=S")
15214 (plus:SI (match_dup 3)
15218 [(set_attr "type" "str")
15219 (set_attr "mode" "SI")
15220 (set_attr "memory" "both")])
15222 (define_insn "*strmovsi_rex_1"
15223 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15224 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15225 (set (match_operand:DI 0 "register_operand" "=D")
15226 (plus:DI (match_dup 2)
15228 (set (match_operand:DI 1 "register_operand" "=S")
15229 (plus:DI (match_dup 3)
15233 [(set_attr "type" "str")
15234 (set_attr "mode" "SI")
15235 (set_attr "memory" "both")])
15237 (define_insn "*strmovhi_1"
15238 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15239 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15240 (set (match_operand:SI 0 "register_operand" "=D")
15241 (plus:SI (match_dup 2)
15243 (set (match_operand:SI 1 "register_operand" "=S")
15244 (plus:SI (match_dup 3)
15248 [(set_attr "type" "str")
15249 (set_attr "memory" "both")
15250 (set_attr "mode" "HI")])
15252 (define_insn "*strmovhi_rex_1"
15253 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15254 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15255 (set (match_operand:DI 0 "register_operand" "=D")
15256 (plus:DI (match_dup 2)
15258 (set (match_operand:DI 1 "register_operand" "=S")
15259 (plus:DI (match_dup 3)
15263 [(set_attr "type" "str")
15264 (set_attr "memory" "both")
15265 (set_attr "mode" "HI")])
15267 (define_insn "*strmovqi_1"
15268 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15269 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15270 (set (match_operand:SI 0 "register_operand" "=D")
15271 (plus:SI (match_dup 2)
15273 (set (match_operand:SI 1 "register_operand" "=S")
15274 (plus:SI (match_dup 3)
15278 [(set_attr "type" "str")
15279 (set_attr "memory" "both")
15280 (set_attr "mode" "QI")])
15282 (define_insn "*strmovqi_rex_1"
15283 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15284 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15285 (set (match_operand:DI 0 "register_operand" "=D")
15286 (plus:DI (match_dup 2)
15288 (set (match_operand:DI 1 "register_operand" "=S")
15289 (plus:DI (match_dup 3)
15293 [(set_attr "type" "str")
15294 (set_attr "memory" "both")
15295 (set_attr "prefix_rex" "0")
15296 (set_attr "mode" "QI")])
15298 (define_expand "rep_mov"
15299 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15300 (set (match_operand 0 "register_operand" "")
15301 (match_operand 5 "" ""))
15302 (set (match_operand 2 "register_operand" "")
15303 (match_operand 6 "" ""))
15304 (set (match_operand 1 "memory_operand" "")
15305 (match_operand 3 "memory_operand" ""))
15306 (use (match_dup 4))])]
15308 "ix86_current_function_needs_cld = 1;")
15310 (define_insn "*rep_movdi_rex64"
15311 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15312 (set (match_operand:DI 0 "register_operand" "=D")
15313 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15315 (match_operand:DI 3 "register_operand" "0")))
15316 (set (match_operand:DI 1 "register_operand" "=S")
15317 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15318 (match_operand:DI 4 "register_operand" "1")))
15319 (set (mem:BLK (match_dup 3))
15320 (mem:BLK (match_dup 4)))
15321 (use (match_dup 5))]
15324 [(set_attr "type" "str")
15325 (set_attr "prefix_rep" "1")
15326 (set_attr "memory" "both")
15327 (set_attr "mode" "DI")])
15329 (define_insn "*rep_movsi"
15330 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15331 (set (match_operand:SI 0 "register_operand" "=D")
15332 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15334 (match_operand:SI 3 "register_operand" "0")))
15335 (set (match_operand:SI 1 "register_operand" "=S")
15336 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15337 (match_operand:SI 4 "register_operand" "1")))
15338 (set (mem:BLK (match_dup 3))
15339 (mem:BLK (match_dup 4)))
15340 (use (match_dup 5))]
15342 "rep{%;} movs{l|d}"
15343 [(set_attr "type" "str")
15344 (set_attr "prefix_rep" "1")
15345 (set_attr "memory" "both")
15346 (set_attr "mode" "SI")])
15348 (define_insn "*rep_movsi_rex64"
15349 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15350 (set (match_operand:DI 0 "register_operand" "=D")
15351 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15353 (match_operand:DI 3 "register_operand" "0")))
15354 (set (match_operand:DI 1 "register_operand" "=S")
15355 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15356 (match_operand:DI 4 "register_operand" "1")))
15357 (set (mem:BLK (match_dup 3))
15358 (mem:BLK (match_dup 4)))
15359 (use (match_dup 5))]
15361 "rep{%;} movs{l|d}"
15362 [(set_attr "type" "str")
15363 (set_attr "prefix_rep" "1")
15364 (set_attr "memory" "both")
15365 (set_attr "mode" "SI")])
15367 (define_insn "*rep_movqi"
15368 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15369 (set (match_operand:SI 0 "register_operand" "=D")
15370 (plus:SI (match_operand:SI 3 "register_operand" "0")
15371 (match_operand:SI 5 "register_operand" "2")))
15372 (set (match_operand:SI 1 "register_operand" "=S")
15373 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15374 (set (mem:BLK (match_dup 3))
15375 (mem:BLK (match_dup 4)))
15376 (use (match_dup 5))]
15379 [(set_attr "type" "str")
15380 (set_attr "prefix_rep" "1")
15381 (set_attr "memory" "both")
15382 (set_attr "mode" "SI")])
15384 (define_insn "*rep_movqi_rex64"
15385 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15386 (set (match_operand:DI 0 "register_operand" "=D")
15387 (plus:DI (match_operand:DI 3 "register_operand" "0")
15388 (match_operand:DI 5 "register_operand" "2")))
15389 (set (match_operand:DI 1 "register_operand" "=S")
15390 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15391 (set (mem:BLK (match_dup 3))
15392 (mem:BLK (match_dup 4)))
15393 (use (match_dup 5))]
15396 [(set_attr "type" "str")
15397 (set_attr "prefix_rep" "1")
15398 (set_attr "memory" "both")
15399 (set_attr "mode" "SI")])
15401 (define_expand "setmemsi"
15402 [(use (match_operand:BLK 0 "memory_operand" ""))
15403 (use (match_operand:SI 1 "nonmemory_operand" ""))
15404 (use (match_operand 2 "const_int_operand" ""))
15405 (use (match_operand 3 "const_int_operand" ""))
15406 (use (match_operand:SI 4 "const_int_operand" ""))
15407 (use (match_operand:SI 5 "const_int_operand" ""))]
15410 if (ix86_expand_setmem (operands[0], operands[1],
15411 operands[2], operands[3],
15412 operands[4], operands[5]))
15418 (define_expand "setmemdi"
15419 [(use (match_operand:BLK 0 "memory_operand" ""))
15420 (use (match_operand:DI 1 "nonmemory_operand" ""))
15421 (use (match_operand 2 "const_int_operand" ""))
15422 (use (match_operand 3 "const_int_operand" ""))
15423 (use (match_operand 4 "const_int_operand" ""))
15424 (use (match_operand 5 "const_int_operand" ""))]
15427 if (ix86_expand_setmem (operands[0], operands[1],
15428 operands[2], operands[3],
15429 operands[4], operands[5]))
15435 ;; Most CPUs don't like single string operations
15436 ;; Handle this case here to simplify previous expander.
15438 (define_expand "strset"
15439 [(set (match_operand 1 "memory_operand" "")
15440 (match_operand 2 "register_operand" ""))
15441 (parallel [(set (match_operand 0 "register_operand" "")
15443 (clobber (reg:CC FLAGS_REG))])]
15446 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15447 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15449 /* If .md ever supports :P for Pmode, this can be directly
15450 in the pattern above. */
15451 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15452 GEN_INT (GET_MODE_SIZE (GET_MODE
15454 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15456 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15462 (define_expand "strset_singleop"
15463 [(parallel [(set (match_operand 1 "memory_operand" "")
15464 (match_operand 2 "register_operand" ""))
15465 (set (match_operand 0 "register_operand" "")
15466 (match_operand 3 "" ""))])]
15468 "ix86_current_function_needs_cld = 1;")
15470 (define_insn "*strsetdi_rex_1"
15471 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15472 (match_operand:DI 2 "register_operand" "a"))
15473 (set (match_operand:DI 0 "register_operand" "=D")
15474 (plus:DI (match_dup 1)
15478 [(set_attr "type" "str")
15479 (set_attr "memory" "store")
15480 (set_attr "mode" "DI")])
15482 (define_insn "*strsetsi_1"
15483 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15484 (match_operand:SI 2 "register_operand" "a"))
15485 (set (match_operand:SI 0 "register_operand" "=D")
15486 (plus:SI (match_dup 1)
15490 [(set_attr "type" "str")
15491 (set_attr "memory" "store")
15492 (set_attr "mode" "SI")])
15494 (define_insn "*strsetsi_rex_1"
15495 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15496 (match_operand:SI 2 "register_operand" "a"))
15497 (set (match_operand:DI 0 "register_operand" "=D")
15498 (plus:DI (match_dup 1)
15502 [(set_attr "type" "str")
15503 (set_attr "memory" "store")
15504 (set_attr "mode" "SI")])
15506 (define_insn "*strsethi_1"
15507 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15508 (match_operand:HI 2 "register_operand" "a"))
15509 (set (match_operand:SI 0 "register_operand" "=D")
15510 (plus:SI (match_dup 1)
15514 [(set_attr "type" "str")
15515 (set_attr "memory" "store")
15516 (set_attr "mode" "HI")])
15518 (define_insn "*strsethi_rex_1"
15519 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15520 (match_operand:HI 2 "register_operand" "a"))
15521 (set (match_operand:DI 0 "register_operand" "=D")
15522 (plus:DI (match_dup 1)
15526 [(set_attr "type" "str")
15527 (set_attr "memory" "store")
15528 (set_attr "mode" "HI")])
15530 (define_insn "*strsetqi_1"
15531 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15532 (match_operand:QI 2 "register_operand" "a"))
15533 (set (match_operand:SI 0 "register_operand" "=D")
15534 (plus:SI (match_dup 1)
15538 [(set_attr "type" "str")
15539 (set_attr "memory" "store")
15540 (set_attr "mode" "QI")])
15542 (define_insn "*strsetqi_rex_1"
15543 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15544 (match_operand:QI 2 "register_operand" "a"))
15545 (set (match_operand:DI 0 "register_operand" "=D")
15546 (plus:DI (match_dup 1)
15550 [(set_attr "type" "str")
15551 (set_attr "memory" "store")
15552 (set_attr "prefix_rex" "0")
15553 (set_attr "mode" "QI")])
15555 (define_expand "rep_stos"
15556 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15557 (set (match_operand 0 "register_operand" "")
15558 (match_operand 4 "" ""))
15559 (set (match_operand 2 "memory_operand" "") (const_int 0))
15560 (use (match_operand 3 "register_operand" ""))
15561 (use (match_dup 1))])]
15563 "ix86_current_function_needs_cld = 1;")
15565 (define_insn "*rep_stosdi_rex64"
15566 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15567 (set (match_operand:DI 0 "register_operand" "=D")
15568 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15570 (match_operand:DI 3 "register_operand" "0")))
15571 (set (mem:BLK (match_dup 3))
15573 (use (match_operand:DI 2 "register_operand" "a"))
15574 (use (match_dup 4))]
15577 [(set_attr "type" "str")
15578 (set_attr "prefix_rep" "1")
15579 (set_attr "memory" "store")
15580 (set_attr "mode" "DI")])
15582 (define_insn "*rep_stossi"
15583 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15584 (set (match_operand:SI 0 "register_operand" "=D")
15585 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15587 (match_operand:SI 3 "register_operand" "0")))
15588 (set (mem:BLK (match_dup 3))
15590 (use (match_operand:SI 2 "register_operand" "a"))
15591 (use (match_dup 4))]
15593 "rep{%;} stos{l|d}"
15594 [(set_attr "type" "str")
15595 (set_attr "prefix_rep" "1")
15596 (set_attr "memory" "store")
15597 (set_attr "mode" "SI")])
15599 (define_insn "*rep_stossi_rex64"
15600 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15601 (set (match_operand:DI 0 "register_operand" "=D")
15602 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15604 (match_operand:DI 3 "register_operand" "0")))
15605 (set (mem:BLK (match_dup 3))
15607 (use (match_operand:SI 2 "register_operand" "a"))
15608 (use (match_dup 4))]
15610 "rep{%;} stos{l|d}"
15611 [(set_attr "type" "str")
15612 (set_attr "prefix_rep" "1")
15613 (set_attr "memory" "store")
15614 (set_attr "mode" "SI")])
15616 (define_insn "*rep_stosqi"
15617 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15618 (set (match_operand:SI 0 "register_operand" "=D")
15619 (plus:SI (match_operand:SI 3 "register_operand" "0")
15620 (match_operand:SI 4 "register_operand" "1")))
15621 (set (mem:BLK (match_dup 3))
15623 (use (match_operand:QI 2 "register_operand" "a"))
15624 (use (match_dup 4))]
15627 [(set_attr "type" "str")
15628 (set_attr "prefix_rep" "1")
15629 (set_attr "memory" "store")
15630 (set_attr "mode" "QI")])
15632 (define_insn "*rep_stosqi_rex64"
15633 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15634 (set (match_operand:DI 0 "register_operand" "=D")
15635 (plus:DI (match_operand:DI 3 "register_operand" "0")
15636 (match_operand:DI 4 "register_operand" "1")))
15637 (set (mem:BLK (match_dup 3))
15639 (use (match_operand:QI 2 "register_operand" "a"))
15640 (use (match_dup 4))]
15643 [(set_attr "type" "str")
15644 (set_attr "prefix_rep" "1")
15645 (set_attr "memory" "store")
15646 (set_attr "prefix_rex" "0")
15647 (set_attr "mode" "QI")])
15649 (define_expand "cmpstrnsi"
15650 [(set (match_operand:SI 0 "register_operand" "")
15651 (compare:SI (match_operand:BLK 1 "general_operand" "")
15652 (match_operand:BLK 2 "general_operand" "")))
15653 (use (match_operand 3 "general_operand" ""))
15654 (use (match_operand 4 "immediate_operand" ""))]
15657 rtx addr1, addr2, out, outlow, count, countreg, align;
15659 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15662 /* Can't use this if the user has appropriated esi or edi. */
15663 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15668 out = gen_reg_rtx (SImode);
15670 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15671 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15672 if (addr1 != XEXP (operands[1], 0))
15673 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15674 if (addr2 != XEXP (operands[2], 0))
15675 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15677 count = operands[3];
15678 countreg = ix86_zero_extend_to_Pmode (count);
15680 /* %%% Iff we are testing strict equality, we can use known alignment
15681 to good advantage. This may be possible with combine, particularly
15682 once cc0 is dead. */
15683 align = operands[4];
15685 if (CONST_INT_P (count))
15687 if (INTVAL (count) == 0)
15689 emit_move_insn (operands[0], const0_rtx);
15692 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15693 operands[1], operands[2]));
15697 rtx (*cmp_insn)(rtx, rtx);
15700 cmp_insn = gen_cmpdi_1;
15702 cmp_insn = gen_cmpsi_1;
15703 emit_insn (cmp_insn (countreg, countreg));
15704 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15705 operands[1], operands[2]));
15708 outlow = gen_lowpart (QImode, out);
15709 emit_insn (gen_cmpintqi (outlow));
15710 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15712 if (operands[0] != out)
15713 emit_move_insn (operands[0], out);
15718 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15720 (define_expand "cmpintqi"
15721 [(set (match_dup 1)
15722 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15724 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15725 (parallel [(set (match_operand:QI 0 "register_operand" "")
15726 (minus:QI (match_dup 1)
15728 (clobber (reg:CC FLAGS_REG))])]
15730 "operands[1] = gen_reg_rtx (QImode);
15731 operands[2] = gen_reg_rtx (QImode);")
15733 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15734 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15736 (define_expand "cmpstrnqi_nz_1"
15737 [(parallel [(set (reg:CC FLAGS_REG)
15738 (compare:CC (match_operand 4 "memory_operand" "")
15739 (match_operand 5 "memory_operand" "")))
15740 (use (match_operand 2 "register_operand" ""))
15741 (use (match_operand:SI 3 "immediate_operand" ""))
15742 (clobber (match_operand 0 "register_operand" ""))
15743 (clobber (match_operand 1 "register_operand" ""))
15744 (clobber (match_dup 2))])]
15746 "ix86_current_function_needs_cld = 1;")
15748 (define_insn "*cmpstrnqi_nz_1"
15749 [(set (reg:CC FLAGS_REG)
15750 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15751 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15752 (use (match_operand:SI 6 "register_operand" "2"))
15753 (use (match_operand:SI 3 "immediate_operand" "i"))
15754 (clobber (match_operand:SI 0 "register_operand" "=S"))
15755 (clobber (match_operand:SI 1 "register_operand" "=D"))
15756 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15759 [(set_attr "type" "str")
15760 (set_attr "mode" "QI")
15761 (set_attr "prefix_rep" "1")])
15763 (define_insn "*cmpstrnqi_nz_rex_1"
15764 [(set (reg:CC FLAGS_REG)
15765 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15766 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15767 (use (match_operand:DI 6 "register_operand" "2"))
15768 (use (match_operand:SI 3 "immediate_operand" "i"))
15769 (clobber (match_operand:DI 0 "register_operand" "=S"))
15770 (clobber (match_operand:DI 1 "register_operand" "=D"))
15771 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15774 [(set_attr "type" "str")
15775 (set_attr "mode" "QI")
15776 (set_attr "prefix_rex" "0")
15777 (set_attr "prefix_rep" "1")])
15779 ;; The same, but the count is not known to not be zero.
15781 (define_expand "cmpstrnqi_1"
15782 [(parallel [(set (reg:CC FLAGS_REG)
15783 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15785 (compare:CC (match_operand 4 "memory_operand" "")
15786 (match_operand 5 "memory_operand" ""))
15788 (use (match_operand:SI 3 "immediate_operand" ""))
15789 (use (reg:CC FLAGS_REG))
15790 (clobber (match_operand 0 "register_operand" ""))
15791 (clobber (match_operand 1 "register_operand" ""))
15792 (clobber (match_dup 2))])]
15794 "ix86_current_function_needs_cld = 1;")
15796 (define_insn "*cmpstrnqi_1"
15797 [(set (reg:CC FLAGS_REG)
15798 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15800 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15801 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15803 (use (match_operand:SI 3 "immediate_operand" "i"))
15804 (use (reg:CC FLAGS_REG))
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_rex_1"
15815 [(set (reg:CC FLAGS_REG)
15816 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15818 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15819 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15821 (use (match_operand:SI 3 "immediate_operand" "i"))
15822 (use (reg:CC FLAGS_REG))
15823 (clobber (match_operand:DI 0 "register_operand" "=S"))
15824 (clobber (match_operand:DI 1 "register_operand" "=D"))
15825 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15828 [(set_attr "type" "str")
15829 (set_attr "mode" "QI")
15830 (set_attr "prefix_rex" "0")
15831 (set_attr "prefix_rep" "1")])
15833 (define_expand "strlensi"
15834 [(set (match_operand:SI 0 "register_operand" "")
15835 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15836 (match_operand:QI 2 "immediate_operand" "")
15837 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15840 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15846 (define_expand "strlendi"
15847 [(set (match_operand:DI 0 "register_operand" "")
15848 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15849 (match_operand:QI 2 "immediate_operand" "")
15850 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15853 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15859 (define_expand "strlenqi_1"
15860 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
15861 (clobber (match_operand 1 "register_operand" ""))
15862 (clobber (reg:CC FLAGS_REG))])]
15864 "ix86_current_function_needs_cld = 1;")
15866 (define_insn "*strlenqi_1"
15867 [(set (match_operand:SI 0 "register_operand" "=&c")
15868 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15869 (match_operand:QI 2 "register_operand" "a")
15870 (match_operand:SI 3 "immediate_operand" "i")
15871 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15872 (clobber (match_operand:SI 1 "register_operand" "=D"))
15873 (clobber (reg:CC FLAGS_REG))]
15876 [(set_attr "type" "str")
15877 (set_attr "mode" "QI")
15878 (set_attr "prefix_rep" "1")])
15880 (define_insn "*strlenqi_rex_1"
15881 [(set (match_operand:DI 0 "register_operand" "=&c")
15882 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15883 (match_operand:QI 2 "register_operand" "a")
15884 (match_operand:DI 3 "immediate_operand" "i")
15885 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15886 (clobber (match_operand:DI 1 "register_operand" "=D"))
15887 (clobber (reg:CC FLAGS_REG))]
15890 [(set_attr "type" "str")
15891 (set_attr "mode" "QI")
15892 (set_attr "prefix_rex" "0")
15893 (set_attr "prefix_rep" "1")])
15895 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15896 ;; handled in combine, but it is not currently up to the task.
15897 ;; When used for their truth value, the cmpstrn* expanders generate
15906 ;; The intermediate three instructions are unnecessary.
15908 ;; This one handles cmpstrn*_nz_1...
15911 (set (reg:CC FLAGS_REG)
15912 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15913 (mem:BLK (match_operand 5 "register_operand" ""))))
15914 (use (match_operand 6 "register_operand" ""))
15915 (use (match_operand:SI 3 "immediate_operand" ""))
15916 (clobber (match_operand 0 "register_operand" ""))
15917 (clobber (match_operand 1 "register_operand" ""))
15918 (clobber (match_operand 2 "register_operand" ""))])
15919 (set (match_operand:QI 7 "register_operand" "")
15920 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15921 (set (match_operand:QI 8 "register_operand" "")
15922 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15923 (set (reg FLAGS_REG)
15924 (compare (match_dup 7) (match_dup 8)))
15926 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15928 (set (reg:CC FLAGS_REG)
15929 (compare:CC (mem:BLK (match_dup 4))
15930 (mem:BLK (match_dup 5))))
15931 (use (match_dup 6))
15932 (use (match_dup 3))
15933 (clobber (match_dup 0))
15934 (clobber (match_dup 1))
15935 (clobber (match_dup 2))])]
15938 ;; ...and this one handles cmpstrn*_1.
15941 (set (reg:CC FLAGS_REG)
15942 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15944 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15945 (mem:BLK (match_operand 5 "register_operand" "")))
15947 (use (match_operand:SI 3 "immediate_operand" ""))
15948 (use (reg:CC FLAGS_REG))
15949 (clobber (match_operand 0 "register_operand" ""))
15950 (clobber (match_operand 1 "register_operand" ""))
15951 (clobber (match_operand 2 "register_operand" ""))])
15952 (set (match_operand:QI 7 "register_operand" "")
15953 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15954 (set (match_operand:QI 8 "register_operand" "")
15955 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15956 (set (reg FLAGS_REG)
15957 (compare (match_dup 7) (match_dup 8)))
15959 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15961 (set (reg:CC FLAGS_REG)
15962 (if_then_else:CC (ne (match_dup 6)
15964 (compare:CC (mem:BLK (match_dup 4))
15965 (mem:BLK (match_dup 5)))
15967 (use (match_dup 3))
15968 (use (reg:CC FLAGS_REG))
15969 (clobber (match_dup 0))
15970 (clobber (match_dup 1))
15971 (clobber (match_dup 2))])]
15976 ;; Conditional move instructions.
15978 (define_expand "mov<mode>cc"
15979 [(set (match_operand:SWIM 0 "register_operand" "")
15980 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
15981 (match_operand:SWIM 2 "general_operand" "")
15982 (match_operand:SWIM 3 "general_operand" "")))]
15984 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15986 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15987 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15988 ;; So just document what we're doing explicitly.
15990 (define_expand "x86_mov<mode>cc_0_m1"
15992 [(set (match_operand:SWI48 0 "register_operand" "")
15993 (if_then_else:SWI48
15994 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15995 [(match_operand 1 "flags_reg_operand" "")
15999 (clobber (reg:CC FLAGS_REG))])]
16003 (define_insn "*x86_mov<mode>cc_0_m1"
16004 [(set (match_operand:SWI48 0 "register_operand" "=r")
16005 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16006 [(reg FLAGS_REG) (const_int 0)])
16009 (clobber (reg:CC FLAGS_REG))]
16011 "sbb{<imodesuffix>}\t%0, %0"
16012 ; Since we don't have the proper number of operands for an alu insn,
16013 ; fill in all the blanks.
16014 [(set_attr "type" "alu")
16015 (set_attr "use_carry" "1")
16016 (set_attr "pent_pair" "pu")
16017 (set_attr "memory" "none")
16018 (set_attr "imm_disp" "false")
16019 (set_attr "mode" "<MODE>")
16020 (set_attr "length_immediate" "0")])
16022 (define_insn "*x86_mov<mode>cc_0_m1_se"
16023 [(set (match_operand:SWI48 0 "register_operand" "=r")
16024 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16025 [(reg FLAGS_REG) (const_int 0)])
16028 (clobber (reg:CC FLAGS_REG))]
16030 "sbb{<imodesuffix>}\t%0, %0"
16031 [(set_attr "type" "alu")
16032 (set_attr "use_carry" "1")
16033 (set_attr "pent_pair" "pu")
16034 (set_attr "memory" "none")
16035 (set_attr "imm_disp" "false")
16036 (set_attr "mode" "<MODE>")
16037 (set_attr "length_immediate" "0")])
16039 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16040 [(set (match_operand:SWI48 0 "register_operand" "=r")
16041 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16042 [(reg FLAGS_REG) (const_int 0)])))]
16044 "sbb{<imodesuffix>}\t%0, %0"
16045 [(set_attr "type" "alu")
16046 (set_attr "use_carry" "1")
16047 (set_attr "pent_pair" "pu")
16048 (set_attr "memory" "none")
16049 (set_attr "imm_disp" "false")
16050 (set_attr "mode" "<MODE>")
16051 (set_attr "length_immediate" "0")])
16053 (define_insn "*mov<mode>cc_noc"
16054 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16055 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16056 [(reg FLAGS_REG) (const_int 0)])
16057 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16058 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16059 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16061 cmov%O2%C1\t{%2, %0|%0, %2}
16062 cmov%O2%c1\t{%3, %0|%0, %3}"
16063 [(set_attr "type" "icmov")
16064 (set_attr "mode" "<MODE>")])
16066 (define_insn_and_split "*movqicc_noc"
16067 [(set (match_operand:QI 0 "register_operand" "=r,r")
16068 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16069 [(match_operand 4 "flags_reg_operand" "")
16071 (match_operand:QI 2 "register_operand" "r,0")
16072 (match_operand:QI 3 "register_operand" "0,r")))]
16073 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16075 "&& reload_completed"
16076 [(set (match_dup 0)
16077 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16080 "operands[0] = gen_lowpart (SImode, operands[0]);
16081 operands[2] = gen_lowpart (SImode, operands[2]);
16082 operands[3] = gen_lowpart (SImode, operands[3]);"
16083 [(set_attr "type" "icmov")
16084 (set_attr "mode" "SI")])
16086 (define_expand "mov<mode>cc"
16087 [(set (match_operand:X87MODEF 0 "register_operand" "")
16088 (if_then_else:X87MODEF
16089 (match_operand 1 "ix86_fp_comparison_operator" "")
16090 (match_operand:X87MODEF 2 "register_operand" "")
16091 (match_operand:X87MODEF 3 "register_operand" "")))]
16092 "(TARGET_80387 && TARGET_CMOVE)
16093 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16094 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16096 (define_insn "*movsfcc_1_387"
16097 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16098 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16099 [(reg FLAGS_REG) (const_int 0)])
16100 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16101 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16102 "TARGET_80387 && TARGET_CMOVE
16103 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16105 fcmov%F1\t{%2, %0|%0, %2}
16106 fcmov%f1\t{%3, %0|%0, %3}
16107 cmov%O2%C1\t{%2, %0|%0, %2}
16108 cmov%O2%c1\t{%3, %0|%0, %3}"
16109 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16110 (set_attr "mode" "SF,SF,SI,SI")])
16112 (define_insn "*movdfcc_1"
16113 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16114 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16115 [(reg FLAGS_REG) (const_int 0)])
16116 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16117 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16118 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16119 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16121 fcmov%F1\t{%2, %0|%0, %2}
16122 fcmov%f1\t{%3, %0|%0, %3}
16125 [(set_attr "type" "fcmov,fcmov,multi,multi")
16126 (set_attr "mode" "DF")])
16128 (define_insn "*movdfcc_1_rex64"
16129 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16130 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16131 [(reg FLAGS_REG) (const_int 0)])
16132 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16133 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16134 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16135 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16137 fcmov%F1\t{%2, %0|%0, %2}
16138 fcmov%f1\t{%3, %0|%0, %3}
16139 cmov%O2%C1\t{%2, %0|%0, %2}
16140 cmov%O2%c1\t{%3, %0|%0, %3}"
16141 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16142 (set_attr "mode" "DF")])
16145 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16146 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16147 [(match_operand 4 "flags_reg_operand" "")
16149 (match_operand:DF 2 "nonimmediate_operand" "")
16150 (match_operand:DF 3 "nonimmediate_operand" "")))]
16151 "!TARGET_64BIT && reload_completed"
16152 [(set (match_dup 2)
16153 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16157 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16161 split_di (&operands[2], 2, &operands[5], &operands[7]);
16162 split_di (&operands[0], 1, &operands[2], &operands[3]);
16165 (define_insn "*movxfcc_1"
16166 [(set (match_operand:XF 0 "register_operand" "=f,f")
16167 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16168 [(reg FLAGS_REG) (const_int 0)])
16169 (match_operand:XF 2 "register_operand" "f,0")
16170 (match_operand:XF 3 "register_operand" "0,f")))]
16171 "TARGET_80387 && TARGET_CMOVE"
16173 fcmov%F1\t{%2, %0|%0, %2}
16174 fcmov%f1\t{%3, %0|%0, %3}"
16175 [(set_attr "type" "fcmov")
16176 (set_attr "mode" "XF")])
16178 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16179 ;; the scalar versions to have only XMM registers as operands.
16181 ;; XOP conditional move
16182 (define_insn "*xop_pcmov_<mode>"
16183 [(set (match_operand:MODEF 0 "register_operand" "=x")
16184 (if_then_else:MODEF
16185 (match_operand:MODEF 1 "register_operand" "x")
16186 (match_operand:MODEF 2 "register_operand" "x")
16187 (match_operand:MODEF 3 "register_operand" "x")))]
16189 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16190 [(set_attr "type" "sse4arg")])
16192 ;; These versions of the min/max patterns are intentionally ignorant of
16193 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16194 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16195 ;; are undefined in this condition, we're certain this is correct.
16197 (define_insn "*avx_<code><mode>3"
16198 [(set (match_operand:MODEF 0 "register_operand" "=x")
16200 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16201 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16202 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16203 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16204 [(set_attr "type" "sseadd")
16205 (set_attr "prefix" "vex")
16206 (set_attr "mode" "<MODE>")])
16208 (define_insn "<code><mode>3"
16209 [(set (match_operand:MODEF 0 "register_operand" "=x")
16211 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16212 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16213 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16214 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16215 [(set_attr "type" "sseadd")
16216 (set_attr "mode" "<MODE>")])
16218 ;; These versions of the min/max patterns implement exactly the operations
16219 ;; min = (op1 < op2 ? op1 : op2)
16220 ;; max = (!(op1 < op2) ? op1 : op2)
16221 ;; Their operands are not commutative, and thus they may be used in the
16222 ;; presence of -0.0 and NaN.
16224 (define_insn "*avx_ieee_smin<mode>3"
16225 [(set (match_operand:MODEF 0 "register_operand" "=x")
16227 [(match_operand:MODEF 1 "register_operand" "x")
16228 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16230 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16231 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16232 [(set_attr "type" "sseadd")
16233 (set_attr "prefix" "vex")
16234 (set_attr "mode" "<MODE>")])
16236 (define_insn "*ieee_smin<mode>3"
16237 [(set (match_operand:MODEF 0 "register_operand" "=x")
16239 [(match_operand:MODEF 1 "register_operand" "0")
16240 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16242 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16243 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16244 [(set_attr "type" "sseadd")
16245 (set_attr "mode" "<MODE>")])
16247 (define_insn "*avx_ieee_smax<mode>3"
16248 [(set (match_operand:MODEF 0 "register_operand" "=x")
16250 [(match_operand:MODEF 1 "register_operand" "0")
16251 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16253 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16254 "vmaxs<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 "*ieee_smax<mode>3"
16260 [(set (match_operand:MODEF 0 "register_operand" "=x")
16262 [(match_operand:MODEF 1 "register_operand" "0")
16263 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16265 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16266 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16267 [(set_attr "type" "sseadd")
16268 (set_attr "mode" "<MODE>")])
16270 ;; Make two stack loads independent:
16272 ;; fld %st(0) -> fld bb
16273 ;; fmul bb fmul %st(1), %st
16275 ;; Actually we only match the last two instructions for simplicity.
16277 [(set (match_operand 0 "fp_register_operand" "")
16278 (match_operand 1 "fp_register_operand" ""))
16280 (match_operator 2 "binary_fp_operator"
16282 (match_operand 3 "memory_operand" "")]))]
16283 "REGNO (operands[0]) != REGNO (operands[1])"
16284 [(set (match_dup 0) (match_dup 3))
16285 (set (match_dup 0) (match_dup 4))]
16287 ;; The % modifier is not operational anymore in peephole2's, so we have to
16288 ;; swap the operands manually in the case of addition and multiplication.
16289 "if (COMMUTATIVE_ARITH_P (operands[2]))
16290 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16291 operands[0], operands[1]);
16293 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16294 operands[1], operands[0]);")
16296 ;; Conditional addition patterns
16297 (define_expand "add<mode>cc"
16298 [(match_operand:SWI 0 "register_operand" "")
16299 (match_operand 1 "comparison_operator" "")
16300 (match_operand:SWI 2 "register_operand" "")
16301 (match_operand:SWI 3 "const_int_operand" "")]
16303 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16306 ;; Misc patterns (?)
16308 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16309 ;; Otherwise there will be nothing to keep
16311 ;; [(set (reg ebp) (reg esp))]
16312 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16313 ;; (clobber (eflags)]
16314 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16316 ;; in proper program order.
16317 (define_insn "pro_epilogue_adjust_stack_1"
16318 [(set (match_operand:SI 0 "register_operand" "=r,r")
16319 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16320 (match_operand:SI 2 "immediate_operand" "i,i")))
16321 (clobber (reg:CC FLAGS_REG))
16322 (clobber (mem:BLK (scratch)))]
16325 switch (get_attr_type (insn))
16328 return "mov{l}\t{%1, %0|%0, %1}";
16331 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16332 if (x86_maybe_negate_const_int (&operands[2], SImode))
16333 return "sub{l}\t{%2, %0|%0, %2}";
16335 return "add{l}\t{%2, %0|%0, %2}";
16338 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16339 return "lea{l}\t{%a2, %0|%0, %a2}";
16342 [(set (attr "type")
16343 (cond [(and (eq_attr "alternative" "0")
16344 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16345 (const_string "alu")
16346 (match_operand:SI 2 "const0_operand" "")
16347 (const_string "imov")
16349 (const_string "lea")))
16350 (set (attr "length_immediate")
16351 (cond [(eq_attr "type" "imov")
16353 (and (eq_attr "type" "alu")
16354 (match_operand 2 "const128_operand" ""))
16357 (const_string "*")))
16358 (set_attr "mode" "SI")])
16360 (define_insn "pro_epilogue_adjust_stack_rex64"
16361 [(set (match_operand:DI 0 "register_operand" "=r,r")
16362 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16363 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16364 (clobber (reg:CC FLAGS_REG))
16365 (clobber (mem:BLK (scratch)))]
16368 switch (get_attr_type (insn))
16371 return "mov{q}\t{%1, %0|%0, %1}";
16374 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16375 if (x86_maybe_negate_const_int (&operands[2], DImode))
16376 return "sub{q}\t{%2, %0|%0, %2}";
16378 return "add{q}\t{%2, %0|%0, %2}";
16381 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16382 return "lea{q}\t{%a2, %0|%0, %a2}";
16385 [(set (attr "type")
16386 (cond [(and (eq_attr "alternative" "0")
16387 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16388 (const_string "alu")
16389 (match_operand:DI 2 "const0_operand" "")
16390 (const_string "imov")
16392 (const_string "lea")))
16393 (set (attr "length_immediate")
16394 (cond [(eq_attr "type" "imov")
16396 (and (eq_attr "type" "alu")
16397 (match_operand 2 "const128_operand" ""))
16400 (const_string "*")))
16401 (set_attr "mode" "DI")])
16403 (define_insn "pro_epilogue_adjust_stack_rex64_2"
16404 [(set (match_operand:DI 0 "register_operand" "=r,r")
16405 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16406 (match_operand:DI 3 "immediate_operand" "i,i")))
16407 (use (match_operand:DI 2 "register_operand" "r,r"))
16408 (clobber (reg:CC FLAGS_REG))
16409 (clobber (mem:BLK (scratch)))]
16412 switch (get_attr_type (insn))
16415 return "add{q}\t{%2, %0|%0, %2}";
16418 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16419 return "lea{q}\t{%a2, %0|%0, %a2}";
16422 gcc_unreachable ();
16425 [(set_attr "type" "alu,lea")
16426 (set_attr "mode" "DI")])
16428 (define_insn "allocate_stack_worker_32"
16429 [(set (match_operand:SI 0 "register_operand" "=a")
16430 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16431 UNSPECV_STACK_PROBE))
16432 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16433 (clobber (reg:CC FLAGS_REG))]
16434 "!TARGET_64BIT && TARGET_STACK_PROBE"
16436 [(set_attr "type" "multi")
16437 (set_attr "length" "5")])
16439 (define_insn "allocate_stack_worker_64"
16440 [(set (match_operand:DI 0 "register_operand" "=a")
16441 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
16442 UNSPECV_STACK_PROBE))
16443 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
16444 (clobber (reg:DI R10_REG))
16445 (clobber (reg:DI R11_REG))
16446 (clobber (reg:CC FLAGS_REG))]
16447 "TARGET_64BIT && TARGET_STACK_PROBE"
16449 [(set_attr "type" "multi")
16450 (set_attr "length" "5")])
16452 (define_expand "allocate_stack"
16453 [(match_operand 0 "register_operand" "")
16454 (match_operand 1 "general_operand" "")]
16455 "TARGET_STACK_PROBE"
16459 #ifndef CHECK_STACK_LIMIT
16460 #define CHECK_STACK_LIMIT 0
16463 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16464 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16466 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16467 stack_pointer_rtx, 0, OPTAB_DIRECT);
16468 if (x != stack_pointer_rtx)
16469 emit_move_insn (stack_pointer_rtx, x);
16473 x = copy_to_mode_reg (Pmode, operands[1]);
16475 x = gen_allocate_stack_worker_64 (x, x);
16477 x = gen_allocate_stack_worker_32 (x, x);
16481 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16485 ;; Use IOR for stack probes, this is shorter.
16486 (define_expand "probe_stack"
16487 [(match_operand 0 "memory_operand" "")]
16490 if (GET_MODE (operands[0]) == DImode)
16491 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
16493 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
16497 (define_expand "builtin_setjmp_receiver"
16498 [(label_ref (match_operand 0 "" ""))]
16499 "!TARGET_64BIT && flag_pic"
16505 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16506 rtx label_rtx = gen_label_rtx ();
16507 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16508 xops[0] = xops[1] = picreg;
16509 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16510 ix86_expand_binary_operator (MINUS, SImode, xops);
16514 emit_insn (gen_set_got (pic_offset_table_rtx));
16518 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16521 [(set (match_operand 0 "register_operand" "")
16522 (match_operator 3 "promotable_binary_operator"
16523 [(match_operand 1 "register_operand" "")
16524 (match_operand 2 "aligned_operand" "")]))
16525 (clobber (reg:CC FLAGS_REG))]
16526 "! TARGET_PARTIAL_REG_STALL && reload_completed
16527 && ((GET_MODE (operands[0]) == HImode
16528 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16529 /* ??? next two lines just !satisfies_constraint_K (...) */
16530 || !CONST_INT_P (operands[2])
16531 || satisfies_constraint_K (operands[2])))
16532 || (GET_MODE (operands[0]) == QImode
16533 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16534 [(parallel [(set (match_dup 0)
16535 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16536 (clobber (reg:CC FLAGS_REG))])]
16537 "operands[0] = gen_lowpart (SImode, operands[0]);
16538 operands[1] = gen_lowpart (SImode, operands[1]);
16539 if (GET_CODE (operands[3]) != ASHIFT)
16540 operands[2] = gen_lowpart (SImode, operands[2]);
16541 PUT_MODE (operands[3], SImode);")
16543 ; Promote the QImode tests, as i386 has encoding of the AND
16544 ; instruction with 32-bit sign-extended immediate and thus the
16545 ; instruction size is unchanged, except in the %eax case for
16546 ; which it is increased by one byte, hence the ! optimize_size.
16548 [(set (match_operand 0 "flags_reg_operand" "")
16549 (match_operator 2 "compare_operator"
16550 [(and (match_operand 3 "aligned_operand" "")
16551 (match_operand 4 "const_int_operand" ""))
16553 (set (match_operand 1 "register_operand" "")
16554 (and (match_dup 3) (match_dup 4)))]
16555 "! TARGET_PARTIAL_REG_STALL && reload_completed
16556 && optimize_insn_for_speed_p ()
16557 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16558 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16559 /* Ensure that the operand will remain sign-extended immediate. */
16560 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16561 [(parallel [(set (match_dup 0)
16562 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16565 (and:SI (match_dup 3) (match_dup 4)))])]
16568 = gen_int_mode (INTVAL (operands[4])
16569 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16570 operands[1] = gen_lowpart (SImode, operands[1]);
16571 operands[3] = gen_lowpart (SImode, operands[3]);
16574 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16575 ; the TEST instruction with 32-bit sign-extended immediate and thus
16576 ; the instruction size would at least double, which is not what we
16577 ; want even with ! optimize_size.
16579 [(set (match_operand 0 "flags_reg_operand" "")
16580 (match_operator 1 "compare_operator"
16581 [(and (match_operand:HI 2 "aligned_operand" "")
16582 (match_operand:HI 3 "const_int_operand" ""))
16584 "! TARGET_PARTIAL_REG_STALL && reload_completed
16585 && ! TARGET_FAST_PREFIX
16586 && optimize_insn_for_speed_p ()
16587 /* Ensure that the operand will remain sign-extended immediate. */
16588 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16589 [(set (match_dup 0)
16590 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16594 = gen_int_mode (INTVAL (operands[3])
16595 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16596 operands[2] = gen_lowpart (SImode, operands[2]);
16600 [(set (match_operand 0 "register_operand" "")
16601 (neg (match_operand 1 "register_operand" "")))
16602 (clobber (reg:CC FLAGS_REG))]
16603 "! TARGET_PARTIAL_REG_STALL && reload_completed
16604 && (GET_MODE (operands[0]) == HImode
16605 || (GET_MODE (operands[0]) == QImode
16606 && (TARGET_PROMOTE_QImode
16607 || optimize_insn_for_size_p ())))"
16608 [(parallel [(set (match_dup 0)
16609 (neg:SI (match_dup 1)))
16610 (clobber (reg:CC FLAGS_REG))])]
16611 "operands[0] = gen_lowpart (SImode, operands[0]);
16612 operands[1] = gen_lowpart (SImode, operands[1]);")
16615 [(set (match_operand 0 "register_operand" "")
16616 (not (match_operand 1 "register_operand" "")))]
16617 "! TARGET_PARTIAL_REG_STALL && reload_completed
16618 && (GET_MODE (operands[0]) == HImode
16619 || (GET_MODE (operands[0]) == QImode
16620 && (TARGET_PROMOTE_QImode
16621 || optimize_insn_for_size_p ())))"
16622 [(set (match_dup 0)
16623 (not:SI (match_dup 1)))]
16624 "operands[0] = gen_lowpart (SImode, operands[0]);
16625 operands[1] = gen_lowpart (SImode, operands[1]);")
16628 [(set (match_operand 0 "register_operand" "")
16629 (if_then_else (match_operator 1 "comparison_operator"
16630 [(reg FLAGS_REG) (const_int 0)])
16631 (match_operand 2 "register_operand" "")
16632 (match_operand 3 "register_operand" "")))]
16633 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16634 && (GET_MODE (operands[0]) == HImode
16635 || (GET_MODE (operands[0]) == QImode
16636 && (TARGET_PROMOTE_QImode
16637 || optimize_insn_for_size_p ())))"
16638 [(set (match_dup 0)
16639 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16640 "operands[0] = gen_lowpart (SImode, operands[0]);
16641 operands[2] = gen_lowpart (SImode, operands[2]);
16642 operands[3] = gen_lowpart (SImode, operands[3]);")
16645 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16646 ;; transform a complex memory operation into two memory to register operations.
16648 ;; Don't push memory operands
16650 [(set (match_operand:SI 0 "push_operand" "")
16651 (match_operand:SI 1 "memory_operand" ""))
16652 (match_scratch:SI 2 "r")]
16653 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16654 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16655 [(set (match_dup 2) (match_dup 1))
16656 (set (match_dup 0) (match_dup 2))]
16660 [(set (match_operand:DI 0 "push_operand" "")
16661 (match_operand:DI 1 "memory_operand" ""))
16662 (match_scratch:DI 2 "r")]
16663 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16664 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16665 [(set (match_dup 2) (match_dup 1))
16666 (set (match_dup 0) (match_dup 2))]
16669 ;; We need to handle SFmode only, because DFmode and XFmode is split to
16672 [(set (match_operand:SF 0 "push_operand" "")
16673 (match_operand:SF 1 "memory_operand" ""))
16674 (match_scratch:SF 2 "r")]
16675 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16676 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16677 [(set (match_dup 2) (match_dup 1))
16678 (set (match_dup 0) (match_dup 2))]
16682 [(set (match_operand:HI 0 "push_operand" "")
16683 (match_operand:HI 1 "memory_operand" ""))
16684 (match_scratch:HI 2 "r")]
16685 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16686 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16687 [(set (match_dup 2) (match_dup 1))
16688 (set (match_dup 0) (match_dup 2))]
16692 [(set (match_operand:QI 0 "push_operand" "")
16693 (match_operand:QI 1 "memory_operand" ""))
16694 (match_scratch:QI 2 "q")]
16695 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16696 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16697 [(set (match_dup 2) (match_dup 1))
16698 (set (match_dup 0) (match_dup 2))]
16701 ;; Don't move an immediate directly to memory when the instruction
16704 [(match_scratch:SI 1 "r")
16705 (set (match_operand:SI 0 "memory_operand" "")
16707 "optimize_insn_for_speed_p ()
16708 && ! TARGET_USE_MOV0
16709 && TARGET_SPLIT_LONG_MOVES
16710 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16711 && peep2_regno_dead_p (0, FLAGS_REG)"
16712 [(parallel [(set (match_dup 1) (const_int 0))
16713 (clobber (reg:CC FLAGS_REG))])
16714 (set (match_dup 0) (match_dup 1))]
16718 [(match_scratch:HI 1 "r")
16719 (set (match_operand:HI 0 "memory_operand" "")
16721 "optimize_insn_for_speed_p ()
16722 && ! TARGET_USE_MOV0
16723 && TARGET_SPLIT_LONG_MOVES
16724 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16725 && peep2_regno_dead_p (0, FLAGS_REG)"
16726 [(parallel [(set (match_dup 2) (const_int 0))
16727 (clobber (reg:CC FLAGS_REG))])
16728 (set (match_dup 0) (match_dup 1))]
16729 "operands[2] = gen_lowpart (SImode, operands[1]);")
16732 [(match_scratch:QI 1 "q")
16733 (set (match_operand:QI 0 "memory_operand" "")
16735 "optimize_insn_for_speed_p ()
16736 && ! TARGET_USE_MOV0
16737 && TARGET_SPLIT_LONG_MOVES
16738 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16739 && peep2_regno_dead_p (0, FLAGS_REG)"
16740 [(parallel [(set (match_dup 2) (const_int 0))
16741 (clobber (reg:CC FLAGS_REG))])
16742 (set (match_dup 0) (match_dup 1))]
16743 "operands[2] = gen_lowpart (SImode, operands[1]);")
16746 [(match_scratch:SI 2 "r")
16747 (set (match_operand:SI 0 "memory_operand" "")
16748 (match_operand:SI 1 "immediate_operand" ""))]
16749 "optimize_insn_for_speed_p ()
16750 && TARGET_SPLIT_LONG_MOVES
16751 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16752 [(set (match_dup 2) (match_dup 1))
16753 (set (match_dup 0) (match_dup 2))]
16757 [(match_scratch:HI 2 "r")
16758 (set (match_operand:HI 0 "memory_operand" "")
16759 (match_operand:HI 1 "immediate_operand" ""))]
16760 "optimize_insn_for_speed_p ()
16761 && TARGET_SPLIT_LONG_MOVES
16762 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16763 [(set (match_dup 2) (match_dup 1))
16764 (set (match_dup 0) (match_dup 2))]
16768 [(match_scratch:QI 2 "q")
16769 (set (match_operand:QI 0 "memory_operand" "")
16770 (match_operand:QI 1 "immediate_operand" ""))]
16771 "optimize_insn_for_speed_p ()
16772 && TARGET_SPLIT_LONG_MOVES
16773 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16774 [(set (match_dup 2) (match_dup 1))
16775 (set (match_dup 0) (match_dup 2))]
16778 ;; Don't compare memory with zero, load and use a test instead.
16780 [(set (match_operand 0 "flags_reg_operand" "")
16781 (match_operator 1 "compare_operator"
16782 [(match_operand:SI 2 "memory_operand" "")
16784 (match_scratch:SI 3 "r")]
16785 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16786 [(set (match_dup 3) (match_dup 2))
16787 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
16790 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16791 ;; Don't split NOTs with a displacement operand, because resulting XOR
16792 ;; will not be pairable anyway.
16794 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16795 ;; represented using a modRM byte. The XOR replacement is long decoded,
16796 ;; so this split helps here as well.
16798 ;; Note: Can't do this as a regular split because we can't get proper
16799 ;; lifetime information then.
16802 [(set (match_operand:SI 0 "nonimmediate_operand" "")
16803 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
16804 "optimize_insn_for_speed_p ()
16805 && ((TARGET_NOT_UNPAIRABLE
16806 && (!MEM_P (operands[0])
16807 || !memory_displacement_operand (operands[0], SImode)))
16808 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
16809 && peep2_regno_dead_p (0, FLAGS_REG)"
16810 [(parallel [(set (match_dup 0)
16811 (xor:SI (match_dup 1) (const_int -1)))
16812 (clobber (reg:CC FLAGS_REG))])]
16816 [(set (match_operand:HI 0 "nonimmediate_operand" "")
16817 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
16818 "optimize_insn_for_speed_p ()
16819 && ((TARGET_NOT_UNPAIRABLE
16820 && (!MEM_P (operands[0])
16821 || !memory_displacement_operand (operands[0], HImode)))
16822 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
16823 && peep2_regno_dead_p (0, FLAGS_REG)"
16824 [(parallel [(set (match_dup 0)
16825 (xor:HI (match_dup 1) (const_int -1)))
16826 (clobber (reg:CC FLAGS_REG))])]
16830 [(set (match_operand:QI 0 "nonimmediate_operand" "")
16831 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
16832 "optimize_insn_for_speed_p ()
16833 && ((TARGET_NOT_UNPAIRABLE
16834 && (!MEM_P (operands[0])
16835 || !memory_displacement_operand (operands[0], QImode)))
16836 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
16837 && peep2_regno_dead_p (0, FLAGS_REG)"
16838 [(parallel [(set (match_dup 0)
16839 (xor:QI (match_dup 1) (const_int -1)))
16840 (clobber (reg:CC FLAGS_REG))])]
16843 ;; Non pairable "test imm, reg" instructions can be translated to
16844 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16845 ;; byte opcode instead of two, have a short form for byte operands),
16846 ;; so do it for other CPUs as well. Given that the value was dead,
16847 ;; this should not create any new dependencies. Pass on the sub-word
16848 ;; versions if we're concerned about partial register stalls.
16851 [(set (match_operand 0 "flags_reg_operand" "")
16852 (match_operator 1 "compare_operator"
16853 [(and:SI (match_operand:SI 2 "register_operand" "")
16854 (match_operand:SI 3 "immediate_operand" ""))
16856 "ix86_match_ccmode (insn, CCNOmode)
16857 && (true_regnum (operands[2]) != AX_REG
16858 || satisfies_constraint_K (operands[3]))
16859 && peep2_reg_dead_p (1, operands[2])"
16861 [(set (match_dup 0)
16862 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16865 (and:SI (match_dup 2) (match_dup 3)))])]
16868 ;; We don't need to handle HImode case, because it will be promoted to SImode
16869 ;; on ! TARGET_PARTIAL_REG_STALL
16872 [(set (match_operand 0 "flags_reg_operand" "")
16873 (match_operator 1 "compare_operator"
16874 [(and:QI (match_operand:QI 2 "register_operand" "")
16875 (match_operand:QI 3 "immediate_operand" ""))
16877 "! TARGET_PARTIAL_REG_STALL
16878 && ix86_match_ccmode (insn, CCNOmode)
16879 && true_regnum (operands[2]) != AX_REG
16880 && peep2_reg_dead_p (1, operands[2])"
16882 [(set (match_dup 0)
16883 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16886 (and:QI (match_dup 2) (match_dup 3)))])]
16890 [(set (match_operand 0 "flags_reg_operand" "")
16891 (match_operator 1 "compare_operator"
16894 (match_operand 2 "ext_register_operand" "")
16897 (match_operand 3 "const_int_operand" ""))
16899 "! TARGET_PARTIAL_REG_STALL
16900 && ix86_match_ccmode (insn, CCNOmode)
16901 && true_regnum (operands[2]) != AX_REG
16902 && peep2_reg_dead_p (1, operands[2])"
16903 [(parallel [(set (match_dup 0)
16912 (set (zero_extract:SI (match_dup 2)
16923 ;; Don't do logical operations with memory inputs.
16925 [(match_scratch:SI 2 "r")
16926 (parallel [(set (match_operand:SI 0 "register_operand" "")
16927 (match_operator:SI 3 "arith_or_logical_operator"
16929 (match_operand:SI 1 "memory_operand" "")]))
16930 (clobber (reg:CC FLAGS_REG))])]
16931 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16932 [(set (match_dup 2) (match_dup 1))
16933 (parallel [(set (match_dup 0)
16934 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16935 (clobber (reg:CC FLAGS_REG))])]
16939 [(match_scratch:SI 2 "r")
16940 (parallel [(set (match_operand:SI 0 "register_operand" "")
16941 (match_operator:SI 3 "arith_or_logical_operator"
16942 [(match_operand:SI 1 "memory_operand" "")
16944 (clobber (reg:CC FLAGS_REG))])]
16945 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16946 [(set (match_dup 2) (match_dup 1))
16947 (parallel [(set (match_dup 0)
16948 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16949 (clobber (reg:CC FLAGS_REG))])]
16952 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16953 ;; refers to the destination of the load!
16956 [(set (match_operand:SI 0 "register_operand" "")
16957 (match_operand:SI 1 "register_operand" ""))
16958 (parallel [(set (match_dup 0)
16959 (match_operator:SI 3 "commutative_operator"
16961 (match_operand:SI 2 "memory_operand" "")]))
16962 (clobber (reg:CC FLAGS_REG))])]
16963 "REGNO (operands[0]) != REGNO (operands[1])
16964 && GENERAL_REGNO_P (REGNO (operands[0]))
16965 && GENERAL_REGNO_P (REGNO (operands[1]))"
16966 [(set (match_dup 0) (match_dup 4))
16967 (parallel [(set (match_dup 0)
16968 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16969 (clobber (reg:CC FLAGS_REG))])]
16970 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16973 [(set (match_operand 0 "register_operand" "")
16974 (match_operand 1 "register_operand" ""))
16976 (match_operator 3 "commutative_operator"
16978 (match_operand 2 "memory_operand" "")]))]
16979 "REGNO (operands[0]) != REGNO (operands[1])
16980 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16981 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16982 [(set (match_dup 0) (match_dup 2))
16984 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
16987 ; Don't do logical operations with memory outputs
16989 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16990 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16991 ; the same decoder scheduling characteristics as the original.
16994 [(match_scratch:SI 2 "r")
16995 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16996 (match_operator:SI 3 "arith_or_logical_operator"
16998 (match_operand:SI 1 "nonmemory_operand" "")]))
16999 (clobber (reg:CC FLAGS_REG))])]
17000 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17001 /* Do not split stack checking probes. */
17002 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17003 [(set (match_dup 2) (match_dup 0))
17004 (parallel [(set (match_dup 2)
17005 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17006 (clobber (reg:CC FLAGS_REG))])
17007 (set (match_dup 0) (match_dup 2))]
17011 [(match_scratch:SI 2 "r")
17012 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17013 (match_operator:SI 3 "arith_or_logical_operator"
17014 [(match_operand:SI 1 "nonmemory_operand" "")
17016 (clobber (reg:CC FLAGS_REG))])]
17017 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17018 /* Do not split stack checking probes. */
17019 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17020 [(set (match_dup 2) (match_dup 0))
17021 (parallel [(set (match_dup 2)
17022 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17023 (clobber (reg:CC FLAGS_REG))])
17024 (set (match_dup 0) (match_dup 2))]
17027 ;; Attempt to always use XOR for zeroing registers.
17029 [(set (match_operand 0 "register_operand" "")
17030 (match_operand 1 "const0_operand" ""))]
17031 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17032 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17033 && GENERAL_REG_P (operands[0])
17034 && peep2_regno_dead_p (0, FLAGS_REG)"
17035 [(parallel [(set (match_dup 0) (const_int 0))
17036 (clobber (reg:CC FLAGS_REG))])]
17038 operands[0] = gen_lowpart (word_mode, operands[0]);
17042 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17044 "(GET_MODE (operands[0]) == QImode
17045 || GET_MODE (operands[0]) == HImode)
17046 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17047 && peep2_regno_dead_p (0, FLAGS_REG)"
17048 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17049 (clobber (reg:CC FLAGS_REG))])])
17051 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17053 [(set (match_operand 0 "register_operand" "")
17055 "(GET_MODE (operands[0]) == HImode
17056 || GET_MODE (operands[0]) == SImode
17057 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17058 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17059 && peep2_regno_dead_p (0, FLAGS_REG)"
17060 [(parallel [(set (match_dup 0) (const_int -1))
17061 (clobber (reg:CC FLAGS_REG))])]
17062 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17065 ;; Attempt to convert simple leas to adds. These can be created by
17068 [(set (match_operand:SI 0 "register_operand" "")
17069 (plus:SI (match_dup 0)
17070 (match_operand:SI 1 "nonmemory_operand" "")))]
17071 "peep2_regno_dead_p (0, FLAGS_REG)"
17072 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17073 (clobber (reg:CC FLAGS_REG))])]
17077 [(set (match_operand:SI 0 "register_operand" "")
17078 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17079 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17080 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17081 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17082 (clobber (reg:CC FLAGS_REG))])]
17083 "operands[2] = gen_lowpart (SImode, operands[2]);")
17086 [(set (match_operand:DI 0 "register_operand" "")
17087 (plus:DI (match_dup 0)
17088 (match_operand:DI 1 "x86_64_general_operand" "")))]
17089 "peep2_regno_dead_p (0, FLAGS_REG)"
17090 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17091 (clobber (reg:CC FLAGS_REG))])]
17095 [(set (match_operand:SI 0 "register_operand" "")
17096 (mult:SI (match_dup 0)
17097 (match_operand:SI 1 "const_int_operand" "")))]
17098 "exact_log2 (INTVAL (operands[1])) >= 0
17099 && peep2_regno_dead_p (0, FLAGS_REG)"
17100 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17101 (clobber (reg:CC FLAGS_REG))])]
17102 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17105 [(set (match_operand:DI 0 "register_operand" "")
17106 (mult:DI (match_dup 0)
17107 (match_operand:DI 1 "const_int_operand" "")))]
17108 "exact_log2 (INTVAL (operands[1])) >= 0
17109 && peep2_regno_dead_p (0, FLAGS_REG)"
17110 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17111 (clobber (reg:CC FLAGS_REG))])]
17112 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17115 [(set (match_operand:SI 0 "register_operand" "")
17116 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17117 (match_operand:DI 2 "const_int_operand" "")) 0))]
17118 "exact_log2 (INTVAL (operands[2])) >= 0
17119 && REGNO (operands[0]) == REGNO (operands[1])
17120 && peep2_regno_dead_p (0, FLAGS_REG)"
17121 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17122 (clobber (reg:CC FLAGS_REG))])]
17123 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17125 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17126 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17127 ;; many CPUs it is also faster, since special hardware to avoid esp
17128 ;; dependencies is present.
17130 ;; While some of these conversions may be done using splitters, we use peepholes
17131 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17133 ;; Convert prologue esp subtractions to push.
17134 ;; We need register to push. In order to keep verify_flow_info happy we have
17136 ;; - use scratch and clobber it in order to avoid dependencies
17137 ;; - use already live register
17138 ;; We can't use the second way right now, since there is no reliable way how to
17139 ;; verify that given register is live. First choice will also most likely in
17140 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17141 ;; call clobbered registers are dead. We may want to use base pointer as an
17142 ;; alternative when no register is available later.
17145 [(match_scratch:SI 0 "r")
17146 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17147 (clobber (reg:CC FLAGS_REG))
17148 (clobber (mem:BLK (scratch)))])]
17149 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17150 [(clobber (match_dup 0))
17151 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17152 (clobber (mem:BLK (scratch)))])])
17155 [(match_scratch:SI 0 "r")
17156 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17157 (clobber (reg:CC FLAGS_REG))
17158 (clobber (mem:BLK (scratch)))])]
17159 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17160 [(clobber (match_dup 0))
17161 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17162 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17163 (clobber (mem:BLK (scratch)))])])
17165 ;; Convert esp subtractions to push.
17167 [(match_scratch:SI 0 "r")
17168 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17169 (clobber (reg:CC FLAGS_REG))])]
17170 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17171 [(clobber (match_dup 0))
17172 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17175 [(match_scratch:SI 0 "r")
17176 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17177 (clobber (reg:CC FLAGS_REG))])]
17178 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17179 [(clobber (match_dup 0))
17180 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17181 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17183 ;; Convert epilogue deallocator to pop.
17185 [(match_scratch:SI 0 "r")
17186 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17187 (clobber (reg:CC FLAGS_REG))
17188 (clobber (mem:BLK (scratch)))])]
17189 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17190 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17191 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17192 (clobber (mem:BLK (scratch)))])]
17195 ;; Two pops case is tricky, since pop causes dependency on destination register.
17196 ;; We use two registers if available.
17198 [(match_scratch:SI 0 "r")
17199 (match_scratch:SI 1 "r")
17200 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17201 (clobber (reg:CC FLAGS_REG))
17202 (clobber (mem:BLK (scratch)))])]
17203 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17204 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17205 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17206 (clobber (mem:BLK (scratch)))])
17207 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17208 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17212 [(match_scratch:SI 0 "r")
17213 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17214 (clobber (reg:CC FLAGS_REG))
17215 (clobber (mem:BLK (scratch)))])]
17216 "optimize_insn_for_size_p ()"
17217 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17218 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17219 (clobber (mem:BLK (scratch)))])
17220 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17221 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17224 ;; Convert esp additions to pop.
17226 [(match_scratch:SI 0 "r")
17227 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17228 (clobber (reg:CC FLAGS_REG))])]
17230 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17231 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17234 ;; Two pops case is tricky, since pop causes dependency on destination register.
17235 ;; We use two registers if available.
17237 [(match_scratch:SI 0 "r")
17238 (match_scratch:SI 1 "r")
17239 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17240 (clobber (reg:CC FLAGS_REG))])]
17242 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17243 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17244 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17245 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17249 [(match_scratch:SI 0 "r")
17250 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17251 (clobber (reg:CC FLAGS_REG))])]
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 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17256 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17259 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17260 ;; required and register dies. Similarly for 128 to -128.
17262 [(set (match_operand 0 "flags_reg_operand" "")
17263 (match_operator 1 "compare_operator"
17264 [(match_operand 2 "register_operand" "")
17265 (match_operand 3 "const_int_operand" "")]))]
17266 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17267 && incdec_operand (operands[3], GET_MODE (operands[3])))
17268 || (!TARGET_FUSE_CMP_AND_BRANCH
17269 && INTVAL (operands[3]) == 128))
17270 && ix86_match_ccmode (insn, CCGCmode)
17271 && peep2_reg_dead_p (1, operands[2])"
17272 [(parallel [(set (match_dup 0)
17273 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17274 (clobber (match_dup 2))])]
17278 [(match_scratch:DI 0 "r")
17279 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17280 (clobber (reg:CC FLAGS_REG))
17281 (clobber (mem:BLK (scratch)))])]
17282 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17283 [(clobber (match_dup 0))
17284 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17285 (clobber (mem:BLK (scratch)))])])
17288 [(match_scratch:DI 0 "r")
17289 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17290 (clobber (reg:CC FLAGS_REG))
17291 (clobber (mem:BLK (scratch)))])]
17292 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17293 [(clobber (match_dup 0))
17294 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17295 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17296 (clobber (mem:BLK (scratch)))])])
17298 ;; Convert esp subtractions to push.
17300 [(match_scratch:DI 0 "r")
17301 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17302 (clobber (reg:CC FLAGS_REG))])]
17303 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17304 [(clobber (match_dup 0))
17305 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17308 [(match_scratch:DI 0 "r")
17309 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17310 (clobber (reg:CC FLAGS_REG))])]
17311 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17312 [(clobber (match_dup 0))
17313 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17314 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17316 ;; Convert epilogue deallocator to pop.
17318 [(match_scratch:DI 0 "r")
17319 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17320 (clobber (reg:CC FLAGS_REG))
17321 (clobber (mem:BLK (scratch)))])]
17322 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17323 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17324 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17325 (clobber (mem:BLK (scratch)))])]
17328 ;; Two pops case is tricky, since pop causes dependency on destination register.
17329 ;; We use two registers if available.
17331 [(match_scratch:DI 0 "r")
17332 (match_scratch:DI 1 "r")
17333 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17334 (clobber (reg:CC FLAGS_REG))
17335 (clobber (mem:BLK (scratch)))])]
17336 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17337 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17338 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17339 (clobber (mem:BLK (scratch)))])
17340 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17341 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17345 [(match_scratch:DI 0 "r")
17346 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17347 (clobber (reg:CC FLAGS_REG))
17348 (clobber (mem:BLK (scratch)))])]
17349 "optimize_insn_for_size_p ()"
17350 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17351 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17352 (clobber (mem:BLK (scratch)))])
17353 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17354 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17357 ;; Convert esp additions to pop.
17359 [(match_scratch:DI 0 "r")
17360 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17361 (clobber (reg:CC FLAGS_REG))])]
17363 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17364 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17367 ;; Two pops case is tricky, since pop causes dependency on destination register.
17368 ;; We use two registers if available.
17370 [(match_scratch:DI 0 "r")
17371 (match_scratch:DI 1 "r")
17372 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17373 (clobber (reg:CC FLAGS_REG))])]
17375 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17376 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17377 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17378 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17382 [(match_scratch:DI 0 "r")
17383 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17384 (clobber (reg:CC FLAGS_REG))])]
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 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17389 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17392 ;; Convert imul by three, five and nine into lea
17395 [(set (match_operand:SI 0 "register_operand" "")
17396 (mult:SI (match_operand:SI 1 "register_operand" "")
17397 (match_operand:SI 2 "const_int_operand" "")))
17398 (clobber (reg:CC FLAGS_REG))])]
17399 "INTVAL (operands[2]) == 3
17400 || INTVAL (operands[2]) == 5
17401 || INTVAL (operands[2]) == 9"
17402 [(set (match_dup 0)
17403 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
17405 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17409 [(set (match_operand:SI 0 "register_operand" "")
17410 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17411 (match_operand:SI 2 "const_int_operand" "")))
17412 (clobber (reg:CC FLAGS_REG))])]
17413 "optimize_insn_for_speed_p ()
17414 && (INTVAL (operands[2]) == 3
17415 || INTVAL (operands[2]) == 5
17416 || INTVAL (operands[2]) == 9)"
17417 [(set (match_dup 0) (match_dup 1))
17419 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
17421 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17425 [(set (match_operand:DI 0 "register_operand" "")
17426 (mult:DI (match_operand:DI 1 "register_operand" "")
17427 (match_operand:DI 2 "const_int_operand" "")))
17428 (clobber (reg:CC FLAGS_REG))])]
17430 && (INTVAL (operands[2]) == 3
17431 || INTVAL (operands[2]) == 5
17432 || INTVAL (operands[2]) == 9)"
17433 [(set (match_dup 0)
17434 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
17436 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17440 [(set (match_operand:DI 0 "register_operand" "")
17441 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17442 (match_operand:DI 2 "const_int_operand" "")))
17443 (clobber (reg:CC FLAGS_REG))])]
17445 && optimize_insn_for_speed_p ()
17446 && (INTVAL (operands[2]) == 3
17447 || INTVAL (operands[2]) == 5
17448 || INTVAL (operands[2]) == 9)"
17449 [(set (match_dup 0) (match_dup 1))
17451 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
17453 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17455 ;; Imul $32bit_imm, mem, reg is vector decoded, while
17456 ;; imul $32bit_imm, reg, reg is direct decoded.
17458 [(match_scratch:DI 3 "r")
17459 (parallel [(set (match_operand:DI 0 "register_operand" "")
17460 (mult:DI (match_operand:DI 1 "memory_operand" "")
17461 (match_operand:DI 2 "immediate_operand" "")))
17462 (clobber (reg:CC FLAGS_REG))])]
17463 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17464 && !satisfies_constraint_K (operands[2])"
17465 [(set (match_dup 3) (match_dup 1))
17466 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
17467 (clobber (reg:CC FLAGS_REG))])]
17471 [(match_scratch:SI 3 "r")
17472 (parallel [(set (match_operand:SI 0 "register_operand" "")
17473 (mult:SI (match_operand:SI 1 "memory_operand" "")
17474 (match_operand:SI 2 "immediate_operand" "")))
17475 (clobber (reg:CC FLAGS_REG))])]
17476 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17477 && !satisfies_constraint_K (operands[2])"
17478 [(set (match_dup 3) (match_dup 1))
17479 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
17480 (clobber (reg:CC FLAGS_REG))])]
17484 [(match_scratch:SI 3 "r")
17485 (parallel [(set (match_operand:DI 0 "register_operand" "")
17487 (mult:SI (match_operand:SI 1 "memory_operand" "")
17488 (match_operand:SI 2 "immediate_operand" ""))))
17489 (clobber (reg:CC FLAGS_REG))])]
17490 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17491 && !satisfies_constraint_K (operands[2])"
17492 [(set (match_dup 3) (match_dup 1))
17493 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17494 (clobber (reg:CC FLAGS_REG))])]
17497 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17498 ;; Convert it into imul reg, reg
17499 ;; It would be better to force assembler to encode instruction using long
17500 ;; immediate, but there is apparently no way to do so.
17502 [(parallel [(set (match_operand:DI 0 "register_operand" "")
17503 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17504 (match_operand:DI 2 "const_int_operand" "")))
17505 (clobber (reg:CC FLAGS_REG))])
17506 (match_scratch:DI 3 "r")]
17507 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17508 && satisfies_constraint_K (operands[2])"
17509 [(set (match_dup 3) (match_dup 2))
17510 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
17511 (clobber (reg:CC FLAGS_REG))])]
17513 if (!rtx_equal_p (operands[0], operands[1]))
17514 emit_move_insn (operands[0], operands[1]);
17518 [(parallel [(set (match_operand:SI 0 "register_operand" "")
17519 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17520 (match_operand:SI 2 "const_int_operand" "")))
17521 (clobber (reg:CC FLAGS_REG))])
17522 (match_scratch:SI 3 "r")]
17523 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17524 && satisfies_constraint_K (operands[2])"
17525 [(set (match_dup 3) (match_dup 2))
17526 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
17527 (clobber (reg:CC FLAGS_REG))])]
17529 if (!rtx_equal_p (operands[0], operands[1]))
17530 emit_move_insn (operands[0], operands[1]);
17534 [(parallel [(set (match_operand:HI 0 "register_operand" "")
17535 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
17536 (match_operand:HI 2 "immediate_operand" "")))
17537 (clobber (reg:CC FLAGS_REG))])
17538 (match_scratch:HI 3 "r")]
17539 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
17540 [(set (match_dup 3) (match_dup 2))
17541 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
17542 (clobber (reg:CC FLAGS_REG))])]
17544 if (!rtx_equal_p (operands[0], operands[1]))
17545 emit_move_insn (operands[0], operands[1]);
17548 ;; After splitting up read-modify operations, array accesses with memory
17549 ;; operands might end up in form:
17551 ;; movl 4(%esp), %edx
17553 ;; instead of pre-splitting:
17555 ;; addl 4(%esp), %eax
17557 ;; movl 4(%esp), %edx
17558 ;; leal (%edx,%eax,4), %eax
17561 [(parallel [(set (match_operand 0 "register_operand" "")
17562 (ashift (match_operand 1 "register_operand" "")
17563 (match_operand 2 "const_int_operand" "")))
17564 (clobber (reg:CC FLAGS_REG))])
17565 (set (match_operand 3 "register_operand")
17566 (match_operand 4 "x86_64_general_operand" ""))
17567 (parallel [(set (match_operand 5 "register_operand" "")
17568 (plus (match_operand 6 "register_operand" "")
17569 (match_operand 7 "register_operand" "")))
17570 (clobber (reg:CC FLAGS_REG))])]
17571 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17572 /* Validate MODE for lea. */
17573 && ((!TARGET_PARTIAL_REG_STALL
17574 && (GET_MODE (operands[0]) == QImode
17575 || GET_MODE (operands[0]) == HImode))
17576 || GET_MODE (operands[0]) == SImode
17577 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17578 /* We reorder load and the shift. */
17579 && !rtx_equal_p (operands[1], operands[3])
17580 && !reg_overlap_mentioned_p (operands[0], operands[4])
17581 /* Last PLUS must consist of operand 0 and 3. */
17582 && !rtx_equal_p (operands[0], operands[3])
17583 && (rtx_equal_p (operands[3], operands[6])
17584 || rtx_equal_p (operands[3], operands[7]))
17585 && (rtx_equal_p (operands[0], operands[6])
17586 || rtx_equal_p (operands[0], operands[7]))
17587 /* The intermediate operand 0 must die or be same as output. */
17588 && (rtx_equal_p (operands[0], operands[5])
17589 || peep2_reg_dead_p (3, operands[0]))"
17590 [(set (match_dup 3) (match_dup 4))
17591 (set (match_dup 0) (match_dup 1))]
17593 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
17594 int scale = 1 << INTVAL (operands[2]);
17595 rtx index = gen_lowpart (Pmode, operands[1]);
17596 rtx base = gen_lowpart (Pmode, operands[3]);
17597 rtx dest = gen_lowpart (mode, operands[5]);
17599 operands[1] = gen_rtx_PLUS (Pmode, base,
17600 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17602 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17603 operands[0] = dest;
17606 ;; Call-value patterns last so that the wildcard operand does not
17607 ;; disrupt insn-recog's switch tables.
17609 (define_insn "*call_value_pop_0"
17610 [(set (match_operand 0 "" "")
17611 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17612 (match_operand:SI 2 "" "")))
17613 (set (reg:SI SP_REG)
17614 (plus:SI (reg:SI SP_REG)
17615 (match_operand:SI 3 "immediate_operand" "")))]
17618 if (SIBLING_CALL_P (insn))
17621 return "call\t%P1";
17623 [(set_attr "type" "callv")])
17625 (define_insn "*call_value_pop_1"
17626 [(set (match_operand 0 "" "")
17627 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17628 (match_operand:SI 2 "" "")))
17629 (set (reg:SI SP_REG)
17630 (plus:SI (reg:SI SP_REG)
17631 (match_operand:SI 3 "immediate_operand" "i")))]
17632 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17634 if (constant_call_address_operand (operands[1], Pmode))
17635 return "call\t%P1";
17636 return "call\t%A1";
17638 [(set_attr "type" "callv")])
17640 (define_insn "*sibcall_value_pop_1"
17641 [(set (match_operand 0 "" "")
17642 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17643 (match_operand:SI 2 "" "")))
17644 (set (reg:SI SP_REG)
17645 (plus:SI (reg:SI SP_REG)
17646 (match_operand:SI 3 "immediate_operand" "i,i")))]
17647 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17651 [(set_attr "type" "callv")])
17653 (define_insn "*call_value_0"
17654 [(set (match_operand 0 "" "")
17655 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17656 (match_operand:SI 2 "" "")))]
17659 if (SIBLING_CALL_P (insn))
17662 return "call\t%P1";
17664 [(set_attr "type" "callv")])
17666 (define_insn "*call_value_0_rex64"
17667 [(set (match_operand 0 "" "")
17668 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17669 (match_operand:DI 2 "const_int_operand" "")))]
17672 if (SIBLING_CALL_P (insn))
17675 return "call\t%P1";
17677 [(set_attr "type" "callv")])
17679 (define_insn "*call_value_0_rex64_ms_sysv"
17680 [(set (match_operand 0 "" "")
17681 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17682 (match_operand:DI 2 "const_int_operand" "")))
17683 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17684 (clobber (reg:TI XMM6_REG))
17685 (clobber (reg:TI XMM7_REG))
17686 (clobber (reg:TI XMM8_REG))
17687 (clobber (reg:TI XMM9_REG))
17688 (clobber (reg:TI XMM10_REG))
17689 (clobber (reg:TI XMM11_REG))
17690 (clobber (reg:TI XMM12_REG))
17691 (clobber (reg:TI XMM13_REG))
17692 (clobber (reg:TI XMM14_REG))
17693 (clobber (reg:TI XMM15_REG))
17694 (clobber (reg:DI SI_REG))
17695 (clobber (reg:DI DI_REG))]
17696 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17698 if (SIBLING_CALL_P (insn))
17701 return "call\t%P1";
17703 [(set_attr "type" "callv")])
17705 (define_insn "*call_value_1"
17706 [(set (match_operand 0 "" "")
17707 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17708 (match_operand:SI 2 "" "")))]
17709 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17711 if (constant_call_address_operand (operands[1], Pmode))
17712 return "call\t%P1";
17713 return "call\t%A1";
17715 [(set_attr "type" "callv")])
17717 (define_insn "*sibcall_value_1"
17718 [(set (match_operand 0 "" "")
17719 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17720 (match_operand:SI 2 "" "")))]
17721 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17725 [(set_attr "type" "callv")])
17727 (define_insn "*call_value_1_rex64"
17728 [(set (match_operand 0 "" "")
17729 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17730 (match_operand:DI 2 "" "")))]
17731 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17732 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17734 if (constant_call_address_operand (operands[1], Pmode))
17735 return "call\t%P1";
17736 return "call\t%A1";
17738 [(set_attr "type" "callv")])
17740 (define_insn "*call_value_1_rex64_ms_sysv"
17741 [(set (match_operand 0 "" "")
17742 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17743 (match_operand:DI 2 "" "")))
17744 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17745 (clobber (reg:TI XMM6_REG))
17746 (clobber (reg:TI XMM7_REG))
17747 (clobber (reg:TI XMM8_REG))
17748 (clobber (reg:TI XMM9_REG))
17749 (clobber (reg:TI XMM10_REG))
17750 (clobber (reg:TI XMM11_REG))
17751 (clobber (reg:TI XMM12_REG))
17752 (clobber (reg:TI XMM13_REG))
17753 (clobber (reg:TI XMM14_REG))
17754 (clobber (reg:TI XMM15_REG))
17755 (clobber (reg:DI SI_REG))
17756 (clobber (reg:DI DI_REG))]
17757 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17759 if (constant_call_address_operand (operands[1], Pmode))
17760 return "call\t%P1";
17761 return "call\t%A1";
17763 [(set_attr "type" "callv")])
17765 (define_insn "*call_value_1_rex64_large"
17766 [(set (match_operand 0 "" "")
17767 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17768 (match_operand:DI 2 "" "")))]
17769 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17771 [(set_attr "type" "callv")])
17773 (define_insn "*sibcall_value_1_rex64"
17774 [(set (match_operand 0 "" "")
17775 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17776 (match_operand:DI 2 "" "")))]
17777 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17781 [(set_attr "type" "callv")])
17783 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17784 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17785 ;; caught for use by garbage collectors and the like. Using an insn that
17786 ;; maps to SIGILL makes it more likely the program will rightfully die.
17787 ;; Keeping with tradition, "6" is in honor of #UD.
17788 (define_insn "trap"
17789 [(trap_if (const_int 1) (const_int 6))]
17791 { return ASM_SHORT "0x0b0f"; }
17792 [(set_attr "length" "2")])
17794 (define_expand "sse_prologue_save"
17795 [(parallel [(set (match_operand:BLK 0 "" "")
17796 (unspec:BLK [(reg:DI XMM0_REG)
17803 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
17804 (clobber (reg:CC FLAGS_REG))
17805 (clobber (match_operand:DI 1 "register_operand" ""))
17806 (use (match_operand:DI 2 "immediate_operand" ""))
17807 (use (label_ref:DI (match_operand 3 "" "")))
17808 (clobber (match_operand:DI 4 "register_operand" ""))
17809 (use (match_dup 1))])]
17813 ;; Pre-reload version of prologue save. Until after prologue generation we don't know
17814 ;; what the size of save instruction will be.
17815 ;; Operand 0+operand 6 is the memory save area
17816 ;; Operand 1 is number of registers to save (will get overwritten to operand 5)
17817 ;; Operand 2 is number of non-vaargs SSE arguments
17818 ;; Operand 3 is label starting the save block
17819 ;; Operand 4 is used for temporary computation of jump address
17820 (define_insn "*sse_prologue_save_insn1"
17821 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
17822 (match_operand:DI 6 "const_int_operand" "n")))
17823 (unspec:BLK [(reg:DI XMM0_REG)
17830 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
17831 (clobber (reg:CC FLAGS_REG))
17832 (clobber (match_operand:DI 1 "register_operand" "=r"))
17833 (use (match_operand:DI 2 "const_int_operand" "i"))
17834 (use (label_ref:DI (match_operand 3 "" "X")))
17835 (clobber (match_operand:DI 4 "register_operand" "=&r"))
17836 (use (match_operand:DI 5 "register_operand" "1"))]
17838 && INTVAL (operands[6]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
17839 && INTVAL (operands[6]) + INTVAL (operands[2]) * 16 >= -128"
17841 [(set_attr "type" "other")
17842 (set_attr "memory" "store")
17843 (set_attr "mode" "DI")])
17845 ;; We know size of save instruction; expand the computation of jump address
17846 ;; in the jumptable.
17848 [(parallel [(set (match_operand:BLK 0 "" "")
17849 (unspec:BLK [(reg:DI XMM0_REG)
17856 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
17857 (clobber (reg:CC FLAGS_REG))
17858 (clobber (match_operand:DI 1 "register_operand" ""))
17859 (use (match_operand:DI 2 "const_int_operand" ""))
17860 (use (match_operand 3 "" ""))
17861 (clobber (match_operand:DI 4 "register_operand" ""))
17862 (use (match_operand:DI 5 "register_operand" ""))])]
17864 [(parallel [(set (match_dup 0)
17865 (unspec:BLK [(reg:DI XMM0_REG)
17872 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
17873 (use (match_dup 1))
17874 (use (match_dup 2))
17875 (use (match_dup 3))
17876 (use (match_dup 5))])]
17878 /* Movaps is 4 bytes, AVX and movsd is 5 bytes. */
17879 int size = 4 + (TARGET_AVX || crtl->stack_alignment_needed < 128);
17881 /* Compute address to jump to:
17882 label - eax*size + nnamed_sse_arguments*size. */
17884 emit_insn (gen_rtx_SET (VOIDmode, operands[4],
17887 gen_rtx_MULT (Pmode, operands[1],
17890 else if (size == 4)
17891 emit_insn (gen_rtx_SET (VOIDmode, operands[4],
17892 gen_rtx_MULT (Pmode, operands[1],
17895 gcc_unreachable ();
17896 if (INTVAL (operands[2]))
17899 gen_rtx_CONST (DImode,
17900 gen_rtx_PLUS (DImode,
17902 GEN_INT (INTVAL (operands[2])
17905 emit_move_insn (operands[1], operands[3]);
17906 emit_insn (gen_subdi3 (operands[1], operands[1], operands[4]));
17907 operands[5] = GEN_INT (size);
17910 (define_insn "sse_prologue_save_insn"
17911 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
17912 (match_operand:DI 4 "const_int_operand" "n")))
17913 (unspec:BLK [(reg:DI XMM0_REG)
17920 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
17921 (use (match_operand:DI 1 "register_operand" "r"))
17922 (use (match_operand:DI 2 "const_int_operand" "i"))
17923 (use (label_ref:DI (match_operand 3 "" "X")))
17924 (use (match_operand:DI 5 "const_int_operand" "i"))]
17926 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
17927 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
17930 operands[0] = gen_rtx_MEM (Pmode,
17931 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
17932 /* VEX instruction with a REX prefix will #UD. */
17933 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
17934 gcc_unreachable ();
17936 output_asm_insn ("jmp\t%A1", operands);
17937 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
17939 operands[4] = adjust_address (operands[0], DImode, i*16);
17940 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
17941 PUT_MODE (operands[4], TImode);
17942 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
17943 output_asm_insn ("rex", operands);
17944 if (crtl->stack_alignment_needed < 128)
17945 output_asm_insn ("%vmovsd\t{%5, %4|%4, %5}", operands);
17947 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
17949 (*targetm.asm_out.internal_label) (asm_out_file, "L",
17950 CODE_LABEL_NUMBER (operands[3]));
17953 [(set_attr "type" "other")
17954 (set_attr "length_immediate" "0")
17955 (set_attr "length_address" "0")
17956 ;; 2 bytes for jump and opernds[4] bytes for each save.
17957 (set (attr "length")
17958 (plus (const_int 2)
17959 (mult (symbol_ref ("INTVAL (operands[5])"))
17960 (symbol_ref ("X86_64_SSE_REGPARM_MAX - INTVAL (operands[2])")))))
17961 (set_attr "memory" "store")
17962 (set_attr "modrm" "0")
17963 (set_attr "prefix" "maybe_vex")
17964 (set_attr "mode" "DI")])
17966 (define_expand "prefetch"
17967 [(prefetch (match_operand 0 "address_operand" "")
17968 (match_operand:SI 1 "const_int_operand" "")
17969 (match_operand:SI 2 "const_int_operand" ""))]
17970 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17972 int rw = INTVAL (operands[1]);
17973 int locality = INTVAL (operands[2]);
17975 gcc_assert (rw == 0 || rw == 1);
17976 gcc_assert (locality >= 0 && locality <= 3);
17977 gcc_assert (GET_MODE (operands[0]) == Pmode
17978 || GET_MODE (operands[0]) == VOIDmode);
17980 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17981 supported by SSE counterpart or the SSE prefetch is not available
17982 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17984 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17985 operands[2] = GEN_INT (3);
17987 operands[1] = const0_rtx;
17990 (define_insn "*prefetch_sse_<mode>"
17991 [(prefetch (match_operand:P 0 "address_operand" "p")
17993 (match_operand:SI 1 "const_int_operand" ""))]
17994 "TARGET_PREFETCH_SSE"
17996 static const char * const patterns[4] = {
17997 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18000 int locality = INTVAL (operands[1]);
18001 gcc_assert (locality >= 0 && locality <= 3);
18003 return patterns[locality];
18005 [(set_attr "type" "sse")
18006 (set_attr "atom_sse_attr" "prefetch")
18007 (set (attr "length_address")
18008 (symbol_ref "memory_address_length (operands[0])"))
18009 (set_attr "memory" "none")])
18011 (define_insn "*prefetch_3dnow_<mode>"
18012 [(prefetch (match_operand:P 0 "address_operand" "p")
18013 (match_operand:SI 1 "const_int_operand" "n")
18017 if (INTVAL (operands[1]) == 0)
18018 return "prefetch\t%a0";
18020 return "prefetchw\t%a0";
18022 [(set_attr "type" "mmx")
18023 (set (attr "length_address")
18024 (symbol_ref "memory_address_length (operands[0])"))
18025 (set_attr "memory" "none")])
18027 (define_expand "stack_protect_set"
18028 [(match_operand 0 "memory_operand" "")
18029 (match_operand 1 "memory_operand" "")]
18032 #ifdef TARGET_THREAD_SSP_OFFSET
18034 emit_insn (gen_stack_tls_protect_set_di (operands[0],
18035 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18037 emit_insn (gen_stack_tls_protect_set_si (operands[0],
18038 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18041 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
18043 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
18048 (define_insn "stack_protect_set_si"
18049 [(set (match_operand:SI 0 "memory_operand" "=m")
18050 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18051 (set (match_scratch:SI 2 "=&r") (const_int 0))
18052 (clobber (reg:CC FLAGS_REG))]
18054 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18055 [(set_attr "type" "multi")])
18057 (define_insn "stack_protect_set_di"
18058 [(set (match_operand:DI 0 "memory_operand" "=m")
18059 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18060 (set (match_scratch:DI 2 "=&r") (const_int 0))
18061 (clobber (reg:CC FLAGS_REG))]
18063 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18064 [(set_attr "type" "multi")])
18066 (define_insn "stack_tls_protect_set_si"
18067 [(set (match_operand:SI 0 "memory_operand" "=m")
18068 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")]
18069 UNSPEC_SP_TLS_SET))
18070 (set (match_scratch:SI 2 "=&r") (const_int 0))
18071 (clobber (reg:CC FLAGS_REG))]
18073 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18074 [(set_attr "type" "multi")])
18076 (define_insn "stack_tls_protect_set_di"
18077 [(set (match_operand:DI 0 "memory_operand" "=m")
18078 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")]
18079 UNSPEC_SP_TLS_SET))
18080 (set (match_scratch:DI 2 "=&r") (const_int 0))
18081 (clobber (reg:CC FLAGS_REG))]
18084 /* The kernel uses a different segment register for performance reasons; a
18085 system call would not have to trash the userspace segment register,
18086 which would be expensive */
18087 if (ix86_cmodel != CM_KERNEL)
18088 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18090 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18092 [(set_attr "type" "multi")])
18094 (define_expand "stack_protect_test"
18095 [(match_operand 0 "memory_operand" "")
18096 (match_operand 1 "memory_operand" "")
18097 (match_operand 2 "" "")]
18100 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18102 #ifdef TARGET_THREAD_SSP_OFFSET
18104 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18105 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18107 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18108 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18111 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18113 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18116 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18117 flags, const0_rtx, operands[2]));
18121 (define_insn "stack_protect_test_si"
18122 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18123 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18124 (match_operand:SI 2 "memory_operand" "m")]
18126 (clobber (match_scratch:SI 3 "=&r"))]
18128 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
18129 [(set_attr "type" "multi")])
18131 (define_insn "stack_protect_test_di"
18132 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18133 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18134 (match_operand:DI 2 "memory_operand" "m")]
18136 (clobber (match_scratch:DI 3 "=&r"))]
18138 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18139 [(set_attr "type" "multi")])
18141 (define_insn "stack_tls_protect_test_si"
18142 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18143 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18144 (match_operand:SI 2 "const_int_operand" "i")]
18145 UNSPEC_SP_TLS_TEST))
18146 (clobber (match_scratch:SI 3 "=r"))]
18148 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18149 [(set_attr "type" "multi")])
18151 (define_insn "stack_tls_protect_test_di"
18152 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18153 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18154 (match_operand:DI 2 "const_int_operand" "i")]
18155 UNSPEC_SP_TLS_TEST))
18156 (clobber (match_scratch:DI 3 "=r"))]
18159 /* The kernel uses a different segment register for performance reasons; a
18160 system call would not have to trash the userspace segment register,
18161 which would be expensive */
18162 if (ix86_cmodel != CM_KERNEL)
18163 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18165 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18167 [(set_attr "type" "multi")])
18169 (define_insn "sse4_2_crc32<mode>"
18170 [(set (match_operand:SI 0 "register_operand" "=r")
18172 [(match_operand:SI 1 "register_operand" "0")
18173 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18175 "TARGET_SSE4_2 || TARGET_CRC32"
18176 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18177 [(set_attr "type" "sselog1")
18178 (set_attr "prefix_rep" "1")
18179 (set_attr "prefix_extra" "1")
18180 (set (attr "prefix_data16")
18181 (if_then_else (match_operand:HI 2 "" "")
18183 (const_string "*")))
18184 (set (attr "prefix_rex")
18185 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18187 (const_string "*")))
18188 (set_attr "mode" "SI")])
18190 (define_insn "sse4_2_crc32di"
18191 [(set (match_operand:DI 0 "register_operand" "=r")
18193 [(match_operand:DI 1 "register_operand" "0")
18194 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18196 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18197 "crc32{q}\t{%2, %0|%0, %2}"
18198 [(set_attr "type" "sselog1")
18199 (set_attr "prefix_rep" "1")
18200 (set_attr "prefix_extra" "1")
18201 (set_attr "mode" "DI")])
18203 (define_expand "rdpmc"
18204 [(match_operand:DI 0 "register_operand" "")
18205 (match_operand:SI 1 "register_operand" "")]
18208 rtx reg = gen_reg_rtx (DImode);
18211 /* Force operand 1 into ECX. */
18212 rtx ecx = gen_rtx_REG (SImode, CX_REG);
18213 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18214 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18219 rtvec vec = rtvec_alloc (2);
18220 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18221 rtx upper = gen_reg_rtx (DImode);
18222 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18223 gen_rtvec (1, const0_rtx),
18225 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18226 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18228 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18229 NULL, 1, OPTAB_DIRECT);
18230 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18234 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18235 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18239 (define_insn "*rdpmc"
18240 [(set (match_operand:DI 0 "register_operand" "=A")
18241 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18245 [(set_attr "type" "other")
18246 (set_attr "length" "2")])
18248 (define_insn "*rdpmc_rex64"
18249 [(set (match_operand:DI 0 "register_operand" "=a")
18250 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18252 (set (match_operand:DI 1 "register_operand" "=d")
18253 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18256 [(set_attr "type" "other")
18257 (set_attr "length" "2")])
18259 (define_expand "rdtsc"
18260 [(set (match_operand:DI 0 "register_operand" "")
18261 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18266 rtvec vec = rtvec_alloc (2);
18267 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18268 rtx upper = gen_reg_rtx (DImode);
18269 rtx lower = gen_reg_rtx (DImode);
18270 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18271 gen_rtvec (1, const0_rtx),
18273 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18274 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18276 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18277 NULL, 1, OPTAB_DIRECT);
18278 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18280 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18285 (define_insn "*rdtsc"
18286 [(set (match_operand:DI 0 "register_operand" "=A")
18287 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18290 [(set_attr "type" "other")
18291 (set_attr "length" "2")])
18293 (define_insn "*rdtsc_rex64"
18294 [(set (match_operand:DI 0 "register_operand" "=a")
18295 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18296 (set (match_operand:DI 1 "register_operand" "=d")
18297 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18300 [(set_attr "type" "other")
18301 (set_attr "length" "2")])
18303 (define_expand "rdtscp"
18304 [(match_operand:DI 0 "register_operand" "")
18305 (match_operand:SI 1 "memory_operand" "")]
18308 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18309 gen_rtvec (1, const0_rtx),
18311 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18312 gen_rtvec (1, const0_rtx),
18314 rtx reg = gen_reg_rtx (DImode);
18315 rtx tmp = gen_reg_rtx (SImode);
18319 rtvec vec = rtvec_alloc (3);
18320 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18321 rtx upper = gen_reg_rtx (DImode);
18322 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18323 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18324 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18326 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18327 NULL, 1, OPTAB_DIRECT);
18328 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18333 rtvec vec = rtvec_alloc (2);
18334 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18335 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18336 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18339 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18340 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18344 (define_insn "*rdtscp"
18345 [(set (match_operand:DI 0 "register_operand" "=A")
18346 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18347 (set (match_operand:SI 1 "register_operand" "=c")
18348 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18351 [(set_attr "type" "other")
18352 (set_attr "length" "3")])
18354 (define_insn "*rdtscp_rex64"
18355 [(set (match_operand:DI 0 "register_operand" "=a")
18356 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18357 (set (match_operand:DI 1 "register_operand" "=d")
18358 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18359 (set (match_operand:SI 2 "register_operand" "=c")
18360 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18363 [(set_attr "type" "other")
18364 (set_attr "length" "3")])
18366 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18368 ;; LWP instructions
18370 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18372 (define_expand "lwp_llwpcb"
18373 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18374 UNSPECV_LLWP_INTRINSIC)]
18378 (define_insn "*lwp_llwpcb<mode>1"
18379 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18380 UNSPECV_LLWP_INTRINSIC)]
18383 [(set_attr "type" "lwp")
18384 (set_attr "mode" "<MODE>")
18385 (set_attr "length" "5")])
18387 (define_expand "lwp_slwpcb"
18388 [(set (match_operand 0 "register_operand" "=r")
18389 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18393 emit_insn (gen_lwp_slwpcbdi (operands[0]));
18395 emit_insn (gen_lwp_slwpcbsi (operands[0]));
18399 (define_insn "lwp_slwpcb<mode>"
18400 [(set (match_operand:P 0 "register_operand" "=r")
18401 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18404 [(set_attr "type" "lwp")
18405 (set_attr "mode" "<MODE>")
18406 (set_attr "length" "5")])
18408 (define_expand "lwp_lwpval<mode>3"
18409 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18410 (match_operand:SI 2 "nonimmediate_operand" "rm")
18411 (match_operand:SI 3 "const_int_operand" "i")]
18412 UNSPECV_LWPVAL_INTRINSIC)]
18414 "/* Avoid unused variable warning. */
18417 (define_insn "*lwp_lwpval<mode>3_1"
18418 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18419 (match_operand:SI 1 "nonimmediate_operand" "rm")
18420 (match_operand:SI 2 "const_int_operand" "i")]
18421 UNSPECV_LWPVAL_INTRINSIC)]
18423 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18424 [(set_attr "type" "lwp")
18425 (set_attr "mode" "<MODE>")
18426 (set (attr "length")
18427 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18429 (define_expand "lwp_lwpins<mode>3"
18430 [(set (reg:CCC FLAGS_REG)
18431 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18432 (match_operand:SI 2 "nonimmediate_operand" "rm")
18433 (match_operand:SI 3 "const_int_operand" "i")]
18434 UNSPECV_LWPINS_INTRINSIC))
18435 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18436 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18440 (define_insn "*lwp_lwpins<mode>3_1"
18441 [(set (reg:CCC FLAGS_REG)
18442 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18443 (match_operand:SI 1 "nonimmediate_operand" "rm")
18444 (match_operand:SI 2 "const_int_operand" "i")]
18445 UNSPECV_LWPINS_INTRINSIC))]
18447 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18448 [(set_attr "type" "lwp")
18449 (set_attr "mode" "<MODE>")
18450 (set (attr "length")
18451 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18455 (include "sync.md")