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).
62 ;; @ -- print a segment register of thread base pointer load
66 (define_c_enum "unspec" [
67 ;; Relocation specifiers
78 UNSPEC_MACHOPIC_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
98 ;; Other random patterns
107 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_DIV_ALREADY_SPLIT
110 UNSPEC_CALL_NEEDS_VZEROUPPER
112 ;; For SSE/MMX support:
130 UNSPEC_MS_TO_SYSV_CALL
132 ;; Generic math support
134 UNSPEC_IEEE_MIN ; not commutative
135 UNSPEC_IEEE_MAX ; not commutative
137 ;; x87 Floating point
153 UNSPEC_FRNDINT_MASK_PM
157 ;; x87 Double output FP
189 ;; For SSE4.1 support
199 ;; For SSE4.2 support
206 UNSPEC_XOP_UNSIGNED_CMP
217 UNSPEC_AESKEYGENASSIST
219 ;; For PCLMUL support
237 ;; For RDRAND support
241 (define_c_enum "unspecv" [
244 UNSPECV_PROBE_STACK_RANGE
264 UNSPECV_LLWP_INTRINSIC
265 UNSPECV_SLWP_INTRINSIC
266 UNSPECV_LWPVAL_INTRINSIC
267 UNSPECV_LWPINS_INTRINSIC
272 UNSPECV_SPLIT_STACK_RETURN
275 ;; Constants to represent pcomtrue/pcomfalse variants
285 ;; Constants used in the XOP pperm instruction
287 [(PPERM_SRC 0x00) /* copy source */
288 (PPERM_INVERT 0x20) /* invert source */
289 (PPERM_REVERSE 0x40) /* bit reverse source */
290 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
291 (PPERM_ZERO 0x80) /* all 0's */
292 (PPERM_ONES 0xa0) /* all 1's */
293 (PPERM_SIGN 0xc0) /* propagate sign bit */
294 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
295 (PPERM_SRC1 0x00) /* use first source byte */
296 (PPERM_SRC2 0x10) /* use second source byte */
299 ;; Registers by name.
352 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
355 ;; In C guard expressions, put expressions which may be compile-time
356 ;; constants first. This allows for better optimization. For
357 ;; example, write "TARGET_64BIT && reload_completed", not
358 ;; "reload_completed && TARGET_64BIT".
362 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
363 atom,generic64,amdfam10,bdver1,btver1"
364 (const (symbol_ref "ix86_schedule")))
366 ;; A basic instruction type. Refinements due to arguments to be
367 ;; provided in other attributes.
370 alu,alu1,negnot,imov,imovx,lea,
371 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
372 icmp,test,ibr,setcc,icmov,
373 push,pop,call,callv,leave,
375 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
376 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
377 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
378 ssemuladd,sse4arg,lwp,
379 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
380 (const_string "other"))
382 ;; Main data type used by the insn
384 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
385 (const_string "unknown"))
387 ;; The CPU unit operations uses.
388 (define_attr "unit" "integer,i387,sse,mmx,unknown"
389 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
390 (const_string "i387")
391 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
392 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
393 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
395 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
397 (eq_attr "type" "other")
398 (const_string "unknown")]
399 (const_string "integer")))
401 ;; The (bounding maximum) length of an instruction immediate.
402 (define_attr "length_immediate" ""
403 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
406 (eq_attr "unit" "i387,sse,mmx")
408 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
410 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
411 (eq_attr "type" "imov,test")
412 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
413 (eq_attr "type" "call")
414 (if_then_else (match_operand 0 "constant_call_address_operand" "")
417 (eq_attr "type" "callv")
418 (if_then_else (match_operand 1 "constant_call_address_operand" "")
421 ;; We don't know the size before shorten_branches. Expect
422 ;; the instruction to fit for better scheduling.
423 (eq_attr "type" "ibr")
426 (symbol_ref "/* Update immediate_length and other attributes! */
427 gcc_unreachable (),1")))
429 ;; The (bounding maximum) length of an instruction address.
430 (define_attr "length_address" ""
431 (cond [(eq_attr "type" "str,other,multi,fxch")
433 (and (eq_attr "type" "call")
434 (match_operand 0 "constant_call_address_operand" ""))
436 (and (eq_attr "type" "callv")
437 (match_operand 1 "constant_call_address_operand" ""))
440 (symbol_ref "ix86_attr_length_address_default (insn)")))
442 ;; Set when length prefix is used.
443 (define_attr "prefix_data16" ""
444 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
446 (eq_attr "mode" "HI")
448 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
453 ;; Set when string REP prefix is used.
454 (define_attr "prefix_rep" ""
455 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
457 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
462 ;; Set when 0f opcode prefix is used.
463 (define_attr "prefix_0f" ""
465 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
466 (eq_attr "unit" "sse,mmx"))
470 ;; Set when REX opcode prefix is used.
471 (define_attr "prefix_rex" ""
472 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
474 (and (eq_attr "mode" "DI")
475 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
476 (eq_attr "unit" "!mmx")))
478 (and (eq_attr "mode" "QI")
479 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
482 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
485 (and (eq_attr "type" "imovx")
486 (match_operand:QI 1 "ext_QIreg_operand" ""))
491 ;; There are also additional prefixes in 3DNOW, SSSE3.
492 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
493 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
494 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
495 (define_attr "prefix_extra" ""
496 (cond [(eq_attr "type" "ssemuladd,sse4arg")
498 (eq_attr "type" "sseiadd1,ssecvt1")
503 ;; Prefix used: original, VEX or maybe VEX.
504 (define_attr "prefix" "orig,vex,maybe_vex"
505 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
507 (const_string "orig")))
509 ;; VEX W bit is used.
510 (define_attr "prefix_vex_w" "" (const_int 0))
512 ;; The length of VEX prefix
513 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
514 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
515 ;; still prefix_0f 1, with prefix_extra 1.
516 (define_attr "length_vex" ""
517 (if_then_else (and (eq_attr "prefix_0f" "1")
518 (eq_attr "prefix_extra" "0"))
519 (if_then_else (eq_attr "prefix_vex_w" "1")
520 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
521 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
522 (if_then_else (eq_attr "prefix_vex_w" "1")
523 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
524 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
526 ;; Set when modrm byte is used.
527 (define_attr "modrm" ""
528 (cond [(eq_attr "type" "str,leave")
530 (eq_attr "unit" "i387")
532 (and (eq_attr "type" "incdec")
533 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
534 (ior (match_operand:SI 1 "register_operand" "")
535 (match_operand:HI 1 "register_operand" ""))))
537 (and (eq_attr "type" "push")
538 (not (match_operand 1 "memory_operand" "")))
540 (and (eq_attr "type" "pop")
541 (not (match_operand 0 "memory_operand" "")))
543 (and (eq_attr "type" "imov")
544 (and (not (eq_attr "mode" "DI"))
545 (ior (and (match_operand 0 "register_operand" "")
546 (match_operand 1 "immediate_operand" ""))
547 (ior (and (match_operand 0 "ax_reg_operand" "")
548 (match_operand 1 "memory_displacement_only_operand" ""))
549 (and (match_operand 0 "memory_displacement_only_operand" "")
550 (match_operand 1 "ax_reg_operand" ""))))))
552 (and (eq_attr "type" "call")
553 (match_operand 0 "constant_call_address_operand" ""))
555 (and (eq_attr "type" "callv")
556 (match_operand 1 "constant_call_address_operand" ""))
558 (and (eq_attr "type" "alu,alu1,icmp,test")
559 (match_operand 0 "ax_reg_operand" ""))
560 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
564 ;; The (bounding maximum) length of an instruction in bytes.
565 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
566 ;; Later we may want to split them and compute proper length as for
568 (define_attr "length" ""
569 (cond [(eq_attr "type" "other,multi,fistp,frndint")
571 (eq_attr "type" "fcmp")
573 (eq_attr "unit" "i387")
575 (plus (attr "prefix_data16")
576 (attr "length_address")))
577 (ior (eq_attr "prefix" "vex")
578 (and (eq_attr "prefix" "maybe_vex")
579 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
580 (plus (attr "length_vex")
581 (plus (attr "length_immediate")
583 (attr "length_address"))))]
584 (plus (plus (attr "modrm")
585 (plus (attr "prefix_0f")
586 (plus (attr "prefix_rex")
587 (plus (attr "prefix_extra")
589 (plus (attr "prefix_rep")
590 (plus (attr "prefix_data16")
591 (plus (attr "length_immediate")
592 (attr "length_address")))))))
594 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
595 ;; `store' if there is a simple memory reference therein, or `unknown'
596 ;; if the instruction is complex.
598 (define_attr "memory" "none,load,store,both,unknown"
599 (cond [(eq_attr "type" "other,multi,str,lwp")
600 (const_string "unknown")
601 (eq_attr "type" "lea,fcmov,fpspc")
602 (const_string "none")
603 (eq_attr "type" "fistp,leave")
604 (const_string "both")
605 (eq_attr "type" "frndint")
606 (const_string "load")
607 (eq_attr "type" "push")
608 (if_then_else (match_operand 1 "memory_operand" "")
609 (const_string "both")
610 (const_string "store"))
611 (eq_attr "type" "pop")
612 (if_then_else (match_operand 0 "memory_operand" "")
613 (const_string "both")
614 (const_string "load"))
615 (eq_attr "type" "setcc")
616 (if_then_else (match_operand 0 "memory_operand" "")
617 (const_string "store")
618 (const_string "none"))
619 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
620 (if_then_else (ior (match_operand 0 "memory_operand" "")
621 (match_operand 1 "memory_operand" ""))
622 (const_string "load")
623 (const_string "none"))
624 (eq_attr "type" "ibr")
625 (if_then_else (match_operand 0 "memory_operand" "")
626 (const_string "load")
627 (const_string "none"))
628 (eq_attr "type" "call")
629 (if_then_else (match_operand 0 "constant_call_address_operand" "")
630 (const_string "none")
631 (const_string "load"))
632 (eq_attr "type" "callv")
633 (if_then_else (match_operand 1 "constant_call_address_operand" "")
634 (const_string "none")
635 (const_string "load"))
636 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
637 (match_operand 1 "memory_operand" ""))
638 (const_string "both")
639 (and (match_operand 0 "memory_operand" "")
640 (match_operand 1 "memory_operand" ""))
641 (const_string "both")
642 (match_operand 0 "memory_operand" "")
643 (const_string "store")
644 (match_operand 1 "memory_operand" "")
645 (const_string "load")
647 "!alu1,negnot,ishift1,
648 imov,imovx,icmp,test,bitmanip,
650 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
651 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
652 (match_operand 2 "memory_operand" ""))
653 (const_string "load")
654 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
655 (match_operand 3 "memory_operand" ""))
656 (const_string "load")
658 (const_string "none")))
660 ;; Indicates if an instruction has both an immediate and a displacement.
662 (define_attr "imm_disp" "false,true,unknown"
663 (cond [(eq_attr "type" "other,multi")
664 (const_string "unknown")
665 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
666 (and (match_operand 0 "memory_displacement_operand" "")
667 (match_operand 1 "immediate_operand" "")))
668 (const_string "true")
669 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
670 (and (match_operand 0 "memory_displacement_operand" "")
671 (match_operand 2 "immediate_operand" "")))
672 (const_string "true")
674 (const_string "false")))
676 ;; Indicates if an FP operation has an integer source.
678 (define_attr "fp_int_src" "false,true"
679 (const_string "false"))
681 ;; Defines rounding mode of an FP operation.
683 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
684 (const_string "any"))
686 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
687 (define_attr "use_carry" "0,1" (const_string "0"))
689 ;; Define attribute to indicate unaligned ssemov insns
690 (define_attr "movu" "0,1" (const_string "0"))
692 ;; Describe a user's asm statement.
693 (define_asm_attributes
694 [(set_attr "length" "128")
695 (set_attr "type" "multi")])
697 (define_code_iterator plusminus [plus minus])
699 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
701 ;; Base name for define_insn
702 (define_code_attr plusminus_insn
703 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
704 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
706 ;; Base name for insn mnemonic.
707 (define_code_attr plusminus_mnemonic
708 [(plus "add") (ss_plus "adds") (us_plus "addus")
709 (minus "sub") (ss_minus "subs") (us_minus "subus")])
710 (define_code_attr plusminus_carry_mnemonic
711 [(plus "adc") (minus "sbb")])
713 ;; Mark commutative operators as such in constraints.
714 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
715 (minus "") (ss_minus "") (us_minus "")])
717 ;; Mapping of signed max and min
718 (define_code_iterator smaxmin [smax smin])
720 ;; Mapping of unsigned max and min
721 (define_code_iterator umaxmin [umax umin])
723 ;; Base name for integer and FP insn mnemonic
724 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
725 (umax "maxu") (umin "minu")])
726 (define_code_attr maxmin_float [(smax "max") (smin "min")])
728 ;; Mapping of logic operators
729 (define_code_iterator any_logic [and ior xor])
730 (define_code_iterator any_or [ior xor])
732 ;; Base name for insn mnemonic.
733 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
735 ;; Mapping of shift-right operators
736 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
738 ;; Base name for define_insn
739 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
741 ;; Base name for insn mnemonic.
742 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
744 ;; Mapping of rotate operators
745 (define_code_iterator any_rotate [rotate rotatert])
747 ;; Base name for define_insn
748 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
750 ;; Base name for insn mnemonic.
751 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
753 ;; Mapping of abs neg operators
754 (define_code_iterator absneg [abs neg])
756 ;; Base name for x87 insn mnemonic.
757 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
759 ;; Used in signed and unsigned widening multiplications.
760 (define_code_iterator any_extend [sign_extend zero_extend])
762 ;; Various insn prefixes for signed and unsigned operations.
763 (define_code_attr u [(sign_extend "") (zero_extend "u")
764 (div "") (udiv "u")])
765 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
767 ;; Used in signed and unsigned divisions.
768 (define_code_iterator any_div [div udiv])
770 ;; Instruction prefix for signed and unsigned operations.
771 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
772 (div "i") (udiv "")])
774 ;; 64bit single word integer modes.
775 (define_mode_iterator SWI1248x [QI HI SI DI])
777 ;; 64bit single word integer modes without QImode and HImode.
778 (define_mode_iterator SWI48x [SI DI])
780 ;; Single word integer modes.
781 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
783 ;; Single word integer modes without SImode and DImode.
784 (define_mode_iterator SWI12 [QI HI])
786 ;; Single word integer modes without DImode.
787 (define_mode_iterator SWI124 [QI HI SI])
789 ;; Single word integer modes without QImode and DImode.
790 (define_mode_iterator SWI24 [HI SI])
792 ;; Single word integer modes without QImode.
793 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
795 ;; Single word integer modes without QImode and HImode.
796 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
798 ;; All math-dependant single and double word integer modes.
799 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
800 (HI "TARGET_HIMODE_MATH")
801 SI DI (TI "TARGET_64BIT")])
803 ;; Math-dependant single word integer modes.
804 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
805 (HI "TARGET_HIMODE_MATH")
806 SI (DI "TARGET_64BIT")])
808 ;; Math-dependant single word integer modes without DImode.
809 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
810 (HI "TARGET_HIMODE_MATH")
813 ;; Math-dependant single word integer modes without QImode.
814 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
815 SI (DI "TARGET_64BIT")])
817 ;; Double word integer modes.
818 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
819 (TI "TARGET_64BIT")])
821 ;; Double word integer modes as mode attribute.
822 (define_mode_attr DWI [(SI "DI") (DI "TI")])
823 (define_mode_attr dwi [(SI "di") (DI "ti")])
825 ;; Half mode for double word integer modes.
826 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
827 (DI "TARGET_64BIT")])
829 ;; Instruction suffix for integer modes.
830 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
832 ;; Pointer size prefix for integer modes (Intel asm dialect)
833 (define_mode_attr iptrsize [(QI "BYTE")
838 ;; Register class for integer modes.
839 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
841 ;; Immediate operand constraint for integer modes.
842 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
844 ;; General operand constraint for word modes.
845 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
847 ;; Immediate operand constraint for double integer modes.
848 (define_mode_attr di [(SI "iF") (DI "e")])
850 ;; Immediate operand constraint for shifts.
851 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
853 ;; General operand predicate for integer modes.
854 (define_mode_attr general_operand
855 [(QI "general_operand")
856 (HI "general_operand")
857 (SI "general_operand")
858 (DI "x86_64_general_operand")
859 (TI "x86_64_general_operand")])
861 ;; General sign/zero extend operand predicate for integer modes.
862 (define_mode_attr general_szext_operand
863 [(QI "general_operand")
864 (HI "general_operand")
865 (SI "general_operand")
866 (DI "x86_64_szext_general_operand")])
868 ;; Immediate operand predicate for integer modes.
869 (define_mode_attr immediate_operand
870 [(QI "immediate_operand")
871 (HI "immediate_operand")
872 (SI "immediate_operand")
873 (DI "x86_64_immediate_operand")])
875 ;; Nonmemory operand predicate for integer modes.
876 (define_mode_attr nonmemory_operand
877 [(QI "nonmemory_operand")
878 (HI "nonmemory_operand")
879 (SI "nonmemory_operand")
880 (DI "x86_64_nonmemory_operand")])
882 ;; Operand predicate for shifts.
883 (define_mode_attr shift_operand
884 [(QI "nonimmediate_operand")
885 (HI "nonimmediate_operand")
886 (SI "nonimmediate_operand")
887 (DI "shiftdi_operand")
888 (TI "register_operand")])
890 ;; Operand predicate for shift argument.
891 (define_mode_attr shift_immediate_operand
892 [(QI "const_1_to_31_operand")
893 (HI "const_1_to_31_operand")
894 (SI "const_1_to_31_operand")
895 (DI "const_1_to_63_operand")])
897 ;; Input operand predicate for arithmetic left shifts.
898 (define_mode_attr ashl_input_operand
899 [(QI "nonimmediate_operand")
900 (HI "nonimmediate_operand")
901 (SI "nonimmediate_operand")
902 (DI "ashldi_input_operand")
903 (TI "reg_or_pm1_operand")])
905 ;; SSE and x87 SFmode and DFmode floating point modes
906 (define_mode_iterator MODEF [SF DF])
908 ;; All x87 floating point modes
909 (define_mode_iterator X87MODEF [SF DF XF])
911 ;; All integer modes handled by x87 fisttp operator.
912 (define_mode_iterator X87MODEI [HI SI DI])
914 ;; All integer modes handled by integer x87 operators.
915 (define_mode_iterator X87MODEI12 [HI SI])
917 ;; All integer modes handled by SSE cvtts?2si* operators.
918 (define_mode_iterator SSEMODEI24 [SI DI])
920 ;; SSE asm suffix for floating point modes
921 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
923 ;; SSE vector mode corresponding to a scalar mode
924 (define_mode_attr ssevecmode
925 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
927 ;; Instruction suffix for REX 64bit operators.
928 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
930 ;; This mode iterator allows :P to be used for patterns that operate on
931 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
932 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
934 ;; Scheduling descriptions
936 (include "pentium.md")
939 (include "athlon.md")
940 (include "bdver1.md")
946 ;; Operand and operator predicates and constraints
948 (include "predicates.md")
949 (include "constraints.md")
952 ;; Compare and branch/compare and store instructions.
954 (define_expand "cbranch<mode>4"
955 [(set (reg:CC FLAGS_REG)
956 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
957 (match_operand:SDWIM 2 "<general_operand>" "")))
958 (set (pc) (if_then_else
959 (match_operator 0 "ordered_comparison_operator"
960 [(reg:CC FLAGS_REG) (const_int 0)])
961 (label_ref (match_operand 3 "" ""))
965 if (MEM_P (operands[1]) && MEM_P (operands[2]))
966 operands[1] = force_reg (<MODE>mode, operands[1]);
967 ix86_expand_branch (GET_CODE (operands[0]),
968 operands[1], operands[2], operands[3]);
972 (define_expand "cstore<mode>4"
973 [(set (reg:CC FLAGS_REG)
974 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
975 (match_operand:SWIM 3 "<general_operand>" "")))
976 (set (match_operand:QI 0 "register_operand" "")
977 (match_operator 1 "ordered_comparison_operator"
978 [(reg:CC FLAGS_REG) (const_int 0)]))]
981 if (MEM_P (operands[2]) && MEM_P (operands[3]))
982 operands[2] = force_reg (<MODE>mode, operands[2]);
983 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
984 operands[2], operands[3]);
988 (define_expand "cmp<mode>_1"
989 [(set (reg:CC FLAGS_REG)
990 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
991 (match_operand:SWI48 1 "<general_operand>" "")))])
993 (define_insn "*cmp<mode>_ccno_1"
994 [(set (reg FLAGS_REG)
995 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
996 (match_operand:SWI 1 "const0_operand" "")))]
997 "ix86_match_ccmode (insn, CCNOmode)"
999 test{<imodesuffix>}\t%0, %0
1000 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1001 [(set_attr "type" "test,icmp")
1002 (set_attr "length_immediate" "0,1")
1003 (set_attr "mode" "<MODE>")])
1005 (define_insn "*cmp<mode>_1"
1006 [(set (reg FLAGS_REG)
1007 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1008 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1009 "ix86_match_ccmode (insn, CCmode)"
1010 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1011 [(set_attr "type" "icmp")
1012 (set_attr "mode" "<MODE>")])
1014 (define_insn "*cmp<mode>_minus_1"
1015 [(set (reg FLAGS_REG)
1017 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1018 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1020 "ix86_match_ccmode (insn, CCGOCmode)"
1021 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1022 [(set_attr "type" "icmp")
1023 (set_attr "mode" "<MODE>")])
1025 (define_insn "*cmpqi_ext_1"
1026 [(set (reg FLAGS_REG)
1028 (match_operand:QI 0 "general_operand" "Qm")
1031 (match_operand 1 "ext_register_operand" "Q")
1033 (const_int 8)) 0)))]
1034 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1035 "cmp{b}\t{%h1, %0|%0, %h1}"
1036 [(set_attr "type" "icmp")
1037 (set_attr "mode" "QI")])
1039 (define_insn "*cmpqi_ext_1_rex64"
1040 [(set (reg FLAGS_REG)
1042 (match_operand:QI 0 "register_operand" "Q")
1045 (match_operand 1 "ext_register_operand" "Q")
1047 (const_int 8)) 0)))]
1048 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1049 "cmp{b}\t{%h1, %0|%0, %h1}"
1050 [(set_attr "type" "icmp")
1051 (set_attr "mode" "QI")])
1053 (define_insn "*cmpqi_ext_2"
1054 [(set (reg FLAGS_REG)
1058 (match_operand 0 "ext_register_operand" "Q")
1061 (match_operand:QI 1 "const0_operand" "")))]
1062 "ix86_match_ccmode (insn, CCNOmode)"
1064 [(set_attr "type" "test")
1065 (set_attr "length_immediate" "0")
1066 (set_attr "mode" "QI")])
1068 (define_expand "cmpqi_ext_3"
1069 [(set (reg:CC FLAGS_REG)
1073 (match_operand 0 "ext_register_operand" "")
1076 (match_operand:QI 1 "immediate_operand" "")))])
1078 (define_insn "*cmpqi_ext_3_insn"
1079 [(set (reg FLAGS_REG)
1083 (match_operand 0 "ext_register_operand" "Q")
1086 (match_operand:QI 1 "general_operand" "Qmn")))]
1087 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1088 "cmp{b}\t{%1, %h0|%h0, %1}"
1089 [(set_attr "type" "icmp")
1090 (set_attr "modrm" "1")
1091 (set_attr "mode" "QI")])
1093 (define_insn "*cmpqi_ext_3_insn_rex64"
1094 [(set (reg FLAGS_REG)
1098 (match_operand 0 "ext_register_operand" "Q")
1101 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1102 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1103 "cmp{b}\t{%1, %h0|%h0, %1}"
1104 [(set_attr "type" "icmp")
1105 (set_attr "modrm" "1")
1106 (set_attr "mode" "QI")])
1108 (define_insn "*cmpqi_ext_4"
1109 [(set (reg FLAGS_REG)
1113 (match_operand 0 "ext_register_operand" "Q")
1118 (match_operand 1 "ext_register_operand" "Q")
1120 (const_int 8)) 0)))]
1121 "ix86_match_ccmode (insn, CCmode)"
1122 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1123 [(set_attr "type" "icmp")
1124 (set_attr "mode" "QI")])
1126 ;; These implement float point compares.
1127 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1128 ;; which would allow mix and match FP modes on the compares. Which is what
1129 ;; the old patterns did, but with many more of them.
1131 (define_expand "cbranchxf4"
1132 [(set (reg:CC FLAGS_REG)
1133 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1134 (match_operand:XF 2 "nonmemory_operand" "")))
1135 (set (pc) (if_then_else
1136 (match_operator 0 "ix86_fp_comparison_operator"
1139 (label_ref (match_operand 3 "" ""))
1143 ix86_expand_branch (GET_CODE (operands[0]),
1144 operands[1], operands[2], operands[3]);
1148 (define_expand "cstorexf4"
1149 [(set (reg:CC FLAGS_REG)
1150 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1151 (match_operand:XF 3 "nonmemory_operand" "")))
1152 (set (match_operand:QI 0 "register_operand" "")
1153 (match_operator 1 "ix86_fp_comparison_operator"
1158 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1159 operands[2], operands[3]);
1163 (define_expand "cbranch<mode>4"
1164 [(set (reg:CC FLAGS_REG)
1165 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1166 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1167 (set (pc) (if_then_else
1168 (match_operator 0 "ix86_fp_comparison_operator"
1171 (label_ref (match_operand 3 "" ""))
1173 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1175 ix86_expand_branch (GET_CODE (operands[0]),
1176 operands[1], operands[2], operands[3]);
1180 (define_expand "cstore<mode>4"
1181 [(set (reg:CC FLAGS_REG)
1182 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1183 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1184 (set (match_operand:QI 0 "register_operand" "")
1185 (match_operator 1 "ix86_fp_comparison_operator"
1188 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1190 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1191 operands[2], operands[3]);
1195 (define_expand "cbranchcc4"
1196 [(set (pc) (if_then_else
1197 (match_operator 0 "comparison_operator"
1198 [(match_operand 1 "flags_reg_operand" "")
1199 (match_operand 2 "const0_operand" "")])
1200 (label_ref (match_operand 3 "" ""))
1204 ix86_expand_branch (GET_CODE (operands[0]),
1205 operands[1], operands[2], operands[3]);
1209 (define_expand "cstorecc4"
1210 [(set (match_operand:QI 0 "register_operand" "")
1211 (match_operator 1 "comparison_operator"
1212 [(match_operand 2 "flags_reg_operand" "")
1213 (match_operand 3 "const0_operand" "")]))]
1216 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1217 operands[2], operands[3]);
1222 ;; FP compares, step 1:
1223 ;; Set the FP condition codes.
1225 ;; CCFPmode compare with exceptions
1226 ;; CCFPUmode compare with no exceptions
1228 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1229 ;; used to manage the reg stack popping would not be preserved.
1231 (define_insn "*cmpfp_0"
1232 [(set (match_operand:HI 0 "register_operand" "=a")
1235 (match_operand 1 "register_operand" "f")
1236 (match_operand 2 "const0_operand" ""))]
1238 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1239 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1240 "* return output_fp_compare (insn, operands, 0, 0);"
1241 [(set_attr "type" "multi")
1242 (set_attr "unit" "i387")
1244 (cond [(match_operand:SF 1 "" "")
1246 (match_operand:DF 1 "" "")
1249 (const_string "XF")))])
1251 (define_insn_and_split "*cmpfp_0_cc"
1252 [(set (reg:CCFP FLAGS_REG)
1254 (match_operand 1 "register_operand" "f")
1255 (match_operand 2 "const0_operand" "")))
1256 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1257 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1258 && TARGET_SAHF && !TARGET_CMOVE
1259 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1261 "&& reload_completed"
1264 [(compare:CCFP (match_dup 1)(match_dup 2))]
1266 (set (reg:CC FLAGS_REG)
1267 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1269 [(set_attr "type" "multi")
1270 (set_attr "unit" "i387")
1272 (cond [(match_operand:SF 1 "" "")
1274 (match_operand:DF 1 "" "")
1277 (const_string "XF")))])
1279 (define_insn "*cmpfp_xf"
1280 [(set (match_operand:HI 0 "register_operand" "=a")
1283 (match_operand:XF 1 "register_operand" "f")
1284 (match_operand:XF 2 "register_operand" "f"))]
1287 "* return output_fp_compare (insn, operands, 0, 0);"
1288 [(set_attr "type" "multi")
1289 (set_attr "unit" "i387")
1290 (set_attr "mode" "XF")])
1292 (define_insn_and_split "*cmpfp_xf_cc"
1293 [(set (reg:CCFP FLAGS_REG)
1295 (match_operand:XF 1 "register_operand" "f")
1296 (match_operand:XF 2 "register_operand" "f")))
1297 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1299 && TARGET_SAHF && !TARGET_CMOVE"
1301 "&& reload_completed"
1304 [(compare:CCFP (match_dup 1)(match_dup 2))]
1306 (set (reg:CC FLAGS_REG)
1307 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1309 [(set_attr "type" "multi")
1310 (set_attr "unit" "i387")
1311 (set_attr "mode" "XF")])
1313 (define_insn "*cmpfp_<mode>"
1314 [(set (match_operand:HI 0 "register_operand" "=a")
1317 (match_operand:MODEF 1 "register_operand" "f")
1318 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1321 "* return output_fp_compare (insn, operands, 0, 0);"
1322 [(set_attr "type" "multi")
1323 (set_attr "unit" "i387")
1324 (set_attr "mode" "<MODE>")])
1326 (define_insn_and_split "*cmpfp_<mode>_cc"
1327 [(set (reg:CCFP FLAGS_REG)
1329 (match_operand:MODEF 1 "register_operand" "f")
1330 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1331 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1333 && TARGET_SAHF && !TARGET_CMOVE"
1335 "&& reload_completed"
1338 [(compare:CCFP (match_dup 1)(match_dup 2))]
1340 (set (reg:CC FLAGS_REG)
1341 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1343 [(set_attr "type" "multi")
1344 (set_attr "unit" "i387")
1345 (set_attr "mode" "<MODE>")])
1347 (define_insn "*cmpfp_u"
1348 [(set (match_operand:HI 0 "register_operand" "=a")
1351 (match_operand 1 "register_operand" "f")
1352 (match_operand 2 "register_operand" "f"))]
1354 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1355 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1356 "* return output_fp_compare (insn, operands, 0, 1);"
1357 [(set_attr "type" "multi")
1358 (set_attr "unit" "i387")
1360 (cond [(match_operand:SF 1 "" "")
1362 (match_operand:DF 1 "" "")
1365 (const_string "XF")))])
1367 (define_insn_and_split "*cmpfp_u_cc"
1368 [(set (reg:CCFPU FLAGS_REG)
1370 (match_operand 1 "register_operand" "f")
1371 (match_operand 2 "register_operand" "f")))
1372 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1373 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1374 && TARGET_SAHF && !TARGET_CMOVE
1375 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1377 "&& reload_completed"
1380 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1382 (set (reg:CC FLAGS_REG)
1383 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1385 [(set_attr "type" "multi")
1386 (set_attr "unit" "i387")
1388 (cond [(match_operand:SF 1 "" "")
1390 (match_operand:DF 1 "" "")
1393 (const_string "XF")))])
1395 (define_insn "*cmpfp_<mode>"
1396 [(set (match_operand:HI 0 "register_operand" "=a")
1399 (match_operand 1 "register_operand" "f")
1400 (match_operator 3 "float_operator"
1401 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1403 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1404 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1405 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1406 "* return output_fp_compare (insn, operands, 0, 0);"
1407 [(set_attr "type" "multi")
1408 (set_attr "unit" "i387")
1409 (set_attr "fp_int_src" "true")
1410 (set_attr "mode" "<MODE>")])
1412 (define_insn_and_split "*cmpfp_<mode>_cc"
1413 [(set (reg:CCFP FLAGS_REG)
1415 (match_operand 1 "register_operand" "f")
1416 (match_operator 3 "float_operator"
1417 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1418 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1419 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1420 && TARGET_SAHF && !TARGET_CMOVE
1421 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1422 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1424 "&& reload_completed"
1429 (match_op_dup 3 [(match_dup 2)]))]
1431 (set (reg:CC FLAGS_REG)
1432 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1434 [(set_attr "type" "multi")
1435 (set_attr "unit" "i387")
1436 (set_attr "fp_int_src" "true")
1437 (set_attr "mode" "<MODE>")])
1439 ;; FP compares, step 2
1440 ;; Move the fpsw to ax.
1442 (define_insn "x86_fnstsw_1"
1443 [(set (match_operand:HI 0 "register_operand" "=a")
1444 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1447 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1448 (set_attr "mode" "SI")
1449 (set_attr "unit" "i387")])
1451 ;; FP compares, step 3
1452 ;; Get ax into flags, general case.
1454 (define_insn "x86_sahf_1"
1455 [(set (reg:CC FLAGS_REG)
1456 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1460 #ifndef HAVE_AS_IX86_SAHF
1462 return ASM_BYTE "0x9e";
1467 [(set_attr "length" "1")
1468 (set_attr "athlon_decode" "vector")
1469 (set_attr "amdfam10_decode" "direct")
1470 (set_attr "bdver1_decode" "direct")
1471 (set_attr "mode" "SI")])
1473 ;; Pentium Pro can do steps 1 through 3 in one go.
1474 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1475 (define_insn "*cmpfp_i_mixed"
1476 [(set (reg:CCFP FLAGS_REG)
1477 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1478 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1479 "TARGET_MIX_SSE_I387
1480 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1481 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1482 "* return output_fp_compare (insn, operands, 1, 0);"
1483 [(set_attr "type" "fcmp,ssecomi")
1484 (set_attr "prefix" "orig,maybe_vex")
1486 (if_then_else (match_operand:SF 1 "" "")
1488 (const_string "DF")))
1489 (set (attr "prefix_rep")
1490 (if_then_else (eq_attr "type" "ssecomi")
1492 (const_string "*")))
1493 (set (attr "prefix_data16")
1494 (cond [(eq_attr "type" "fcmp")
1496 (eq_attr "mode" "DF")
1499 (const_string "0")))
1500 (set_attr "athlon_decode" "vector")
1501 (set_attr "amdfam10_decode" "direct")
1502 (set_attr "bdver1_decode" "double")])
1504 (define_insn "*cmpfp_i_sse"
1505 [(set (reg:CCFP FLAGS_REG)
1506 (compare:CCFP (match_operand 0 "register_operand" "x")
1507 (match_operand 1 "nonimmediate_operand" "xm")))]
1509 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1510 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1511 "* return output_fp_compare (insn, operands, 1, 0);"
1512 [(set_attr "type" "ssecomi")
1513 (set_attr "prefix" "maybe_vex")
1515 (if_then_else (match_operand:SF 1 "" "")
1517 (const_string "DF")))
1518 (set_attr "prefix_rep" "0")
1519 (set (attr "prefix_data16")
1520 (if_then_else (eq_attr "mode" "DF")
1522 (const_string "0")))
1523 (set_attr "athlon_decode" "vector")
1524 (set_attr "amdfam10_decode" "direct")
1525 (set_attr "bdver1_decode" "double")])
1527 (define_insn "*cmpfp_i_i387"
1528 [(set (reg:CCFP FLAGS_REG)
1529 (compare:CCFP (match_operand 0 "register_operand" "f")
1530 (match_operand 1 "register_operand" "f")))]
1531 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1533 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1534 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1535 "* return output_fp_compare (insn, operands, 1, 0);"
1536 [(set_attr "type" "fcmp")
1538 (cond [(match_operand:SF 1 "" "")
1540 (match_operand:DF 1 "" "")
1543 (const_string "XF")))
1544 (set_attr "athlon_decode" "vector")
1545 (set_attr "amdfam10_decode" "direct")
1546 (set_attr "bdver1_decode" "double")])
1548 (define_insn "*cmpfp_iu_mixed"
1549 [(set (reg:CCFPU FLAGS_REG)
1550 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1551 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1552 "TARGET_MIX_SSE_I387
1553 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1554 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1555 "* return output_fp_compare (insn, operands, 1, 1);"
1556 [(set_attr "type" "fcmp,ssecomi")
1557 (set_attr "prefix" "orig,maybe_vex")
1559 (if_then_else (match_operand:SF 1 "" "")
1561 (const_string "DF")))
1562 (set (attr "prefix_rep")
1563 (if_then_else (eq_attr "type" "ssecomi")
1565 (const_string "*")))
1566 (set (attr "prefix_data16")
1567 (cond [(eq_attr "type" "fcmp")
1569 (eq_attr "mode" "DF")
1572 (const_string "0")))
1573 (set_attr "athlon_decode" "vector")
1574 (set_attr "amdfam10_decode" "direct")
1575 (set_attr "bdver1_decode" "double")])
1577 (define_insn "*cmpfp_iu_sse"
1578 [(set (reg:CCFPU FLAGS_REG)
1579 (compare:CCFPU (match_operand 0 "register_operand" "x")
1580 (match_operand 1 "nonimmediate_operand" "xm")))]
1582 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1583 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1584 "* return output_fp_compare (insn, operands, 1, 1);"
1585 [(set_attr "type" "ssecomi")
1586 (set_attr "prefix" "maybe_vex")
1588 (if_then_else (match_operand:SF 1 "" "")
1590 (const_string "DF")))
1591 (set_attr "prefix_rep" "0")
1592 (set (attr "prefix_data16")
1593 (if_then_else (eq_attr "mode" "DF")
1595 (const_string "0")))
1596 (set_attr "athlon_decode" "vector")
1597 (set_attr "amdfam10_decode" "direct")
1598 (set_attr "bdver1_decode" "double")])
1600 (define_insn "*cmpfp_iu_387"
1601 [(set (reg:CCFPU FLAGS_REG)
1602 (compare:CCFPU (match_operand 0 "register_operand" "f")
1603 (match_operand 1 "register_operand" "f")))]
1604 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1606 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1607 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1608 "* return output_fp_compare (insn, operands, 1, 1);"
1609 [(set_attr "type" "fcmp")
1611 (cond [(match_operand:SF 1 "" "")
1613 (match_operand:DF 1 "" "")
1616 (const_string "XF")))
1617 (set_attr "athlon_decode" "vector")
1618 (set_attr "amdfam10_decode" "direct")
1619 (set_attr "bdver1_decode" "direct")])
1621 ;; Push/pop instructions.
1623 (define_insn "*push<mode>2"
1624 [(set (match_operand:DWI 0 "push_operand" "=<")
1625 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1630 [(set (match_operand:TI 0 "push_operand" "")
1631 (match_operand:TI 1 "general_operand" ""))]
1632 "TARGET_64BIT && reload_completed
1633 && !SSE_REG_P (operands[1])"
1635 "ix86_split_long_move (operands); DONE;")
1637 (define_insn "*pushdi2_rex64"
1638 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1639 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1644 [(set_attr "type" "push,multi")
1645 (set_attr "mode" "DI")])
1647 ;; Convert impossible pushes of immediate to existing instructions.
1648 ;; First try to get scratch register and go through it. In case this
1649 ;; fails, push sign extended lower part first and then overwrite
1650 ;; upper part by 32bit move.
1652 [(match_scratch:DI 2 "r")
1653 (set (match_operand:DI 0 "push_operand" "")
1654 (match_operand:DI 1 "immediate_operand" ""))]
1655 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1656 && !x86_64_immediate_operand (operands[1], DImode)"
1657 [(set (match_dup 2) (match_dup 1))
1658 (set (match_dup 0) (match_dup 2))])
1660 ;; We need to define this as both peepholer and splitter for case
1661 ;; peephole2 pass is not run.
1662 ;; "&& 1" is needed to keep it from matching the previous pattern.
1664 [(set (match_operand:DI 0 "push_operand" "")
1665 (match_operand:DI 1 "immediate_operand" ""))]
1666 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1667 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1668 [(set (match_dup 0) (match_dup 1))
1669 (set (match_dup 2) (match_dup 3))]
1671 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1673 operands[1] = gen_lowpart (DImode, operands[2]);
1674 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1679 [(set (match_operand:DI 0 "push_operand" "")
1680 (match_operand:DI 1 "immediate_operand" ""))]
1681 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1682 ? epilogue_completed : reload_completed)
1683 && !symbolic_operand (operands[1], DImode)
1684 && !x86_64_immediate_operand (operands[1], DImode)"
1685 [(set (match_dup 0) (match_dup 1))
1686 (set (match_dup 2) (match_dup 3))]
1688 split_double_mode (DImode, &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 "general_operand" ""))]
1698 "!TARGET_64BIT && reload_completed
1699 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1701 "ix86_split_long_move (operands); DONE;")
1703 (define_insn "*pushsi2"
1704 [(set (match_operand:SI 0 "push_operand" "=<")
1705 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1708 [(set_attr "type" "push")
1709 (set_attr "mode" "SI")])
1711 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1712 ;; "push a byte/word". But actually we use pushl, which has the effect
1713 ;; of rounding the amount pushed up to a word.
1715 ;; For TARGET_64BIT we always round up to 8 bytes.
1716 (define_insn "*push<mode>2_rex64"
1717 [(set (match_operand:SWI124 0 "push_operand" "=X")
1718 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1721 [(set_attr "type" "push")
1722 (set_attr "mode" "DI")])
1724 (define_insn "*push<mode>2"
1725 [(set (match_operand:SWI12 0 "push_operand" "=X")
1726 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1729 [(set_attr "type" "push")
1730 (set_attr "mode" "SI")])
1732 (define_insn "*push<mode>2_prologue"
1733 [(set (match_operand:P 0 "push_operand" "=<")
1734 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1735 (clobber (mem:BLK (scratch)))]
1737 "push{<imodesuffix>}\t%1"
1738 [(set_attr "type" "push")
1739 (set_attr "mode" "<MODE>")])
1741 (define_insn "*pop<mode>1"
1742 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1743 (match_operand:P 1 "pop_operand" ">"))]
1745 "pop{<imodesuffix>}\t%0"
1746 [(set_attr "type" "pop")
1747 (set_attr "mode" "<MODE>")])
1749 (define_insn "*pop<mode>1_epilogue"
1750 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1751 (match_operand:P 1 "pop_operand" ">"))
1752 (clobber (mem:BLK (scratch)))]
1754 "pop{<imodesuffix>}\t%0"
1755 [(set_attr "type" "pop")
1756 (set_attr "mode" "<MODE>")])
1758 ;; Move instructions.
1760 (define_expand "movoi"
1761 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1762 (match_operand:OI 1 "general_operand" ""))]
1764 "ix86_expand_move (OImode, operands); DONE;")
1766 (define_expand "movti"
1767 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1768 (match_operand:TI 1 "nonimmediate_operand" ""))]
1769 "TARGET_64BIT || TARGET_SSE"
1772 ix86_expand_move (TImode, operands);
1773 else if (push_operand (operands[0], TImode))
1774 ix86_expand_push (TImode, operands[1]);
1776 ix86_expand_vector_move (TImode, operands);
1780 ;; This expands to what emit_move_complex would generate if we didn't
1781 ;; have a movti pattern. Having this avoids problems with reload on
1782 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1783 ;; to have around all the time.
1784 (define_expand "movcdi"
1785 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1786 (match_operand:CDI 1 "general_operand" ""))]
1789 if (push_operand (operands[0], CDImode))
1790 emit_move_complex_push (CDImode, operands[0], operands[1]);
1792 emit_move_complex_parts (operands[0], operands[1]);
1796 (define_expand "mov<mode>"
1797 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1798 (match_operand:SWI1248x 1 "general_operand" ""))]
1800 "ix86_expand_move (<MODE>mode, operands); DONE;")
1802 (define_insn "*mov<mode>_xor"
1803 [(set (match_operand:SWI48 0 "register_operand" "=r")
1804 (match_operand:SWI48 1 "const0_operand" ""))
1805 (clobber (reg:CC FLAGS_REG))]
1808 [(set_attr "type" "alu1")
1809 (set_attr "mode" "SI")
1810 (set_attr "length_immediate" "0")])
1812 (define_insn "*mov<mode>_or"
1813 [(set (match_operand:SWI48 0 "register_operand" "=r")
1814 (match_operand:SWI48 1 "const_int_operand" ""))
1815 (clobber (reg:CC FLAGS_REG))]
1817 && operands[1] == constm1_rtx"
1818 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1819 [(set_attr "type" "alu1")
1820 (set_attr "mode" "<MODE>")
1821 (set_attr "length_immediate" "1")])
1823 (define_insn "*movoi_internal_avx"
1824 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1825 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1826 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1828 switch (which_alternative)
1831 return "vxorps\t%0, %0, %0";
1834 if (misaligned_operand (operands[0], OImode)
1835 || misaligned_operand (operands[1], OImode))
1836 return "vmovdqu\t{%1, %0|%0, %1}";
1838 return "vmovdqa\t{%1, %0|%0, %1}";
1843 [(set_attr "type" "sselog1,ssemov,ssemov")
1844 (set_attr "prefix" "vex")
1845 (set_attr "mode" "OI")])
1847 (define_insn "*movti_internal_rex64"
1848 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1849 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1850 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1852 switch (which_alternative)
1858 if (get_attr_mode (insn) == MODE_V4SF)
1859 return "%vxorps\t%0, %d0";
1861 return "%vpxor\t%0, %d0";
1864 /* TDmode values are passed as TImode on the stack. Moving them
1865 to stack may result in unaligned memory access. */
1866 if (misaligned_operand (operands[0], TImode)
1867 || misaligned_operand (operands[1], TImode))
1869 if (get_attr_mode (insn) == MODE_V4SF)
1870 return "%vmovups\t{%1, %0|%0, %1}";
1872 return "%vmovdqu\t{%1, %0|%0, %1}";
1876 if (get_attr_mode (insn) == MODE_V4SF)
1877 return "%vmovaps\t{%1, %0|%0, %1}";
1879 return "%vmovdqa\t{%1, %0|%0, %1}";
1885 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1886 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1888 (cond [(eq_attr "alternative" "2,3")
1890 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1892 (const_string "V4SF")
1893 (const_string "TI"))
1894 (eq_attr "alternative" "4")
1896 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1898 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1900 (const_string "V4SF")
1901 (const_string "TI"))]
1902 (const_string "DI")))])
1905 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1906 (match_operand:TI 1 "general_operand" ""))]
1908 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1910 "ix86_split_long_move (operands); DONE;")
1912 (define_insn "*movti_internal_sse"
1913 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1914 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1915 "TARGET_SSE && !TARGET_64BIT
1916 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1918 switch (which_alternative)
1921 if (get_attr_mode (insn) == MODE_V4SF)
1922 return "%vxorps\t%0, %d0";
1924 return "%vpxor\t%0, %d0";
1927 /* TDmode values are passed as TImode on the stack. Moving them
1928 to stack may result in unaligned memory access. */
1929 if (misaligned_operand (operands[0], TImode)
1930 || misaligned_operand (operands[1], TImode))
1932 if (get_attr_mode (insn) == MODE_V4SF)
1933 return "%vmovups\t{%1, %0|%0, %1}";
1935 return "%vmovdqu\t{%1, %0|%0, %1}";
1939 if (get_attr_mode (insn) == MODE_V4SF)
1940 return "%vmovaps\t{%1, %0|%0, %1}";
1942 return "%vmovdqa\t{%1, %0|%0, %1}";
1948 [(set_attr "type" "sselog1,ssemov,ssemov")
1949 (set_attr "prefix" "maybe_vex")
1951 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1952 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1954 (const_string "V4SF")
1955 (and (eq_attr "alternative" "2")
1956 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1958 (const_string "V4SF")]
1959 (const_string "TI")))])
1961 (define_insn "*movdi_internal_rex64"
1962 [(set (match_operand:DI 0 "nonimmediate_operand"
1963 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1964 (match_operand:DI 1 "general_operand"
1965 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1966 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1968 switch (get_attr_type (insn))
1971 if (SSE_REG_P (operands[0]))
1972 return "movq2dq\t{%1, %0|%0, %1}";
1974 return "movdq2q\t{%1, %0|%0, %1}";
1979 if (get_attr_mode (insn) == MODE_TI)
1980 return "vmovdqa\t{%1, %0|%0, %1}";
1982 return "vmovq\t{%1, %0|%0, %1}";
1985 if (get_attr_mode (insn) == MODE_TI)
1986 return "movdqa\t{%1, %0|%0, %1}";
1990 /* Moves from and into integer register is done using movd
1991 opcode with REX prefix. */
1992 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1993 return "movd\t{%1, %0|%0, %1}";
1994 return "movq\t{%1, %0|%0, %1}";
1997 return "%vpxor\t%0, %d0";
2000 return "pxor\t%0, %0";
2006 return "lea{q}\t{%a1, %0|%0, %a1}";
2009 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2010 if (get_attr_mode (insn) == MODE_SI)
2011 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2012 else if (which_alternative == 2)
2013 return "movabs{q}\t{%1, %0|%0, %1}";
2015 return "mov{q}\t{%1, %0|%0, %1}";
2019 (cond [(eq_attr "alternative" "5")
2020 (const_string "mmx")
2021 (eq_attr "alternative" "6,7,8,9,10")
2022 (const_string "mmxmov")
2023 (eq_attr "alternative" "11")
2024 (const_string "sselog1")
2025 (eq_attr "alternative" "12,13,14,15,16")
2026 (const_string "ssemov")
2027 (eq_attr "alternative" "17,18")
2028 (const_string "ssecvt")
2029 (eq_attr "alternative" "4")
2030 (const_string "multi")
2031 (match_operand:DI 1 "pic_32bit_operand" "")
2032 (const_string "lea")
2034 (const_string "imov")))
2037 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2039 (const_string "*")))
2040 (set (attr "length_immediate")
2042 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2044 (const_string "*")))
2045 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2046 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2047 (set (attr "prefix")
2048 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2049 (const_string "maybe_vex")
2050 (const_string "orig")))
2051 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2053 ;; Convert impossible stores of immediate to existing instructions.
2054 ;; First try to get scratch register and go through it. In case this
2055 ;; fails, move by 32bit parts.
2057 [(match_scratch:DI 2 "r")
2058 (set (match_operand:DI 0 "memory_operand" "")
2059 (match_operand:DI 1 "immediate_operand" ""))]
2060 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2061 && !x86_64_immediate_operand (operands[1], DImode)"
2062 [(set (match_dup 2) (match_dup 1))
2063 (set (match_dup 0) (match_dup 2))])
2065 ;; We need to define this as both peepholer and splitter for case
2066 ;; peephole2 pass is not run.
2067 ;; "&& 1" is needed to keep it from matching the previous pattern.
2069 [(set (match_operand:DI 0 "memory_operand" "")
2070 (match_operand:DI 1 "immediate_operand" ""))]
2071 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2072 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2073 [(set (match_dup 2) (match_dup 3))
2074 (set (match_dup 4) (match_dup 5))]
2075 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2078 [(set (match_operand:DI 0 "memory_operand" "")
2079 (match_operand:DI 1 "immediate_operand" ""))]
2080 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2081 ? epilogue_completed : reload_completed)
2082 && !symbolic_operand (operands[1], DImode)
2083 && !x86_64_immediate_operand (operands[1], DImode)"
2084 [(set (match_dup 2) (match_dup 3))
2085 (set (match_dup 4) (match_dup 5))]
2086 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2088 (define_insn "*movdi_internal"
2089 [(set (match_operand:DI 0 "nonimmediate_operand"
2090 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2091 (match_operand:DI 1 "general_operand"
2092 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2093 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2098 movq\t{%1, %0|%0, %1}
2099 movq\t{%1, %0|%0, %1}
2101 %vmovq\t{%1, %0|%0, %1}
2102 %vmovdqa\t{%1, %0|%0, %1}
2103 %vmovq\t{%1, %0|%0, %1}
2105 movlps\t{%1, %0|%0, %1}
2106 movaps\t{%1, %0|%0, %1}
2107 movlps\t{%1, %0|%0, %1}"
2108 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2109 (set (attr "prefix")
2110 (if_then_else (eq_attr "alternative" "5,6,7,8")
2111 (const_string "vex")
2112 (const_string "orig")))
2113 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2116 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2117 (match_operand:DI 1 "general_operand" ""))]
2118 "!TARGET_64BIT && reload_completed
2119 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2120 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2122 "ix86_split_long_move (operands); DONE;")
2124 (define_insn "*movsi_internal"
2125 [(set (match_operand:SI 0 "nonimmediate_operand"
2126 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2127 (match_operand:SI 1 "general_operand"
2128 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2129 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2131 switch (get_attr_type (insn))
2134 if (get_attr_mode (insn) == MODE_TI)
2135 return "%vpxor\t%0, %d0";
2136 return "%vxorps\t%0, %d0";
2139 switch (get_attr_mode (insn))
2142 return "%vmovdqa\t{%1, %0|%0, %1}";
2144 return "%vmovaps\t{%1, %0|%0, %1}";
2146 return "%vmovd\t{%1, %0|%0, %1}";
2148 return "%vmovss\t{%1, %0|%0, %1}";
2154 return "pxor\t%0, %0";
2157 if (get_attr_mode (insn) == MODE_DI)
2158 return "movq\t{%1, %0|%0, %1}";
2159 return "movd\t{%1, %0|%0, %1}";
2162 return "lea{l}\t{%a1, %0|%0, %a1}";
2165 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2166 return "mov{l}\t{%1, %0|%0, %1}";
2170 (cond [(eq_attr "alternative" "2")
2171 (const_string "mmx")
2172 (eq_attr "alternative" "3,4,5")
2173 (const_string "mmxmov")
2174 (eq_attr "alternative" "6")
2175 (const_string "sselog1")
2176 (eq_attr "alternative" "7,8,9,10,11")
2177 (const_string "ssemov")
2178 (match_operand:DI 1 "pic_32bit_operand" "")
2179 (const_string "lea")
2181 (const_string "imov")))
2182 (set (attr "prefix")
2183 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2184 (const_string "orig")
2185 (const_string "maybe_vex")))
2186 (set (attr "prefix_data16")
2187 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2189 (const_string "*")))
2191 (cond [(eq_attr "alternative" "2,3")
2193 (eq_attr "alternative" "6,7")
2195 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2196 (const_string "V4SF")
2197 (const_string "TI"))
2198 (and (eq_attr "alternative" "8,9,10,11")
2199 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2202 (const_string "SI")))])
2204 (define_insn "*movhi_internal"
2205 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2206 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2207 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2209 switch (get_attr_type (insn))
2212 /* movzwl is faster than movw on p2 due to partial word stalls,
2213 though not as fast as an aligned movl. */
2214 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2216 if (get_attr_mode (insn) == MODE_SI)
2217 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2219 return "mov{w}\t{%1, %0|%0, %1}";
2223 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2225 (const_string "imov")
2226 (and (eq_attr "alternative" "0")
2227 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2229 (eq (symbol_ref "TARGET_HIMODE_MATH")
2231 (const_string "imov")
2232 (and (eq_attr "alternative" "1,2")
2233 (match_operand:HI 1 "aligned_operand" ""))
2234 (const_string "imov")
2235 (and (ne (symbol_ref "TARGET_MOVX")
2237 (eq_attr "alternative" "0,2"))
2238 (const_string "imovx")
2240 (const_string "imov")))
2242 (cond [(eq_attr "type" "imovx")
2244 (and (eq_attr "alternative" "1,2")
2245 (match_operand:HI 1 "aligned_operand" ""))
2247 (and (eq_attr "alternative" "0")
2248 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2250 (eq (symbol_ref "TARGET_HIMODE_MATH")
2254 (const_string "HI")))])
2256 ;; Situation is quite tricky about when to choose full sized (SImode) move
2257 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2258 ;; partial register dependency machines (such as AMD Athlon), where QImode
2259 ;; moves issue extra dependency and for partial register stalls machines
2260 ;; that don't use QImode patterns (and QImode move cause stall on the next
2263 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2264 ;; register stall machines with, where we use QImode instructions, since
2265 ;; partial register stall can be caused there. Then we use movzx.
2266 (define_insn "*movqi_internal"
2267 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2268 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2269 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2271 switch (get_attr_type (insn))
2274 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2275 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2277 if (get_attr_mode (insn) == MODE_SI)
2278 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2280 return "mov{b}\t{%1, %0|%0, %1}";
2284 (cond [(and (eq_attr "alternative" "5")
2285 (not (match_operand:QI 1 "aligned_operand" "")))
2286 (const_string "imovx")
2287 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2289 (const_string "imov")
2290 (and (eq_attr "alternative" "3")
2291 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2293 (eq (symbol_ref "TARGET_QIMODE_MATH")
2295 (const_string "imov")
2296 (eq_attr "alternative" "3,5")
2297 (const_string "imovx")
2298 (and (ne (symbol_ref "TARGET_MOVX")
2300 (eq_attr "alternative" "2"))
2301 (const_string "imovx")
2303 (const_string "imov")))
2305 (cond [(eq_attr "alternative" "3,4,5")
2307 (eq_attr "alternative" "6")
2309 (eq_attr "type" "imovx")
2311 (and (eq_attr "type" "imov")
2312 (and (eq_attr "alternative" "0,1")
2313 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2315 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2317 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2320 ;; Avoid partial register stalls when not using QImode arithmetic
2321 (and (eq_attr "type" "imov")
2322 (and (eq_attr "alternative" "0,1")
2323 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2325 (eq (symbol_ref "TARGET_QIMODE_MATH")
2329 (const_string "QI")))])
2331 ;; Stores and loads of ax to arbitrary constant address.
2332 ;; We fake an second form of instruction to force reload to load address
2333 ;; into register when rax is not available
2334 (define_insn "*movabs<mode>_1"
2335 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2336 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2337 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2339 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2340 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2341 [(set_attr "type" "imov")
2342 (set_attr "modrm" "0,*")
2343 (set_attr "length_address" "8,0")
2344 (set_attr "length_immediate" "0,*")
2345 (set_attr "memory" "store")
2346 (set_attr "mode" "<MODE>")])
2348 (define_insn "*movabs<mode>_2"
2349 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2350 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2351 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2353 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2354 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2355 [(set_attr "type" "imov")
2356 (set_attr "modrm" "0,*")
2357 (set_attr "length_address" "8,0")
2358 (set_attr "length_immediate" "0")
2359 (set_attr "memory" "load")
2360 (set_attr "mode" "<MODE>")])
2362 (define_insn "*swap<mode>"
2363 [(set (match_operand:SWI48 0 "register_operand" "+r")
2364 (match_operand:SWI48 1 "register_operand" "+r"))
2368 "xchg{<imodesuffix>}\t%1, %0"
2369 [(set_attr "type" "imov")
2370 (set_attr "mode" "<MODE>")
2371 (set_attr "pent_pair" "np")
2372 (set_attr "athlon_decode" "vector")
2373 (set_attr "amdfam10_decode" "double")
2374 (set_attr "bdver1_decode" "double")])
2376 (define_insn "*swap<mode>_1"
2377 [(set (match_operand:SWI12 0 "register_operand" "+r")
2378 (match_operand:SWI12 1 "register_operand" "+r"))
2381 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2383 [(set_attr "type" "imov")
2384 (set_attr "mode" "SI")
2385 (set_attr "pent_pair" "np")
2386 (set_attr "athlon_decode" "vector")
2387 (set_attr "amdfam10_decode" "double")
2388 (set_attr "bdver1_decode" "double")])
2390 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2391 ;; is disabled for AMDFAM10
2392 (define_insn "*swap<mode>_2"
2393 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2394 (match_operand:SWI12 1 "register_operand" "+<r>"))
2397 "TARGET_PARTIAL_REG_STALL"
2398 "xchg{<imodesuffix>}\t%1, %0"
2399 [(set_attr "type" "imov")
2400 (set_attr "mode" "<MODE>")
2401 (set_attr "pent_pair" "np")
2402 (set_attr "athlon_decode" "vector")])
2404 (define_expand "movstrict<mode>"
2405 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2406 (match_operand:SWI12 1 "general_operand" ""))]
2409 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2411 /* Don't generate memory->memory moves, go through a register */
2412 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2413 operands[1] = force_reg (<MODE>mode, operands[1]);
2416 (define_insn "*movstrict<mode>_1"
2417 [(set (strict_low_part
2418 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2419 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2420 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2421 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2422 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2423 [(set_attr "type" "imov")
2424 (set_attr "mode" "<MODE>")])
2426 (define_insn "*movstrict<mode>_xor"
2427 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2428 (match_operand:SWI12 1 "const0_operand" ""))
2429 (clobber (reg:CC FLAGS_REG))]
2431 "xor{<imodesuffix>}\t%0, %0"
2432 [(set_attr "type" "alu1")
2433 (set_attr "mode" "<MODE>")
2434 (set_attr "length_immediate" "0")])
2436 (define_insn "*mov<mode>_extv_1"
2437 [(set (match_operand:SWI24 0 "register_operand" "=R")
2438 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2442 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2443 [(set_attr "type" "imovx")
2444 (set_attr "mode" "SI")])
2446 (define_insn "*movqi_extv_1_rex64"
2447 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2448 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2453 switch (get_attr_type (insn))
2456 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2458 return "mov{b}\t{%h1, %0|%0, %h1}";
2462 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2463 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2464 (ne (symbol_ref "TARGET_MOVX")
2466 (const_string "imovx")
2467 (const_string "imov")))
2469 (if_then_else (eq_attr "type" "imovx")
2471 (const_string "QI")))])
2473 (define_insn "*movqi_extv_1"
2474 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2475 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2480 switch (get_attr_type (insn))
2483 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2485 return "mov{b}\t{%h1, %0|%0, %h1}";
2489 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2490 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2491 (ne (symbol_ref "TARGET_MOVX")
2493 (const_string "imovx")
2494 (const_string "imov")))
2496 (if_then_else (eq_attr "type" "imovx")
2498 (const_string "QI")))])
2500 (define_insn "*mov<mode>_extzv_1"
2501 [(set (match_operand:SWI48 0 "register_operand" "=R")
2502 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2506 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2507 [(set_attr "type" "imovx")
2508 (set_attr "mode" "SI")])
2510 (define_insn "*movqi_extzv_2_rex64"
2511 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2513 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2518 switch (get_attr_type (insn))
2521 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2523 return "mov{b}\t{%h1, %0|%0, %h1}";
2527 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2528 (ne (symbol_ref "TARGET_MOVX")
2530 (const_string "imovx")
2531 (const_string "imov")))
2533 (if_then_else (eq_attr "type" "imovx")
2535 (const_string "QI")))])
2537 (define_insn "*movqi_extzv_2"
2538 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2540 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2545 switch (get_attr_type (insn))
2548 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2550 return "mov{b}\t{%h1, %0|%0, %h1}";
2554 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2555 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2556 (ne (symbol_ref "TARGET_MOVX")
2558 (const_string "imovx")
2559 (const_string "imov")))
2561 (if_then_else (eq_attr "type" "imovx")
2563 (const_string "QI")))])
2565 (define_expand "mov<mode>_insv_1"
2566 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2569 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2571 (define_insn "*mov<mode>_insv_1_rex64"
2572 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2575 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2577 "mov{b}\t{%b1, %h0|%h0, %b1}"
2578 [(set_attr "type" "imov")
2579 (set_attr "mode" "QI")])
2581 (define_insn "*movsi_insv_1"
2582 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2585 (match_operand:SI 1 "general_operand" "Qmn"))]
2587 "mov{b}\t{%b1, %h0|%h0, %b1}"
2588 [(set_attr "type" "imov")
2589 (set_attr "mode" "QI")])
2591 (define_insn "*movqi_insv_2"
2592 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2595 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2598 "mov{b}\t{%h1, %h0|%h0, %h1}"
2599 [(set_attr "type" "imov")
2600 (set_attr "mode" "QI")])
2602 ;; Floating point push instructions.
2604 (define_insn "*pushtf"
2605 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2606 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2609 /* This insn should be already split before reg-stack. */
2612 [(set_attr "type" "multi")
2613 (set_attr "unit" "sse,*,*")
2614 (set_attr "mode" "TF,SI,SI")])
2617 [(set (match_operand:TF 0 "push_operand" "")
2618 (match_operand:TF 1 "sse_reg_operand" ""))]
2619 "TARGET_SSE2 && reload_completed"
2620 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2621 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2624 [(set (match_operand:TF 0 "push_operand" "")
2625 (match_operand:TF 1 "general_operand" ""))]
2626 "TARGET_SSE2 && reload_completed
2627 && !SSE_REG_P (operands[1])"
2629 "ix86_split_long_move (operands); DONE;")
2631 (define_insn "*pushxf"
2632 [(set (match_operand:XF 0 "push_operand" "=<,<")
2633 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2634 "optimize_function_for_speed_p (cfun)"
2636 /* This insn should be already split before reg-stack. */
2639 [(set_attr "type" "multi")
2640 (set_attr "unit" "i387,*")
2641 (set_attr "mode" "XF,SI")])
2643 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2644 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2645 ;; Pushing using integer instructions is longer except for constants
2646 ;; and direct memory references (assuming that any given constant is pushed
2647 ;; only once, but this ought to be handled elsewhere).
2649 (define_insn "*pushxf_nointeger"
2650 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2651 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2652 "optimize_function_for_size_p (cfun)"
2654 /* This insn should be already split before reg-stack. */
2657 [(set_attr "type" "multi")
2658 (set_attr "unit" "i387,*,*")
2659 (set_attr "mode" "XF,SI,SI")])
2662 [(set (match_operand:XF 0 "push_operand" "")
2663 (match_operand:XF 1 "fp_register_operand" ""))]
2665 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2666 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2667 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2670 [(set (match_operand:XF 0 "push_operand" "")
2671 (match_operand:XF 1 "general_operand" ""))]
2673 && !FP_REG_P (operands[1])"
2675 "ix86_split_long_move (operands); DONE;")
2677 (define_insn "*pushdf"
2678 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2679 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2680 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2682 /* This insn should be already split before reg-stack. */
2685 [(set_attr "type" "multi")
2686 (set_attr "unit" "i387,*,*")
2687 (set_attr "mode" "DF,SI,DF")])
2689 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2690 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2691 ;; On the average, pushdf using integers can be still shorter. Allow this
2692 ;; pattern for optimize_size too.
2694 (define_insn "*pushdf_nointeger"
2695 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2696 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2697 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2699 /* This insn should be already split before reg-stack. */
2702 [(set_attr "type" "multi")
2703 (set_attr "unit" "i387,*,*,*")
2704 (set_attr "mode" "DF,SI,SI,DF")])
2706 ;; %%% Kill this when call knows how to work this out.
2708 [(set (match_operand:DF 0 "push_operand" "")
2709 (match_operand:DF 1 "any_fp_register_operand" ""))]
2711 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2712 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2715 [(set (match_operand:DF 0 "push_operand" "")
2716 (match_operand:DF 1 "general_operand" ""))]
2718 && !ANY_FP_REG_P (operands[1])"
2720 "ix86_split_long_move (operands); DONE;")
2722 (define_insn "*pushsf_rex64"
2723 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2724 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2727 /* Anything else should be already split before reg-stack. */
2728 gcc_assert (which_alternative == 1);
2729 return "push{q}\t%q1";
2731 [(set_attr "type" "multi,push,multi")
2732 (set_attr "unit" "i387,*,*")
2733 (set_attr "mode" "SF,DI,SF")])
2735 (define_insn "*pushsf"
2736 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2737 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2740 /* Anything else should be already split before reg-stack. */
2741 gcc_assert (which_alternative == 1);
2742 return "push{l}\t%1";
2744 [(set_attr "type" "multi,push,multi")
2745 (set_attr "unit" "i387,*,*")
2746 (set_attr "mode" "SF,SI,SF")])
2749 [(set (match_operand:SF 0 "push_operand" "")
2750 (match_operand:SF 1 "memory_operand" ""))]
2752 && MEM_P (operands[1])
2753 && (operands[2] = find_constant_src (insn))"
2757 ;; %%% Kill this when call knows how to work this out.
2759 [(set (match_operand:SF 0 "push_operand" "")
2760 (match_operand:SF 1 "any_fp_register_operand" ""))]
2762 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2763 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2764 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2766 ;; Floating point move instructions.
2768 (define_expand "movtf"
2769 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2770 (match_operand:TF 1 "nonimmediate_operand" ""))]
2773 ix86_expand_move (TFmode, operands);
2777 (define_expand "mov<mode>"
2778 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2779 (match_operand:X87MODEF 1 "general_operand" ""))]
2781 "ix86_expand_move (<MODE>mode, operands); DONE;")
2783 (define_insn "*movtf_internal"
2784 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2785 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2787 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2789 switch (which_alternative)
2793 if (get_attr_mode (insn) == MODE_V4SF)
2794 return "%vmovaps\t{%1, %0|%0, %1}";
2796 return "%vmovdqa\t{%1, %0|%0, %1}";
2798 if (get_attr_mode (insn) == MODE_V4SF)
2799 return "%vxorps\t%0, %d0";
2801 return "%vpxor\t%0, %d0";
2809 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2810 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2812 (cond [(eq_attr "alternative" "0,2")
2814 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2816 (const_string "V4SF")
2817 (const_string "TI"))
2818 (eq_attr "alternative" "1")
2820 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2822 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2824 (const_string "V4SF")
2825 (const_string "TI"))]
2826 (const_string "DI")))])
2829 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2830 (match_operand:TF 1 "general_operand" ""))]
2832 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2834 "ix86_split_long_move (operands); DONE;")
2836 (define_insn "*movxf_internal"
2837 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2838 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2839 "optimize_function_for_speed_p (cfun)
2840 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2841 && (reload_in_progress || reload_completed
2842 || GET_CODE (operands[1]) != CONST_DOUBLE
2843 || memory_operand (operands[0], XFmode))"
2845 switch (which_alternative)
2849 return output_387_reg_move (insn, operands);
2852 return standard_80387_constant_opcode (operands[1]);
2861 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2862 (set_attr "mode" "XF,XF,XF,SI,SI")])
2864 ;; Do not use integer registers when optimizing for size
2865 (define_insn "*movxf_internal_nointeger"
2866 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2867 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2868 "optimize_function_for_size_p (cfun)
2869 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2870 && (reload_in_progress || reload_completed
2871 || standard_80387_constant_p (operands[1])
2872 || GET_CODE (operands[1]) != CONST_DOUBLE
2873 || memory_operand (operands[0], XFmode))"
2875 switch (which_alternative)
2879 return output_387_reg_move (insn, operands);
2882 return standard_80387_constant_opcode (operands[1]);
2890 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2891 (set_attr "mode" "XF,XF,XF,SI,SI")])
2894 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2895 (match_operand:XF 1 "general_operand" ""))]
2897 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2898 && ! (FP_REG_P (operands[0]) ||
2899 (GET_CODE (operands[0]) == SUBREG
2900 && FP_REG_P (SUBREG_REG (operands[0]))))
2901 && ! (FP_REG_P (operands[1]) ||
2902 (GET_CODE (operands[1]) == SUBREG
2903 && FP_REG_P (SUBREG_REG (operands[1]))))"
2905 "ix86_split_long_move (operands); DONE;")
2907 (define_insn "*movdf_internal_rex64"
2908 [(set (match_operand:DF 0 "nonimmediate_operand"
2909 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2910 (match_operand:DF 1 "general_operand"
2911 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2912 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2913 && (reload_in_progress || reload_completed
2914 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2915 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2916 && optimize_function_for_size_p (cfun)
2917 && standard_80387_constant_p (operands[1]))
2918 || GET_CODE (operands[1]) != CONST_DOUBLE
2919 || memory_operand (operands[0], DFmode))"
2921 switch (which_alternative)
2925 return output_387_reg_move (insn, operands);
2928 return standard_80387_constant_opcode (operands[1]);
2935 switch (get_attr_mode (insn))
2938 return "%vxorps\t%0, %d0";
2940 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2941 return "%vxorps\t%0, %d0";
2943 return "%vxorpd\t%0, %d0";
2945 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2946 return "%vxorps\t%0, %d0";
2948 return "%vpxor\t%0, %d0";
2955 switch (get_attr_mode (insn))
2958 return "%vmovaps\t{%1, %0|%0, %1}";
2960 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2961 return "%vmovaps\t{%1, %0|%0, %1}";
2963 return "%vmovapd\t{%1, %0|%0, %1}";
2965 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2966 return "%vmovaps\t{%1, %0|%0, %1}";
2968 return "%vmovdqa\t{%1, %0|%0, %1}";
2970 return "%vmovq\t{%1, %0|%0, %1}";
2974 if (REG_P (operands[0]) && REG_P (operands[1]))
2975 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2977 return "vmovsd\t{%1, %0|%0, %1}";
2980 return "movsd\t{%1, %0|%0, %1}";
2982 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2984 return "%vmovlps\t{%1, %d0|%d0, %1}";
2991 return "%vmovd\t{%1, %0|%0, %1}";
2997 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2998 (set (attr "prefix")
2999 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3000 (const_string "orig")
3001 (const_string "maybe_vex")))
3002 (set (attr "prefix_data16")
3003 (if_then_else (eq_attr "mode" "V1DF")
3005 (const_string "*")))
3007 (cond [(eq_attr "alternative" "0,1,2")
3009 (eq_attr "alternative" "3,4,9,10")
3012 /* For SSE1, we have many fewer alternatives. */
3013 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3014 (cond [(eq_attr "alternative" "5,6")
3015 (const_string "V4SF")
3017 (const_string "V2SF"))
3019 /* xorps is one byte shorter. */
3020 (eq_attr "alternative" "5")
3021 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3023 (const_string "V4SF")
3024 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3028 (const_string "V2DF"))
3030 /* For architectures resolving dependencies on
3031 whole SSE registers use APD move to break dependency
3032 chains, otherwise use short move to avoid extra work.
3034 movaps encodes one byte shorter. */
3035 (eq_attr "alternative" "6")
3037 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3039 (const_string "V4SF")
3040 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3042 (const_string "V2DF")
3044 (const_string "DF"))
3045 /* For architectures resolving dependencies on register
3046 parts we may avoid extra work to zero out upper part
3048 (eq_attr "alternative" "7")
3050 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3052 (const_string "V1DF")
3053 (const_string "DF"))
3055 (const_string "DF")))])
3057 (define_insn "*movdf_internal"
3058 [(set (match_operand:DF 0 "nonimmediate_operand"
3059 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3060 (match_operand:DF 1 "general_operand"
3061 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3062 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3063 && optimize_function_for_speed_p (cfun)
3064 && TARGET_INTEGER_DFMODE_MOVES
3065 && (reload_in_progress || reload_completed
3066 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3067 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3068 && optimize_function_for_size_p (cfun)
3069 && standard_80387_constant_p (operands[1]))
3070 || GET_CODE (operands[1]) != CONST_DOUBLE
3071 || memory_operand (operands[0], DFmode))"
3073 switch (which_alternative)
3077 return output_387_reg_move (insn, operands);
3080 return standard_80387_constant_opcode (operands[1]);
3087 switch (get_attr_mode (insn))
3090 return "xorps\t%0, %0";
3092 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3093 return "xorps\t%0, %0";
3095 return "xorpd\t%0, %0";
3097 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3098 return "xorps\t%0, %0";
3100 return "pxor\t%0, %0";
3107 switch (get_attr_mode (insn))
3110 return "movaps\t{%1, %0|%0, %1}";
3112 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3113 return "movaps\t{%1, %0|%0, %1}";
3115 return "movapd\t{%1, %0|%0, %1}";
3117 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3118 return "movaps\t{%1, %0|%0, %1}";
3120 return "movdqa\t{%1, %0|%0, %1}";
3122 return "movq\t{%1, %0|%0, %1}";
3124 return "movsd\t{%1, %0|%0, %1}";
3126 return "movlpd\t{%1, %0|%0, %1}";
3128 return "movlps\t{%1, %0|%0, %1}";
3137 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3138 (set (attr "prefix_data16")
3139 (if_then_else (eq_attr "mode" "V1DF")
3141 (const_string "*")))
3143 (cond [(eq_attr "alternative" "0,1,2")
3145 (eq_attr "alternative" "3,4")
3148 /* For SSE1, we have many fewer alternatives. */
3149 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3150 (cond [(eq_attr "alternative" "5,6")
3151 (const_string "V4SF")
3153 (const_string "V2SF"))
3155 /* xorps is one byte shorter. */
3156 (eq_attr "alternative" "5")
3157 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3159 (const_string "V4SF")
3160 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3164 (const_string "V2DF"))
3166 /* For architectures resolving dependencies on
3167 whole SSE registers use APD move to break dependency
3168 chains, otherwise use short move to avoid extra work.
3170 movaps encodes one byte shorter. */
3171 (eq_attr "alternative" "6")
3173 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3175 (const_string "V4SF")
3176 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3178 (const_string "V2DF")
3180 (const_string "DF"))
3181 /* For architectures resolving dependencies on register
3182 parts we may avoid extra work to zero out upper part
3184 (eq_attr "alternative" "7")
3186 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3188 (const_string "V1DF")
3189 (const_string "DF"))
3191 (const_string "DF")))])
3193 ;; Moving is usually shorter when only FP registers are used. This separate
3194 ;; movdf pattern avoids the use of integer registers for FP operations
3195 ;; when optimizing for size.
3197 (define_insn "*movdf_internal_nointeger"
3198 [(set (match_operand:DF 0 "nonimmediate_operand"
3199 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3200 (match_operand:DF 1 "general_operand"
3201 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3202 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3203 && ((optimize_function_for_size_p (cfun)
3204 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3205 && (reload_in_progress || reload_completed
3206 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3207 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3208 && optimize_function_for_size_p (cfun)
3209 && !memory_operand (operands[0], DFmode)
3210 && standard_80387_constant_p (operands[1]))
3211 || GET_CODE (operands[1]) != CONST_DOUBLE
3212 || ((optimize_function_for_size_p (cfun)
3213 || !TARGET_MEMORY_MISMATCH_STALL
3214 || reload_in_progress || reload_completed)
3215 && memory_operand (operands[0], DFmode)))"
3217 switch (which_alternative)
3221 return output_387_reg_move (insn, operands);
3224 return standard_80387_constant_opcode (operands[1]);
3231 switch (get_attr_mode (insn))
3234 return "%vxorps\t%0, %d0";
3236 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3237 return "%vxorps\t%0, %d0";
3239 return "%vxorpd\t%0, %d0";
3241 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3242 return "%vxorps\t%0, %d0";
3244 return "%vpxor\t%0, %d0";
3251 switch (get_attr_mode (insn))
3254 return "%vmovaps\t{%1, %0|%0, %1}";
3256 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3257 return "%vmovaps\t{%1, %0|%0, %1}";
3259 return "%vmovapd\t{%1, %0|%0, %1}";
3261 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3262 return "%vmovaps\t{%1, %0|%0, %1}";
3264 return "%vmovdqa\t{%1, %0|%0, %1}";
3266 return "%vmovq\t{%1, %0|%0, %1}";
3270 if (REG_P (operands[0]) && REG_P (operands[1]))
3271 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3273 return "vmovsd\t{%1, %0|%0, %1}";
3276 return "movsd\t{%1, %0|%0, %1}";
3280 if (REG_P (operands[0]))
3281 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3283 return "vmovlpd\t{%1, %0|%0, %1}";
3286 return "movlpd\t{%1, %0|%0, %1}";
3290 if (REG_P (operands[0]))
3291 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3293 return "vmovlps\t{%1, %0|%0, %1}";
3296 return "movlps\t{%1, %0|%0, %1}";
3305 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3306 (set (attr "prefix")
3307 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3308 (const_string "orig")
3309 (const_string "maybe_vex")))
3310 (set (attr "prefix_data16")
3311 (if_then_else (eq_attr "mode" "V1DF")
3313 (const_string "*")))
3315 (cond [(eq_attr "alternative" "0,1,2")
3317 (eq_attr "alternative" "3,4")
3320 /* For SSE1, we have many fewer alternatives. */
3321 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3322 (cond [(eq_attr "alternative" "5,6")
3323 (const_string "V4SF")
3325 (const_string "V2SF"))
3327 /* xorps is one byte shorter. */
3328 (eq_attr "alternative" "5")
3329 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3331 (const_string "V4SF")
3332 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3336 (const_string "V2DF"))
3338 /* For architectures resolving dependencies on
3339 whole SSE registers use APD move to break dependency
3340 chains, otherwise use short move to avoid extra work.
3342 movaps encodes one byte shorter. */
3343 (eq_attr "alternative" "6")
3345 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3347 (const_string "V4SF")
3348 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3350 (const_string "V2DF")
3352 (const_string "DF"))
3353 /* For architectures resolving dependencies on register
3354 parts we may avoid extra work to zero out upper part
3356 (eq_attr "alternative" "7")
3358 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3360 (const_string "V1DF")
3361 (const_string "DF"))
3363 (const_string "DF")))])
3366 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3367 (match_operand:DF 1 "general_operand" ""))]
3369 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3370 && ! (ANY_FP_REG_P (operands[0]) ||
3371 (GET_CODE (operands[0]) == SUBREG
3372 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3373 && ! (ANY_FP_REG_P (operands[1]) ||
3374 (GET_CODE (operands[1]) == SUBREG
3375 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3377 "ix86_split_long_move (operands); DONE;")
3379 (define_insn "*movsf_internal"
3380 [(set (match_operand:SF 0 "nonimmediate_operand"
3381 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3382 (match_operand:SF 1 "general_operand"
3383 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3384 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3385 && (reload_in_progress || reload_completed
3386 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3387 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3388 && standard_80387_constant_p (operands[1]))
3389 || GET_CODE (operands[1]) != CONST_DOUBLE
3390 || memory_operand (operands[0], SFmode))"
3392 switch (which_alternative)
3396 return output_387_reg_move (insn, operands);
3399 return standard_80387_constant_opcode (operands[1]);
3403 return "mov{l}\t{%1, %0|%0, %1}";
3405 if (get_attr_mode (insn) == MODE_TI)
3406 return "%vpxor\t%0, %d0";
3408 return "%vxorps\t%0, %d0";
3410 if (get_attr_mode (insn) == MODE_V4SF)
3411 return "%vmovaps\t{%1, %0|%0, %1}";
3413 return "%vmovss\t{%1, %d0|%d0, %1}";
3416 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3417 : "vmovss\t{%1, %0|%0, %1}";
3419 return "movss\t{%1, %0|%0, %1}";
3421 return "%vmovss\t{%1, %0|%0, %1}";
3423 case 9: case 10: case 14: case 15:
3424 return "movd\t{%1, %0|%0, %1}";
3426 return "%vmovd\t{%1, %0|%0, %1}";
3429 return "movq\t{%1, %0|%0, %1}";
3435 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3436 (set (attr "prefix")
3437 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3438 (const_string "maybe_vex")
3439 (const_string "orig")))
3441 (cond [(eq_attr "alternative" "3,4,9,10")
3443 (eq_attr "alternative" "5")
3445 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3447 (ne (symbol_ref "TARGET_SSE2")
3449 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3452 (const_string "V4SF"))
3453 /* For architectures resolving dependencies on
3454 whole SSE registers use APS move to break dependency
3455 chains, otherwise use short move to avoid extra work.
3457 Do the same for architectures resolving dependencies on
3458 the parts. While in DF mode it is better to always handle
3459 just register parts, the SF mode is different due to lack
3460 of instructions to load just part of the register. It is
3461 better to maintain the whole registers in single format
3462 to avoid problems on using packed logical operations. */
3463 (eq_attr "alternative" "6")
3465 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3467 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3469 (const_string "V4SF")
3470 (const_string "SF"))
3471 (eq_attr "alternative" "11")
3472 (const_string "DI")]
3473 (const_string "SF")))])
3476 [(set (match_operand 0 "register_operand" "")
3477 (match_operand 1 "memory_operand" ""))]
3479 && MEM_P (operands[1])
3480 && (GET_MODE (operands[0]) == TFmode
3481 || GET_MODE (operands[0]) == XFmode
3482 || GET_MODE (operands[0]) == DFmode
3483 || GET_MODE (operands[0]) == SFmode)
3484 && (operands[2] = find_constant_src (insn))"
3485 [(set (match_dup 0) (match_dup 2))]
3487 rtx c = operands[2];
3488 rtx r = operands[0];
3490 if (GET_CODE (r) == SUBREG)
3495 if (!standard_sse_constant_p (c))
3498 else if (FP_REG_P (r))
3500 if (!standard_80387_constant_p (c))
3503 else if (MMX_REG_P (r))
3508 [(set (match_operand 0 "register_operand" "")
3509 (float_extend (match_operand 1 "memory_operand" "")))]
3511 && MEM_P (operands[1])
3512 && (GET_MODE (operands[0]) == TFmode
3513 || GET_MODE (operands[0]) == XFmode
3514 || GET_MODE (operands[0]) == DFmode
3515 || GET_MODE (operands[0]) == SFmode)
3516 && (operands[2] = find_constant_src (insn))"
3517 [(set (match_dup 0) (match_dup 2))]
3519 rtx c = operands[2];
3520 rtx r = operands[0];
3522 if (GET_CODE (r) == SUBREG)
3527 if (!standard_sse_constant_p (c))
3530 else if (FP_REG_P (r))
3532 if (!standard_80387_constant_p (c))
3535 else if (MMX_REG_P (r))
3539 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3541 [(set (match_operand:X87MODEF 0 "register_operand" "")
3542 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3543 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3544 && (standard_80387_constant_p (operands[1]) == 8
3545 || standard_80387_constant_p (operands[1]) == 9)"
3546 [(set (match_dup 0)(match_dup 1))
3548 (neg:X87MODEF (match_dup 0)))]
3552 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3553 if (real_isnegzero (&r))
3554 operands[1] = CONST0_RTX (<MODE>mode);
3556 operands[1] = CONST1_RTX (<MODE>mode);
3559 (define_insn "swapxf"
3560 [(set (match_operand:XF 0 "register_operand" "+f")
3561 (match_operand:XF 1 "register_operand" "+f"))
3566 if (STACK_TOP_P (operands[0]))
3571 [(set_attr "type" "fxch")
3572 (set_attr "mode" "XF")])
3574 (define_insn "*swap<mode>"
3575 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3576 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3579 "TARGET_80387 || reload_completed"
3581 if (STACK_TOP_P (operands[0]))
3586 [(set_attr "type" "fxch")
3587 (set_attr "mode" "<MODE>")])
3589 ;; Zero extension instructions
3591 (define_expand "zero_extendsidi2"
3592 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3593 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3598 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3603 (define_insn "*zero_extendsidi2_rex64"
3604 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3606 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3609 mov\t{%k1, %k0|%k0, %k1}
3611 movd\t{%1, %0|%0, %1}
3612 movd\t{%1, %0|%0, %1}
3613 %vmovd\t{%1, %0|%0, %1}
3614 %vmovd\t{%1, %0|%0, %1}"
3615 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3616 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3617 (set_attr "prefix_0f" "0,*,*,*,*,*")
3618 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3621 [(set (match_operand:DI 0 "memory_operand" "")
3622 (zero_extend:DI (match_dup 0)))]
3624 [(set (match_dup 4) (const_int 0))]
3625 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3627 ;; %%% Kill me once multi-word ops are sane.
3628 (define_insn "zero_extendsidi2_1"
3629 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3631 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3632 (clobber (reg:CC FLAGS_REG))]
3638 movd\t{%1, %0|%0, %1}
3639 movd\t{%1, %0|%0, %1}
3640 %vmovd\t{%1, %0|%0, %1}
3641 %vmovd\t{%1, %0|%0, %1}"
3642 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3643 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3644 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3647 [(set (match_operand:DI 0 "register_operand" "")
3648 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3649 (clobber (reg:CC FLAGS_REG))]
3650 "!TARGET_64BIT && reload_completed
3651 && true_regnum (operands[0]) == true_regnum (operands[1])"
3652 [(set (match_dup 4) (const_int 0))]
3653 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3656 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3657 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3658 (clobber (reg:CC FLAGS_REG))]
3659 "!TARGET_64BIT && reload_completed
3660 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3661 [(set (match_dup 3) (match_dup 1))
3662 (set (match_dup 4) (const_int 0))]
3663 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3665 (define_insn "zero_extend<mode>di2"
3666 [(set (match_operand:DI 0 "register_operand" "=r")
3668 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3670 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3671 [(set_attr "type" "imovx")
3672 (set_attr "mode" "SI")])
3674 (define_expand "zero_extendhisi2"
3675 [(set (match_operand:SI 0 "register_operand" "")
3676 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3679 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3681 operands[1] = force_reg (HImode, operands[1]);
3682 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3687 (define_insn_and_split "zero_extendhisi2_and"
3688 [(set (match_operand:SI 0 "register_operand" "=r")
3689 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3690 (clobber (reg:CC FLAGS_REG))]
3691 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3693 "&& reload_completed"
3694 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3695 (clobber (reg:CC FLAGS_REG))])]
3697 [(set_attr "type" "alu1")
3698 (set_attr "mode" "SI")])
3700 (define_insn "*zero_extendhisi2_movzwl"
3701 [(set (match_operand:SI 0 "register_operand" "=r")
3702 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3703 "!TARGET_ZERO_EXTEND_WITH_AND
3704 || optimize_function_for_size_p (cfun)"
3705 "movz{wl|x}\t{%1, %0|%0, %1}"
3706 [(set_attr "type" "imovx")
3707 (set_attr "mode" "SI")])
3709 (define_expand "zero_extendqi<mode>2"
3711 [(set (match_operand:SWI24 0 "register_operand" "")
3712 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3713 (clobber (reg:CC FLAGS_REG))])])
3715 (define_insn "*zero_extendqi<mode>2_and"
3716 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3717 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3718 (clobber (reg:CC FLAGS_REG))]
3719 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3721 [(set_attr "type" "alu1")
3722 (set_attr "mode" "<MODE>")])
3724 ;; When source and destination does not overlap, clear destination
3725 ;; first and then do the movb
3727 [(set (match_operand:SWI24 0 "register_operand" "")
3728 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3729 (clobber (reg:CC FLAGS_REG))]
3731 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3732 && ANY_QI_REG_P (operands[0])
3733 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3734 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3735 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3737 operands[2] = gen_lowpart (QImode, operands[0]);
3738 ix86_expand_clear (operands[0]);
3741 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3742 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3743 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3744 (clobber (reg:CC FLAGS_REG))]
3745 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3747 [(set_attr "type" "imovx,alu1")
3748 (set_attr "mode" "<MODE>")])
3750 ;; For the movzbl case strip only the clobber
3752 [(set (match_operand:SWI24 0 "register_operand" "")
3753 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3754 (clobber (reg:CC FLAGS_REG))]
3756 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3757 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3759 (zero_extend:SWI24 (match_dup 1)))])
3761 ; zero extend to SImode to avoid partial register stalls
3762 (define_insn "*zero_extendqi<mode>2_movzbl"
3763 [(set (match_operand:SWI24 0 "register_operand" "=r")
3764 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3766 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3767 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3768 [(set_attr "type" "imovx")
3769 (set_attr "mode" "SI")])
3771 ;; Rest is handled by single and.
3773 [(set (match_operand:SWI24 0 "register_operand" "")
3774 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3775 (clobber (reg:CC FLAGS_REG))]
3777 && true_regnum (operands[0]) == true_regnum (operands[1])"
3778 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3779 (clobber (reg:CC FLAGS_REG))])])
3781 ;; Sign extension instructions
3783 (define_expand "extendsidi2"
3784 [(set (match_operand:DI 0 "register_operand" "")
3785 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3790 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3795 (define_insn "*extendsidi2_rex64"
3796 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3797 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3801 movs{lq|x}\t{%1, %0|%0, %1}"
3802 [(set_attr "type" "imovx")
3803 (set_attr "mode" "DI")
3804 (set_attr "prefix_0f" "0")
3805 (set_attr "modrm" "0,1")])
3807 (define_insn "extendsidi2_1"
3808 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3809 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3810 (clobber (reg:CC FLAGS_REG))
3811 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3815 ;; Extend to memory case when source register does die.
3817 [(set (match_operand:DI 0 "memory_operand" "")
3818 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3819 (clobber (reg:CC FLAGS_REG))
3820 (clobber (match_operand:SI 2 "register_operand" ""))]
3822 && dead_or_set_p (insn, operands[1])
3823 && !reg_mentioned_p (operands[1], operands[0]))"
3824 [(set (match_dup 3) (match_dup 1))
3825 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3826 (clobber (reg:CC FLAGS_REG))])
3827 (set (match_dup 4) (match_dup 1))]
3828 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3830 ;; Extend to memory case when source register does not die.
3832 [(set (match_operand:DI 0 "memory_operand" "")
3833 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3834 (clobber (reg:CC FLAGS_REG))
3835 (clobber (match_operand:SI 2 "register_operand" ""))]
3839 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3841 emit_move_insn (operands[3], operands[1]);
3843 /* Generate a cltd if possible and doing so it profitable. */
3844 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3845 && true_regnum (operands[1]) == AX_REG
3846 && true_regnum (operands[2]) == DX_REG)
3848 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3852 emit_move_insn (operands[2], operands[1]);
3853 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3855 emit_move_insn (operands[4], operands[2]);
3859 ;; Extend to register case. Optimize case where source and destination
3860 ;; registers match and cases where we can use cltd.
3862 [(set (match_operand:DI 0 "register_operand" "")
3863 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3864 (clobber (reg:CC FLAGS_REG))
3865 (clobber (match_scratch:SI 2 ""))]
3869 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3871 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3872 emit_move_insn (operands[3], operands[1]);
3874 /* Generate a cltd if possible and doing so it profitable. */
3875 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3876 && true_regnum (operands[3]) == AX_REG
3877 && true_regnum (operands[4]) == DX_REG)
3879 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3883 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3884 emit_move_insn (operands[4], operands[1]);
3886 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3890 (define_insn "extend<mode>di2"
3891 [(set (match_operand:DI 0 "register_operand" "=r")
3893 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3895 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3896 [(set_attr "type" "imovx")
3897 (set_attr "mode" "DI")])
3899 (define_insn "extendhisi2"
3900 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3901 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3904 switch (get_attr_prefix_0f (insn))
3907 return "{cwtl|cwde}";
3909 return "movs{wl|x}\t{%1, %0|%0, %1}";
3912 [(set_attr "type" "imovx")
3913 (set_attr "mode" "SI")
3914 (set (attr "prefix_0f")
3915 ;; movsx is short decodable while cwtl is vector decoded.
3916 (if_then_else (and (eq_attr "cpu" "!k6")
3917 (eq_attr "alternative" "0"))
3919 (const_string "1")))
3921 (if_then_else (eq_attr "prefix_0f" "0")
3923 (const_string "1")))])
3925 (define_insn "*extendhisi2_zext"
3926 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3929 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3932 switch (get_attr_prefix_0f (insn))
3935 return "{cwtl|cwde}";
3937 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3940 [(set_attr "type" "imovx")
3941 (set_attr "mode" "SI")
3942 (set (attr "prefix_0f")
3943 ;; movsx is short decodable while cwtl is vector decoded.
3944 (if_then_else (and (eq_attr "cpu" "!k6")
3945 (eq_attr "alternative" "0"))
3947 (const_string "1")))
3949 (if_then_else (eq_attr "prefix_0f" "0")
3951 (const_string "1")))])
3953 (define_insn "extendqisi2"
3954 [(set (match_operand:SI 0 "register_operand" "=r")
3955 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3957 "movs{bl|x}\t{%1, %0|%0, %1}"
3958 [(set_attr "type" "imovx")
3959 (set_attr "mode" "SI")])
3961 (define_insn "*extendqisi2_zext"
3962 [(set (match_operand:DI 0 "register_operand" "=r")
3964 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3966 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3967 [(set_attr "type" "imovx")
3968 (set_attr "mode" "SI")])
3970 (define_insn "extendqihi2"
3971 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3972 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3975 switch (get_attr_prefix_0f (insn))
3978 return "{cbtw|cbw}";
3980 return "movs{bw|x}\t{%1, %0|%0, %1}";
3983 [(set_attr "type" "imovx")
3984 (set_attr "mode" "HI")
3985 (set (attr "prefix_0f")
3986 ;; movsx is short decodable while cwtl is vector decoded.
3987 (if_then_else (and (eq_attr "cpu" "!k6")
3988 (eq_attr "alternative" "0"))
3990 (const_string "1")))
3992 (if_then_else (eq_attr "prefix_0f" "0")
3994 (const_string "1")))])
3996 ;; Conversions between float and double.
3998 ;; These are all no-ops in the model used for the 80387.
3999 ;; So just emit moves.
4001 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4003 [(set (match_operand:DF 0 "push_operand" "")
4004 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4006 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4007 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4010 [(set (match_operand:XF 0 "push_operand" "")
4011 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
4013 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4014 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4015 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4017 (define_expand "extendsfdf2"
4018 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4019 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4020 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4022 /* ??? Needed for compress_float_constant since all fp constants
4023 are LEGITIMATE_CONSTANT_P. */
4024 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4026 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4027 && standard_80387_constant_p (operands[1]) > 0)
4029 operands[1] = simplify_const_unary_operation
4030 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4031 emit_move_insn_1 (operands[0], operands[1]);
4034 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4038 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4040 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4042 We do the conversion post reload to avoid producing of 128bit spills
4043 that might lead to ICE on 32bit target. The sequence unlikely combine
4046 [(set (match_operand:DF 0 "register_operand" "")
4048 (match_operand:SF 1 "nonimmediate_operand" "")))]
4049 "TARGET_USE_VECTOR_FP_CONVERTS
4050 && optimize_insn_for_speed_p ()
4051 && reload_completed && SSE_REG_P (operands[0])"
4056 (parallel [(const_int 0) (const_int 1)]))))]
4058 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4059 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4060 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4061 Try to avoid move when unpacking can be done in source. */
4062 if (REG_P (operands[1]))
4064 /* If it is unsafe to overwrite upper half of source, we need
4065 to move to destination and unpack there. */
4066 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4067 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4068 && true_regnum (operands[0]) != true_regnum (operands[1]))
4070 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4071 emit_move_insn (tmp, operands[1]);
4074 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4075 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4079 emit_insn (gen_vec_setv4sf_0 (operands[3],
4080 CONST0_RTX (V4SFmode), operands[1]));
4083 (define_insn "*extendsfdf2_mixed"
4084 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4086 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4087 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4089 switch (which_alternative)
4093 return output_387_reg_move (insn, operands);
4096 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4102 [(set_attr "type" "fmov,fmov,ssecvt")
4103 (set_attr "prefix" "orig,orig,maybe_vex")
4104 (set_attr "mode" "SF,XF,DF")])
4106 (define_insn "*extendsfdf2_sse"
4107 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4108 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4109 "TARGET_SSE2 && TARGET_SSE_MATH"
4110 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4111 [(set_attr "type" "ssecvt")
4112 (set_attr "prefix" "maybe_vex")
4113 (set_attr "mode" "DF")])
4115 (define_insn "*extendsfdf2_i387"
4116 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4117 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4119 "* return output_387_reg_move (insn, operands);"
4120 [(set_attr "type" "fmov")
4121 (set_attr "mode" "SF,XF")])
4123 (define_expand "extend<mode>xf2"
4124 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4125 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4128 /* ??? Needed for compress_float_constant since all fp constants
4129 are LEGITIMATE_CONSTANT_P. */
4130 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4132 if (standard_80387_constant_p (operands[1]) > 0)
4134 operands[1] = simplify_const_unary_operation
4135 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4136 emit_move_insn_1 (operands[0], operands[1]);
4139 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4143 (define_insn "*extend<mode>xf2_i387"
4144 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4146 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4148 "* return output_387_reg_move (insn, operands);"
4149 [(set_attr "type" "fmov")
4150 (set_attr "mode" "<MODE>,XF")])
4152 ;; %%% This seems bad bad news.
4153 ;; This cannot output into an f-reg because there is no way to be sure
4154 ;; of truncating in that case. Otherwise this is just like a simple move
4155 ;; insn. So we pretend we can output to a reg in order to get better
4156 ;; register preferencing, but we really use a stack slot.
4158 ;; Conversion from DFmode to SFmode.
4160 (define_expand "truncdfsf2"
4161 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4163 (match_operand:DF 1 "nonimmediate_operand" "")))]
4164 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4166 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4168 else if (flag_unsafe_math_optimizations)
4172 enum ix86_stack_slot slot = (virtuals_instantiated
4175 rtx temp = assign_386_stack_local (SFmode, slot);
4176 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4181 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4183 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4185 We do the conversion post reload to avoid producing of 128bit spills
4186 that might lead to ICE on 32bit target. The sequence unlikely combine
4189 [(set (match_operand:SF 0 "register_operand" "")
4191 (match_operand:DF 1 "nonimmediate_operand" "")))]
4192 "TARGET_USE_VECTOR_FP_CONVERTS
4193 && optimize_insn_for_speed_p ()
4194 && reload_completed && SSE_REG_P (operands[0])"
4197 (float_truncate:V2SF
4201 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4202 operands[3] = CONST0_RTX (V2SFmode);
4203 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4204 /* Use movsd for loading from memory, unpcklpd for registers.
4205 Try to avoid move when unpacking can be done in source, or SSE3
4206 movddup is available. */
4207 if (REG_P (operands[1]))
4210 && true_regnum (operands[0]) != true_regnum (operands[1])
4211 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4212 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4214 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4215 emit_move_insn (tmp, operands[1]);
4218 else if (!TARGET_SSE3)
4219 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4220 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4223 emit_insn (gen_sse2_loadlpd (operands[4],
4224 CONST0_RTX (V2DFmode), operands[1]));
4227 (define_expand "truncdfsf2_with_temp"
4228 [(parallel [(set (match_operand:SF 0 "" "")
4229 (float_truncate:SF (match_operand:DF 1 "" "")))
4230 (clobber (match_operand:SF 2 "" ""))])])
4232 (define_insn "*truncdfsf_fast_mixed"
4233 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4235 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4236 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4238 switch (which_alternative)
4241 return output_387_reg_move (insn, operands);
4243 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4248 [(set_attr "type" "fmov,ssecvt")
4249 (set_attr "prefix" "orig,maybe_vex")
4250 (set_attr "mode" "SF")])
4252 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4253 ;; because nothing we do here is unsafe.
4254 (define_insn "*truncdfsf_fast_sse"
4255 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4257 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4258 "TARGET_SSE2 && TARGET_SSE_MATH"
4259 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4260 [(set_attr "type" "ssecvt")
4261 (set_attr "prefix" "maybe_vex")
4262 (set_attr "mode" "SF")])
4264 (define_insn "*truncdfsf_fast_i387"
4265 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4267 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4268 "TARGET_80387 && flag_unsafe_math_optimizations"
4269 "* return output_387_reg_move (insn, operands);"
4270 [(set_attr "type" "fmov")
4271 (set_attr "mode" "SF")])
4273 (define_insn "*truncdfsf_mixed"
4274 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4276 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4277 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4278 "TARGET_MIX_SSE_I387"
4280 switch (which_alternative)
4283 return output_387_reg_move (insn, operands);
4285 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4291 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4292 (set_attr "unit" "*,*,i387,i387,i387")
4293 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4294 (set_attr "mode" "SF")])
4296 (define_insn "*truncdfsf_i387"
4297 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4299 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4300 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4303 switch (which_alternative)
4306 return output_387_reg_move (insn, operands);
4312 [(set_attr "type" "fmov,multi,multi,multi")
4313 (set_attr "unit" "*,i387,i387,i387")
4314 (set_attr "mode" "SF")])
4316 (define_insn "*truncdfsf2_i387_1"
4317 [(set (match_operand:SF 0 "memory_operand" "=m")
4319 (match_operand:DF 1 "register_operand" "f")))]
4321 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4322 && !TARGET_MIX_SSE_I387"
4323 "* return output_387_reg_move (insn, operands);"
4324 [(set_attr "type" "fmov")
4325 (set_attr "mode" "SF")])
4328 [(set (match_operand:SF 0 "register_operand" "")
4330 (match_operand:DF 1 "fp_register_operand" "")))
4331 (clobber (match_operand 2 "" ""))]
4333 [(set (match_dup 2) (match_dup 1))
4334 (set (match_dup 0) (match_dup 2))]
4335 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4337 ;; Conversion from XFmode to {SF,DF}mode
4339 (define_expand "truncxf<mode>2"
4340 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4341 (float_truncate:MODEF
4342 (match_operand:XF 1 "register_operand" "")))
4343 (clobber (match_dup 2))])]
4346 if (flag_unsafe_math_optimizations)
4348 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4349 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4350 if (reg != operands[0])
4351 emit_move_insn (operands[0], reg);
4356 enum ix86_stack_slot slot = (virtuals_instantiated
4359 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4363 (define_insn "*truncxfsf2_mixed"
4364 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4366 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4367 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4370 gcc_assert (!which_alternative);
4371 return output_387_reg_move (insn, operands);
4373 [(set_attr "type" "fmov,multi,multi,multi")
4374 (set_attr "unit" "*,i387,i387,i387")
4375 (set_attr "mode" "SF")])
4377 (define_insn "*truncxfdf2_mixed"
4378 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4380 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4381 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4384 gcc_assert (!which_alternative);
4385 return output_387_reg_move (insn, operands);
4387 [(set_attr "type" "fmov,multi,multi,multi")
4388 (set_attr "unit" "*,i387,i387,i387")
4389 (set_attr "mode" "DF")])
4391 (define_insn "truncxf<mode>2_i387_noop"
4392 [(set (match_operand:MODEF 0 "register_operand" "=f")
4393 (float_truncate:MODEF
4394 (match_operand:XF 1 "register_operand" "f")))]
4395 "TARGET_80387 && flag_unsafe_math_optimizations"
4396 "* return output_387_reg_move (insn, operands);"
4397 [(set_attr "type" "fmov")
4398 (set_attr "mode" "<MODE>")])
4400 (define_insn "*truncxf<mode>2_i387"
4401 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4402 (float_truncate:MODEF
4403 (match_operand:XF 1 "register_operand" "f")))]
4405 "* return output_387_reg_move (insn, operands);"
4406 [(set_attr "type" "fmov")
4407 (set_attr "mode" "<MODE>")])
4410 [(set (match_operand:MODEF 0 "register_operand" "")
4411 (float_truncate:MODEF
4412 (match_operand:XF 1 "register_operand" "")))
4413 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4414 "TARGET_80387 && reload_completed"
4415 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4416 (set (match_dup 0) (match_dup 2))])
4419 [(set (match_operand:MODEF 0 "memory_operand" "")
4420 (float_truncate:MODEF
4421 (match_operand:XF 1 "register_operand" "")))
4422 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4424 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4426 ;; Signed conversion to DImode.
4428 (define_expand "fix_truncxfdi2"
4429 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4430 (fix:DI (match_operand:XF 1 "register_operand" "")))
4431 (clobber (reg:CC FLAGS_REG))])]
4436 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4441 (define_expand "fix_trunc<mode>di2"
4442 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4443 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4444 (clobber (reg:CC FLAGS_REG))])]
4445 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4448 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4450 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4453 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4455 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4456 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4457 if (out != operands[0])
4458 emit_move_insn (operands[0], out);
4463 ;; Signed conversion to SImode.
4465 (define_expand "fix_truncxfsi2"
4466 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4467 (fix:SI (match_operand:XF 1 "register_operand" "")))
4468 (clobber (reg:CC FLAGS_REG))])]
4473 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4478 (define_expand "fix_trunc<mode>si2"
4479 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4480 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4481 (clobber (reg:CC FLAGS_REG))])]
4482 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4485 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4487 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4490 if (SSE_FLOAT_MODE_P (<MODE>mode))
4492 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4493 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4494 if (out != operands[0])
4495 emit_move_insn (operands[0], out);
4500 ;; Signed conversion to HImode.
4502 (define_expand "fix_trunc<mode>hi2"
4503 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4504 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4505 (clobber (reg:CC FLAGS_REG))])]
4507 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4511 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4516 ;; Unsigned conversion to SImode.
4518 (define_expand "fixuns_trunc<mode>si2"
4520 [(set (match_operand:SI 0 "register_operand" "")
4522 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4524 (clobber (match_scratch:<ssevecmode> 3 ""))
4525 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4526 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4528 enum machine_mode mode = <MODE>mode;
4529 enum machine_mode vecmode = <ssevecmode>mode;
4530 REAL_VALUE_TYPE TWO31r;
4533 if (optimize_insn_for_size_p ())
4536 real_ldexp (&TWO31r, &dconst1, 31);
4537 two31 = const_double_from_real_value (TWO31r, mode);
4538 two31 = ix86_build_const_vector (vecmode, true, two31);
4539 operands[2] = force_reg (vecmode, two31);
4542 (define_insn_and_split "*fixuns_trunc<mode>_1"
4543 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4545 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4546 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4547 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4548 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4549 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4550 && optimize_function_for_speed_p (cfun)"
4552 "&& reload_completed"
4555 ix86_split_convert_uns_si_sse (operands);
4559 ;; Unsigned conversion to HImode.
4560 ;; Without these patterns, we'll try the unsigned SI conversion which
4561 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4563 (define_expand "fixuns_trunc<mode>hi2"
4565 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4566 (set (match_operand:HI 0 "nonimmediate_operand" "")
4567 (subreg:HI (match_dup 2) 0))]
4568 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4569 "operands[2] = gen_reg_rtx (SImode);")
4571 ;; When SSE is available, it is always faster to use it!
4572 (define_insn "fix_trunc<mode>di_sse"
4573 [(set (match_operand:DI 0 "register_operand" "=r,r")
4574 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4575 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4576 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4577 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4578 [(set_attr "type" "sseicvt")
4579 (set_attr "prefix" "maybe_vex")
4580 (set_attr "prefix_rex" "1")
4581 (set_attr "mode" "<MODE>")
4582 (set_attr "athlon_decode" "double,vector")
4583 (set_attr "amdfam10_decode" "double,double")
4584 (set_attr "bdver1_decode" "double,double")])
4586 (define_insn "fix_trunc<mode>si_sse"
4587 [(set (match_operand:SI 0 "register_operand" "=r,r")
4588 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4589 "SSE_FLOAT_MODE_P (<MODE>mode)
4590 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4591 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4592 [(set_attr "type" "sseicvt")
4593 (set_attr "prefix" "maybe_vex")
4594 (set_attr "mode" "<MODE>")
4595 (set_attr "athlon_decode" "double,vector")
4596 (set_attr "amdfam10_decode" "double,double")
4597 (set_attr "bdver1_decode" "double,double")])
4599 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4601 [(set (match_operand:MODEF 0 "register_operand" "")
4602 (match_operand:MODEF 1 "memory_operand" ""))
4603 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4604 (fix:SSEMODEI24 (match_dup 0)))]
4605 "TARGET_SHORTEN_X87_SSE
4606 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4607 && peep2_reg_dead_p (2, operands[0])"
4608 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4610 ;; Avoid vector decoded forms of the instruction.
4612 [(match_scratch:DF 2 "Y2")
4613 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4614 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4615 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4616 [(set (match_dup 2) (match_dup 1))
4617 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4620 [(match_scratch:SF 2 "x")
4621 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4622 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4623 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4624 [(set (match_dup 2) (match_dup 1))
4625 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4627 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4628 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4629 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4630 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4632 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4633 && (TARGET_64BIT || <MODE>mode != DImode))
4635 && can_create_pseudo_p ()"
4640 if (memory_operand (operands[0], VOIDmode))
4641 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4644 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4645 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4651 [(set_attr "type" "fisttp")
4652 (set_attr "mode" "<MODE>")])
4654 (define_insn "fix_trunc<mode>_i387_fisttp"
4655 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4656 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4657 (clobber (match_scratch:XF 2 "=&1f"))]
4658 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4660 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4661 && (TARGET_64BIT || <MODE>mode != DImode))
4662 && TARGET_SSE_MATH)"
4663 "* return output_fix_trunc (insn, operands, 1);"
4664 [(set_attr "type" "fisttp")
4665 (set_attr "mode" "<MODE>")])
4667 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4668 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4669 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4670 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4671 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4672 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4674 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4675 && (TARGET_64BIT || <MODE>mode != DImode))
4676 && TARGET_SSE_MATH)"
4678 [(set_attr "type" "fisttp")
4679 (set_attr "mode" "<MODE>")])
4682 [(set (match_operand:X87MODEI 0 "register_operand" "")
4683 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4684 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4685 (clobber (match_scratch 3 ""))]
4687 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4688 (clobber (match_dup 3))])
4689 (set (match_dup 0) (match_dup 2))])
4692 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4693 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4694 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4695 (clobber (match_scratch 3 ""))]
4697 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4698 (clobber (match_dup 3))])])
4700 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4701 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4702 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4703 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4704 ;; function in i386.c.
4705 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4706 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4707 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4708 (clobber (reg:CC FLAGS_REG))]
4709 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4711 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4712 && (TARGET_64BIT || <MODE>mode != DImode))
4713 && can_create_pseudo_p ()"
4718 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4720 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4721 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4722 if (memory_operand (operands[0], VOIDmode))
4723 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4724 operands[2], operands[3]));
4727 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4728 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4729 operands[2], operands[3],
4734 [(set_attr "type" "fistp")
4735 (set_attr "i387_cw" "trunc")
4736 (set_attr "mode" "<MODE>")])
4738 (define_insn "fix_truncdi_i387"
4739 [(set (match_operand:DI 0 "memory_operand" "=m")
4740 (fix:DI (match_operand 1 "register_operand" "f")))
4741 (use (match_operand:HI 2 "memory_operand" "m"))
4742 (use (match_operand:HI 3 "memory_operand" "m"))
4743 (clobber (match_scratch:XF 4 "=&1f"))]
4744 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4746 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4747 "* return output_fix_trunc (insn, operands, 0);"
4748 [(set_attr "type" "fistp")
4749 (set_attr "i387_cw" "trunc")
4750 (set_attr "mode" "DI")])
4752 (define_insn "fix_truncdi_i387_with_temp"
4753 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4754 (fix:DI (match_operand 1 "register_operand" "f,f")))
4755 (use (match_operand:HI 2 "memory_operand" "m,m"))
4756 (use (match_operand:HI 3 "memory_operand" "m,m"))
4757 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4758 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4759 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4761 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4763 [(set_attr "type" "fistp")
4764 (set_attr "i387_cw" "trunc")
4765 (set_attr "mode" "DI")])
4768 [(set (match_operand:DI 0 "register_operand" "")
4769 (fix:DI (match_operand 1 "register_operand" "")))
4770 (use (match_operand:HI 2 "memory_operand" ""))
4771 (use (match_operand:HI 3 "memory_operand" ""))
4772 (clobber (match_operand:DI 4 "memory_operand" ""))
4773 (clobber (match_scratch 5 ""))]
4775 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4778 (clobber (match_dup 5))])
4779 (set (match_dup 0) (match_dup 4))])
4782 [(set (match_operand:DI 0 "memory_operand" "")
4783 (fix:DI (match_operand 1 "register_operand" "")))
4784 (use (match_operand:HI 2 "memory_operand" ""))
4785 (use (match_operand:HI 3 "memory_operand" ""))
4786 (clobber (match_operand:DI 4 "memory_operand" ""))
4787 (clobber (match_scratch 5 ""))]
4789 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4792 (clobber (match_dup 5))])])
4794 (define_insn "fix_trunc<mode>_i387"
4795 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4796 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4797 (use (match_operand:HI 2 "memory_operand" "m"))
4798 (use (match_operand:HI 3 "memory_operand" "m"))]
4799 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4801 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4802 "* return output_fix_trunc (insn, operands, 0);"
4803 [(set_attr "type" "fistp")
4804 (set_attr "i387_cw" "trunc")
4805 (set_attr "mode" "<MODE>")])
4807 (define_insn "fix_trunc<mode>_i387_with_temp"
4808 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4809 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4810 (use (match_operand:HI 2 "memory_operand" "m,m"))
4811 (use (match_operand:HI 3 "memory_operand" "m,m"))
4812 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4813 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4815 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4817 [(set_attr "type" "fistp")
4818 (set_attr "i387_cw" "trunc")
4819 (set_attr "mode" "<MODE>")])
4822 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4823 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4824 (use (match_operand:HI 2 "memory_operand" ""))
4825 (use (match_operand:HI 3 "memory_operand" ""))
4826 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4828 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4830 (use (match_dup 3))])
4831 (set (match_dup 0) (match_dup 4))])
4834 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4835 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4836 (use (match_operand:HI 2 "memory_operand" ""))
4837 (use (match_operand:HI 3 "memory_operand" ""))
4838 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4840 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4842 (use (match_dup 3))])])
4844 (define_insn "x86_fnstcw_1"
4845 [(set (match_operand:HI 0 "memory_operand" "=m")
4846 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4849 [(set (attr "length")
4850 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4851 (set_attr "mode" "HI")
4852 (set_attr "unit" "i387")
4853 (set_attr "bdver1_decode" "vector")])
4855 (define_insn "x86_fldcw_1"
4856 [(set (reg:HI FPCR_REG)
4857 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4860 [(set (attr "length")
4861 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4862 (set_attr "mode" "HI")
4863 (set_attr "unit" "i387")
4864 (set_attr "athlon_decode" "vector")
4865 (set_attr "amdfam10_decode" "vector")
4866 (set_attr "bdver1_decode" "vector")])
4868 ;; Conversion between fixed point and floating point.
4870 ;; Even though we only accept memory inputs, the backend _really_
4871 ;; wants to be able to do this between registers.
4873 (define_expand "floathi<mode>2"
4874 [(set (match_operand:X87MODEF 0 "register_operand" "")
4875 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4877 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4878 || TARGET_MIX_SSE_I387)")
4880 ;; Pre-reload splitter to add memory clobber to the pattern.
4881 (define_insn_and_split "*floathi<mode>2_1"
4882 [(set (match_operand:X87MODEF 0 "register_operand" "")
4883 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4885 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4886 || TARGET_MIX_SSE_I387)
4887 && can_create_pseudo_p ()"
4890 [(parallel [(set (match_dup 0)
4891 (float:X87MODEF (match_dup 1)))
4892 (clobber (match_dup 2))])]
4893 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4895 (define_insn "*floathi<mode>2_i387_with_temp"
4896 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4897 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4898 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4900 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4901 || TARGET_MIX_SSE_I387)"
4903 [(set_attr "type" "fmov,multi")
4904 (set_attr "mode" "<MODE>")
4905 (set_attr "unit" "*,i387")
4906 (set_attr "fp_int_src" "true")])
4908 (define_insn "*floathi<mode>2_i387"
4909 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4910 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4912 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4913 || TARGET_MIX_SSE_I387)"
4915 [(set_attr "type" "fmov")
4916 (set_attr "mode" "<MODE>")
4917 (set_attr "fp_int_src" "true")])
4920 [(set (match_operand:X87MODEF 0 "register_operand" "")
4921 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4922 (clobber (match_operand:HI 2 "memory_operand" ""))]
4924 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4925 || TARGET_MIX_SSE_I387)
4926 && reload_completed"
4927 [(set (match_dup 2) (match_dup 1))
4928 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4931 [(set (match_operand:X87MODEF 0 "register_operand" "")
4932 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4933 (clobber (match_operand:HI 2 "memory_operand" ""))]
4935 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4936 || TARGET_MIX_SSE_I387)
4937 && reload_completed"
4938 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4940 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4941 [(set (match_operand:X87MODEF 0 "register_operand" "")
4943 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4945 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4946 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4948 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4949 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4950 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4952 rtx reg = gen_reg_rtx (XFmode);
4955 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4957 if (<X87MODEF:MODE>mode == SFmode)
4958 insn = gen_truncxfsf2 (operands[0], reg);
4959 else if (<X87MODEF:MODE>mode == DFmode)
4960 insn = gen_truncxfdf2 (operands[0], reg);
4969 ;; Pre-reload splitter to add memory clobber to the pattern.
4970 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4971 [(set (match_operand:X87MODEF 0 "register_operand" "")
4972 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4974 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4975 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4976 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4977 || TARGET_MIX_SSE_I387))
4978 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4979 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4980 && ((<SSEMODEI24:MODE>mode == SImode
4981 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4982 && optimize_function_for_speed_p (cfun)
4983 && flag_trapping_math)
4984 || !(TARGET_INTER_UNIT_CONVERSIONS
4985 || optimize_function_for_size_p (cfun)))))
4986 && can_create_pseudo_p ()"
4989 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4990 (clobber (match_dup 2))])]
4992 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4994 /* Avoid store forwarding (partial memory) stall penalty
4995 by passing DImode value through XMM registers. */
4996 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4997 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4998 && optimize_function_for_speed_p (cfun))
5000 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5007 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5008 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5010 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5011 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5012 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5013 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5015 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5016 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5017 (set_attr "unit" "*,i387,*,*,*")
5018 (set_attr "athlon_decode" "*,*,double,direct,double")
5019 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5020 (set_attr "bdver1_decode" "*,*,double,direct,double")
5021 (set_attr "fp_int_src" "true")])
5023 (define_insn "*floatsi<mode>2_vector_mixed"
5024 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5025 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5026 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5027 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5031 [(set_attr "type" "fmov,sseicvt")
5032 (set_attr "mode" "<MODE>,<ssevecmode>")
5033 (set_attr "unit" "i387,*")
5034 (set_attr "athlon_decode" "*,direct")
5035 (set_attr "amdfam10_decode" "*,double")
5036 (set_attr "bdver1_decode" "*,direct")
5037 (set_attr "fp_int_src" "true")])
5039 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5040 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5042 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5043 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5044 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5045 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5047 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5048 (set_attr "mode" "<MODEF:MODE>")
5049 (set_attr "unit" "*,i387,*,*")
5050 (set_attr "athlon_decode" "*,*,double,direct")
5051 (set_attr "amdfam10_decode" "*,*,vector,double")
5052 (set_attr "bdver1_decode" "*,*,double,direct")
5053 (set_attr "fp_int_src" "true")])
5056 [(set (match_operand:MODEF 0 "register_operand" "")
5057 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5058 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5059 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5060 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5061 && TARGET_INTER_UNIT_CONVERSIONS
5063 && (SSE_REG_P (operands[0])
5064 || (GET_CODE (operands[0]) == SUBREG
5065 && SSE_REG_P (operands[0])))"
5066 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5069 [(set (match_operand:MODEF 0 "register_operand" "")
5070 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5071 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5072 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5073 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5074 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5076 && (SSE_REG_P (operands[0])
5077 || (GET_CODE (operands[0]) == SUBREG
5078 && SSE_REG_P (operands[0])))"
5079 [(set (match_dup 2) (match_dup 1))
5080 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5082 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5083 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5085 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5086 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5087 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5088 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5091 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5092 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5093 [(set_attr "type" "fmov,sseicvt,sseicvt")
5094 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5095 (set_attr "mode" "<MODEF:MODE>")
5096 (set (attr "prefix_rex")
5098 (and (eq_attr "prefix" "maybe_vex")
5099 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5101 (const_string "*")))
5102 (set_attr "unit" "i387,*,*")
5103 (set_attr "athlon_decode" "*,double,direct")
5104 (set_attr "amdfam10_decode" "*,vector,double")
5105 (set_attr "bdver1_decode" "*,double,direct")
5106 (set_attr "fp_int_src" "true")])
5108 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5109 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5111 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5112 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5113 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5114 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5117 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5118 [(set_attr "type" "fmov,sseicvt")
5119 (set_attr "prefix" "orig,maybe_vex")
5120 (set_attr "mode" "<MODEF:MODE>")
5121 (set (attr "prefix_rex")
5123 (and (eq_attr "prefix" "maybe_vex")
5124 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5126 (const_string "*")))
5127 (set_attr "athlon_decode" "*,direct")
5128 (set_attr "amdfam10_decode" "*,double")
5129 (set_attr "bdver1_decode" "*,direct")
5130 (set_attr "fp_int_src" "true")])
5132 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5133 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5135 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5136 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5137 "TARGET_SSE2 && TARGET_SSE_MATH
5138 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5140 [(set_attr "type" "sseicvt")
5141 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5142 (set_attr "athlon_decode" "double,direct,double")
5143 (set_attr "amdfam10_decode" "vector,double,double")
5144 (set_attr "bdver1_decode" "double,direct,double")
5145 (set_attr "fp_int_src" "true")])
5147 (define_insn "*floatsi<mode>2_vector_sse"
5148 [(set (match_operand:MODEF 0 "register_operand" "=x")
5149 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5150 "TARGET_SSE2 && TARGET_SSE_MATH
5151 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5153 [(set_attr "type" "sseicvt")
5154 (set_attr "mode" "<MODE>")
5155 (set_attr "athlon_decode" "direct")
5156 (set_attr "amdfam10_decode" "double")
5157 (set_attr "bdver1_decode" "direct")
5158 (set_attr "fp_int_src" "true")])
5161 [(set (match_operand:MODEF 0 "register_operand" "")
5162 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5163 (clobber (match_operand:SI 2 "memory_operand" ""))]
5164 "TARGET_SSE2 && TARGET_SSE_MATH
5165 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5167 && (SSE_REG_P (operands[0])
5168 || (GET_CODE (operands[0]) == SUBREG
5169 && SSE_REG_P (operands[0])))"
5172 rtx op1 = operands[1];
5174 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5176 if (GET_CODE (op1) == SUBREG)
5177 op1 = SUBREG_REG (op1);
5179 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5181 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5182 emit_insn (gen_sse2_loadld (operands[4],
5183 CONST0_RTX (V4SImode), operands[1]));
5185 /* We can ignore possible trapping value in the
5186 high part of SSE register for non-trapping math. */
5187 else if (SSE_REG_P (op1) && !flag_trapping_math)
5188 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5191 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5192 emit_move_insn (operands[2], operands[1]);
5193 emit_insn (gen_sse2_loadld (operands[4],
5194 CONST0_RTX (V4SImode), operands[2]));
5197 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5202 [(set (match_operand:MODEF 0 "register_operand" "")
5203 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5204 (clobber (match_operand:SI 2 "memory_operand" ""))]
5205 "TARGET_SSE2 && TARGET_SSE_MATH
5206 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5208 && (SSE_REG_P (operands[0])
5209 || (GET_CODE (operands[0]) == SUBREG
5210 && SSE_REG_P (operands[0])))"
5213 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5215 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5217 emit_insn (gen_sse2_loadld (operands[4],
5218 CONST0_RTX (V4SImode), operands[1]));
5220 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5225 [(set (match_operand:MODEF 0 "register_operand" "")
5226 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5227 "TARGET_SSE2 && TARGET_SSE_MATH
5228 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5230 && (SSE_REG_P (operands[0])
5231 || (GET_CODE (operands[0]) == SUBREG
5232 && SSE_REG_P (operands[0])))"
5235 rtx op1 = operands[1];
5237 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5239 if (GET_CODE (op1) == SUBREG)
5240 op1 = SUBREG_REG (op1);
5242 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5244 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5245 emit_insn (gen_sse2_loadld (operands[4],
5246 CONST0_RTX (V4SImode), operands[1]));
5248 /* We can ignore possible trapping value in the
5249 high part of SSE register for non-trapping math. */
5250 else if (SSE_REG_P (op1) && !flag_trapping_math)
5251 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5255 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5260 [(set (match_operand:MODEF 0 "register_operand" "")
5261 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5262 "TARGET_SSE2 && TARGET_SSE_MATH
5263 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5265 && (SSE_REG_P (operands[0])
5266 || (GET_CODE (operands[0]) == SUBREG
5267 && SSE_REG_P (operands[0])))"
5270 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5272 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5274 emit_insn (gen_sse2_loadld (operands[4],
5275 CONST0_RTX (V4SImode), operands[1]));
5277 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5281 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5282 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5284 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5285 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5286 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5287 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5289 [(set_attr "type" "sseicvt")
5290 (set_attr "mode" "<MODEF:MODE>")
5291 (set_attr "athlon_decode" "double,direct")
5292 (set_attr "amdfam10_decode" "vector,double")
5293 (set_attr "bdver1_decode" "double,direct")
5294 (set_attr "fp_int_src" "true")])
5296 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5297 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5299 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5300 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5301 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5302 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5303 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5304 [(set_attr "type" "sseicvt")
5305 (set_attr "prefix" "maybe_vex")
5306 (set_attr "mode" "<MODEF:MODE>")
5307 (set (attr "prefix_rex")
5309 (and (eq_attr "prefix" "maybe_vex")
5310 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5312 (const_string "*")))
5313 (set_attr "athlon_decode" "double,direct")
5314 (set_attr "amdfam10_decode" "vector,double")
5315 (set_attr "bdver1_decode" "double,direct")
5316 (set_attr "fp_int_src" "true")])
5319 [(set (match_operand:MODEF 0 "register_operand" "")
5320 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5321 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5322 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5323 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5324 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5326 && (SSE_REG_P (operands[0])
5327 || (GET_CODE (operands[0]) == SUBREG
5328 && SSE_REG_P (operands[0])))"
5329 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5331 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5332 [(set (match_operand:MODEF 0 "register_operand" "=x")
5334 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5335 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5336 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5337 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5338 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5339 [(set_attr "type" "sseicvt")
5340 (set_attr "prefix" "maybe_vex")
5341 (set_attr "mode" "<MODEF:MODE>")
5342 (set (attr "prefix_rex")
5344 (and (eq_attr "prefix" "maybe_vex")
5345 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5347 (const_string "*")))
5348 (set_attr "athlon_decode" "direct")
5349 (set_attr "amdfam10_decode" "double")
5350 (set_attr "bdver1_decode" "direct")
5351 (set_attr "fp_int_src" "true")])
5354 [(set (match_operand:MODEF 0 "register_operand" "")
5355 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5356 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5357 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5358 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5359 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5361 && (SSE_REG_P (operands[0])
5362 || (GET_CODE (operands[0]) == SUBREG
5363 && SSE_REG_P (operands[0])))"
5364 [(set (match_dup 2) (match_dup 1))
5365 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5368 [(set (match_operand:MODEF 0 "register_operand" "")
5369 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5370 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5371 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5372 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5374 && (SSE_REG_P (operands[0])
5375 || (GET_CODE (operands[0]) == SUBREG
5376 && SSE_REG_P (operands[0])))"
5377 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5379 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5380 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5382 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5383 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5385 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5389 [(set_attr "type" "fmov,multi")
5390 (set_attr "mode" "<X87MODEF:MODE>")
5391 (set_attr "unit" "*,i387")
5392 (set_attr "fp_int_src" "true")])
5394 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5395 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5397 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5399 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5401 [(set_attr "type" "fmov")
5402 (set_attr "mode" "<X87MODEF:MODE>")
5403 (set_attr "fp_int_src" "true")])
5406 [(set (match_operand:X87MODEF 0 "register_operand" "")
5407 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5408 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5410 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5412 && FP_REG_P (operands[0])"
5413 [(set (match_dup 2) (match_dup 1))
5414 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5417 [(set (match_operand:X87MODEF 0 "register_operand" "")
5418 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5419 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5421 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5423 && FP_REG_P (operands[0])"
5424 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5426 ;; Avoid store forwarding (partial memory) stall penalty
5427 ;; by passing DImode value through XMM registers. */
5429 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5430 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5432 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5433 (clobber (match_scratch:V4SI 3 "=X,x"))
5434 (clobber (match_scratch:V4SI 4 "=X,x"))
5435 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5436 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5437 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5438 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5440 [(set_attr "type" "multi")
5441 (set_attr "mode" "<X87MODEF:MODE>")
5442 (set_attr "unit" "i387")
5443 (set_attr "fp_int_src" "true")])
5446 [(set (match_operand:X87MODEF 0 "register_operand" "")
5447 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5448 (clobber (match_scratch:V4SI 3 ""))
5449 (clobber (match_scratch:V4SI 4 ""))
5450 (clobber (match_operand:DI 2 "memory_operand" ""))]
5451 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5452 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5453 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5455 && FP_REG_P (operands[0])"
5456 [(set (match_dup 2) (match_dup 3))
5457 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5459 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5460 Assemble the 64-bit DImode value in an xmm register. */
5461 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5462 gen_rtx_SUBREG (SImode, operands[1], 0)));
5463 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5464 gen_rtx_SUBREG (SImode, operands[1], 4)));
5465 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5468 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5472 [(set (match_operand:X87MODEF 0 "register_operand" "")
5473 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5474 (clobber (match_scratch:V4SI 3 ""))
5475 (clobber (match_scratch:V4SI 4 ""))
5476 (clobber (match_operand:DI 2 "memory_operand" ""))]
5477 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5478 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5479 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5481 && FP_REG_P (operands[0])"
5482 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5484 ;; Avoid store forwarding (partial memory) stall penalty by extending
5485 ;; SImode value to DImode through XMM register instead of pushing two
5486 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5487 ;; targets benefit from this optimization. Also note that fild
5488 ;; loads from memory only.
5490 (define_insn "*floatunssi<mode>2_1"
5491 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5492 (unsigned_float:X87MODEF
5493 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5494 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5495 (clobber (match_scratch:SI 3 "=X,x"))]
5497 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5500 [(set_attr "type" "multi")
5501 (set_attr "mode" "<MODE>")])
5504 [(set (match_operand:X87MODEF 0 "register_operand" "")
5505 (unsigned_float:X87MODEF
5506 (match_operand:SI 1 "register_operand" "")))
5507 (clobber (match_operand:DI 2 "memory_operand" ""))
5508 (clobber (match_scratch:SI 3 ""))]
5510 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5512 && reload_completed"
5513 [(set (match_dup 2) (match_dup 1))
5515 (float:X87MODEF (match_dup 2)))]
5516 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5519 [(set (match_operand:X87MODEF 0 "register_operand" "")
5520 (unsigned_float:X87MODEF
5521 (match_operand:SI 1 "memory_operand" "")))
5522 (clobber (match_operand:DI 2 "memory_operand" ""))
5523 (clobber (match_scratch:SI 3 ""))]
5525 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5527 && reload_completed"
5528 [(set (match_dup 2) (match_dup 3))
5530 (float:X87MODEF (match_dup 2)))]
5532 emit_move_insn (operands[3], operands[1]);
5533 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5536 (define_expand "floatunssi<mode>2"
5538 [(set (match_operand:X87MODEF 0 "register_operand" "")
5539 (unsigned_float:X87MODEF
5540 (match_operand:SI 1 "nonimmediate_operand" "")))
5541 (clobber (match_dup 2))
5542 (clobber (match_scratch:SI 3 ""))])]
5544 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5546 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5548 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5550 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5555 enum ix86_stack_slot slot = (virtuals_instantiated
5558 operands[2] = assign_386_stack_local (DImode, slot);
5562 (define_expand "floatunsdisf2"
5563 [(use (match_operand:SF 0 "register_operand" ""))
5564 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5565 "TARGET_64BIT && TARGET_SSE_MATH"
5566 "x86_emit_floatuns (operands); DONE;")
5568 (define_expand "floatunsdidf2"
5569 [(use (match_operand:DF 0 "register_operand" ""))
5570 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5571 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5572 && TARGET_SSE2 && TARGET_SSE_MATH"
5575 x86_emit_floatuns (operands);
5577 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5583 (define_expand "add<mode>3"
5584 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5585 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5586 (match_operand:SDWIM 2 "<general_operand>" "")))]
5588 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5590 (define_insn_and_split "*add<dwi>3_doubleword"
5591 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5593 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5594 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5595 (clobber (reg:CC FLAGS_REG))]
5596 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5599 [(parallel [(set (reg:CC FLAGS_REG)
5600 (unspec:CC [(match_dup 1) (match_dup 2)]
5603 (plus:DWIH (match_dup 1) (match_dup 2)))])
5604 (parallel [(set (match_dup 3)
5608 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5610 (clobber (reg:CC FLAGS_REG))])]
5611 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5613 (define_insn "*add<mode>3_cc"
5614 [(set (reg:CC FLAGS_REG)
5616 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5617 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5619 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5620 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5621 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5622 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5623 [(set_attr "type" "alu")
5624 (set_attr "mode" "<MODE>")])
5626 (define_insn "addqi3_cc"
5627 [(set (reg:CC FLAGS_REG)
5629 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5630 (match_operand:QI 2 "general_operand" "qn,qm")]
5632 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5633 (plus:QI (match_dup 1) (match_dup 2)))]
5634 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5635 "add{b}\t{%2, %0|%0, %2}"
5636 [(set_attr "type" "alu")
5637 (set_attr "mode" "QI")])
5639 (define_insn "*lea_1"
5640 [(set (match_operand:P 0 "register_operand" "=r")
5641 (match_operand:P 1 "no_seg_address_operand" "p"))]
5643 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5644 [(set_attr "type" "lea")
5645 (set_attr "mode" "<MODE>")])
5647 (define_insn "*lea_2"
5648 [(set (match_operand:SI 0 "register_operand" "=r")
5649 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5651 "lea{l}\t{%a1, %0|%0, %a1}"
5652 [(set_attr "type" "lea")
5653 (set_attr "mode" "SI")])
5655 (define_insn "*lea_2_zext"
5656 [(set (match_operand:DI 0 "register_operand" "=r")
5658 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5660 "lea{l}\t{%a1, %k0|%k0, %a1}"
5661 [(set_attr "type" "lea")
5662 (set_attr "mode" "SI")])
5664 (define_insn "*add<mode>_1"
5665 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5667 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5668 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5669 (clobber (reg:CC FLAGS_REG))]
5670 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5672 switch (get_attr_type (insn))
5678 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5679 if (operands[2] == const1_rtx)
5680 return "inc{<imodesuffix>}\t%0";
5683 gcc_assert (operands[2] == constm1_rtx);
5684 return "dec{<imodesuffix>}\t%0";
5688 /* For most processors, ADD is faster than LEA. This alternative
5689 was added to use ADD as much as possible. */
5690 if (which_alternative == 2)
5693 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5696 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5697 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5698 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5700 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5704 (cond [(eq_attr "alternative" "3")
5705 (const_string "lea")
5706 (match_operand:SWI48 2 "incdec_operand" "")
5707 (const_string "incdec")
5709 (const_string "alu")))
5710 (set (attr "length_immediate")
5712 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5714 (const_string "*")))
5715 (set_attr "mode" "<MODE>")])
5717 ;; It may seem that nonimmediate operand is proper one for operand 1.
5718 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5719 ;; we take care in ix86_binary_operator_ok to not allow two memory
5720 ;; operands so proper swapping will be done in reload. This allow
5721 ;; patterns constructed from addsi_1 to match.
5723 (define_insn "*addsi_1_zext"
5724 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5726 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5727 (match_operand:SI 2 "general_operand" "g,0,li"))))
5728 (clobber (reg:CC FLAGS_REG))]
5729 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5731 switch (get_attr_type (insn))
5737 if (operands[2] == const1_rtx)
5738 return "inc{l}\t%k0";
5741 gcc_assert (operands[2] == constm1_rtx);
5742 return "dec{l}\t%k0";
5746 /* For most processors, ADD is faster than LEA. This alternative
5747 was added to use ADD as much as possible. */
5748 if (which_alternative == 1)
5751 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5754 if (x86_maybe_negate_const_int (&operands[2], SImode))
5755 return "sub{l}\t{%2, %k0|%k0, %2}";
5757 return "add{l}\t{%2, %k0|%k0, %2}";
5761 (cond [(eq_attr "alternative" "2")
5762 (const_string "lea")
5763 (match_operand:SI 2 "incdec_operand" "")
5764 (const_string "incdec")
5766 (const_string "alu")))
5767 (set (attr "length_immediate")
5769 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5771 (const_string "*")))
5772 (set_attr "mode" "SI")])
5774 (define_insn "*addhi_1"
5775 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5776 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5777 (match_operand:HI 2 "general_operand" "rn,rm")))
5778 (clobber (reg:CC FLAGS_REG))]
5779 "TARGET_PARTIAL_REG_STALL
5780 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5782 switch (get_attr_type (insn))
5785 if (operands[2] == const1_rtx)
5786 return "inc{w}\t%0";
5789 gcc_assert (operands[2] == constm1_rtx);
5790 return "dec{w}\t%0";
5794 if (x86_maybe_negate_const_int (&operands[2], HImode))
5795 return "sub{w}\t{%2, %0|%0, %2}";
5797 return "add{w}\t{%2, %0|%0, %2}";
5801 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5802 (const_string "incdec")
5803 (const_string "alu")))
5804 (set (attr "length_immediate")
5806 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5808 (const_string "*")))
5809 (set_attr "mode" "HI")])
5811 (define_insn "*addhi_1_lea"
5812 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5813 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5814 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5815 (clobber (reg:CC FLAGS_REG))]
5816 "!TARGET_PARTIAL_REG_STALL
5817 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5819 switch (get_attr_type (insn))
5825 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5826 if (operands[2] == const1_rtx)
5827 return "inc{w}\t%0";
5830 gcc_assert (operands[2] == constm1_rtx);
5831 return "dec{w}\t%0";
5835 /* For most processors, ADD is faster than LEA. This alternative
5836 was added to use ADD as much as possible. */
5837 if (which_alternative == 2)
5840 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5843 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5844 if (x86_maybe_negate_const_int (&operands[2], HImode))
5845 return "sub{w}\t{%2, %0|%0, %2}";
5847 return "add{w}\t{%2, %0|%0, %2}";
5851 (cond [(eq_attr "alternative" "3")
5852 (const_string "lea")
5853 (match_operand:HI 2 "incdec_operand" "")
5854 (const_string "incdec")
5856 (const_string "alu")))
5857 (set (attr "length_immediate")
5859 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5861 (const_string "*")))
5862 (set_attr "mode" "HI,HI,HI,SI")])
5864 ;; %%% Potential partial reg stall on alternative 2. What to do?
5865 (define_insn "*addqi_1"
5866 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5867 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5868 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5869 (clobber (reg:CC FLAGS_REG))]
5870 "TARGET_PARTIAL_REG_STALL
5871 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5873 int widen = (which_alternative == 2);
5874 switch (get_attr_type (insn))
5877 if (operands[2] == const1_rtx)
5878 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5881 gcc_assert (operands[2] == constm1_rtx);
5882 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5886 if (x86_maybe_negate_const_int (&operands[2], QImode))
5889 return "sub{l}\t{%2, %k0|%k0, %2}";
5891 return "sub{b}\t{%2, %0|%0, %2}";
5894 return "add{l}\t{%k2, %k0|%k0, %k2}";
5896 return "add{b}\t{%2, %0|%0, %2}";
5900 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5901 (const_string "incdec")
5902 (const_string "alu")))
5903 (set (attr "length_immediate")
5905 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5907 (const_string "*")))
5908 (set_attr "mode" "QI,QI,SI")])
5910 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5911 (define_insn "*addqi_1_lea"
5912 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5913 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5914 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5915 (clobber (reg:CC FLAGS_REG))]
5916 "!TARGET_PARTIAL_REG_STALL
5917 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5919 int widen = (which_alternative == 3 || which_alternative == 4);
5921 switch (get_attr_type (insn))
5927 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5928 if (operands[2] == const1_rtx)
5929 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5932 gcc_assert (operands[2] == constm1_rtx);
5933 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5937 /* For most processors, ADD is faster than LEA. These alternatives
5938 were added to use ADD as much as possible. */
5939 if (which_alternative == 2 || which_alternative == 4)
5942 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5945 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5946 if (x86_maybe_negate_const_int (&operands[2], QImode))
5949 return "sub{l}\t{%2, %k0|%k0, %2}";
5951 return "sub{b}\t{%2, %0|%0, %2}";
5954 return "add{l}\t{%k2, %k0|%k0, %k2}";
5956 return "add{b}\t{%2, %0|%0, %2}";
5960 (cond [(eq_attr "alternative" "5")
5961 (const_string "lea")
5962 (match_operand:QI 2 "incdec_operand" "")
5963 (const_string "incdec")
5965 (const_string "alu")))
5966 (set (attr "length_immediate")
5968 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5970 (const_string "*")))
5971 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5973 (define_insn "*addqi_1_slp"
5974 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5975 (plus:QI (match_dup 0)
5976 (match_operand:QI 1 "general_operand" "qn,qnm")))
5977 (clobber (reg:CC FLAGS_REG))]
5978 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5979 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5981 switch (get_attr_type (insn))
5984 if (operands[1] == const1_rtx)
5985 return "inc{b}\t%0";
5988 gcc_assert (operands[1] == constm1_rtx);
5989 return "dec{b}\t%0";
5993 if (x86_maybe_negate_const_int (&operands[1], QImode))
5994 return "sub{b}\t{%1, %0|%0, %1}";
5996 return "add{b}\t{%1, %0|%0, %1}";
6000 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6001 (const_string "incdec")
6002 (const_string "alu1")))
6003 (set (attr "memory")
6004 (if_then_else (match_operand 1 "memory_operand" "")
6005 (const_string "load")
6006 (const_string "none")))
6007 (set_attr "mode" "QI")])
6009 ;; Convert lea to the lea pattern to avoid flags dependency.
6011 [(set (match_operand 0 "register_operand" "")
6012 (plus (match_operand 1 "register_operand" "")
6013 (match_operand 2 "nonmemory_operand" "")))
6014 (clobber (reg:CC FLAGS_REG))]
6015 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6019 enum machine_mode mode = GET_MODE (operands[0]);
6021 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6022 may confuse gen_lowpart. */
6025 operands[1] = gen_lowpart (Pmode, operands[1]);
6026 operands[2] = gen_lowpart (Pmode, operands[2]);
6029 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6031 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6032 operands[0] = gen_lowpart (SImode, operands[0]);
6034 if (TARGET_64BIT && mode != Pmode)
6035 pat = gen_rtx_SUBREG (SImode, pat, 0);
6037 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6041 ;; Convert lea to the lea pattern to avoid flags dependency.
6042 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6043 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6045 [(set (match_operand:DI 0 "register_operand" "")
6046 (plus:DI (match_operand:DI 1 "register_operand" "")
6047 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6048 (clobber (reg:CC FLAGS_REG))]
6049 "TARGET_64BIT && reload_completed
6050 && true_regnum (operands[0]) != true_regnum (operands[1])"
6052 (plus:DI (match_dup 1) (match_dup 2)))])
6054 ;; Convert lea to the lea pattern to avoid flags dependency.
6056 [(set (match_operand:DI 0 "register_operand" "")
6058 (plus:SI (match_operand:SI 1 "register_operand" "")
6059 (match_operand:SI 2 "nonmemory_operand" ""))))
6060 (clobber (reg:CC FLAGS_REG))]
6061 "TARGET_64BIT && reload_completed
6062 && ix86_lea_for_add_ok (insn, operands)"
6064 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6066 operands[1] = gen_lowpart (DImode, operands[1]);
6067 operands[2] = gen_lowpart (DImode, operands[2]);
6070 (define_insn "*add<mode>_2"
6071 [(set (reg FLAGS_REG)
6074 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6075 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6077 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6078 (plus:SWI (match_dup 1) (match_dup 2)))]
6079 "ix86_match_ccmode (insn, CCGOCmode)
6080 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6082 switch (get_attr_type (insn))
6085 if (operands[2] == const1_rtx)
6086 return "inc{<imodesuffix>}\t%0";
6089 gcc_assert (operands[2] == constm1_rtx);
6090 return "dec{<imodesuffix>}\t%0";
6094 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6095 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6097 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6101 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6102 (const_string "incdec")
6103 (const_string "alu")))
6104 (set (attr "length_immediate")
6106 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6108 (const_string "*")))
6109 (set_attr "mode" "<MODE>")])
6111 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6112 (define_insn "*addsi_2_zext"
6113 [(set (reg FLAGS_REG)
6115 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6116 (match_operand:SI 2 "general_operand" "g"))
6118 (set (match_operand:DI 0 "register_operand" "=r")
6119 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6120 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6121 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6123 switch (get_attr_type (insn))
6126 if (operands[2] == const1_rtx)
6127 return "inc{l}\t%k0";
6130 gcc_assert (operands[2] == constm1_rtx);
6131 return "dec{l}\t%k0";
6135 if (x86_maybe_negate_const_int (&operands[2], SImode))
6136 return "sub{l}\t{%2, %k0|%k0, %2}";
6138 return "add{l}\t{%2, %k0|%k0, %2}";
6142 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6143 (const_string "incdec")
6144 (const_string "alu")))
6145 (set (attr "length_immediate")
6147 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6149 (const_string "*")))
6150 (set_attr "mode" "SI")])
6152 (define_insn "*add<mode>_3"
6153 [(set (reg FLAGS_REG)
6155 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6156 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6157 (clobber (match_scratch:SWI 0 "=<r>"))]
6158 "ix86_match_ccmode (insn, CCZmode)
6159 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6161 switch (get_attr_type (insn))
6164 if (operands[2] == const1_rtx)
6165 return "inc{<imodesuffix>}\t%0";
6168 gcc_assert (operands[2] == constm1_rtx);
6169 return "dec{<imodesuffix>}\t%0";
6173 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6174 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6176 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6180 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6181 (const_string "incdec")
6182 (const_string "alu")))
6183 (set (attr "length_immediate")
6185 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6187 (const_string "*")))
6188 (set_attr "mode" "<MODE>")])
6190 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6191 (define_insn "*addsi_3_zext"
6192 [(set (reg FLAGS_REG)
6194 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6195 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6196 (set (match_operand:DI 0 "register_operand" "=r")
6197 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6198 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6199 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6201 switch (get_attr_type (insn))
6204 if (operands[2] == const1_rtx)
6205 return "inc{l}\t%k0";
6208 gcc_assert (operands[2] == constm1_rtx);
6209 return "dec{l}\t%k0";
6213 if (x86_maybe_negate_const_int (&operands[2], SImode))
6214 return "sub{l}\t{%2, %k0|%k0, %2}";
6216 return "add{l}\t{%2, %k0|%k0, %2}";
6220 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6221 (const_string "incdec")
6222 (const_string "alu")))
6223 (set (attr "length_immediate")
6225 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6227 (const_string "*")))
6228 (set_attr "mode" "SI")])
6230 ; For comparisons against 1, -1 and 128, we may generate better code
6231 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6232 ; is matched then. We can't accept general immediate, because for
6233 ; case of overflows, the result is messed up.
6234 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6235 ; only for comparisons not depending on it.
6237 (define_insn "*adddi_4"
6238 [(set (reg FLAGS_REG)
6240 (match_operand:DI 1 "nonimmediate_operand" "0")
6241 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6242 (clobber (match_scratch:DI 0 "=rm"))]
6244 && ix86_match_ccmode (insn, CCGCmode)"
6246 switch (get_attr_type (insn))
6249 if (operands[2] == constm1_rtx)
6250 return "inc{q}\t%0";
6253 gcc_assert (operands[2] == const1_rtx);
6254 return "dec{q}\t%0";
6258 if (x86_maybe_negate_const_int (&operands[2], DImode))
6259 return "add{q}\t{%2, %0|%0, %2}";
6261 return "sub{q}\t{%2, %0|%0, %2}";
6265 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6266 (const_string "incdec")
6267 (const_string "alu")))
6268 (set (attr "length_immediate")
6270 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6272 (const_string "*")))
6273 (set_attr "mode" "DI")])
6275 ; For comparisons against 1, -1 and 128, we may generate better code
6276 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6277 ; is matched then. We can't accept general immediate, because for
6278 ; case of overflows, the result is messed up.
6279 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6280 ; only for comparisons not depending on it.
6282 (define_insn "*add<mode>_4"
6283 [(set (reg FLAGS_REG)
6285 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6286 (match_operand:SWI124 2 "const_int_operand" "n")))
6287 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6288 "ix86_match_ccmode (insn, CCGCmode)"
6290 switch (get_attr_type (insn))
6293 if (operands[2] == constm1_rtx)
6294 return "inc{<imodesuffix>}\t%0";
6297 gcc_assert (operands[2] == const1_rtx);
6298 return "dec{<imodesuffix>}\t%0";
6302 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6303 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6305 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6309 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6310 (const_string "incdec")
6311 (const_string "alu")))
6312 (set (attr "length_immediate")
6314 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6316 (const_string "*")))
6317 (set_attr "mode" "<MODE>")])
6319 (define_insn "*add<mode>_5"
6320 [(set (reg FLAGS_REG)
6323 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6324 (match_operand:SWI 2 "<general_operand>" "<g>"))
6326 (clobber (match_scratch:SWI 0 "=<r>"))]
6327 "ix86_match_ccmode (insn, CCGOCmode)
6328 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6330 switch (get_attr_type (insn))
6333 if (operands[2] == const1_rtx)
6334 return "inc{<imodesuffix>}\t%0";
6337 gcc_assert (operands[2] == constm1_rtx);
6338 return "dec{<imodesuffix>}\t%0";
6342 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6343 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6345 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6349 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6350 (const_string "incdec")
6351 (const_string "alu")))
6352 (set (attr "length_immediate")
6354 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6356 (const_string "*")))
6357 (set_attr "mode" "<MODE>")])
6359 (define_insn "*addqi_ext_1_rex64"
6360 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6365 (match_operand 1 "ext_register_operand" "0")
6368 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6369 (clobber (reg:CC FLAGS_REG))]
6372 switch (get_attr_type (insn))
6375 if (operands[2] == const1_rtx)
6376 return "inc{b}\t%h0";
6379 gcc_assert (operands[2] == constm1_rtx);
6380 return "dec{b}\t%h0";
6384 return "add{b}\t{%2, %h0|%h0, %2}";
6388 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6389 (const_string "incdec")
6390 (const_string "alu")))
6391 (set_attr "modrm" "1")
6392 (set_attr "mode" "QI")])
6394 (define_insn "addqi_ext_1"
6395 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6400 (match_operand 1 "ext_register_operand" "0")
6403 (match_operand:QI 2 "general_operand" "Qmn")))
6404 (clobber (reg:CC FLAGS_REG))]
6407 switch (get_attr_type (insn))
6410 if (operands[2] == const1_rtx)
6411 return "inc{b}\t%h0";
6414 gcc_assert (operands[2] == constm1_rtx);
6415 return "dec{b}\t%h0";
6419 return "add{b}\t{%2, %h0|%h0, %2}";
6423 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6424 (const_string "incdec")
6425 (const_string "alu")))
6426 (set_attr "modrm" "1")
6427 (set_attr "mode" "QI")])
6429 (define_insn "*addqi_ext_2"
6430 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6435 (match_operand 1 "ext_register_operand" "%0")
6439 (match_operand 2 "ext_register_operand" "Q")
6442 (clobber (reg:CC FLAGS_REG))]
6444 "add{b}\t{%h2, %h0|%h0, %h2}"
6445 [(set_attr "type" "alu")
6446 (set_attr "mode" "QI")])
6448 ;; The lea patterns for non-Pmodes needs to be matched by
6449 ;; several insns converted to real lea by splitters.
6451 (define_insn_and_split "*lea_general_1"
6452 [(set (match_operand 0 "register_operand" "=r")
6453 (plus (plus (match_operand 1 "index_register_operand" "l")
6454 (match_operand 2 "register_operand" "r"))
6455 (match_operand 3 "immediate_operand" "i")))]
6456 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6457 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6458 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6459 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6460 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6461 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6462 || GET_MODE (operands[3]) == VOIDmode)"
6464 "&& reload_completed"
6468 operands[0] = gen_lowpart (SImode, operands[0]);
6469 operands[1] = gen_lowpart (Pmode, operands[1]);
6470 operands[2] = gen_lowpart (Pmode, operands[2]);
6471 operands[3] = gen_lowpart (Pmode, operands[3]);
6472 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6474 if (Pmode != SImode)
6475 pat = gen_rtx_SUBREG (SImode, pat, 0);
6476 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6479 [(set_attr "type" "lea")
6480 (set_attr "mode" "SI")])
6482 (define_insn_and_split "*lea_general_1_zext"
6483 [(set (match_operand:DI 0 "register_operand" "=r")
6486 (match_operand:SI 1 "index_register_operand" "l")
6487 (match_operand:SI 2 "register_operand" "r"))
6488 (match_operand:SI 3 "immediate_operand" "i"))))]
6491 "&& reload_completed"
6493 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6495 (match_dup 3)) 0)))]
6497 operands[1] = gen_lowpart (Pmode, operands[1]);
6498 operands[2] = gen_lowpart (Pmode, operands[2]);
6499 operands[3] = gen_lowpart (Pmode, operands[3]);
6501 [(set_attr "type" "lea")
6502 (set_attr "mode" "SI")])
6504 (define_insn_and_split "*lea_general_2"
6505 [(set (match_operand 0 "register_operand" "=r")
6506 (plus (mult (match_operand 1 "index_register_operand" "l")
6507 (match_operand 2 "const248_operand" "i"))
6508 (match_operand 3 "nonmemory_operand" "ri")))]
6509 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6510 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6511 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6512 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6513 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6514 || GET_MODE (operands[3]) == VOIDmode)"
6516 "&& reload_completed"
6520 operands[0] = gen_lowpart (SImode, operands[0]);
6521 operands[1] = gen_lowpart (Pmode, operands[1]);
6522 operands[3] = gen_lowpart (Pmode, operands[3]);
6523 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6525 if (Pmode != SImode)
6526 pat = gen_rtx_SUBREG (SImode, pat, 0);
6527 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6530 [(set_attr "type" "lea")
6531 (set_attr "mode" "SI")])
6533 (define_insn_and_split "*lea_general_2_zext"
6534 [(set (match_operand:DI 0 "register_operand" "=r")
6537 (match_operand:SI 1 "index_register_operand" "l")
6538 (match_operand:SI 2 "const248_operand" "n"))
6539 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6542 "&& reload_completed"
6544 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6546 (match_dup 3)) 0)))]
6548 operands[1] = gen_lowpart (Pmode, operands[1]);
6549 operands[3] = gen_lowpart (Pmode, operands[3]);
6551 [(set_attr "type" "lea")
6552 (set_attr "mode" "SI")])
6554 (define_insn_and_split "*lea_general_3"
6555 [(set (match_operand 0 "register_operand" "=r")
6556 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6557 (match_operand 2 "const248_operand" "i"))
6558 (match_operand 3 "register_operand" "r"))
6559 (match_operand 4 "immediate_operand" "i")))]
6560 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6561 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6562 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6563 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6564 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6566 "&& reload_completed"
6570 operands[0] = gen_lowpart (SImode, operands[0]);
6571 operands[1] = gen_lowpart (Pmode, operands[1]);
6572 operands[3] = gen_lowpart (Pmode, operands[3]);
6573 operands[4] = gen_lowpart (Pmode, operands[4]);
6574 pat = gen_rtx_PLUS (Pmode,
6575 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6579 if (Pmode != SImode)
6580 pat = gen_rtx_SUBREG (SImode, pat, 0);
6581 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6584 [(set_attr "type" "lea")
6585 (set_attr "mode" "SI")])
6587 (define_insn_and_split "*lea_general_3_zext"
6588 [(set (match_operand:DI 0 "register_operand" "=r")
6592 (match_operand:SI 1 "index_register_operand" "l")
6593 (match_operand:SI 2 "const248_operand" "n"))
6594 (match_operand:SI 3 "register_operand" "r"))
6595 (match_operand:SI 4 "immediate_operand" "i"))))]
6598 "&& reload_completed"
6600 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6603 (match_dup 4)) 0)))]
6605 operands[1] = gen_lowpart (Pmode, operands[1]);
6606 operands[3] = gen_lowpart (Pmode, operands[3]);
6607 operands[4] = gen_lowpart (Pmode, operands[4]);
6609 [(set_attr "type" "lea")
6610 (set_attr "mode" "SI")])
6612 ;; Subtract instructions
6614 (define_expand "sub<mode>3"
6615 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6616 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6617 (match_operand:SDWIM 2 "<general_operand>" "")))]
6619 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6621 (define_insn_and_split "*sub<dwi>3_doubleword"
6622 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6624 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6625 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6626 (clobber (reg:CC FLAGS_REG))]
6627 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6630 [(parallel [(set (reg:CC FLAGS_REG)
6631 (compare:CC (match_dup 1) (match_dup 2)))
6633 (minus:DWIH (match_dup 1) (match_dup 2)))])
6634 (parallel [(set (match_dup 3)
6638 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6640 (clobber (reg:CC FLAGS_REG))])]
6641 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6643 (define_insn "*sub<mode>_1"
6644 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6646 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6647 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6648 (clobber (reg:CC FLAGS_REG))]
6649 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6650 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6651 [(set_attr "type" "alu")
6652 (set_attr "mode" "<MODE>")])
6654 (define_insn "*subsi_1_zext"
6655 [(set (match_operand:DI 0 "register_operand" "=r")
6657 (minus:SI (match_operand:SI 1 "register_operand" "0")
6658 (match_operand:SI 2 "general_operand" "g"))))
6659 (clobber (reg:CC FLAGS_REG))]
6660 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6661 "sub{l}\t{%2, %k0|%k0, %2}"
6662 [(set_attr "type" "alu")
6663 (set_attr "mode" "SI")])
6665 (define_insn "*subqi_1_slp"
6666 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6667 (minus:QI (match_dup 0)
6668 (match_operand:QI 1 "general_operand" "qn,qm")))
6669 (clobber (reg:CC FLAGS_REG))]
6670 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6671 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6672 "sub{b}\t{%1, %0|%0, %1}"
6673 [(set_attr "type" "alu1")
6674 (set_attr "mode" "QI")])
6676 (define_insn "*sub<mode>_2"
6677 [(set (reg FLAGS_REG)
6680 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6681 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6683 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6684 (minus:SWI (match_dup 1) (match_dup 2)))]
6685 "ix86_match_ccmode (insn, CCGOCmode)
6686 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6687 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6688 [(set_attr "type" "alu")
6689 (set_attr "mode" "<MODE>")])
6691 (define_insn "*subsi_2_zext"
6692 [(set (reg FLAGS_REG)
6694 (minus:SI (match_operand:SI 1 "register_operand" "0")
6695 (match_operand:SI 2 "general_operand" "g"))
6697 (set (match_operand:DI 0 "register_operand" "=r")
6699 (minus:SI (match_dup 1)
6701 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6702 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6703 "sub{l}\t{%2, %k0|%k0, %2}"
6704 [(set_attr "type" "alu")
6705 (set_attr "mode" "SI")])
6707 (define_insn "*sub<mode>_3"
6708 [(set (reg FLAGS_REG)
6709 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6710 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6711 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6712 (minus:SWI (match_dup 1) (match_dup 2)))]
6713 "ix86_match_ccmode (insn, CCmode)
6714 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6715 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6716 [(set_attr "type" "alu")
6717 (set_attr "mode" "<MODE>")])
6719 (define_insn "*subsi_3_zext"
6720 [(set (reg FLAGS_REG)
6721 (compare (match_operand:SI 1 "register_operand" "0")
6722 (match_operand:SI 2 "general_operand" "g")))
6723 (set (match_operand:DI 0 "register_operand" "=r")
6725 (minus:SI (match_dup 1)
6727 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6728 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6729 "sub{l}\t{%2, %1|%1, %2}"
6730 [(set_attr "type" "alu")
6731 (set_attr "mode" "SI")])
6733 ;; Add with carry and subtract with borrow
6735 (define_expand "<plusminus_insn><mode>3_carry"
6737 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6739 (match_operand:SWI 1 "nonimmediate_operand" "")
6740 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6741 [(match_operand 3 "flags_reg_operand" "")
6743 (match_operand:SWI 2 "<general_operand>" ""))))
6744 (clobber (reg:CC FLAGS_REG))])]
6745 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6747 (define_insn "*<plusminus_insn><mode>3_carry"
6748 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6750 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6752 (match_operator 3 "ix86_carry_flag_operator"
6753 [(reg FLAGS_REG) (const_int 0)])
6754 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6755 (clobber (reg:CC FLAGS_REG))]
6756 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6757 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6758 [(set_attr "type" "alu")
6759 (set_attr "use_carry" "1")
6760 (set_attr "pent_pair" "pu")
6761 (set_attr "mode" "<MODE>")])
6763 (define_insn "*addsi3_carry_zext"
6764 [(set (match_operand:DI 0 "register_operand" "=r")
6766 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6767 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6768 [(reg FLAGS_REG) (const_int 0)])
6769 (match_operand:SI 2 "general_operand" "g")))))
6770 (clobber (reg:CC FLAGS_REG))]
6771 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6772 "adc{l}\t{%2, %k0|%k0, %2}"
6773 [(set_attr "type" "alu")
6774 (set_attr "use_carry" "1")
6775 (set_attr "pent_pair" "pu")
6776 (set_attr "mode" "SI")])
6778 (define_insn "*subsi3_carry_zext"
6779 [(set (match_operand:DI 0 "register_operand" "=r")
6781 (minus:SI (match_operand:SI 1 "register_operand" "0")
6782 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6783 [(reg FLAGS_REG) (const_int 0)])
6784 (match_operand:SI 2 "general_operand" "g")))))
6785 (clobber (reg:CC FLAGS_REG))]
6786 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6787 "sbb{l}\t{%2, %k0|%k0, %2}"
6788 [(set_attr "type" "alu")
6789 (set_attr "pent_pair" "pu")
6790 (set_attr "mode" "SI")])
6792 ;; Overflow setting add and subtract instructions
6794 (define_insn "*add<mode>3_cconly_overflow"
6795 [(set (reg:CCC FLAGS_REG)
6798 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6799 (match_operand:SWI 2 "<general_operand>" "<g>"))
6801 (clobber (match_scratch:SWI 0 "=<r>"))]
6802 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6803 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6804 [(set_attr "type" "alu")
6805 (set_attr "mode" "<MODE>")])
6807 (define_insn "*sub<mode>3_cconly_overflow"
6808 [(set (reg:CCC FLAGS_REG)
6811 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6812 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6815 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6816 [(set_attr "type" "icmp")
6817 (set_attr "mode" "<MODE>")])
6819 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6820 [(set (reg:CCC FLAGS_REG)
6823 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6824 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6826 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6827 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6828 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6829 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6830 [(set_attr "type" "alu")
6831 (set_attr "mode" "<MODE>")])
6833 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6834 [(set (reg:CCC FLAGS_REG)
6837 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6838 (match_operand:SI 2 "general_operand" "g"))
6840 (set (match_operand:DI 0 "register_operand" "=r")
6841 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6842 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6843 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6844 [(set_attr "type" "alu")
6845 (set_attr "mode" "SI")])
6847 ;; The patterns that match these are at the end of this file.
6849 (define_expand "<plusminus_insn>xf3"
6850 [(set (match_operand:XF 0 "register_operand" "")
6852 (match_operand:XF 1 "register_operand" "")
6853 (match_operand:XF 2 "register_operand" "")))]
6856 (define_expand "<plusminus_insn><mode>3"
6857 [(set (match_operand:MODEF 0 "register_operand" "")
6859 (match_operand:MODEF 1 "register_operand" "")
6860 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6861 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6862 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6864 ;; Multiply instructions
6866 (define_expand "mul<mode>3"
6867 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6869 (match_operand:SWIM248 1 "register_operand" "")
6870 (match_operand:SWIM248 2 "<general_operand>" "")))
6871 (clobber (reg:CC FLAGS_REG))])])
6873 (define_expand "mulqi3"
6874 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6876 (match_operand:QI 1 "register_operand" "")
6877 (match_operand:QI 2 "nonimmediate_operand" "")))
6878 (clobber (reg:CC FLAGS_REG))])]
6879 "TARGET_QIMODE_MATH")
6882 ;; IMUL reg32/64, reg32/64, imm8 Direct
6883 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6884 ;; IMUL reg32/64, reg32/64, imm32 Direct
6885 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6886 ;; IMUL reg32/64, reg32/64 Direct
6887 ;; IMUL reg32/64, mem32/64 Direct
6889 ;; On BDVER1, all above IMULs use DirectPath
6891 (define_insn "*mul<mode>3_1"
6892 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6894 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6895 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6896 (clobber (reg:CC FLAGS_REG))]
6897 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6899 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6900 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6901 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6902 [(set_attr "type" "imul")
6903 (set_attr "prefix_0f" "0,0,1")
6904 (set (attr "athlon_decode")
6905 (cond [(eq_attr "cpu" "athlon")
6906 (const_string "vector")
6907 (eq_attr "alternative" "1")
6908 (const_string "vector")
6909 (and (eq_attr "alternative" "2")
6910 (match_operand 1 "memory_operand" ""))
6911 (const_string "vector")]
6912 (const_string "direct")))
6913 (set (attr "amdfam10_decode")
6914 (cond [(and (eq_attr "alternative" "0,1")
6915 (match_operand 1 "memory_operand" ""))
6916 (const_string "vector")]
6917 (const_string "direct")))
6918 (set_attr "bdver1_decode" "direct")
6919 (set_attr "mode" "<MODE>")])
6921 (define_insn "*mulsi3_1_zext"
6922 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6924 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6925 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6926 (clobber (reg:CC FLAGS_REG))]
6928 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6930 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6931 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6932 imul{l}\t{%2, %k0|%k0, %2}"
6933 [(set_attr "type" "imul")
6934 (set_attr "prefix_0f" "0,0,1")
6935 (set (attr "athlon_decode")
6936 (cond [(eq_attr "cpu" "athlon")
6937 (const_string "vector")
6938 (eq_attr "alternative" "1")
6939 (const_string "vector")
6940 (and (eq_attr "alternative" "2")
6941 (match_operand 1 "memory_operand" ""))
6942 (const_string "vector")]
6943 (const_string "direct")))
6944 (set (attr "amdfam10_decode")
6945 (cond [(and (eq_attr "alternative" "0,1")
6946 (match_operand 1 "memory_operand" ""))
6947 (const_string "vector")]
6948 (const_string "direct")))
6949 (set_attr "bdver1_decode" "direct")
6950 (set_attr "mode" "SI")])
6953 ;; IMUL reg16, reg16, imm8 VectorPath
6954 ;; IMUL reg16, mem16, imm8 VectorPath
6955 ;; IMUL reg16, reg16, imm16 VectorPath
6956 ;; IMUL reg16, mem16, imm16 VectorPath
6957 ;; IMUL reg16, reg16 Direct
6958 ;; IMUL reg16, mem16 Direct
6960 ;; On BDVER1, all HI MULs use DoublePath
6962 (define_insn "*mulhi3_1"
6963 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6964 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6965 (match_operand:HI 2 "general_operand" "K,n,mr")))
6966 (clobber (reg:CC FLAGS_REG))]
6968 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6970 imul{w}\t{%2, %1, %0|%0, %1, %2}
6971 imul{w}\t{%2, %1, %0|%0, %1, %2}
6972 imul{w}\t{%2, %0|%0, %2}"
6973 [(set_attr "type" "imul")
6974 (set_attr "prefix_0f" "0,0,1")
6975 (set (attr "athlon_decode")
6976 (cond [(eq_attr "cpu" "athlon")
6977 (const_string "vector")
6978 (eq_attr "alternative" "1,2")
6979 (const_string "vector")]
6980 (const_string "direct")))
6981 (set (attr "amdfam10_decode")
6982 (cond [(eq_attr "alternative" "0,1")
6983 (const_string "vector")]
6984 (const_string "direct")))
6985 (set_attr "bdver1_decode" "double")
6986 (set_attr "mode" "HI")])
6988 ;;On AMDFAM10 and BDVER1
6992 (define_insn "*mulqi3_1"
6993 [(set (match_operand:QI 0 "register_operand" "=a")
6994 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6995 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6996 (clobber (reg:CC FLAGS_REG))]
6998 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7000 [(set_attr "type" "imul")
7001 (set_attr "length_immediate" "0")
7002 (set (attr "athlon_decode")
7003 (if_then_else (eq_attr "cpu" "athlon")
7004 (const_string "vector")
7005 (const_string "direct")))
7006 (set_attr "amdfam10_decode" "direct")
7007 (set_attr "bdver1_decode" "direct")
7008 (set_attr "mode" "QI")])
7010 (define_expand "<u>mul<mode><dwi>3"
7011 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7014 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7016 (match_operand:DWIH 2 "register_operand" ""))))
7017 (clobber (reg:CC FLAGS_REG))])])
7019 (define_expand "<u>mulqihi3"
7020 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7023 (match_operand:QI 1 "nonimmediate_operand" ""))
7025 (match_operand:QI 2 "register_operand" ""))))
7026 (clobber (reg:CC FLAGS_REG))])]
7027 "TARGET_QIMODE_MATH")
7029 (define_insn "*<u>mul<mode><dwi>3_1"
7030 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7033 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7035 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7036 (clobber (reg:CC FLAGS_REG))]
7037 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7038 "<sgnprefix>mul{<imodesuffix>}\t%2"
7039 [(set_attr "type" "imul")
7040 (set_attr "length_immediate" "0")
7041 (set (attr "athlon_decode")
7042 (if_then_else (eq_attr "cpu" "athlon")
7043 (const_string "vector")
7044 (const_string "double")))
7045 (set_attr "amdfam10_decode" "double")
7046 (set_attr "bdver1_decode" "direct")
7047 (set_attr "mode" "<MODE>")])
7049 (define_insn "*<u>mulqihi3_1"
7050 [(set (match_operand:HI 0 "register_operand" "=a")
7053 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7055 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7056 (clobber (reg:CC FLAGS_REG))]
7058 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7059 "<sgnprefix>mul{b}\t%2"
7060 [(set_attr "type" "imul")
7061 (set_attr "length_immediate" "0")
7062 (set (attr "athlon_decode")
7063 (if_then_else (eq_attr "cpu" "athlon")
7064 (const_string "vector")
7065 (const_string "direct")))
7066 (set_attr "amdfam10_decode" "direct")
7067 (set_attr "bdver1_decode" "direct")
7068 (set_attr "mode" "QI")])
7070 (define_expand "<s>mul<mode>3_highpart"
7071 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7076 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7078 (match_operand:SWI48 2 "register_operand" "")))
7080 (clobber (match_scratch:SWI48 3 ""))
7081 (clobber (reg:CC FLAGS_REG))])]
7083 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7085 (define_insn "*<s>muldi3_highpart_1"
7086 [(set (match_operand:DI 0 "register_operand" "=d")
7091 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7093 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7095 (clobber (match_scratch:DI 3 "=1"))
7096 (clobber (reg:CC FLAGS_REG))]
7098 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7099 "<sgnprefix>mul{q}\t%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 "double")))
7106 (set_attr "amdfam10_decode" "double")
7107 (set_attr "bdver1_decode" "direct")
7108 (set_attr "mode" "DI")])
7110 (define_insn "*<s>mulsi3_highpart_1"
7111 [(set (match_operand:SI 0 "register_operand" "=d")
7116 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7118 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7120 (clobber (match_scratch:SI 3 "=1"))
7121 (clobber (reg:CC FLAGS_REG))]
7122 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7123 "<sgnprefix>mul{l}\t%2"
7124 [(set_attr "type" "imul")
7125 (set_attr "length_immediate" "0")
7126 (set (attr "athlon_decode")
7127 (if_then_else (eq_attr "cpu" "athlon")
7128 (const_string "vector")
7129 (const_string "double")))
7130 (set_attr "amdfam10_decode" "double")
7131 (set_attr "bdver1_decode" "direct")
7132 (set_attr "mode" "SI")])
7134 (define_insn "*<s>mulsi3_highpart_zext"
7135 [(set (match_operand:DI 0 "register_operand" "=d")
7136 (zero_extend:DI (truncate:SI
7138 (mult:DI (any_extend:DI
7139 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7141 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7143 (clobber (match_scratch:SI 3 "=1"))
7144 (clobber (reg:CC FLAGS_REG))]
7146 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7147 "<sgnprefix>mul{l}\t%2"
7148 [(set_attr "type" "imul")
7149 (set_attr "length_immediate" "0")
7150 (set (attr "athlon_decode")
7151 (if_then_else (eq_attr "cpu" "athlon")
7152 (const_string "vector")
7153 (const_string "double")))
7154 (set_attr "amdfam10_decode" "double")
7155 (set_attr "bdver1_decode" "direct")
7156 (set_attr "mode" "SI")])
7158 ;; The patterns that match these are at the end of this file.
7160 (define_expand "mulxf3"
7161 [(set (match_operand:XF 0 "register_operand" "")
7162 (mult:XF (match_operand:XF 1 "register_operand" "")
7163 (match_operand:XF 2 "register_operand" "")))]
7166 (define_expand "mul<mode>3"
7167 [(set (match_operand:MODEF 0 "register_operand" "")
7168 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7169 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7170 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7171 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7173 ;; Divide instructions
7175 ;; The patterns that match these are at the end of this file.
7177 (define_expand "divxf3"
7178 [(set (match_operand:XF 0 "register_operand" "")
7179 (div:XF (match_operand:XF 1 "register_operand" "")
7180 (match_operand:XF 2 "register_operand" "")))]
7183 (define_expand "divdf3"
7184 [(set (match_operand:DF 0 "register_operand" "")
7185 (div:DF (match_operand:DF 1 "register_operand" "")
7186 (match_operand:DF 2 "nonimmediate_operand" "")))]
7187 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7188 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7190 (define_expand "divsf3"
7191 [(set (match_operand:SF 0 "register_operand" "")
7192 (div:SF (match_operand:SF 1 "register_operand" "")
7193 (match_operand:SF 2 "nonimmediate_operand" "")))]
7194 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7197 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7198 && flag_finite_math_only && !flag_trapping_math
7199 && flag_unsafe_math_optimizations)
7201 ix86_emit_swdivsf (operands[0], operands[1],
7202 operands[2], SFmode);
7207 ;; Divmod instructions.
7209 (define_expand "divmod<mode>4"
7210 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7212 (match_operand:SWIM248 1 "register_operand" "")
7213 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7214 (set (match_operand:SWIM248 3 "register_operand" "")
7215 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7216 (clobber (reg:CC FLAGS_REG))])])
7218 ;; Split with 8bit unsigned divide:
7219 ;; if (dividend an divisor are in [0-255])
7220 ;; use 8bit unsigned integer divide
7222 ;; use original integer divide
7224 [(set (match_operand:SWI48 0 "register_operand" "")
7225 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7226 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7227 (set (match_operand:SWI48 1 "register_operand" "")
7228 (mod:SWI48 (match_dup 2) (match_dup 3)))
7229 (clobber (reg:CC FLAGS_REG))]
7230 "TARGET_USE_8BIT_IDIV
7231 && TARGET_QIMODE_MATH
7232 && can_create_pseudo_p ()
7233 && !optimize_insn_for_size_p ()"
7235 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7237 (define_insn_and_split "divmod<mode>4_1"
7238 [(set (match_operand:SWI48 0 "register_operand" "=a")
7239 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7240 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7241 (set (match_operand:SWI48 1 "register_operand" "=&d")
7242 (mod:SWI48 (match_dup 2) (match_dup 3)))
7243 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7244 (clobber (reg:CC FLAGS_REG))]
7248 [(parallel [(set (match_dup 1)
7249 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7250 (clobber (reg:CC FLAGS_REG))])
7251 (parallel [(set (match_dup 0)
7252 (div:SWI48 (match_dup 2) (match_dup 3)))
7254 (mod:SWI48 (match_dup 2) (match_dup 3)))
7256 (clobber (reg:CC FLAGS_REG))])]
7258 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7260 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7261 operands[4] = operands[2];
7264 /* Avoid use of cltd in favor of a mov+shift. */
7265 emit_move_insn (operands[1], operands[2]);
7266 operands[4] = operands[1];
7269 [(set_attr "type" "multi")
7270 (set_attr "mode" "<MODE>")])
7272 (define_insn_and_split "*divmod<mode>4"
7273 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7274 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7275 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7276 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7277 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7278 (clobber (reg:CC FLAGS_REG))]
7282 [(parallel [(set (match_dup 1)
7283 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7284 (clobber (reg:CC FLAGS_REG))])
7285 (parallel [(set (match_dup 0)
7286 (div:SWIM248 (match_dup 2) (match_dup 3)))
7288 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7290 (clobber (reg:CC FLAGS_REG))])]
7292 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7294 if (<MODE>mode != HImode
7295 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7296 operands[4] = operands[2];
7299 /* Avoid use of cltd in favor of a mov+shift. */
7300 emit_move_insn (operands[1], operands[2]);
7301 operands[4] = operands[1];
7304 [(set_attr "type" "multi")
7305 (set_attr "mode" "<MODE>")])
7307 (define_insn "*divmod<mode>4_noext"
7308 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7309 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7310 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7311 (set (match_operand:SWIM248 1 "register_operand" "=d")
7312 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7313 (use (match_operand:SWIM248 4 "register_operand" "1"))
7314 (clobber (reg:CC FLAGS_REG))]
7316 "idiv{<imodesuffix>}\t%3"
7317 [(set_attr "type" "idiv")
7318 (set_attr "mode" "<MODE>")])
7320 (define_expand "divmodqi4"
7321 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7323 (match_operand:QI 1 "register_operand" "")
7324 (match_operand:QI 2 "nonimmediate_operand" "")))
7325 (set (match_operand:QI 3 "register_operand" "")
7326 (mod:QI (match_dup 1) (match_dup 2)))
7327 (clobber (reg:CC FLAGS_REG))])]
7328 "TARGET_QIMODE_MATH"
7333 tmp0 = gen_reg_rtx (HImode);
7334 tmp1 = gen_reg_rtx (HImode);
7336 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7338 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7339 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7341 /* Extract remainder from AH. */
7342 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7343 insn = emit_move_insn (operands[3], tmp1);
7345 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7346 set_unique_reg_note (insn, REG_EQUAL, mod);
7348 /* Extract quotient from AL. */
7349 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7351 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7352 set_unique_reg_note (insn, REG_EQUAL, div);
7357 ;; Divide AX by r/m8, with result stored in
7360 ;; Change div/mod to HImode and extend the second argument to HImode
7361 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7362 ;; combine may fail.
7363 (define_insn "divmodhiqi3"
7364 [(set (match_operand:HI 0 "register_operand" "=a")
7369 (mod:HI (match_operand:HI 1 "register_operand" "0")
7371 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7375 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7376 (clobber (reg:CC FLAGS_REG))]
7377 "TARGET_QIMODE_MATH"
7379 [(set_attr "type" "idiv")
7380 (set_attr "mode" "QI")])
7382 (define_expand "udivmod<mode>4"
7383 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7385 (match_operand:SWIM248 1 "register_operand" "")
7386 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7387 (set (match_operand:SWIM248 3 "register_operand" "")
7388 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7389 (clobber (reg:CC FLAGS_REG))])])
7391 ;; Split with 8bit unsigned divide:
7392 ;; if (dividend an divisor are in [0-255])
7393 ;; use 8bit unsigned integer divide
7395 ;; use original integer divide
7397 [(set (match_operand:SWI48 0 "register_operand" "")
7398 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7399 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7400 (set (match_operand:SWI48 1 "register_operand" "")
7401 (umod:SWI48 (match_dup 2) (match_dup 3)))
7402 (clobber (reg:CC FLAGS_REG))]
7403 "TARGET_USE_8BIT_IDIV
7404 && TARGET_QIMODE_MATH
7405 && can_create_pseudo_p ()
7406 && !optimize_insn_for_size_p ()"
7408 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7410 (define_insn_and_split "udivmod<mode>4_1"
7411 [(set (match_operand:SWI48 0 "register_operand" "=a")
7412 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7413 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7414 (set (match_operand:SWI48 1 "register_operand" "=&d")
7415 (umod:SWI48 (match_dup 2) (match_dup 3)))
7416 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7417 (clobber (reg:CC FLAGS_REG))]
7421 [(set (match_dup 1) (const_int 0))
7422 (parallel [(set (match_dup 0)
7423 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7425 (umod:SWI48 (match_dup 2) (match_dup 3)))
7427 (clobber (reg:CC FLAGS_REG))])]
7429 [(set_attr "type" "multi")
7430 (set_attr "mode" "<MODE>")])
7432 (define_insn_and_split "*udivmod<mode>4"
7433 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7434 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7435 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7436 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7437 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7438 (clobber (reg:CC FLAGS_REG))]
7442 [(set (match_dup 1) (const_int 0))
7443 (parallel [(set (match_dup 0)
7444 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7446 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7448 (clobber (reg:CC FLAGS_REG))])]
7450 [(set_attr "type" "multi")
7451 (set_attr "mode" "<MODE>")])
7453 (define_insn "*udivmod<mode>4_noext"
7454 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7455 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7456 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7457 (set (match_operand:SWIM248 1 "register_operand" "=d")
7458 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7459 (use (match_operand:SWIM248 4 "register_operand" "1"))
7460 (clobber (reg:CC FLAGS_REG))]
7462 "div{<imodesuffix>}\t%3"
7463 [(set_attr "type" "idiv")
7464 (set_attr "mode" "<MODE>")])
7466 (define_expand "udivmodqi4"
7467 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7469 (match_operand:QI 1 "register_operand" "")
7470 (match_operand:QI 2 "nonimmediate_operand" "")))
7471 (set (match_operand:QI 3 "register_operand" "")
7472 (umod:QI (match_dup 1) (match_dup 2)))
7473 (clobber (reg:CC FLAGS_REG))])]
7474 "TARGET_QIMODE_MATH"
7479 tmp0 = gen_reg_rtx (HImode);
7480 tmp1 = gen_reg_rtx (HImode);
7482 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7484 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7485 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7487 /* Extract remainder from AH. */
7488 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7489 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7490 insn = emit_move_insn (operands[3], tmp1);
7492 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7493 set_unique_reg_note (insn, REG_EQUAL, mod);
7495 /* Extract quotient from AL. */
7496 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7498 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7499 set_unique_reg_note (insn, REG_EQUAL, div);
7504 (define_insn "udivmodhiqi3"
7505 [(set (match_operand:HI 0 "register_operand" "=a")
7510 (mod:HI (match_operand:HI 1 "register_operand" "0")
7512 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7516 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7517 (clobber (reg:CC FLAGS_REG))]
7518 "TARGET_QIMODE_MATH"
7520 [(set_attr "type" "idiv")
7521 (set_attr "mode" "QI")])
7523 ;; We cannot use div/idiv for double division, because it causes
7524 ;; "division by zero" on the overflow and that's not what we expect
7525 ;; from truncate. Because true (non truncating) double division is
7526 ;; never generated, we can't create this insn anyway.
7529 ; [(set (match_operand:SI 0 "register_operand" "=a")
7531 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7533 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7534 ; (set (match_operand:SI 3 "register_operand" "=d")
7536 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7537 ; (clobber (reg:CC FLAGS_REG))]
7539 ; "div{l}\t{%2, %0|%0, %2}"
7540 ; [(set_attr "type" "idiv")])
7542 ;;- Logical AND instructions
7544 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7545 ;; Note that this excludes ah.
7547 (define_expand "testsi_ccno_1"
7548 [(set (reg:CCNO FLAGS_REG)
7550 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7551 (match_operand:SI 1 "nonmemory_operand" ""))
7554 (define_expand "testqi_ccz_1"
7555 [(set (reg:CCZ FLAGS_REG)
7556 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7557 (match_operand:QI 1 "nonmemory_operand" ""))
7560 (define_expand "testdi_ccno_1"
7561 [(set (reg:CCNO FLAGS_REG)
7563 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7564 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7566 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7568 (define_insn "*testdi_1"
7569 [(set (reg FLAGS_REG)
7572 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7573 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7575 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7576 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7578 test{l}\t{%k1, %k0|%k0, %k1}
7579 test{l}\t{%k1, %k0|%k0, %k1}
7580 test{q}\t{%1, %0|%0, %1}
7581 test{q}\t{%1, %0|%0, %1}
7582 test{q}\t{%1, %0|%0, %1}"
7583 [(set_attr "type" "test")
7584 (set_attr "modrm" "0,1,0,1,1")
7585 (set_attr "mode" "SI,SI,DI,DI,DI")])
7587 (define_insn "*testqi_1_maybe_si"
7588 [(set (reg FLAGS_REG)
7591 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7592 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7594 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7595 && ix86_match_ccmode (insn,
7596 CONST_INT_P (operands[1])
7597 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7599 if (which_alternative == 3)
7601 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7602 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7603 return "test{l}\t{%1, %k0|%k0, %1}";
7605 return "test{b}\t{%1, %0|%0, %1}";
7607 [(set_attr "type" "test")
7608 (set_attr "modrm" "0,1,1,1")
7609 (set_attr "mode" "QI,QI,QI,SI")
7610 (set_attr "pent_pair" "uv,np,uv,np")])
7612 (define_insn "*test<mode>_1"
7613 [(set (reg FLAGS_REG)
7616 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7617 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7619 "ix86_match_ccmode (insn, CCNOmode)
7620 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7621 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7622 [(set_attr "type" "test")
7623 (set_attr "modrm" "0,1,1")
7624 (set_attr "mode" "<MODE>")
7625 (set_attr "pent_pair" "uv,np,uv")])
7627 (define_expand "testqi_ext_ccno_0"
7628 [(set (reg:CCNO FLAGS_REG)
7632 (match_operand 0 "ext_register_operand" "")
7635 (match_operand 1 "const_int_operand" ""))
7638 (define_insn "*testqi_ext_0"
7639 [(set (reg FLAGS_REG)
7643 (match_operand 0 "ext_register_operand" "Q")
7646 (match_operand 1 "const_int_operand" "n"))
7648 "ix86_match_ccmode (insn, CCNOmode)"
7649 "test{b}\t{%1, %h0|%h0, %1}"
7650 [(set_attr "type" "test")
7651 (set_attr "mode" "QI")
7652 (set_attr "length_immediate" "1")
7653 (set_attr "modrm" "1")
7654 (set_attr "pent_pair" "np")])
7656 (define_insn "*testqi_ext_1_rex64"
7657 [(set (reg FLAGS_REG)
7661 (match_operand 0 "ext_register_operand" "Q")
7665 (match_operand:QI 1 "register_operand" "Q")))
7667 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7668 "test{b}\t{%1, %h0|%h0, %1}"
7669 [(set_attr "type" "test")
7670 (set_attr "mode" "QI")])
7672 (define_insn "*testqi_ext_1"
7673 [(set (reg FLAGS_REG)
7677 (match_operand 0 "ext_register_operand" "Q")
7681 (match_operand:QI 1 "general_operand" "Qm")))
7683 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7684 "test{b}\t{%1, %h0|%h0, %1}"
7685 [(set_attr "type" "test")
7686 (set_attr "mode" "QI")])
7688 (define_insn "*testqi_ext_2"
7689 [(set (reg FLAGS_REG)
7693 (match_operand 0 "ext_register_operand" "Q")
7697 (match_operand 1 "ext_register_operand" "Q")
7701 "ix86_match_ccmode (insn, CCNOmode)"
7702 "test{b}\t{%h1, %h0|%h0, %h1}"
7703 [(set_attr "type" "test")
7704 (set_attr "mode" "QI")])
7706 (define_insn "*testqi_ext_3_rex64"
7707 [(set (reg FLAGS_REG)
7708 (compare (zero_extract:DI
7709 (match_operand 0 "nonimmediate_operand" "rm")
7710 (match_operand:DI 1 "const_int_operand" "")
7711 (match_operand:DI 2 "const_int_operand" ""))
7714 && ix86_match_ccmode (insn, CCNOmode)
7715 && INTVAL (operands[1]) > 0
7716 && INTVAL (operands[2]) >= 0
7717 /* Ensure that resulting mask is zero or sign extended operand. */
7718 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7719 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7720 && INTVAL (operands[1]) > 32))
7721 && (GET_MODE (operands[0]) == SImode
7722 || GET_MODE (operands[0]) == DImode
7723 || GET_MODE (operands[0]) == HImode
7724 || GET_MODE (operands[0]) == QImode)"
7727 ;; Combine likes to form bit extractions for some tests. Humor it.
7728 (define_insn "*testqi_ext_3"
7729 [(set (reg FLAGS_REG)
7730 (compare (zero_extract:SI
7731 (match_operand 0 "nonimmediate_operand" "rm")
7732 (match_operand:SI 1 "const_int_operand" "")
7733 (match_operand:SI 2 "const_int_operand" ""))
7735 "ix86_match_ccmode (insn, CCNOmode)
7736 && INTVAL (operands[1]) > 0
7737 && INTVAL (operands[2]) >= 0
7738 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7739 && (GET_MODE (operands[0]) == SImode
7740 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7741 || GET_MODE (operands[0]) == HImode
7742 || GET_MODE (operands[0]) == QImode)"
7746 [(set (match_operand 0 "flags_reg_operand" "")
7747 (match_operator 1 "compare_operator"
7749 (match_operand 2 "nonimmediate_operand" "")
7750 (match_operand 3 "const_int_operand" "")
7751 (match_operand 4 "const_int_operand" ""))
7753 "ix86_match_ccmode (insn, CCNOmode)"
7754 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7756 rtx val = operands[2];
7757 HOST_WIDE_INT len = INTVAL (operands[3]);
7758 HOST_WIDE_INT pos = INTVAL (operands[4]);
7760 enum machine_mode mode, submode;
7762 mode = GET_MODE (val);
7765 /* ??? Combine likes to put non-volatile mem extractions in QImode
7766 no matter the size of the test. So find a mode that works. */
7767 if (! MEM_VOLATILE_P (val))
7769 mode = smallest_mode_for_size (pos + len, MODE_INT);
7770 val = adjust_address (val, mode, 0);
7773 else if (GET_CODE (val) == SUBREG
7774 && (submode = GET_MODE (SUBREG_REG (val)),
7775 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7776 && pos + len <= GET_MODE_BITSIZE (submode)
7777 && GET_MODE_CLASS (submode) == MODE_INT)
7779 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7781 val = SUBREG_REG (val);
7783 else if (mode == HImode && pos + len <= 8)
7785 /* Small HImode tests can be converted to QImode. */
7787 val = gen_lowpart (QImode, val);
7790 if (len == HOST_BITS_PER_WIDE_INT)
7793 mask = ((HOST_WIDE_INT)1 << len) - 1;
7796 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7799 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7800 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7801 ;; this is relatively important trick.
7802 ;; Do the conversion only post-reload to avoid limiting of the register class
7805 [(set (match_operand 0 "flags_reg_operand" "")
7806 (match_operator 1 "compare_operator"
7807 [(and (match_operand 2 "register_operand" "")
7808 (match_operand 3 "const_int_operand" ""))
7811 && QI_REG_P (operands[2])
7812 && GET_MODE (operands[2]) != QImode
7813 && ((ix86_match_ccmode (insn, CCZmode)
7814 && !(INTVAL (operands[3]) & ~(255 << 8)))
7815 || (ix86_match_ccmode (insn, CCNOmode)
7816 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7819 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7822 "operands[2] = gen_lowpart (SImode, operands[2]);
7823 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7826 [(set (match_operand 0 "flags_reg_operand" "")
7827 (match_operator 1 "compare_operator"
7828 [(and (match_operand 2 "nonimmediate_operand" "")
7829 (match_operand 3 "const_int_operand" ""))
7832 && GET_MODE (operands[2]) != QImode
7833 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7834 && ((ix86_match_ccmode (insn, CCZmode)
7835 && !(INTVAL (operands[3]) & ~255))
7836 || (ix86_match_ccmode (insn, CCNOmode)
7837 && !(INTVAL (operands[3]) & ~127)))"
7839 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7841 "operands[2] = gen_lowpart (QImode, operands[2]);
7842 operands[3] = gen_lowpart (QImode, operands[3]);")
7844 ;; %%% This used to optimize known byte-wide and operations to memory,
7845 ;; and sometimes to QImode registers. If this is considered useful,
7846 ;; it should be done with splitters.
7848 (define_expand "and<mode>3"
7849 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7850 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7851 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7853 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7855 (define_insn "*anddi_1"
7856 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7858 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7859 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7860 (clobber (reg:CC FLAGS_REG))]
7861 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7863 switch (get_attr_type (insn))
7867 enum machine_mode mode;
7869 gcc_assert (CONST_INT_P (operands[2]));
7870 if (INTVAL (operands[2]) == 0xff)
7874 gcc_assert (INTVAL (operands[2]) == 0xffff);
7878 operands[1] = gen_lowpart (mode, operands[1]);
7880 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7882 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7886 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7887 if (get_attr_mode (insn) == MODE_SI)
7888 return "and{l}\t{%k2, %k0|%k0, %k2}";
7890 return "and{q}\t{%2, %0|%0, %2}";
7893 [(set_attr "type" "alu,alu,alu,imovx")
7894 (set_attr "length_immediate" "*,*,*,0")
7895 (set (attr "prefix_rex")
7897 (and (eq_attr "type" "imovx")
7898 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7899 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7901 (const_string "*")))
7902 (set_attr "mode" "SI,DI,DI,SI")])
7904 (define_insn "*andsi_1"
7905 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7906 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7907 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7908 (clobber (reg:CC FLAGS_REG))]
7909 "ix86_binary_operator_ok (AND, SImode, operands)"
7911 switch (get_attr_type (insn))
7915 enum machine_mode mode;
7917 gcc_assert (CONST_INT_P (operands[2]));
7918 if (INTVAL (operands[2]) == 0xff)
7922 gcc_assert (INTVAL (operands[2]) == 0xffff);
7926 operands[1] = gen_lowpart (mode, operands[1]);
7928 return "movz{bl|x}\t{%1, %0|%0, %1}";
7930 return "movz{wl|x}\t{%1, %0|%0, %1}";
7934 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7935 return "and{l}\t{%2, %0|%0, %2}";
7938 [(set_attr "type" "alu,alu,imovx")
7939 (set (attr "prefix_rex")
7941 (and (eq_attr "type" "imovx")
7942 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7943 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7945 (const_string "*")))
7946 (set_attr "length_immediate" "*,*,0")
7947 (set_attr "mode" "SI")])
7949 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7950 (define_insn "*andsi_1_zext"
7951 [(set (match_operand:DI 0 "register_operand" "=r")
7953 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7954 (match_operand:SI 2 "general_operand" "g"))))
7955 (clobber (reg:CC FLAGS_REG))]
7956 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7957 "and{l}\t{%2, %k0|%k0, %2}"
7958 [(set_attr "type" "alu")
7959 (set_attr "mode" "SI")])
7961 (define_insn "*andhi_1"
7962 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7963 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7964 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7965 (clobber (reg:CC FLAGS_REG))]
7966 "ix86_binary_operator_ok (AND, HImode, operands)"
7968 switch (get_attr_type (insn))
7971 gcc_assert (CONST_INT_P (operands[2]));
7972 gcc_assert (INTVAL (operands[2]) == 0xff);
7973 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7976 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7978 return "and{w}\t{%2, %0|%0, %2}";
7981 [(set_attr "type" "alu,alu,imovx")
7982 (set_attr "length_immediate" "*,*,0")
7983 (set (attr "prefix_rex")
7985 (and (eq_attr "type" "imovx")
7986 (match_operand 1 "ext_QIreg_nomode_operand" ""))
7988 (const_string "*")))
7989 (set_attr "mode" "HI,HI,SI")])
7991 ;; %%% Potential partial reg stall on alternative 2. What to do?
7992 (define_insn "*andqi_1"
7993 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7994 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7995 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7996 (clobber (reg:CC FLAGS_REG))]
7997 "ix86_binary_operator_ok (AND, QImode, operands)"
7999 and{b}\t{%2, %0|%0, %2}
8000 and{b}\t{%2, %0|%0, %2}
8001 and{l}\t{%k2, %k0|%k0, %k2}"
8002 [(set_attr "type" "alu")
8003 (set_attr "mode" "QI,QI,SI")])
8005 (define_insn "*andqi_1_slp"
8006 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8007 (and:QI (match_dup 0)
8008 (match_operand:QI 1 "general_operand" "qn,qmn")))
8009 (clobber (reg:CC FLAGS_REG))]
8010 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8011 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8012 "and{b}\t{%1, %0|%0, %1}"
8013 [(set_attr "type" "alu1")
8014 (set_attr "mode" "QI")])
8017 [(set (match_operand 0 "register_operand" "")
8019 (const_int -65536)))
8020 (clobber (reg:CC FLAGS_REG))]
8021 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8022 || optimize_function_for_size_p (cfun)"
8023 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8024 "operands[1] = gen_lowpart (HImode, operands[0]);")
8027 [(set (match_operand 0 "ext_register_operand" "")
8030 (clobber (reg:CC FLAGS_REG))]
8031 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8032 && reload_completed"
8033 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8034 "operands[1] = gen_lowpart (QImode, operands[0]);")
8037 [(set (match_operand 0 "ext_register_operand" "")
8039 (const_int -65281)))
8040 (clobber (reg:CC FLAGS_REG))]
8041 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8042 && reload_completed"
8043 [(parallel [(set (zero_extract:SI (match_dup 0)
8047 (zero_extract:SI (match_dup 0)
8050 (zero_extract:SI (match_dup 0)
8053 (clobber (reg:CC FLAGS_REG))])]
8054 "operands[0] = gen_lowpart (SImode, operands[0]);")
8056 (define_insn "*anddi_2"
8057 [(set (reg FLAGS_REG)
8060 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8061 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8063 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8064 (and:DI (match_dup 1) (match_dup 2)))]
8065 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8066 && ix86_binary_operator_ok (AND, DImode, operands)"
8068 and{l}\t{%k2, %k0|%k0, %k2}
8069 and{q}\t{%2, %0|%0, %2}
8070 and{q}\t{%2, %0|%0, %2}"
8071 [(set_attr "type" "alu")
8072 (set_attr "mode" "SI,DI,DI")])
8074 (define_insn "*andqi_2_maybe_si"
8075 [(set (reg FLAGS_REG)
8077 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8078 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8080 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8081 (and:QI (match_dup 1) (match_dup 2)))]
8082 "ix86_binary_operator_ok (AND, QImode, operands)
8083 && ix86_match_ccmode (insn,
8084 CONST_INT_P (operands[2])
8085 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8087 if (which_alternative == 2)
8089 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8090 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8091 return "and{l}\t{%2, %k0|%k0, %2}";
8093 return "and{b}\t{%2, %0|%0, %2}";
8095 [(set_attr "type" "alu")
8096 (set_attr "mode" "QI,QI,SI")])
8098 (define_insn "*and<mode>_2"
8099 [(set (reg FLAGS_REG)
8100 (compare (and:SWI124
8101 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8102 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8104 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8105 (and:SWI124 (match_dup 1) (match_dup 2)))]
8106 "ix86_match_ccmode (insn, CCNOmode)
8107 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8108 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8109 [(set_attr "type" "alu")
8110 (set_attr "mode" "<MODE>")])
8112 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8113 (define_insn "*andsi_2_zext"
8114 [(set (reg FLAGS_REG)
8116 (match_operand:SI 1 "nonimmediate_operand" "%0")
8117 (match_operand:SI 2 "general_operand" "g"))
8119 (set (match_operand:DI 0 "register_operand" "=r")
8120 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8121 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8122 && ix86_binary_operator_ok (AND, SImode, operands)"
8123 "and{l}\t{%2, %k0|%k0, %2}"
8124 [(set_attr "type" "alu")
8125 (set_attr "mode" "SI")])
8127 (define_insn "*andqi_2_slp"
8128 [(set (reg FLAGS_REG)
8130 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8131 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8133 (set (strict_low_part (match_dup 0))
8134 (and:QI (match_dup 0) (match_dup 1)))]
8135 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8136 && ix86_match_ccmode (insn, CCNOmode)
8137 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8138 "and{b}\t{%1, %0|%0, %1}"
8139 [(set_attr "type" "alu1")
8140 (set_attr "mode" "QI")])
8142 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8143 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8144 ;; for a QImode operand, which of course failed.
8145 (define_insn "andqi_ext_0"
8146 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8151 (match_operand 1 "ext_register_operand" "0")
8154 (match_operand 2 "const_int_operand" "n")))
8155 (clobber (reg:CC FLAGS_REG))]
8157 "and{b}\t{%2, %h0|%h0, %2}"
8158 [(set_attr "type" "alu")
8159 (set_attr "length_immediate" "1")
8160 (set_attr "modrm" "1")
8161 (set_attr "mode" "QI")])
8163 ;; Generated by peephole translating test to and. This shows up
8164 ;; often in fp comparisons.
8165 (define_insn "*andqi_ext_0_cc"
8166 [(set (reg FLAGS_REG)
8170 (match_operand 1 "ext_register_operand" "0")
8173 (match_operand 2 "const_int_operand" "n"))
8175 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8184 "ix86_match_ccmode (insn, CCNOmode)"
8185 "and{b}\t{%2, %h0|%h0, %2}"
8186 [(set_attr "type" "alu")
8187 (set_attr "length_immediate" "1")
8188 (set_attr "modrm" "1")
8189 (set_attr "mode" "QI")])
8191 (define_insn "*andqi_ext_1_rex64"
8192 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8197 (match_operand 1 "ext_register_operand" "0")
8201 (match_operand 2 "ext_register_operand" "Q"))))
8202 (clobber (reg:CC FLAGS_REG))]
8204 "and{b}\t{%2, %h0|%h0, %2}"
8205 [(set_attr "type" "alu")
8206 (set_attr "length_immediate" "0")
8207 (set_attr "mode" "QI")])
8209 (define_insn "*andqi_ext_1"
8210 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8215 (match_operand 1 "ext_register_operand" "0")
8219 (match_operand:QI 2 "general_operand" "Qm"))))
8220 (clobber (reg:CC FLAGS_REG))]
8222 "and{b}\t{%2, %h0|%h0, %2}"
8223 [(set_attr "type" "alu")
8224 (set_attr "length_immediate" "0")
8225 (set_attr "mode" "QI")])
8227 (define_insn "*andqi_ext_2"
8228 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8233 (match_operand 1 "ext_register_operand" "%0")
8237 (match_operand 2 "ext_register_operand" "Q")
8240 (clobber (reg:CC FLAGS_REG))]
8242 "and{b}\t{%h2, %h0|%h0, %h2}"
8243 [(set_attr "type" "alu")
8244 (set_attr "length_immediate" "0")
8245 (set_attr "mode" "QI")])
8247 ;; Convert wide AND instructions with immediate operand to shorter QImode
8248 ;; equivalents when possible.
8249 ;; Don't do the splitting with memory operands, since it introduces risk
8250 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8251 ;; for size, but that can (should?) be handled by generic code instead.
8253 [(set (match_operand 0 "register_operand" "")
8254 (and (match_operand 1 "register_operand" "")
8255 (match_operand 2 "const_int_operand" "")))
8256 (clobber (reg:CC FLAGS_REG))]
8258 && QI_REG_P (operands[0])
8259 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8260 && !(~INTVAL (operands[2]) & ~(255 << 8))
8261 && GET_MODE (operands[0]) != QImode"
8262 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8263 (and:SI (zero_extract:SI (match_dup 1)
8264 (const_int 8) (const_int 8))
8266 (clobber (reg:CC FLAGS_REG))])]
8267 "operands[0] = gen_lowpart (SImode, operands[0]);
8268 operands[1] = gen_lowpart (SImode, operands[1]);
8269 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8271 ;; Since AND can be encoded with sign extended immediate, this is only
8272 ;; profitable when 7th bit is not set.
8274 [(set (match_operand 0 "register_operand" "")
8275 (and (match_operand 1 "general_operand" "")
8276 (match_operand 2 "const_int_operand" "")))
8277 (clobber (reg:CC FLAGS_REG))]
8279 && ANY_QI_REG_P (operands[0])
8280 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8281 && !(~INTVAL (operands[2]) & ~255)
8282 && !(INTVAL (operands[2]) & 128)
8283 && GET_MODE (operands[0]) != QImode"
8284 [(parallel [(set (strict_low_part (match_dup 0))
8285 (and:QI (match_dup 1)
8287 (clobber (reg:CC FLAGS_REG))])]
8288 "operands[0] = gen_lowpart (QImode, operands[0]);
8289 operands[1] = gen_lowpart (QImode, operands[1]);
8290 operands[2] = gen_lowpart (QImode, operands[2]);")
8292 ;; Logical inclusive and exclusive OR instructions
8294 ;; %%% This used to optimize known byte-wide and operations to memory.
8295 ;; If this is considered useful, it should be done with splitters.
8297 (define_expand "<code><mode>3"
8298 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8299 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8300 (match_operand:SWIM 2 "<general_operand>" "")))]
8302 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8304 (define_insn "*<code><mode>_1"
8305 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8307 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8308 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8309 (clobber (reg:CC FLAGS_REG))]
8310 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8311 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8312 [(set_attr "type" "alu")
8313 (set_attr "mode" "<MODE>")])
8315 ;; %%% Potential partial reg stall on alternative 2. What to do?
8316 (define_insn "*<code>qi_1"
8317 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8318 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8319 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8320 (clobber (reg:CC FLAGS_REG))]
8321 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8323 <logic>{b}\t{%2, %0|%0, %2}
8324 <logic>{b}\t{%2, %0|%0, %2}
8325 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8326 [(set_attr "type" "alu")
8327 (set_attr "mode" "QI,QI,SI")])
8329 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8330 (define_insn "*<code>si_1_zext"
8331 [(set (match_operand:DI 0 "register_operand" "=r")
8333 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8334 (match_operand:SI 2 "general_operand" "g"))))
8335 (clobber (reg:CC FLAGS_REG))]
8336 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8337 "<logic>{l}\t{%2, %k0|%k0, %2}"
8338 [(set_attr "type" "alu")
8339 (set_attr "mode" "SI")])
8341 (define_insn "*<code>si_1_zext_imm"
8342 [(set (match_operand:DI 0 "register_operand" "=r")
8344 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8345 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8346 (clobber (reg:CC FLAGS_REG))]
8347 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8348 "<logic>{l}\t{%2, %k0|%k0, %2}"
8349 [(set_attr "type" "alu")
8350 (set_attr "mode" "SI")])
8352 (define_insn "*<code>qi_1_slp"
8353 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8354 (any_or:QI (match_dup 0)
8355 (match_operand:QI 1 "general_operand" "qmn,qn")))
8356 (clobber (reg:CC FLAGS_REG))]
8357 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8358 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8359 "<logic>{b}\t{%1, %0|%0, %1}"
8360 [(set_attr "type" "alu1")
8361 (set_attr "mode" "QI")])
8363 (define_insn "*<code><mode>_2"
8364 [(set (reg FLAGS_REG)
8365 (compare (any_or:SWI
8366 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8367 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8369 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8370 (any_or:SWI (match_dup 1) (match_dup 2)))]
8371 "ix86_match_ccmode (insn, CCNOmode)
8372 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8373 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8374 [(set_attr "type" "alu")
8375 (set_attr "mode" "<MODE>")])
8377 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8378 ;; ??? Special case for immediate operand is missing - it is tricky.
8379 (define_insn "*<code>si_2_zext"
8380 [(set (reg FLAGS_REG)
8381 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8382 (match_operand:SI 2 "general_operand" "g"))
8384 (set (match_operand:DI 0 "register_operand" "=r")
8385 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8386 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8387 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8388 "<logic>{l}\t{%2, %k0|%k0, %2}"
8389 [(set_attr "type" "alu")
8390 (set_attr "mode" "SI")])
8392 (define_insn "*<code>si_2_zext_imm"
8393 [(set (reg FLAGS_REG)
8395 (match_operand:SI 1 "nonimmediate_operand" "%0")
8396 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8398 (set (match_operand:DI 0 "register_operand" "=r")
8399 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8400 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8401 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8402 "<logic>{l}\t{%2, %k0|%k0, %2}"
8403 [(set_attr "type" "alu")
8404 (set_attr "mode" "SI")])
8406 (define_insn "*<code>qi_2_slp"
8407 [(set (reg FLAGS_REG)
8408 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8409 (match_operand:QI 1 "general_operand" "qmn,qn"))
8411 (set (strict_low_part (match_dup 0))
8412 (any_or:QI (match_dup 0) (match_dup 1)))]
8413 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8414 && ix86_match_ccmode (insn, CCNOmode)
8415 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8416 "<logic>{b}\t{%1, %0|%0, %1}"
8417 [(set_attr "type" "alu1")
8418 (set_attr "mode" "QI")])
8420 (define_insn "*<code><mode>_3"
8421 [(set (reg FLAGS_REG)
8422 (compare (any_or:SWI
8423 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8424 (match_operand:SWI 2 "<general_operand>" "<g>"))
8426 (clobber (match_scratch:SWI 0 "=<r>"))]
8427 "ix86_match_ccmode (insn, CCNOmode)
8428 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8429 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8430 [(set_attr "type" "alu")
8431 (set_attr "mode" "<MODE>")])
8433 (define_insn "*<code>qi_ext_0"
8434 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8439 (match_operand 1 "ext_register_operand" "0")
8442 (match_operand 2 "const_int_operand" "n")))
8443 (clobber (reg:CC FLAGS_REG))]
8444 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8445 "<logic>{b}\t{%2, %h0|%h0, %2}"
8446 [(set_attr "type" "alu")
8447 (set_attr "length_immediate" "1")
8448 (set_attr "modrm" "1")
8449 (set_attr "mode" "QI")])
8451 (define_insn "*<code>qi_ext_1_rex64"
8452 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8457 (match_operand 1 "ext_register_operand" "0")
8461 (match_operand 2 "ext_register_operand" "Q"))))
8462 (clobber (reg:CC FLAGS_REG))]
8464 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8465 "<logic>{b}\t{%2, %h0|%h0, %2}"
8466 [(set_attr "type" "alu")
8467 (set_attr "length_immediate" "0")
8468 (set_attr "mode" "QI")])
8470 (define_insn "*<code>qi_ext_1"
8471 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8476 (match_operand 1 "ext_register_operand" "0")
8480 (match_operand:QI 2 "general_operand" "Qm"))))
8481 (clobber (reg:CC FLAGS_REG))]
8483 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8484 "<logic>{b}\t{%2, %h0|%h0, %2}"
8485 [(set_attr "type" "alu")
8486 (set_attr "length_immediate" "0")
8487 (set_attr "mode" "QI")])
8489 (define_insn "*<code>qi_ext_2"
8490 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8494 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8497 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8500 (clobber (reg:CC FLAGS_REG))]
8501 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8502 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8503 [(set_attr "type" "alu")
8504 (set_attr "length_immediate" "0")
8505 (set_attr "mode" "QI")])
8508 [(set (match_operand 0 "register_operand" "")
8509 (any_or (match_operand 1 "register_operand" "")
8510 (match_operand 2 "const_int_operand" "")))
8511 (clobber (reg:CC FLAGS_REG))]
8513 && QI_REG_P (operands[0])
8514 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8515 && !(INTVAL (operands[2]) & ~(255 << 8))
8516 && GET_MODE (operands[0]) != QImode"
8517 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8518 (any_or:SI (zero_extract:SI (match_dup 1)
8519 (const_int 8) (const_int 8))
8521 (clobber (reg:CC FLAGS_REG))])]
8522 "operands[0] = gen_lowpart (SImode, operands[0]);
8523 operands[1] = gen_lowpart (SImode, operands[1]);
8524 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8526 ;; Since OR can be encoded with sign extended immediate, this is only
8527 ;; profitable when 7th bit is set.
8529 [(set (match_operand 0 "register_operand" "")
8530 (any_or (match_operand 1 "general_operand" "")
8531 (match_operand 2 "const_int_operand" "")))
8532 (clobber (reg:CC FLAGS_REG))]
8534 && ANY_QI_REG_P (operands[0])
8535 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8536 && !(INTVAL (operands[2]) & ~255)
8537 && (INTVAL (operands[2]) & 128)
8538 && GET_MODE (operands[0]) != QImode"
8539 [(parallel [(set (strict_low_part (match_dup 0))
8540 (any_or:QI (match_dup 1)
8542 (clobber (reg:CC FLAGS_REG))])]
8543 "operands[0] = gen_lowpart (QImode, operands[0]);
8544 operands[1] = gen_lowpart (QImode, operands[1]);
8545 operands[2] = gen_lowpart (QImode, operands[2]);")
8547 (define_expand "xorqi_cc_ext_1"
8549 (set (reg:CCNO FLAGS_REG)
8553 (match_operand 1 "ext_register_operand" "")
8556 (match_operand:QI 2 "general_operand" ""))
8558 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8568 (define_insn "*xorqi_cc_ext_1_rex64"
8569 [(set (reg FLAGS_REG)
8573 (match_operand 1 "ext_register_operand" "0")
8576 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8578 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8587 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8588 "xor{b}\t{%2, %h0|%h0, %2}"
8589 [(set_attr "type" "alu")
8590 (set_attr "modrm" "1")
8591 (set_attr "mode" "QI")])
8593 (define_insn "*xorqi_cc_ext_1"
8594 [(set (reg FLAGS_REG)
8598 (match_operand 1 "ext_register_operand" "0")
8601 (match_operand:QI 2 "general_operand" "qmn"))
8603 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8612 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8613 "xor{b}\t{%2, %h0|%h0, %2}"
8614 [(set_attr "type" "alu")
8615 (set_attr "modrm" "1")
8616 (set_attr "mode" "QI")])
8618 ;; Negation instructions
8620 (define_expand "neg<mode>2"
8621 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8622 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8624 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8626 (define_insn_and_split "*neg<dwi>2_doubleword"
8627 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8628 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8629 (clobber (reg:CC FLAGS_REG))]
8630 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8634 [(set (reg:CCZ FLAGS_REG)
8635 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8636 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8639 (plus:DWIH (match_dup 3)
8640 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8642 (clobber (reg:CC FLAGS_REG))])
8645 (neg:DWIH (match_dup 2)))
8646 (clobber (reg:CC FLAGS_REG))])]
8647 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8649 (define_insn "*neg<mode>2_1"
8650 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8651 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8652 (clobber (reg:CC FLAGS_REG))]
8653 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8654 "neg{<imodesuffix>}\t%0"
8655 [(set_attr "type" "negnot")
8656 (set_attr "mode" "<MODE>")])
8658 ;; Combine is quite creative about this pattern.
8659 (define_insn "*negsi2_1_zext"
8660 [(set (match_operand:DI 0 "register_operand" "=r")
8662 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8665 (clobber (reg:CC FLAGS_REG))]
8666 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8668 [(set_attr "type" "negnot")
8669 (set_attr "mode" "SI")])
8671 ;; The problem with neg is that it does not perform (compare x 0),
8672 ;; it really performs (compare 0 x), which leaves us with the zero
8673 ;; flag being the only useful item.
8675 (define_insn "*neg<mode>2_cmpz"
8676 [(set (reg:CCZ FLAGS_REG)
8678 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8680 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8681 (neg:SWI (match_dup 1)))]
8682 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8683 "neg{<imodesuffix>}\t%0"
8684 [(set_attr "type" "negnot")
8685 (set_attr "mode" "<MODE>")])
8687 (define_insn "*negsi2_cmpz_zext"
8688 [(set (reg:CCZ FLAGS_REG)
8692 (match_operand:DI 1 "register_operand" "0")
8696 (set (match_operand:DI 0 "register_operand" "=r")
8697 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8700 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8702 [(set_attr "type" "negnot")
8703 (set_attr "mode" "SI")])
8705 ;; Changing of sign for FP values is doable using integer unit too.
8707 (define_expand "<code><mode>2"
8708 [(set (match_operand:X87MODEF 0 "register_operand" "")
8709 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8710 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8711 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8713 (define_insn "*absneg<mode>2_mixed"
8714 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8715 (match_operator:MODEF 3 "absneg_operator"
8716 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8717 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8718 (clobber (reg:CC FLAGS_REG))]
8719 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8722 (define_insn "*absneg<mode>2_sse"
8723 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8724 (match_operator:MODEF 3 "absneg_operator"
8725 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8726 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8727 (clobber (reg:CC FLAGS_REG))]
8728 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8731 (define_insn "*absneg<mode>2_i387"
8732 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8733 (match_operator:X87MODEF 3 "absneg_operator"
8734 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8735 (use (match_operand 2 "" ""))
8736 (clobber (reg:CC FLAGS_REG))]
8737 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8740 (define_expand "<code>tf2"
8741 [(set (match_operand:TF 0 "register_operand" "")
8742 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8744 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8746 (define_insn "*absnegtf2_sse"
8747 [(set (match_operand:TF 0 "register_operand" "=x,x")
8748 (match_operator:TF 3 "absneg_operator"
8749 [(match_operand:TF 1 "register_operand" "0,x")]))
8750 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8751 (clobber (reg:CC FLAGS_REG))]
8755 ;; Splitters for fp abs and neg.
8758 [(set (match_operand 0 "fp_register_operand" "")
8759 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8760 (use (match_operand 2 "" ""))
8761 (clobber (reg:CC FLAGS_REG))]
8763 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8766 [(set (match_operand 0 "register_operand" "")
8767 (match_operator 3 "absneg_operator"
8768 [(match_operand 1 "register_operand" "")]))
8769 (use (match_operand 2 "nonimmediate_operand" ""))
8770 (clobber (reg:CC FLAGS_REG))]
8771 "reload_completed && SSE_REG_P (operands[0])"
8772 [(set (match_dup 0) (match_dup 3))]
8774 enum machine_mode mode = GET_MODE (operands[0]);
8775 enum machine_mode vmode = GET_MODE (operands[2]);
8778 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8779 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8780 if (operands_match_p (operands[0], operands[2]))
8783 operands[1] = operands[2];
8786 if (GET_CODE (operands[3]) == ABS)
8787 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8789 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8794 [(set (match_operand:SF 0 "register_operand" "")
8795 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8796 (use (match_operand:V4SF 2 "" ""))
8797 (clobber (reg:CC FLAGS_REG))]
8799 [(parallel [(set (match_dup 0) (match_dup 1))
8800 (clobber (reg:CC FLAGS_REG))])]
8803 operands[0] = gen_lowpart (SImode, operands[0]);
8804 if (GET_CODE (operands[1]) == ABS)
8806 tmp = gen_int_mode (0x7fffffff, SImode);
8807 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8811 tmp = gen_int_mode (0x80000000, SImode);
8812 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8818 [(set (match_operand:DF 0 "register_operand" "")
8819 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8820 (use (match_operand 2 "" ""))
8821 (clobber (reg:CC FLAGS_REG))]
8823 [(parallel [(set (match_dup 0) (match_dup 1))
8824 (clobber (reg:CC FLAGS_REG))])]
8829 tmp = gen_lowpart (DImode, operands[0]);
8830 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8833 if (GET_CODE (operands[1]) == ABS)
8836 tmp = gen_rtx_NOT (DImode, tmp);
8840 operands[0] = gen_highpart (SImode, operands[0]);
8841 if (GET_CODE (operands[1]) == ABS)
8843 tmp = gen_int_mode (0x7fffffff, SImode);
8844 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8848 tmp = gen_int_mode (0x80000000, SImode);
8849 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8856 [(set (match_operand:XF 0 "register_operand" "")
8857 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8858 (use (match_operand 2 "" ""))
8859 (clobber (reg:CC FLAGS_REG))]
8861 [(parallel [(set (match_dup 0) (match_dup 1))
8862 (clobber (reg:CC FLAGS_REG))])]
8865 operands[0] = gen_rtx_REG (SImode,
8866 true_regnum (operands[0])
8867 + (TARGET_64BIT ? 1 : 2));
8868 if (GET_CODE (operands[1]) == ABS)
8870 tmp = GEN_INT (0x7fff);
8871 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8875 tmp = GEN_INT (0x8000);
8876 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8881 ;; Conditionalize these after reload. If they match before reload, we
8882 ;; lose the clobber and ability to use integer instructions.
8884 (define_insn "*<code><mode>2_1"
8885 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8886 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8888 && (reload_completed
8889 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8890 "f<absneg_mnemonic>"
8891 [(set_attr "type" "fsgn")
8892 (set_attr "mode" "<MODE>")])
8894 (define_insn "*<code>extendsfdf2"
8895 [(set (match_operand:DF 0 "register_operand" "=f")
8896 (absneg:DF (float_extend:DF
8897 (match_operand:SF 1 "register_operand" "0"))))]
8898 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8899 "f<absneg_mnemonic>"
8900 [(set_attr "type" "fsgn")
8901 (set_attr "mode" "DF")])
8903 (define_insn "*<code>extendsfxf2"
8904 [(set (match_operand:XF 0 "register_operand" "=f")
8905 (absneg:XF (float_extend:XF
8906 (match_operand:SF 1 "register_operand" "0"))))]
8908 "f<absneg_mnemonic>"
8909 [(set_attr "type" "fsgn")
8910 (set_attr "mode" "XF")])
8912 (define_insn "*<code>extenddfxf2"
8913 [(set (match_operand:XF 0 "register_operand" "=f")
8914 (absneg:XF (float_extend:XF
8915 (match_operand:DF 1 "register_operand" "0"))))]
8917 "f<absneg_mnemonic>"
8918 [(set_attr "type" "fsgn")
8919 (set_attr "mode" "XF")])
8921 ;; Copysign instructions
8923 (define_mode_iterator CSGNMODE [SF DF TF])
8924 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8926 (define_expand "copysign<mode>3"
8927 [(match_operand:CSGNMODE 0 "register_operand" "")
8928 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8929 (match_operand:CSGNMODE 2 "register_operand" "")]
8930 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8931 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8932 "ix86_expand_copysign (operands); DONE;")
8934 (define_insn_and_split "copysign<mode>3_const"
8935 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8937 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8938 (match_operand:CSGNMODE 2 "register_operand" "0")
8939 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8941 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8942 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8944 "&& reload_completed"
8946 "ix86_split_copysign_const (operands); DONE;")
8948 (define_insn "copysign<mode>3_var"
8949 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8951 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8952 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8953 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8954 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8956 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8957 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8958 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8962 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8964 [(match_operand:CSGNMODE 2 "register_operand" "")
8965 (match_operand:CSGNMODE 3 "register_operand" "")
8966 (match_operand:<CSGNVMODE> 4 "" "")
8967 (match_operand:<CSGNVMODE> 5 "" "")]
8969 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8970 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8971 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8972 && reload_completed"
8974 "ix86_split_copysign_var (operands); DONE;")
8976 ;; One complement instructions
8978 (define_expand "one_cmpl<mode>2"
8979 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8980 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8982 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8984 (define_insn "*one_cmpl<mode>2_1"
8985 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8986 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8987 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8988 "not{<imodesuffix>}\t%0"
8989 [(set_attr "type" "negnot")
8990 (set_attr "mode" "<MODE>")])
8992 ;; %%% Potential partial reg stall on alternative 1. What to do?
8993 (define_insn "*one_cmplqi2_1"
8994 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8995 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8996 "ix86_unary_operator_ok (NOT, QImode, operands)"
9000 [(set_attr "type" "negnot")
9001 (set_attr "mode" "QI,SI")])
9003 ;; ??? Currently never generated - xor is used instead.
9004 (define_insn "*one_cmplsi2_1_zext"
9005 [(set (match_operand:DI 0 "register_operand" "=r")
9007 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9008 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9010 [(set_attr "type" "negnot")
9011 (set_attr "mode" "SI")])
9013 (define_insn "*one_cmpl<mode>2_2"
9014 [(set (reg FLAGS_REG)
9015 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9017 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9018 (not:SWI (match_dup 1)))]
9019 "ix86_match_ccmode (insn, CCNOmode)
9020 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9022 [(set_attr "type" "alu1")
9023 (set_attr "mode" "<MODE>")])
9026 [(set (match_operand 0 "flags_reg_operand" "")
9027 (match_operator 2 "compare_operator"
9028 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9030 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9031 (not:SWI (match_dup 3)))]
9032 "ix86_match_ccmode (insn, CCNOmode)"
9033 [(parallel [(set (match_dup 0)
9034 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9037 (xor:SWI (match_dup 3) (const_int -1)))])])
9039 ;; ??? Currently never generated - xor is used instead.
9040 (define_insn "*one_cmplsi2_2_zext"
9041 [(set (reg FLAGS_REG)
9042 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9044 (set (match_operand:DI 0 "register_operand" "=r")
9045 (zero_extend:DI (not:SI (match_dup 1))))]
9046 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9047 && ix86_unary_operator_ok (NOT, SImode, operands)"
9049 [(set_attr "type" "alu1")
9050 (set_attr "mode" "SI")])
9053 [(set (match_operand 0 "flags_reg_operand" "")
9054 (match_operator 2 "compare_operator"
9055 [(not:SI (match_operand:SI 3 "register_operand" ""))
9057 (set (match_operand:DI 1 "register_operand" "")
9058 (zero_extend:DI (not:SI (match_dup 3))))]
9059 "ix86_match_ccmode (insn, CCNOmode)"
9060 [(parallel [(set (match_dup 0)
9061 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9064 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9066 ;; Shift instructions
9068 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9069 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9070 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9071 ;; from the assembler input.
9073 ;; This instruction shifts the target reg/mem as usual, but instead of
9074 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9075 ;; is a left shift double, bits are taken from the high order bits of
9076 ;; reg, else if the insn is a shift right double, bits are taken from the
9077 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9078 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9080 ;; Since sh[lr]d does not change the `reg' operand, that is done
9081 ;; separately, making all shifts emit pairs of shift double and normal
9082 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9083 ;; support a 63 bit shift, each shift where the count is in a reg expands
9084 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9086 ;; If the shift count is a constant, we need never emit more than one
9087 ;; shift pair, instead using moves and sign extension for counts greater
9090 (define_expand "ashl<mode>3"
9091 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9092 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9093 (match_operand:QI 2 "nonmemory_operand" "")))]
9095 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9097 (define_insn "*ashl<mode>3_doubleword"
9098 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9099 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9100 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9101 (clobber (reg:CC FLAGS_REG))]
9104 [(set_attr "type" "multi")])
9107 [(set (match_operand:DWI 0 "register_operand" "")
9108 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9109 (match_operand:QI 2 "nonmemory_operand" "")))
9110 (clobber (reg:CC FLAGS_REG))]
9111 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9113 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9115 ;; By default we don't ask for a scratch register, because when DWImode
9116 ;; values are manipulated, registers are already at a premium. But if
9117 ;; we have one handy, we won't turn it away.
9120 [(match_scratch:DWIH 3 "r")
9121 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9123 (match_operand:<DWI> 1 "nonmemory_operand" "")
9124 (match_operand:QI 2 "nonmemory_operand" "")))
9125 (clobber (reg:CC FLAGS_REG))])
9129 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9131 (define_insn "x86_64_shld"
9132 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9133 (ior:DI (ashift:DI (match_dup 0)
9134 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9135 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9136 (minus:QI (const_int 64) (match_dup 2)))))
9137 (clobber (reg:CC FLAGS_REG))]
9139 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9140 [(set_attr "type" "ishift")
9141 (set_attr "prefix_0f" "1")
9142 (set_attr "mode" "DI")
9143 (set_attr "athlon_decode" "vector")
9144 (set_attr "amdfam10_decode" "vector")
9145 (set_attr "bdver1_decode" "vector")])
9147 (define_insn "x86_shld"
9148 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9149 (ior:SI (ashift:SI (match_dup 0)
9150 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9151 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9152 (minus:QI (const_int 32) (match_dup 2)))))
9153 (clobber (reg:CC FLAGS_REG))]
9155 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9156 [(set_attr "type" "ishift")
9157 (set_attr "prefix_0f" "1")
9158 (set_attr "mode" "SI")
9159 (set_attr "pent_pair" "np")
9160 (set_attr "athlon_decode" "vector")
9161 (set_attr "amdfam10_decode" "vector")
9162 (set_attr "bdver1_decode" "vector")])
9164 (define_expand "x86_shift<mode>_adj_1"
9165 [(set (reg:CCZ FLAGS_REG)
9166 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9169 (set (match_operand:SWI48 0 "register_operand" "")
9170 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9171 (match_operand:SWI48 1 "register_operand" "")
9174 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9175 (match_operand:SWI48 3 "register_operand" "r")
9178 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9180 (define_expand "x86_shift<mode>_adj_2"
9181 [(use (match_operand:SWI48 0 "register_operand" ""))
9182 (use (match_operand:SWI48 1 "register_operand" ""))
9183 (use (match_operand:QI 2 "register_operand" ""))]
9186 rtx label = gen_label_rtx ();
9189 emit_insn (gen_testqi_ccz_1 (operands[2],
9190 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9192 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9193 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9194 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9195 gen_rtx_LABEL_REF (VOIDmode, label),
9197 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9198 JUMP_LABEL (tmp) = label;
9200 emit_move_insn (operands[0], operands[1]);
9201 ix86_expand_clear (operands[1]);
9204 LABEL_NUSES (label) = 1;
9209 ;; Avoid useless masking of count operand.
9210 (define_insn_and_split "*ashl<mode>3_mask"
9211 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9213 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9216 (match_operand:SI 2 "nonimmediate_operand" "c")
9217 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9218 (clobber (reg:CC FLAGS_REG))]
9219 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9220 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9221 == GET_MODE_BITSIZE (<MODE>mode)-1"
9224 [(parallel [(set (match_dup 0)
9225 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9226 (clobber (reg:CC FLAGS_REG))])]
9228 if (can_create_pseudo_p ())
9229 operands [2] = force_reg (SImode, operands[2]);
9231 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9233 [(set_attr "type" "ishift")
9234 (set_attr "mode" "<MODE>")])
9236 (define_insn "*ashl<mode>3_1"
9237 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9238 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9239 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9240 (clobber (reg:CC FLAGS_REG))]
9241 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9243 switch (get_attr_type (insn))
9249 gcc_assert (operands[2] == const1_rtx);
9250 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9251 return "add{<imodesuffix>}\t%0, %0";
9254 if (operands[2] == const1_rtx
9255 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9256 return "sal{<imodesuffix>}\t%0";
9258 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9262 (cond [(eq_attr "alternative" "1")
9263 (const_string "lea")
9264 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9266 (match_operand 0 "register_operand" ""))
9267 (match_operand 2 "const1_operand" ""))
9268 (const_string "alu")
9270 (const_string "ishift")))
9271 (set (attr "length_immediate")
9273 (ior (eq_attr "type" "alu")
9274 (and (eq_attr "type" "ishift")
9275 (and (match_operand 2 "const1_operand" "")
9276 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9279 (const_string "*")))
9280 (set_attr "mode" "<MODE>")])
9282 (define_insn "*ashlsi3_1_zext"
9283 [(set (match_operand:DI 0 "register_operand" "=r,r")
9285 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9286 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9287 (clobber (reg:CC FLAGS_REG))]
9288 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9290 switch (get_attr_type (insn))
9296 gcc_assert (operands[2] == const1_rtx);
9297 return "add{l}\t%k0, %k0";
9300 if (operands[2] == const1_rtx
9301 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9302 return "sal{l}\t%k0";
9304 return "sal{l}\t{%2, %k0|%k0, %2}";
9308 (cond [(eq_attr "alternative" "1")
9309 (const_string "lea")
9310 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
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" "SI")])
9327 (define_insn "*ashlhi3_1"
9328 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9329 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9330 (match_operand:QI 2 "nonmemory_operand" "cI")))
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))
9338 gcc_assert (operands[2] == const1_rtx);
9339 return "add{w}\t%0, %0";
9342 if (operands[2] == const1_rtx
9343 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9344 return "sal{w}\t%0";
9346 return "sal{w}\t{%2, %0|%0, %2}";
9350 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9352 (match_operand 0 "register_operand" ""))
9353 (match_operand 2 "const1_operand" ""))
9354 (const_string "alu")
9356 (const_string "ishift")))
9357 (set (attr "length_immediate")
9359 (ior (eq_attr "type" "alu")
9360 (and (eq_attr "type" "ishift")
9361 (and (match_operand 2 "const1_operand" "")
9362 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9365 (const_string "*")))
9366 (set_attr "mode" "HI")])
9368 (define_insn "*ashlhi3_1_lea"
9369 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9370 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9371 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9372 (clobber (reg:CC FLAGS_REG))]
9373 "!TARGET_PARTIAL_REG_STALL
9374 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9376 switch (get_attr_type (insn))
9382 gcc_assert (operands[2] == const1_rtx);
9383 return "add{w}\t%0, %0";
9386 if (operands[2] == const1_rtx
9387 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9388 return "sal{w}\t%0";
9390 return "sal{w}\t{%2, %0|%0, %2}";
9394 (cond [(eq_attr "alternative" "1")
9395 (const_string "lea")
9396 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9398 (match_operand 0 "register_operand" ""))
9399 (match_operand 2 "const1_operand" ""))
9400 (const_string "alu")
9402 (const_string "ishift")))
9403 (set (attr "length_immediate")
9405 (ior (eq_attr "type" "alu")
9406 (and (eq_attr "type" "ishift")
9407 (and (match_operand 2 "const1_operand" "")
9408 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9411 (const_string "*")))
9412 (set_attr "mode" "HI,SI")])
9414 (define_insn "*ashlqi3_1"
9415 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9416 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9417 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9418 (clobber (reg:CC FLAGS_REG))]
9419 "TARGET_PARTIAL_REG_STALL
9420 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9422 switch (get_attr_type (insn))
9425 gcc_assert (operands[2] == const1_rtx);
9426 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9427 return "add{l}\t%k0, %k0";
9429 return "add{b}\t%0, %0";
9432 if (operands[2] == const1_rtx
9433 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9435 if (get_attr_mode (insn) == MODE_SI)
9436 return "sal{l}\t%k0";
9438 return "sal{b}\t%0";
9442 if (get_attr_mode (insn) == MODE_SI)
9443 return "sal{l}\t{%2, %k0|%k0, %2}";
9445 return "sal{b}\t{%2, %0|%0, %2}";
9450 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9452 (match_operand 0 "register_operand" ""))
9453 (match_operand 2 "const1_operand" ""))
9454 (const_string "alu")
9456 (const_string "ishift")))
9457 (set (attr "length_immediate")
9459 (ior (eq_attr "type" "alu")
9460 (and (eq_attr "type" "ishift")
9461 (and (match_operand 2 "const1_operand" "")
9462 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9465 (const_string "*")))
9466 (set_attr "mode" "QI,SI")])
9468 ;; %%% Potential partial reg stall on alternative 2. What to do?
9469 (define_insn "*ashlqi3_1_lea"
9470 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9471 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9472 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9473 (clobber (reg:CC FLAGS_REG))]
9474 "!TARGET_PARTIAL_REG_STALL
9475 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9477 switch (get_attr_type (insn))
9483 gcc_assert (operands[2] == const1_rtx);
9484 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9485 return "add{l}\t%k0, %k0";
9487 return "add{b}\t%0, %0";
9490 if (operands[2] == const1_rtx
9491 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9493 if (get_attr_mode (insn) == MODE_SI)
9494 return "sal{l}\t%k0";
9496 return "sal{b}\t%0";
9500 if (get_attr_mode (insn) == MODE_SI)
9501 return "sal{l}\t{%2, %k0|%k0, %2}";
9503 return "sal{b}\t{%2, %0|%0, %2}";
9508 (cond [(eq_attr "alternative" "2")
9509 (const_string "lea")
9510 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9512 (match_operand 0 "register_operand" ""))
9513 (match_operand 2 "const1_operand" ""))
9514 (const_string "alu")
9516 (const_string "ishift")))
9517 (set (attr "length_immediate")
9519 (ior (eq_attr "type" "alu")
9520 (and (eq_attr "type" "ishift")
9521 (and (match_operand 2 "const1_operand" "")
9522 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9525 (const_string "*")))
9526 (set_attr "mode" "QI,SI,SI")])
9528 (define_insn "*ashlqi3_1_slp"
9529 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9530 (ashift:QI (match_dup 0)
9531 (match_operand:QI 1 "nonmemory_operand" "cI")))
9532 (clobber (reg:CC FLAGS_REG))]
9533 "(optimize_function_for_size_p (cfun)
9534 || !TARGET_PARTIAL_FLAG_REG_STALL
9535 || (operands[1] == const1_rtx
9537 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9539 switch (get_attr_type (insn))
9542 gcc_assert (operands[1] == const1_rtx);
9543 return "add{b}\t%0, %0";
9546 if (operands[1] == const1_rtx
9547 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9548 return "sal{b}\t%0";
9550 return "sal{b}\t{%1, %0|%0, %1}";
9554 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9556 (match_operand 0 "register_operand" ""))
9557 (match_operand 1 "const1_operand" ""))
9558 (const_string "alu")
9560 (const_string "ishift1")))
9561 (set (attr "length_immediate")
9563 (ior (eq_attr "type" "alu")
9564 (and (eq_attr "type" "ishift1")
9565 (and (match_operand 1 "const1_operand" "")
9566 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9569 (const_string "*")))
9570 (set_attr "mode" "QI")])
9572 ;; Convert lea to the lea pattern to avoid flags dependency.
9574 [(set (match_operand 0 "register_operand" "")
9575 (ashift (match_operand 1 "index_register_operand" "")
9576 (match_operand:QI 2 "const_int_operand" "")))
9577 (clobber (reg:CC FLAGS_REG))]
9579 && true_regnum (operands[0]) != true_regnum (operands[1])"
9583 enum machine_mode mode = GET_MODE (operands[0]);
9586 operands[1] = gen_lowpart (Pmode, operands[1]);
9587 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9589 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9591 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9592 operands[0] = gen_lowpart (SImode, operands[0]);
9594 if (TARGET_64BIT && mode != Pmode)
9595 pat = gen_rtx_SUBREG (SImode, pat, 0);
9597 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9601 ;; Convert lea to the lea pattern to avoid flags dependency.
9603 [(set (match_operand:DI 0 "register_operand" "")
9605 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9606 (match_operand:QI 2 "const_int_operand" ""))))
9607 (clobber (reg:CC FLAGS_REG))]
9608 "TARGET_64BIT && reload_completed
9609 && true_regnum (operands[0]) != true_regnum (operands[1])"
9611 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9613 operands[1] = gen_lowpart (DImode, operands[1]);
9614 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9617 ;; This pattern can't accept a variable shift count, since shifts by
9618 ;; zero don't affect the flags. We assume that shifts by constant
9619 ;; zero are optimized away.
9620 (define_insn "*ashl<mode>3_cmp"
9621 [(set (reg FLAGS_REG)
9623 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9624 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9626 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9627 (ashift:SWI (match_dup 1) (match_dup 2)))]
9628 "(optimize_function_for_size_p (cfun)
9629 || !TARGET_PARTIAL_FLAG_REG_STALL
9630 || (operands[2] == const1_rtx
9632 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9633 && ix86_match_ccmode (insn, CCGOCmode)
9634 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9636 switch (get_attr_type (insn))
9639 gcc_assert (operands[2] == const1_rtx);
9640 return "add{<imodesuffix>}\t%0, %0";
9643 if (operands[2] == const1_rtx
9644 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9645 return "sal{<imodesuffix>}\t%0";
9647 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9651 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9653 (match_operand 0 "register_operand" ""))
9654 (match_operand 2 "const1_operand" ""))
9655 (const_string "alu")
9657 (const_string "ishift")))
9658 (set (attr "length_immediate")
9660 (ior (eq_attr "type" "alu")
9661 (and (eq_attr "type" "ishift")
9662 (and (match_operand 2 "const1_operand" "")
9663 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9666 (const_string "*")))
9667 (set_attr "mode" "<MODE>")])
9669 (define_insn "*ashlsi3_cmp_zext"
9670 [(set (reg FLAGS_REG)
9672 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9673 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9675 (set (match_operand:DI 0 "register_operand" "=r")
9676 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9678 && (optimize_function_for_size_p (cfun)
9679 || !TARGET_PARTIAL_FLAG_REG_STALL
9680 || (operands[2] == const1_rtx
9682 || TARGET_DOUBLE_WITH_ADD)))
9683 && ix86_match_ccmode (insn, CCGOCmode)
9684 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9686 switch (get_attr_type (insn))
9689 gcc_assert (operands[2] == const1_rtx);
9690 return "add{l}\t%k0, %k0";
9693 if (operands[2] == const1_rtx
9694 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9695 return "sal{l}\t%k0";
9697 return "sal{l}\t{%2, %k0|%k0, %2}";
9701 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9703 (match_operand 2 "const1_operand" ""))
9704 (const_string "alu")
9706 (const_string "ishift")))
9707 (set (attr "length_immediate")
9709 (ior (eq_attr "type" "alu")
9710 (and (eq_attr "type" "ishift")
9711 (and (match_operand 2 "const1_operand" "")
9712 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9715 (const_string "*")))
9716 (set_attr "mode" "SI")])
9718 (define_insn "*ashl<mode>3_cconly"
9719 [(set (reg FLAGS_REG)
9721 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9722 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9724 (clobber (match_scratch:SWI 0 "=<r>"))]
9725 "(optimize_function_for_size_p (cfun)
9726 || !TARGET_PARTIAL_FLAG_REG_STALL
9727 || (operands[2] == const1_rtx
9729 || TARGET_DOUBLE_WITH_ADD)))
9730 && ix86_match_ccmode (insn, CCGOCmode)"
9732 switch (get_attr_type (insn))
9735 gcc_assert (operands[2] == const1_rtx);
9736 return "add{<imodesuffix>}\t%0, %0";
9739 if (operands[2] == const1_rtx
9740 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9741 return "sal{<imodesuffix>}\t%0";
9743 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9747 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9749 (match_operand 0 "register_operand" ""))
9750 (match_operand 2 "const1_operand" ""))
9751 (const_string "alu")
9753 (const_string "ishift")))
9754 (set (attr "length_immediate")
9756 (ior (eq_attr "type" "alu")
9757 (and (eq_attr "type" "ishift")
9758 (and (match_operand 2 "const1_operand" "")
9759 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9762 (const_string "*")))
9763 (set_attr "mode" "<MODE>")])
9765 ;; See comment above `ashl<mode>3' about how this works.
9767 (define_expand "<shiftrt_insn><mode>3"
9768 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9769 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9770 (match_operand:QI 2 "nonmemory_operand" "")))]
9772 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9774 ;; Avoid useless masking of count operand.
9775 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9776 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9778 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9781 (match_operand:SI 2 "nonimmediate_operand" "c")
9782 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9783 (clobber (reg:CC FLAGS_REG))]
9784 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9785 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9786 == GET_MODE_BITSIZE (<MODE>mode)-1"
9789 [(parallel [(set (match_dup 0)
9790 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9791 (clobber (reg:CC FLAGS_REG))])]
9793 if (can_create_pseudo_p ())
9794 operands [2] = force_reg (SImode, operands[2]);
9796 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9798 [(set_attr "type" "ishift")
9799 (set_attr "mode" "<MODE>")])
9801 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9802 [(set (match_operand:DWI 0 "register_operand" "=r")
9803 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9804 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9805 (clobber (reg:CC FLAGS_REG))]
9808 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9810 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9811 [(set_attr "type" "multi")])
9813 ;; By default we don't ask for a scratch register, because when DWImode
9814 ;; values are manipulated, registers are already at a premium. But if
9815 ;; we have one handy, we won't turn it away.
9818 [(match_scratch:DWIH 3 "r")
9819 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9821 (match_operand:<DWI> 1 "register_operand" "")
9822 (match_operand:QI 2 "nonmemory_operand" "")))
9823 (clobber (reg:CC FLAGS_REG))])
9827 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9829 (define_insn "x86_64_shrd"
9830 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9831 (ior:DI (ashiftrt:DI (match_dup 0)
9832 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9833 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9834 (minus:QI (const_int 64) (match_dup 2)))))
9835 (clobber (reg:CC FLAGS_REG))]
9837 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9838 [(set_attr "type" "ishift")
9839 (set_attr "prefix_0f" "1")
9840 (set_attr "mode" "DI")
9841 (set_attr "athlon_decode" "vector")
9842 (set_attr "amdfam10_decode" "vector")
9843 (set_attr "bdver1_decode" "vector")])
9845 (define_insn "x86_shrd"
9846 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9847 (ior:SI (ashiftrt:SI (match_dup 0)
9848 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9849 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9850 (minus:QI (const_int 32) (match_dup 2)))))
9851 (clobber (reg:CC FLAGS_REG))]
9853 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9854 [(set_attr "type" "ishift")
9855 (set_attr "prefix_0f" "1")
9856 (set_attr "mode" "SI")
9857 (set_attr "pent_pair" "np")
9858 (set_attr "athlon_decode" "vector")
9859 (set_attr "amdfam10_decode" "vector")
9860 (set_attr "bdver1_decode" "vector")])
9862 (define_insn "ashrdi3_cvt"
9863 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9864 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9865 (match_operand:QI 2 "const_int_operand" "")))
9866 (clobber (reg:CC FLAGS_REG))]
9867 "TARGET_64BIT && INTVAL (operands[2]) == 63
9868 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9869 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9872 sar{q}\t{%2, %0|%0, %2}"
9873 [(set_attr "type" "imovx,ishift")
9874 (set_attr "prefix_0f" "0,*")
9875 (set_attr "length_immediate" "0,*")
9876 (set_attr "modrm" "0,1")
9877 (set_attr "mode" "DI")])
9879 (define_insn "ashrsi3_cvt"
9880 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9881 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9882 (match_operand:QI 2 "const_int_operand" "")))
9883 (clobber (reg:CC FLAGS_REG))]
9884 "INTVAL (operands[2]) == 31
9885 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9886 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9889 sar{l}\t{%2, %0|%0, %2}"
9890 [(set_attr "type" "imovx,ishift")
9891 (set_attr "prefix_0f" "0,*")
9892 (set_attr "length_immediate" "0,*")
9893 (set_attr "modrm" "0,1")
9894 (set_attr "mode" "SI")])
9896 (define_insn "*ashrsi3_cvt_zext"
9897 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9899 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9900 (match_operand:QI 2 "const_int_operand" ""))))
9901 (clobber (reg:CC FLAGS_REG))]
9902 "TARGET_64BIT && INTVAL (operands[2]) == 31
9903 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9904 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9907 sar{l}\t{%2, %k0|%k0, %2}"
9908 [(set_attr "type" "imovx,ishift")
9909 (set_attr "prefix_0f" "0,*")
9910 (set_attr "length_immediate" "0,*")
9911 (set_attr "modrm" "0,1")
9912 (set_attr "mode" "SI")])
9914 (define_expand "x86_shift<mode>_adj_3"
9915 [(use (match_operand:SWI48 0 "register_operand" ""))
9916 (use (match_operand:SWI48 1 "register_operand" ""))
9917 (use (match_operand:QI 2 "register_operand" ""))]
9920 rtx label = gen_label_rtx ();
9923 emit_insn (gen_testqi_ccz_1 (operands[2],
9924 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9926 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9927 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9928 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9929 gen_rtx_LABEL_REF (VOIDmode, label),
9931 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9932 JUMP_LABEL (tmp) = label;
9934 emit_move_insn (operands[0], operands[1]);
9935 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9936 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9938 LABEL_NUSES (label) = 1;
9943 (define_insn "*<shiftrt_insn><mode>3_1"
9944 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9945 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9946 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9947 (clobber (reg:CC FLAGS_REG))]
9948 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9950 if (operands[2] == const1_rtx
9951 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9952 return "<shiftrt>{<imodesuffix>}\t%0";
9954 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9956 [(set_attr "type" "ishift")
9957 (set (attr "length_immediate")
9959 (and (match_operand 2 "const1_operand" "")
9960 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9963 (const_string "*")))
9964 (set_attr "mode" "<MODE>")])
9966 (define_insn "*<shiftrt_insn>si3_1_zext"
9967 [(set (match_operand:DI 0 "register_operand" "=r")
9969 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9970 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9971 (clobber (reg:CC FLAGS_REG))]
9972 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9974 if (operands[2] == const1_rtx
9975 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9976 return "<shiftrt>{l}\t%k0";
9978 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9980 [(set_attr "type" "ishift")
9981 (set (attr "length_immediate")
9983 (and (match_operand 2 "const1_operand" "")
9984 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9987 (const_string "*")))
9988 (set_attr "mode" "SI")])
9990 (define_insn "*<shiftrt_insn>qi3_1_slp"
9991 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9992 (any_shiftrt:QI (match_dup 0)
9993 (match_operand:QI 1 "nonmemory_operand" "cI")))
9994 (clobber (reg:CC FLAGS_REG))]
9995 "(optimize_function_for_size_p (cfun)
9996 || !TARGET_PARTIAL_REG_STALL
9997 || (operands[1] == const1_rtx
10000 if (operands[1] == const1_rtx
10001 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10002 return "<shiftrt>{b}\t%0";
10004 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10006 [(set_attr "type" "ishift1")
10007 (set (attr "length_immediate")
10009 (and (match_operand 1 "const1_operand" "")
10010 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10013 (const_string "*")))
10014 (set_attr "mode" "QI")])
10016 ;; This pattern can't accept a variable shift count, since shifts by
10017 ;; zero don't affect the flags. We assume that shifts by constant
10018 ;; zero are optimized away.
10019 (define_insn "*<shiftrt_insn><mode>3_cmp"
10020 [(set (reg FLAGS_REG)
10023 (match_operand:SWI 1 "nonimmediate_operand" "0")
10024 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10026 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10027 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10028 "(optimize_function_for_size_p (cfun)
10029 || !TARGET_PARTIAL_FLAG_REG_STALL
10030 || (operands[2] == const1_rtx
10032 && ix86_match_ccmode (insn, CCGOCmode)
10033 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10035 if (operands[2] == const1_rtx
10036 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10037 return "<shiftrt>{<imodesuffix>}\t%0";
10039 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10041 [(set_attr "type" "ishift")
10042 (set (attr "length_immediate")
10044 (and (match_operand 2 "const1_operand" "")
10045 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10048 (const_string "*")))
10049 (set_attr "mode" "<MODE>")])
10051 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10052 [(set (reg FLAGS_REG)
10054 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10055 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10057 (set (match_operand:DI 0 "register_operand" "=r")
10058 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10060 && (optimize_function_for_size_p (cfun)
10061 || !TARGET_PARTIAL_FLAG_REG_STALL
10062 || (operands[2] == const1_rtx
10064 && ix86_match_ccmode (insn, CCGOCmode)
10065 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10067 if (operands[2] == const1_rtx
10068 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10069 return "<shiftrt>{l}\t%k0";
10071 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10073 [(set_attr "type" "ishift")
10074 (set (attr "length_immediate")
10076 (and (match_operand 2 "const1_operand" "")
10077 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10080 (const_string "*")))
10081 (set_attr "mode" "SI")])
10083 (define_insn "*<shiftrt_insn><mode>3_cconly"
10084 [(set (reg FLAGS_REG)
10087 (match_operand:SWI 1 "register_operand" "0")
10088 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10090 (clobber (match_scratch:SWI 0 "=<r>"))]
10091 "(optimize_function_for_size_p (cfun)
10092 || !TARGET_PARTIAL_FLAG_REG_STALL
10093 || (operands[2] == const1_rtx
10095 && ix86_match_ccmode (insn, CCGOCmode)"
10097 if (operands[2] == const1_rtx
10098 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10099 return "<shiftrt>{<imodesuffix>}\t%0";
10101 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10103 [(set_attr "type" "ishift")
10104 (set (attr "length_immediate")
10106 (and (match_operand 2 "const1_operand" "")
10107 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10110 (const_string "*")))
10111 (set_attr "mode" "<MODE>")])
10113 ;; Rotate instructions
10115 (define_expand "<rotate_insn>ti3"
10116 [(set (match_operand:TI 0 "register_operand" "")
10117 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10118 (match_operand:QI 2 "nonmemory_operand" "")))]
10121 if (const_1_to_63_operand (operands[2], VOIDmode))
10122 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10123 (operands[0], operands[1], operands[2]));
10130 (define_expand "<rotate_insn>di3"
10131 [(set (match_operand:DI 0 "shiftdi_operand" "")
10132 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10133 (match_operand:QI 2 "nonmemory_operand" "")))]
10137 ix86_expand_binary_operator (<CODE>, DImode, operands);
10138 else if (const_1_to_31_operand (operands[2], VOIDmode))
10139 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10140 (operands[0], operands[1], operands[2]));
10147 (define_expand "<rotate_insn><mode>3"
10148 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10149 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10150 (match_operand:QI 2 "nonmemory_operand" "")))]
10152 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10154 ;; Avoid useless masking of count operand.
10155 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10156 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10158 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10161 (match_operand:SI 2 "nonimmediate_operand" "c")
10162 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10163 (clobber (reg:CC FLAGS_REG))]
10164 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10165 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10166 == GET_MODE_BITSIZE (<MODE>mode)-1"
10169 [(parallel [(set (match_dup 0)
10170 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10171 (clobber (reg:CC FLAGS_REG))])]
10173 if (can_create_pseudo_p ())
10174 operands [2] = force_reg (SImode, operands[2]);
10176 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10178 [(set_attr "type" "rotate")
10179 (set_attr "mode" "<MODE>")])
10181 ;; Implement rotation using two double-precision
10182 ;; shift instructions and a scratch register.
10184 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10185 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10186 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10187 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10188 (clobber (reg:CC FLAGS_REG))
10189 (clobber (match_scratch:DWIH 3 "=&r"))]
10193 [(set (match_dup 3) (match_dup 4))
10195 [(set (match_dup 4)
10196 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10197 (lshiftrt:DWIH (match_dup 5)
10198 (minus:QI (match_dup 6) (match_dup 2)))))
10199 (clobber (reg:CC FLAGS_REG))])
10201 [(set (match_dup 5)
10202 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10203 (lshiftrt:DWIH (match_dup 3)
10204 (minus:QI (match_dup 6) (match_dup 2)))))
10205 (clobber (reg:CC FLAGS_REG))])]
10207 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10209 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10212 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10213 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10214 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10215 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10216 (clobber (reg:CC FLAGS_REG))
10217 (clobber (match_scratch:DWIH 3 "=&r"))]
10221 [(set (match_dup 3) (match_dup 4))
10223 [(set (match_dup 4)
10224 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10225 (ashift:DWIH (match_dup 5)
10226 (minus:QI (match_dup 6) (match_dup 2)))))
10227 (clobber (reg:CC FLAGS_REG))])
10229 [(set (match_dup 5)
10230 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10231 (ashift:DWIH (match_dup 3)
10232 (minus:QI (match_dup 6) (match_dup 2)))))
10233 (clobber (reg:CC FLAGS_REG))])]
10235 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10237 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10240 (define_insn "*<rotate_insn><mode>3_1"
10241 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10242 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10243 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10244 (clobber (reg:CC FLAGS_REG))]
10245 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10247 if (operands[2] == const1_rtx
10248 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10249 return "<rotate>{<imodesuffix>}\t%0";
10251 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10253 [(set_attr "type" "rotate")
10254 (set (attr "length_immediate")
10256 (and (match_operand 2 "const1_operand" "")
10257 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10260 (const_string "*")))
10261 (set_attr "mode" "<MODE>")])
10263 (define_insn "*<rotate_insn>si3_1_zext"
10264 [(set (match_operand:DI 0 "register_operand" "=r")
10266 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10267 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10268 (clobber (reg:CC FLAGS_REG))]
10269 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10271 if (operands[2] == const1_rtx
10272 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10273 return "<rotate>{l}\t%k0";
10275 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10277 [(set_attr "type" "rotate")
10278 (set (attr "length_immediate")
10280 (and (match_operand 2 "const1_operand" "")
10281 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10284 (const_string "*")))
10285 (set_attr "mode" "SI")])
10287 (define_insn "*<rotate_insn>qi3_1_slp"
10288 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10289 (any_rotate:QI (match_dup 0)
10290 (match_operand:QI 1 "nonmemory_operand" "cI")))
10291 (clobber (reg:CC FLAGS_REG))]
10292 "(optimize_function_for_size_p (cfun)
10293 || !TARGET_PARTIAL_REG_STALL
10294 || (operands[1] == const1_rtx
10295 && TARGET_SHIFT1))"
10297 if (operands[1] == const1_rtx
10298 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10299 return "<rotate>{b}\t%0";
10301 return "<rotate>{b}\t{%1, %0|%0, %1}";
10303 [(set_attr "type" "rotate1")
10304 (set (attr "length_immediate")
10306 (and (match_operand 1 "const1_operand" "")
10307 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10310 (const_string "*")))
10311 (set_attr "mode" "QI")])
10314 [(set (match_operand:HI 0 "register_operand" "")
10315 (any_rotate:HI (match_dup 0) (const_int 8)))
10316 (clobber (reg:CC FLAGS_REG))]
10318 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10319 [(parallel [(set (strict_low_part (match_dup 0))
10320 (bswap:HI (match_dup 0)))
10321 (clobber (reg:CC FLAGS_REG))])])
10323 ;; Bit set / bit test instructions
10325 (define_expand "extv"
10326 [(set (match_operand:SI 0 "register_operand" "")
10327 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10328 (match_operand:SI 2 "const8_operand" "")
10329 (match_operand:SI 3 "const8_operand" "")))]
10332 /* Handle extractions from %ah et al. */
10333 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10336 /* From mips.md: extract_bit_field doesn't verify that our source
10337 matches the predicate, so check it again here. */
10338 if (! ext_register_operand (operands[1], VOIDmode))
10342 (define_expand "extzv"
10343 [(set (match_operand:SI 0 "register_operand" "")
10344 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10345 (match_operand:SI 2 "const8_operand" "")
10346 (match_operand:SI 3 "const8_operand" "")))]
10349 /* Handle extractions from %ah et al. */
10350 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10353 /* From mips.md: extract_bit_field doesn't verify that our source
10354 matches the predicate, so check it again here. */
10355 if (! ext_register_operand (operands[1], VOIDmode))
10359 (define_expand "insv"
10360 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10361 (match_operand 1 "const8_operand" "")
10362 (match_operand 2 "const8_operand" ""))
10363 (match_operand 3 "register_operand" ""))]
10366 rtx (*gen_mov_insv_1) (rtx, rtx);
10368 /* Handle insertions to %ah et al. */
10369 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10372 /* From mips.md: insert_bit_field doesn't verify that our source
10373 matches the predicate, so check it again here. */
10374 if (! ext_register_operand (operands[0], VOIDmode))
10377 gen_mov_insv_1 = (TARGET_64BIT
10378 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10380 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10384 ;; %%% bts, btr, btc, bt.
10385 ;; In general these instructions are *slow* when applied to memory,
10386 ;; since they enforce atomic operation. When applied to registers,
10387 ;; it depends on the cpu implementation. They're never faster than
10388 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10389 ;; no point. But in 64-bit, we can't hold the relevant immediates
10390 ;; within the instruction itself, so operating on bits in the high
10391 ;; 32-bits of a register becomes easier.
10393 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10394 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10395 ;; negdf respectively, so they can never be disabled entirely.
10397 (define_insn "*btsq"
10398 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10400 (match_operand:DI 1 "const_0_to_63_operand" ""))
10402 (clobber (reg:CC FLAGS_REG))]
10403 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10404 "bts{q}\t{%1, %0|%0, %1}"
10405 [(set_attr "type" "alu1")
10406 (set_attr "prefix_0f" "1")
10407 (set_attr "mode" "DI")])
10409 (define_insn "*btrq"
10410 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10412 (match_operand:DI 1 "const_0_to_63_operand" ""))
10414 (clobber (reg:CC FLAGS_REG))]
10415 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10416 "btr{q}\t{%1, %0|%0, %1}"
10417 [(set_attr "type" "alu1")
10418 (set_attr "prefix_0f" "1")
10419 (set_attr "mode" "DI")])
10421 (define_insn "*btcq"
10422 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10424 (match_operand:DI 1 "const_0_to_63_operand" ""))
10425 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10426 (clobber (reg:CC FLAGS_REG))]
10427 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10428 "btc{q}\t{%1, %0|%0, %1}"
10429 [(set_attr "type" "alu1")
10430 (set_attr "prefix_0f" "1")
10431 (set_attr "mode" "DI")])
10433 ;; Allow Nocona to avoid these instructions if a register is available.
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" ""))
10442 (clobber (reg:CC FLAGS_REG))])]
10443 "TARGET_64BIT && !TARGET_USE_BT"
10446 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10449 if (HOST_BITS_PER_WIDE_INT >= 64)
10450 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10451 else if (i < HOST_BITS_PER_WIDE_INT)
10452 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10454 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10456 op1 = immed_double_const (lo, hi, DImode);
10459 emit_move_insn (operands[2], op1);
10463 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10468 [(match_scratch:DI 2 "r")
10469 (parallel [(set (zero_extract:DI
10470 (match_operand:DI 0 "register_operand" "")
10472 (match_operand:DI 1 "const_0_to_63_operand" ""))
10474 (clobber (reg:CC FLAGS_REG))])]
10475 "TARGET_64BIT && !TARGET_USE_BT"
10478 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10481 if (HOST_BITS_PER_WIDE_INT >= 64)
10482 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10483 else if (i < HOST_BITS_PER_WIDE_INT)
10484 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10486 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10488 op1 = immed_double_const (~lo, ~hi, DImode);
10491 emit_move_insn (operands[2], op1);
10495 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10500 [(match_scratch:DI 2 "r")
10501 (parallel [(set (zero_extract:DI
10502 (match_operand:DI 0 "register_operand" "")
10504 (match_operand:DI 1 "const_0_to_63_operand" ""))
10505 (not:DI (zero_extract:DI
10506 (match_dup 0) (const_int 1) (match_dup 1))))
10507 (clobber (reg:CC FLAGS_REG))])]
10508 "TARGET_64BIT && !TARGET_USE_BT"
10511 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10514 if (HOST_BITS_PER_WIDE_INT >= 64)
10515 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10516 else if (i < HOST_BITS_PER_WIDE_INT)
10517 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10519 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10521 op1 = immed_double_const (lo, hi, DImode);
10524 emit_move_insn (operands[2], op1);
10528 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10532 (define_insn "*bt<mode>"
10533 [(set (reg:CCC FLAGS_REG)
10535 (zero_extract:SWI48
10536 (match_operand:SWI48 0 "register_operand" "r")
10538 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10540 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10541 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10542 [(set_attr "type" "alu1")
10543 (set_attr "prefix_0f" "1")
10544 (set_attr "mode" "<MODE>")])
10546 ;; Store-flag instructions.
10548 ;; For all sCOND expanders, also expand the compare or test insn that
10549 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10551 (define_insn_and_split "*setcc_di_1"
10552 [(set (match_operand:DI 0 "register_operand" "=q")
10553 (match_operator:DI 1 "ix86_comparison_operator"
10554 [(reg FLAGS_REG) (const_int 0)]))]
10555 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10557 "&& reload_completed"
10558 [(set (match_dup 2) (match_dup 1))
10559 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10561 PUT_MODE (operands[1], QImode);
10562 operands[2] = gen_lowpart (QImode, operands[0]);
10565 (define_insn_and_split "*setcc_si_1_and"
10566 [(set (match_operand:SI 0 "register_operand" "=q")
10567 (match_operator:SI 1 "ix86_comparison_operator"
10568 [(reg FLAGS_REG) (const_int 0)]))
10569 (clobber (reg:CC FLAGS_REG))]
10570 "!TARGET_PARTIAL_REG_STALL
10571 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10573 "&& reload_completed"
10574 [(set (match_dup 2) (match_dup 1))
10575 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10576 (clobber (reg:CC FLAGS_REG))])]
10578 PUT_MODE (operands[1], QImode);
10579 operands[2] = gen_lowpart (QImode, operands[0]);
10582 (define_insn_and_split "*setcc_si_1_movzbl"
10583 [(set (match_operand:SI 0 "register_operand" "=q")
10584 (match_operator:SI 1 "ix86_comparison_operator"
10585 [(reg FLAGS_REG) (const_int 0)]))]
10586 "!TARGET_PARTIAL_REG_STALL
10587 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10589 "&& reload_completed"
10590 [(set (match_dup 2) (match_dup 1))
10591 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10593 PUT_MODE (operands[1], QImode);
10594 operands[2] = gen_lowpart (QImode, operands[0]);
10597 (define_insn "*setcc_qi"
10598 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10599 (match_operator:QI 1 "ix86_comparison_operator"
10600 [(reg FLAGS_REG) (const_int 0)]))]
10603 [(set_attr "type" "setcc")
10604 (set_attr "mode" "QI")])
10606 (define_insn "*setcc_qi_slp"
10607 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10608 (match_operator:QI 1 "ix86_comparison_operator"
10609 [(reg FLAGS_REG) (const_int 0)]))]
10612 [(set_attr "type" "setcc")
10613 (set_attr "mode" "QI")])
10615 ;; In general it is not safe to assume too much about CCmode registers,
10616 ;; so simplify-rtx stops when it sees a second one. Under certain
10617 ;; conditions this is safe on x86, so help combine not create
10624 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10625 (ne:QI (match_operator 1 "ix86_comparison_operator"
10626 [(reg FLAGS_REG) (const_int 0)])
10629 [(set (match_dup 0) (match_dup 1))]
10630 "PUT_MODE (operands[1], QImode);")
10633 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10634 (ne:QI (match_operator 1 "ix86_comparison_operator"
10635 [(reg FLAGS_REG) (const_int 0)])
10638 [(set (match_dup 0) (match_dup 1))]
10639 "PUT_MODE (operands[1], QImode);")
10642 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10643 (eq:QI (match_operator 1 "ix86_comparison_operator"
10644 [(reg FLAGS_REG) (const_int 0)])
10647 [(set (match_dup 0) (match_dup 1))]
10649 rtx new_op1 = copy_rtx (operands[1]);
10650 operands[1] = new_op1;
10651 PUT_MODE (new_op1, QImode);
10652 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10653 GET_MODE (XEXP (new_op1, 0))));
10655 /* Make sure that (a) the CCmode we have for the flags is strong
10656 enough for the reversed compare or (b) we have a valid FP compare. */
10657 if (! ix86_comparison_operator (new_op1, VOIDmode))
10662 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10663 (eq:QI (match_operator 1 "ix86_comparison_operator"
10664 [(reg FLAGS_REG) (const_int 0)])
10667 [(set (match_dup 0) (match_dup 1))]
10669 rtx new_op1 = copy_rtx (operands[1]);
10670 operands[1] = new_op1;
10671 PUT_MODE (new_op1, QImode);
10672 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10673 GET_MODE (XEXP (new_op1, 0))));
10675 /* Make sure that (a) the CCmode we have for the flags is strong
10676 enough for the reversed compare or (b) we have a valid FP compare. */
10677 if (! ix86_comparison_operator (new_op1, VOIDmode))
10681 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10682 ;; subsequent logical operations are used to imitate conditional moves.
10683 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10686 (define_insn "*avx_setcc<mode>"
10687 [(set (match_operand:MODEF 0 "register_operand" "=x")
10688 (match_operator:MODEF 1 "avx_comparison_float_operator"
10689 [(match_operand:MODEF 2 "register_operand" "x")
10690 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10692 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10693 [(set_attr "type" "ssecmp")
10694 (set_attr "prefix" "vex")
10695 (set_attr "length_immediate" "1")
10696 (set_attr "mode" "<MODE>")])
10698 (define_insn "*sse_setcc<mode>"
10699 [(set (match_operand:MODEF 0 "register_operand" "=x")
10700 (match_operator:MODEF 1 "sse_comparison_operator"
10701 [(match_operand:MODEF 2 "register_operand" "0")
10702 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10703 "SSE_FLOAT_MODE_P (<MODE>mode)"
10704 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10705 [(set_attr "type" "ssecmp")
10706 (set_attr "length_immediate" "1")
10707 (set_attr "mode" "<MODE>")])
10709 ;; Basic conditional jump instructions.
10710 ;; We ignore the overflow flag for signed branch instructions.
10712 (define_insn "*jcc_1"
10714 (if_then_else (match_operator 1 "ix86_comparison_operator"
10715 [(reg FLAGS_REG) (const_int 0)])
10716 (label_ref (match_operand 0 "" ""))
10720 [(set_attr "type" "ibr")
10721 (set_attr "modrm" "0")
10722 (set (attr "length")
10723 (if_then_else (and (ge (minus (match_dup 0) (pc))
10725 (lt (minus (match_dup 0) (pc))
10730 (define_insn "*jcc_2"
10732 (if_then_else (match_operator 1 "ix86_comparison_operator"
10733 [(reg FLAGS_REG) (const_int 0)])
10735 (label_ref (match_operand 0 "" ""))))]
10738 [(set_attr "type" "ibr")
10739 (set_attr "modrm" "0")
10740 (set (attr "length")
10741 (if_then_else (and (ge (minus (match_dup 0) (pc))
10743 (lt (minus (match_dup 0) (pc))
10748 ;; In general it is not safe to assume too much about CCmode registers,
10749 ;; so simplify-rtx stops when it sees a second one. Under certain
10750 ;; conditions this is safe on x86, so help combine not create
10758 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10759 [(reg FLAGS_REG) (const_int 0)])
10761 (label_ref (match_operand 1 "" ""))
10765 (if_then_else (match_dup 0)
10766 (label_ref (match_dup 1))
10768 "PUT_MODE (operands[0], VOIDmode);")
10772 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10773 [(reg FLAGS_REG) (const_int 0)])
10775 (label_ref (match_operand 1 "" ""))
10779 (if_then_else (match_dup 0)
10780 (label_ref (match_dup 1))
10783 rtx new_op0 = copy_rtx (operands[0]);
10784 operands[0] = new_op0;
10785 PUT_MODE (new_op0, VOIDmode);
10786 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10787 GET_MODE (XEXP (new_op0, 0))));
10789 /* Make sure that (a) the CCmode we have for the flags is strong
10790 enough for the reversed compare or (b) we have a valid FP compare. */
10791 if (! ix86_comparison_operator (new_op0, VOIDmode))
10795 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10796 ;; pass generates from shift insn with QImode operand. Actually, the mode
10797 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10798 ;; appropriate modulo of the bit offset value.
10800 (define_insn_and_split "*jcc_bt<mode>"
10802 (if_then_else (match_operator 0 "bt_comparison_operator"
10803 [(zero_extract:SWI48
10804 (match_operand:SWI48 1 "register_operand" "r")
10807 (match_operand:QI 2 "register_operand" "r")))
10809 (label_ref (match_operand 3 "" ""))
10811 (clobber (reg:CC FLAGS_REG))]
10812 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10815 [(set (reg:CCC FLAGS_REG)
10817 (zero_extract:SWI48
10823 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10824 (label_ref (match_dup 3))
10827 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10829 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10832 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10833 ;; also for DImode, this is what combine produces.
10834 (define_insn_and_split "*jcc_bt<mode>_mask"
10836 (if_then_else (match_operator 0 "bt_comparison_operator"
10837 [(zero_extract:SWI48
10838 (match_operand:SWI48 1 "register_operand" "r")
10841 (match_operand:SI 2 "register_operand" "r")
10842 (match_operand:SI 3 "const_int_operand" "n")))])
10843 (label_ref (match_operand 4 "" ""))
10845 (clobber (reg:CC FLAGS_REG))]
10846 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10847 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10848 == GET_MODE_BITSIZE (<MODE>mode)-1"
10851 [(set (reg:CCC FLAGS_REG)
10853 (zero_extract:SWI48
10859 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10860 (label_ref (match_dup 4))
10863 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10865 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10868 (define_insn_and_split "*jcc_btsi_1"
10870 (if_then_else (match_operator 0 "bt_comparison_operator"
10873 (match_operand:SI 1 "register_operand" "r")
10874 (match_operand:QI 2 "register_operand" "r"))
10877 (label_ref (match_operand 3 "" ""))
10879 (clobber (reg:CC FLAGS_REG))]
10880 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10883 [(set (reg:CCC FLAGS_REG)
10891 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10892 (label_ref (match_dup 3))
10895 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10897 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10900 ;; avoid useless masking of bit offset operand
10901 (define_insn_and_split "*jcc_btsi_mask_1"
10904 (match_operator 0 "bt_comparison_operator"
10907 (match_operand:SI 1 "register_operand" "r")
10910 (match_operand:SI 2 "register_operand" "r")
10911 (match_operand:SI 3 "const_int_operand" "n")) 0))
10914 (label_ref (match_operand 4 "" ""))
10916 (clobber (reg:CC FLAGS_REG))]
10917 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10918 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10921 [(set (reg:CCC FLAGS_REG)
10929 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10930 (label_ref (match_dup 4))
10932 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10934 ;; Define combination compare-and-branch fp compare instructions to help
10937 (define_insn "*fp_jcc_1_387"
10939 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10940 [(match_operand 1 "register_operand" "f")
10941 (match_operand 2 "nonimmediate_operand" "fm")])
10942 (label_ref (match_operand 3 "" ""))
10944 (clobber (reg:CCFP FPSR_REG))
10945 (clobber (reg:CCFP FLAGS_REG))
10946 (clobber (match_scratch:HI 4 "=a"))]
10948 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10949 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10950 && SELECT_CC_MODE (GET_CODE (operands[0]),
10951 operands[1], operands[2]) == CCFPmode
10955 (define_insn "*fp_jcc_1r_387"
10957 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10958 [(match_operand 1 "register_operand" "f")
10959 (match_operand 2 "nonimmediate_operand" "fm")])
10961 (label_ref (match_operand 3 "" ""))))
10962 (clobber (reg:CCFP FPSR_REG))
10963 (clobber (reg:CCFP FLAGS_REG))
10964 (clobber (match_scratch:HI 4 "=a"))]
10966 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10967 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10968 && SELECT_CC_MODE (GET_CODE (operands[0]),
10969 operands[1], operands[2]) == CCFPmode
10973 (define_insn "*fp_jcc_2_387"
10975 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10976 [(match_operand 1 "register_operand" "f")
10977 (match_operand 2 "register_operand" "f")])
10978 (label_ref (match_operand 3 "" ""))
10980 (clobber (reg:CCFP FPSR_REG))
10981 (clobber (reg:CCFP FLAGS_REG))
10982 (clobber (match_scratch:HI 4 "=a"))]
10983 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10984 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10988 (define_insn "*fp_jcc_2r_387"
10990 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10991 [(match_operand 1 "register_operand" "f")
10992 (match_operand 2 "register_operand" "f")])
10994 (label_ref (match_operand 3 "" ""))))
10995 (clobber (reg:CCFP FPSR_REG))
10996 (clobber (reg:CCFP FLAGS_REG))
10997 (clobber (match_scratch:HI 4 "=a"))]
10998 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10999 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11003 (define_insn "*fp_jcc_3_387"
11005 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11006 [(match_operand 1 "register_operand" "f")
11007 (match_operand 2 "const0_operand" "")])
11008 (label_ref (match_operand 3 "" ""))
11010 (clobber (reg:CCFP FPSR_REG))
11011 (clobber (reg:CCFP FLAGS_REG))
11012 (clobber (match_scratch:HI 4 "=a"))]
11013 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11014 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11015 && SELECT_CC_MODE (GET_CODE (operands[0]),
11016 operands[1], operands[2]) == CCFPmode
11022 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11023 [(match_operand 1 "register_operand" "")
11024 (match_operand 2 "nonimmediate_operand" "")])
11025 (match_operand 3 "" "")
11026 (match_operand 4 "" "")))
11027 (clobber (reg:CCFP FPSR_REG))
11028 (clobber (reg:CCFP FLAGS_REG))]
11032 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11033 operands[3], operands[4], NULL_RTX, NULL_RTX);
11039 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11040 [(match_operand 1 "register_operand" "")
11041 (match_operand 2 "general_operand" "")])
11042 (match_operand 3 "" "")
11043 (match_operand 4 "" "")))
11044 (clobber (reg:CCFP FPSR_REG))
11045 (clobber (reg:CCFP FLAGS_REG))
11046 (clobber (match_scratch:HI 5 "=a"))]
11050 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11051 operands[3], operands[4], operands[5], NULL_RTX);
11055 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11056 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11057 ;; with a precedence over other operators and is always put in the first
11058 ;; place. Swap condition and operands to match ficom instruction.
11060 (define_insn "*fp_jcc_4_<mode>_387"
11063 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11064 [(match_operator 1 "float_operator"
11065 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11066 (match_operand 3 "register_operand" "f,f")])
11067 (label_ref (match_operand 4 "" ""))
11069 (clobber (reg:CCFP FPSR_REG))
11070 (clobber (reg:CCFP FLAGS_REG))
11071 (clobber (match_scratch:HI 5 "=a,a"))]
11072 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11073 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11074 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11075 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11082 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11083 [(match_operator 1 "float_operator"
11084 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11085 (match_operand 3 "register_operand" "")])
11086 (match_operand 4 "" "")
11087 (match_operand 5 "" "")))
11088 (clobber (reg:CCFP FPSR_REG))
11089 (clobber (reg:CCFP FLAGS_REG))
11090 (clobber (match_scratch:HI 6 "=a"))]
11094 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11096 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11097 operands[3], operands[7],
11098 operands[4], operands[5], operands[6], NULL_RTX);
11102 ;; %%% Kill this when reload knows how to do it.
11106 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11107 [(match_operator 1 "float_operator"
11108 [(match_operand:X87MODEI12 2 "register_operand" "")])
11109 (match_operand 3 "register_operand" "")])
11110 (match_operand 4 "" "")
11111 (match_operand 5 "" "")))
11112 (clobber (reg:CCFP FPSR_REG))
11113 (clobber (reg:CCFP FLAGS_REG))
11114 (clobber (match_scratch:HI 6 "=a"))]
11118 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11119 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11121 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11122 operands[3], operands[7],
11123 operands[4], operands[5], operands[6], operands[2]);
11127 ;; Unconditional and other jump instructions
11129 (define_insn "jump"
11131 (label_ref (match_operand 0 "" "")))]
11134 [(set_attr "type" "ibr")
11135 (set (attr "length")
11136 (if_then_else (and (ge (minus (match_dup 0) (pc))
11138 (lt (minus (match_dup 0) (pc))
11142 (set_attr "modrm" "0")])
11144 (define_expand "indirect_jump"
11145 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11149 (define_insn "*indirect_jump"
11150 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11153 [(set_attr "type" "ibr")
11154 (set_attr "length_immediate" "0")])
11156 (define_expand "tablejump"
11157 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11158 (use (label_ref (match_operand 1 "" "")))])]
11161 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11162 relative. Convert the relative address to an absolute address. */
11166 enum rtx_code code;
11168 /* We can't use @GOTOFF for text labels on VxWorks;
11169 see gotoff_operand. */
11170 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11174 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11176 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11180 op1 = pic_offset_table_rtx;
11185 op0 = pic_offset_table_rtx;
11189 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11194 (define_insn "*tablejump_1"
11195 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11196 (use (label_ref (match_operand 1 "" "")))]
11199 [(set_attr "type" "ibr")
11200 (set_attr "length_immediate" "0")])
11202 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11205 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11206 (set (match_operand:QI 1 "register_operand" "")
11207 (match_operator:QI 2 "ix86_comparison_operator"
11208 [(reg FLAGS_REG) (const_int 0)]))
11209 (set (match_operand 3 "q_regs_operand" "")
11210 (zero_extend (match_dup 1)))]
11211 "(peep2_reg_dead_p (3, operands[1])
11212 || operands_match_p (operands[1], operands[3]))
11213 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11214 [(set (match_dup 4) (match_dup 0))
11215 (set (strict_low_part (match_dup 5))
11218 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11219 operands[5] = gen_lowpart (QImode, operands[3]);
11220 ix86_expand_clear (operands[3]);
11223 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11226 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11227 (set (match_operand:QI 1 "register_operand" "")
11228 (match_operator:QI 2 "ix86_comparison_operator"
11229 [(reg FLAGS_REG) (const_int 0)]))
11230 (parallel [(set (match_operand 3 "q_regs_operand" "")
11231 (zero_extend (match_dup 1)))
11232 (clobber (reg:CC FLAGS_REG))])]
11233 "(peep2_reg_dead_p (3, operands[1])
11234 || operands_match_p (operands[1], operands[3]))
11235 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11236 [(set (match_dup 4) (match_dup 0))
11237 (set (strict_low_part (match_dup 5))
11240 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11241 operands[5] = gen_lowpart (QImode, operands[3]);
11242 ix86_expand_clear (operands[3]);
11245 ;; Call instructions.
11247 ;; The predicates normally associated with named expanders are not properly
11248 ;; checked for calls. This is a bug in the generic code, but it isn't that
11249 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11251 ;; P6 processors will jump to the address after the decrement when %esp
11252 ;; is used as a call operand, so they will execute return address as a code.
11253 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11255 ;; Call subroutine returning no value.
11257 (define_expand "call_pop"
11258 [(parallel [(call (match_operand:QI 0 "" "")
11259 (match_operand:SI 1 "" ""))
11260 (set (reg:SI SP_REG)
11261 (plus:SI (reg:SI SP_REG)
11262 (match_operand:SI 3 "" "")))])]
11265 ix86_expand_call (NULL, operands[0], operands[1],
11266 operands[2], operands[3], 0);
11270 (define_insn_and_split "*call_pop_0_vzeroupper"
11272 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11273 (match_operand:SI 1 "" ""))
11274 (set (reg:SI SP_REG)
11275 (plus:SI (reg:SI SP_REG)
11276 (match_operand:SI 2 "immediate_operand" "")))])
11277 (unspec [(match_operand 3 "const_int_operand" "")]
11278 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11279 "TARGET_VZEROUPPER && !TARGET_64BIT"
11281 "&& reload_completed"
11283 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11284 [(set_attr "type" "call")])
11286 (define_insn "*call_pop_0"
11287 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11288 (match_operand:SI 1 "" ""))
11289 (set (reg:SI SP_REG)
11290 (plus:SI (reg:SI SP_REG)
11291 (match_operand:SI 2 "immediate_operand" "")))]
11294 if (SIBLING_CALL_P (insn))
11297 return "call\t%P0";
11299 [(set_attr "type" "call")])
11301 (define_insn_and_split "*call_pop_1_vzeroupper"
11303 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11304 (match_operand:SI 1 "" ""))
11305 (set (reg:SI SP_REG)
11306 (plus:SI (reg:SI SP_REG)
11307 (match_operand:SI 2 "immediate_operand" "i")))])
11308 (unspec [(match_operand 3 "const_int_operand" "")]
11309 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11310 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11312 "&& reload_completed"
11314 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11315 [(set_attr "type" "call")])
11317 (define_insn "*call_pop_1"
11318 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11319 (match_operand:SI 1 "" ""))
11320 (set (reg:SI SP_REG)
11321 (plus:SI (reg:SI SP_REG)
11322 (match_operand:SI 2 "immediate_operand" "i")))]
11323 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11325 if (constant_call_address_operand (operands[0], Pmode))
11326 return "call\t%P0";
11327 return "call\t%A0";
11329 [(set_attr "type" "call")])
11331 (define_insn_and_split "*sibcall_pop_1_vzeroupper"
11333 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11334 (match_operand:SI 1 "" ""))
11335 (set (reg:SI SP_REG)
11336 (plus:SI (reg:SI SP_REG)
11337 (match_operand:SI 2 "immediate_operand" "i,i")))])
11338 (unspec [(match_operand 3 "const_int_operand" "")]
11339 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11340 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11342 "&& reload_completed"
11344 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11345 [(set_attr "type" "call")])
11347 (define_insn "*sibcall_pop_1"
11348 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11349 (match_operand:SI 1 "" ""))
11350 (set (reg:SI SP_REG)
11351 (plus:SI (reg:SI SP_REG)
11352 (match_operand:SI 2 "immediate_operand" "i,i")))]
11353 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11357 [(set_attr "type" "call")])
11359 (define_expand "call"
11360 [(call (match_operand:QI 0 "" "")
11361 (match_operand 1 "" ""))
11362 (use (match_operand 2 "" ""))]
11365 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11369 (define_expand "sibcall"
11370 [(call (match_operand:QI 0 "" "")
11371 (match_operand 1 "" ""))
11372 (use (match_operand 2 "" ""))]
11375 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11379 (define_insn_and_split "*call_0_vzeroupper"
11380 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11381 (match_operand 1 "" ""))
11382 (unspec [(match_operand 2 "const_int_operand" "")]
11383 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11384 "TARGET_VZEROUPPER"
11386 "&& reload_completed"
11388 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11389 [(set_attr "type" "call")])
11391 (define_insn "*call_0"
11392 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11393 (match_operand 1 "" ""))]
11395 { return ix86_output_call_insn (insn, operands[0], 0); }
11396 [(set_attr "type" "call")])
11398 (define_insn_and_split "*call_1_vzeroupper"
11399 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11400 (match_operand 1 "" ""))
11401 (unspec [(match_operand 2 "const_int_operand" "")]
11402 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11403 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11405 "&& reload_completed"
11407 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11408 [(set_attr "type" "call")])
11410 (define_insn "*call_1"
11411 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11412 (match_operand 1 "" ""))]
11413 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11414 { return ix86_output_call_insn (insn, operands[0], 0); }
11415 [(set_attr "type" "call")])
11417 (define_insn_and_split "*sibcall_1_vzeroupper"
11418 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11419 (match_operand 1 "" ""))
11420 (unspec [(match_operand 2 "const_int_operand" "")]
11421 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11422 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11424 "&& reload_completed"
11426 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11427 [(set_attr "type" "call")])
11429 (define_insn "*sibcall_1"
11430 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11431 (match_operand 1 "" ""))]
11432 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11433 { return ix86_output_call_insn (insn, operands[0], 0); }
11434 [(set_attr "type" "call")])
11436 (define_insn_and_split "*call_1_rex64_vzeroupper"
11437 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11438 (match_operand 1 "" ""))
11439 (unspec [(match_operand 2 "const_int_operand" "")]
11440 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11441 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
11442 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11444 "&& reload_completed"
11446 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11447 [(set_attr "type" "call")])
11449 (define_insn "*call_1_rex64"
11450 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11451 (match_operand 1 "" ""))]
11452 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11453 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11454 { return ix86_output_call_insn (insn, operands[0], 0); }
11455 [(set_attr "type" "call")])
11457 (define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
11459 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11460 (match_operand 1 "" ""))
11461 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11462 (clobber (reg:TI XMM6_REG))
11463 (clobber (reg:TI XMM7_REG))
11464 (clobber (reg:TI XMM8_REG))
11465 (clobber (reg:TI XMM9_REG))
11466 (clobber (reg:TI XMM10_REG))
11467 (clobber (reg:TI XMM11_REG))
11468 (clobber (reg:TI XMM12_REG))
11469 (clobber (reg:TI XMM13_REG))
11470 (clobber (reg:TI XMM14_REG))
11471 (clobber (reg:TI XMM15_REG))
11472 (clobber (reg:DI SI_REG))
11473 (clobber (reg:DI DI_REG))])
11474 (unspec [(match_operand 2 "const_int_operand" "")]
11475 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11476 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11478 "&& reload_completed"
11480 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11481 [(set_attr "type" "call")])
11483 (define_insn "*call_1_rex64_ms_sysv"
11484 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11485 (match_operand 1 "" ""))
11486 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11487 (clobber (reg:TI XMM6_REG))
11488 (clobber (reg:TI XMM7_REG))
11489 (clobber (reg:TI XMM8_REG))
11490 (clobber (reg:TI XMM9_REG))
11491 (clobber (reg:TI XMM10_REG))
11492 (clobber (reg:TI XMM11_REG))
11493 (clobber (reg:TI XMM12_REG))
11494 (clobber (reg:TI XMM13_REG))
11495 (clobber (reg:TI XMM14_REG))
11496 (clobber (reg:TI XMM15_REG))
11497 (clobber (reg:DI SI_REG))
11498 (clobber (reg:DI DI_REG))]
11499 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11500 { return ix86_output_call_insn (insn, operands[0], 0); }
11501 [(set_attr "type" "call")])
11503 (define_insn_and_split "*call_1_rex64_large_vzeroupper"
11504 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11505 (match_operand 1 "" ""))
11506 (unspec [(match_operand 2 "const_int_operand" "")]
11507 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11508 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11510 "&& reload_completed"
11512 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11513 [(set_attr "type" "call")])
11515 (define_insn "*call_1_rex64_large"
11516 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11517 (match_operand 1 "" ""))]
11518 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11519 { return ix86_output_call_insn (insn, operands[0], 0); }
11520 [(set_attr "type" "call")])
11522 (define_insn_and_split "*sibcall_1_rex64_vzeroupper"
11523 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11524 (match_operand 1 "" ""))
11525 (unspec [(match_operand 2 "const_int_operand" "")]
11526 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11527 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
11529 "&& reload_completed"
11531 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11532 [(set_attr "type" "call")])
11534 (define_insn "*sibcall_1_rex64"
11535 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11536 (match_operand 1 "" ""))]
11537 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11538 { return ix86_output_call_insn (insn, operands[0], 0); }
11539 [(set_attr "type" "call")])
11541 ;; Call subroutine, returning value in operand 0
11542 (define_expand "call_value_pop"
11543 [(parallel [(set (match_operand 0 "" "")
11544 (call (match_operand:QI 1 "" "")
11545 (match_operand:SI 2 "" "")))
11546 (set (reg:SI SP_REG)
11547 (plus:SI (reg:SI SP_REG)
11548 (match_operand:SI 4 "" "")))])]
11551 ix86_expand_call (operands[0], operands[1], operands[2],
11552 operands[3], operands[4], 0);
11556 (define_expand "call_value"
11557 [(set (match_operand 0 "" "")
11558 (call (match_operand:QI 1 "" "")
11559 (match_operand:SI 2 "" "")))
11560 (use (match_operand:SI 3 "" ""))]
11561 ;; Operand 3 is not used on the i386.
11564 ix86_expand_call (operands[0], operands[1], operands[2],
11565 operands[3], NULL, 0);
11569 (define_expand "sibcall_value"
11570 [(set (match_operand 0 "" "")
11571 (call (match_operand:QI 1 "" "")
11572 (match_operand:SI 2 "" "")))
11573 (use (match_operand:SI 3 "" ""))]
11574 ;; Operand 3 is not used on the i386.
11577 ix86_expand_call (operands[0], operands[1], operands[2],
11578 operands[3], NULL, 1);
11582 ;; Call subroutine returning any type.
11584 (define_expand "untyped_call"
11585 [(parallel [(call (match_operand 0 "" "")
11587 (match_operand 1 "" "")
11588 (match_operand 2 "" "")])]
11593 /* In order to give reg-stack an easier job in validating two
11594 coprocessor registers as containing a possible return value,
11595 simply pretend the untyped call returns a complex long double
11598 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11599 and should have the default ABI. */
11601 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11602 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11603 operands[0], const0_rtx,
11604 GEN_INT ((TARGET_64BIT
11605 ? (ix86_abi == SYSV_ABI
11606 ? X86_64_SSE_REGPARM_MAX
11607 : X86_64_MS_SSE_REGPARM_MAX)
11608 : X86_32_SSE_REGPARM_MAX)
11612 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11614 rtx set = XVECEXP (operands[2], 0, i);
11615 emit_move_insn (SET_DEST (set), SET_SRC (set));
11618 /* The optimizer does not know that the call sets the function value
11619 registers we stored in the result block. We avoid problems by
11620 claiming that all hard registers are used and clobbered at this
11622 emit_insn (gen_blockage ());
11627 ;; Prologue and epilogue instructions
11629 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11630 ;; all of memory. This blocks insns from being moved across this point.
11632 (define_insn "blockage"
11633 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11636 [(set_attr "length" "0")])
11638 ;; Do not schedule instructions accessing memory across this point.
11640 (define_expand "memory_blockage"
11641 [(set (match_dup 0)
11642 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11645 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11646 MEM_VOLATILE_P (operands[0]) = 1;
11649 (define_insn "*memory_blockage"
11650 [(set (match_operand:BLK 0 "" "")
11651 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11654 [(set_attr "length" "0")])
11656 ;; As USE insns aren't meaningful after reload, this is used instead
11657 ;; to prevent deleting instructions setting registers for PIC code
11658 (define_insn "prologue_use"
11659 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11662 [(set_attr "length" "0")])
11664 ;; Insn emitted into the body of a function to return from a function.
11665 ;; This is only done if the function's epilogue is known to be simple.
11666 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11668 (define_expand "return"
11670 "ix86_can_use_return_insn_p ()"
11672 if (crtl->args.pops_args)
11674 rtx popc = GEN_INT (crtl->args.pops_args);
11675 emit_jump_insn (gen_return_pop_internal (popc));
11680 (define_insn "return_internal"
11684 [(set_attr "length" "1")
11685 (set_attr "atom_unit" "jeu")
11686 (set_attr "length_immediate" "0")
11687 (set_attr "modrm" "0")])
11689 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11690 ;; instruction Athlon and K8 have.
11692 (define_insn "return_internal_long"
11694 (unspec [(const_int 0)] UNSPEC_REP)]
11697 [(set_attr "length" "2")
11698 (set_attr "atom_unit" "jeu")
11699 (set_attr "length_immediate" "0")
11700 (set_attr "prefix_rep" "1")
11701 (set_attr "modrm" "0")])
11703 (define_insn "return_pop_internal"
11705 (use (match_operand:SI 0 "const_int_operand" ""))]
11708 [(set_attr "length" "3")
11709 (set_attr "atom_unit" "jeu")
11710 (set_attr "length_immediate" "2")
11711 (set_attr "modrm" "0")])
11713 (define_insn "return_indirect_internal"
11715 (use (match_operand:SI 0 "register_operand" "r"))]
11718 [(set_attr "type" "ibr")
11719 (set_attr "length_immediate" "0")])
11725 [(set_attr "length" "1")
11726 (set_attr "length_immediate" "0")
11727 (set_attr "modrm" "0")])
11729 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11730 (define_insn "nops"
11731 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11735 int num = INTVAL (operands[0]);
11737 gcc_assert (num >= 1 && num <= 8);
11740 fputs ("\tnop\n", asm_out_file);
11744 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11745 (set_attr "length_immediate" "0")
11746 (set_attr "modrm" "0")])
11748 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11749 ;; branch prediction penalty for the third jump in a 16-byte
11753 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11756 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11757 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11759 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11760 The align insn is used to avoid 3 jump instructions in the row to improve
11761 branch prediction and the benefits hardly outweigh the cost of extra 8
11762 nops on the average inserted by full alignment pseudo operation. */
11766 [(set_attr "length" "16")])
11768 (define_expand "prologue"
11771 "ix86_expand_prologue (); DONE;")
11773 (define_insn "set_got"
11774 [(set (match_operand:SI 0 "register_operand" "=r")
11775 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11776 (clobber (reg:CC FLAGS_REG))]
11778 "* return output_set_got (operands[0], NULL_RTX);"
11779 [(set_attr "type" "multi")
11780 (set_attr "length" "12")])
11782 (define_insn "set_got_labelled"
11783 [(set (match_operand:SI 0 "register_operand" "=r")
11784 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11786 (clobber (reg:CC FLAGS_REG))]
11788 "* return output_set_got (operands[0], operands[1]);"
11789 [(set_attr "type" "multi")
11790 (set_attr "length" "12")])
11792 (define_insn "set_got_rex64"
11793 [(set (match_operand:DI 0 "register_operand" "=r")
11794 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11796 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11797 [(set_attr "type" "lea")
11798 (set_attr "length_address" "4")
11799 (set_attr "mode" "DI")])
11801 (define_insn "set_rip_rex64"
11802 [(set (match_operand:DI 0 "register_operand" "=r")
11803 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11805 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11806 [(set_attr "type" "lea")
11807 (set_attr "length_address" "4")
11808 (set_attr "mode" "DI")])
11810 (define_insn "set_got_offset_rex64"
11811 [(set (match_operand:DI 0 "register_operand" "=r")
11813 [(label_ref (match_operand 1 "" ""))]
11814 UNSPEC_SET_GOT_OFFSET))]
11816 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11817 [(set_attr "type" "imov")
11818 (set_attr "length_immediate" "0")
11819 (set_attr "length_address" "8")
11820 (set_attr "mode" "DI")])
11822 (define_expand "epilogue"
11825 "ix86_expand_epilogue (1); DONE;")
11827 (define_expand "sibcall_epilogue"
11830 "ix86_expand_epilogue (0); DONE;")
11832 (define_expand "eh_return"
11833 [(use (match_operand 0 "register_operand" ""))]
11836 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11838 /* Tricky bit: we write the address of the handler to which we will
11839 be returning into someone else's stack frame, one word below the
11840 stack address we wish to restore. */
11841 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11842 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11843 tmp = gen_rtx_MEM (Pmode, tmp);
11844 emit_move_insn (tmp, ra);
11846 emit_jump_insn (gen_eh_return_internal ());
11851 (define_insn_and_split "eh_return_internal"
11855 "epilogue_completed"
11857 "ix86_expand_epilogue (2); DONE;")
11859 (define_insn "leave"
11860 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11861 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11862 (clobber (mem:BLK (scratch)))]
11865 [(set_attr "type" "leave")])
11867 (define_insn "leave_rex64"
11868 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11869 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11870 (clobber (mem:BLK (scratch)))]
11873 [(set_attr "type" "leave")])
11875 ;; Handle -fsplit-stack.
11877 (define_expand "split_stack_prologue"
11881 ix86_expand_split_stack_prologue ();
11885 ;; In order to support the call/return predictor, we use a return
11886 ;; instruction which the middle-end doesn't see.
11887 (define_insn "split_stack_return"
11888 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11889 UNSPECV_SPLIT_STACK_RETURN)]
11892 if (operands[0] == const0_rtx)
11897 [(set_attr "atom_unit" "jeu")
11898 (set_attr "modrm" "0")
11899 (set (attr "length")
11900 (if_then_else (match_operand:SI 0 "const0_operand" "")
11903 (set (attr "length_immediate")
11904 (if_then_else (match_operand:SI 0 "const0_operand" "")
11908 ;; If there are operand 0 bytes available on the stack, jump to
11911 (define_expand "split_stack_space_check"
11912 [(set (pc) (if_then_else
11913 (ltu (minus (reg SP_REG)
11914 (match_operand 0 "register_operand" ""))
11915 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11916 (label_ref (match_operand 1 "" ""))
11920 rtx reg, size, limit;
11922 reg = gen_reg_rtx (Pmode);
11923 size = force_reg (Pmode, operands[0]);
11924 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11925 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11926 UNSPEC_STACK_CHECK);
11927 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11928 ix86_expand_branch (GEU, reg, limit, operands[1]);
11933 ;; Bit manipulation instructions.
11935 (define_expand "ffs<mode>2"
11936 [(set (match_dup 2) (const_int -1))
11937 (parallel [(set (reg:CCZ FLAGS_REG)
11939 (match_operand:SWI48 1 "nonimmediate_operand" "")
11941 (set (match_operand:SWI48 0 "register_operand" "")
11942 (ctz:SWI48 (match_dup 1)))])
11943 (set (match_dup 0) (if_then_else:SWI48
11944 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11947 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11948 (clobber (reg:CC FLAGS_REG))])]
11951 if (<MODE>mode == SImode && !TARGET_CMOVE)
11953 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11956 operands[2] = gen_reg_rtx (<MODE>mode);
11959 (define_insn_and_split "ffssi2_no_cmove"
11960 [(set (match_operand:SI 0 "register_operand" "=r")
11961 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11962 (clobber (match_scratch:SI 2 "=&q"))
11963 (clobber (reg:CC FLAGS_REG))]
11966 "&& reload_completed"
11967 [(parallel [(set (reg:CCZ FLAGS_REG)
11968 (compare:CCZ (match_dup 1) (const_int 0)))
11969 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11970 (set (strict_low_part (match_dup 3))
11971 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11972 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11973 (clobber (reg:CC FLAGS_REG))])
11974 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11975 (clobber (reg:CC FLAGS_REG))])
11976 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11977 (clobber (reg:CC FLAGS_REG))])]
11979 operands[3] = gen_lowpart (QImode, operands[2]);
11980 ix86_expand_clear (operands[2]);
11983 (define_insn "*ffs<mode>_1"
11984 [(set (reg:CCZ FLAGS_REG)
11985 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11987 (set (match_operand:SWI48 0 "register_operand" "=r")
11988 (ctz:SWI48 (match_dup 1)))]
11990 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11991 [(set_attr "type" "alu1")
11992 (set_attr "prefix_0f" "1")
11993 (set_attr "mode" "<MODE>")])
11995 (define_insn "ctz<mode>2"
11996 [(set (match_operand:SWI248 0 "register_operand" "=r")
11997 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11998 (clobber (reg:CC FLAGS_REG))]
12002 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12004 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12006 [(set_attr "type" "alu1")
12007 (set_attr "prefix_0f" "1")
12008 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12009 (set_attr "mode" "<MODE>")])
12011 (define_expand "clz<mode>2"
12013 [(set (match_operand:SWI248 0 "register_operand" "")
12016 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12017 (clobber (reg:CC FLAGS_REG))])
12019 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12020 (clobber (reg:CC FLAGS_REG))])]
12025 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12028 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12031 (define_insn "clz<mode>2_abm"
12032 [(set (match_operand:SWI248 0 "register_operand" "=r")
12033 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12034 (clobber (reg:CC FLAGS_REG))]
12035 "TARGET_ABM || TARGET_BMI"
12036 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12037 [(set_attr "prefix_rep" "1")
12038 (set_attr "type" "bitmanip")
12039 (set_attr "mode" "<MODE>")])
12041 ;; BMI instructions.
12042 (define_insn "*bmi_andn_<mode>"
12043 [(set (match_operand:SWI48 0 "register_operand" "=r")
12046 (match_operand:SWI48 1 "register_operand" "r"))
12047 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12048 (clobber (reg:CC FLAGS_REG))]
12050 "andn\t{%2, %1, %0|%0, %1, %2}"
12051 [(set_attr "type" "bitmanip")
12052 (set_attr "mode" "<MODE>")])
12054 (define_insn "bmi_bextr_<mode>"
12055 [(set (match_operand:SWI48 0 "register_operand" "=r")
12056 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12057 (match_operand:SWI48 2 "register_operand" "r")]
12059 (clobber (reg:CC FLAGS_REG))]
12061 "bextr\t{%2, %1, %0|%0, %1, %2}"
12062 [(set_attr "type" "bitmanip")
12063 (set_attr "mode" "<MODE>")])
12065 (define_insn "*bmi_blsi_<mode>"
12066 [(set (match_operand:SWI48 0 "register_operand" "=r")
12069 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12071 (clobber (reg:CC FLAGS_REG))]
12073 "blsi\t{%1, %0|%0, %1}"
12074 [(set_attr "type" "bitmanip")
12075 (set_attr "mode" "<MODE>")])
12077 (define_insn "*bmi_blsmsk_<mode>"
12078 [(set (match_operand:SWI48 0 "register_operand" "=r")
12081 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12084 (clobber (reg:CC FLAGS_REG))]
12086 "blsmsk\t{%1, %0|%0, %1}"
12087 [(set_attr "type" "bitmanip")
12088 (set_attr "mode" "<MODE>")])
12090 (define_insn "*bmi_blsr_<mode>"
12091 [(set (match_operand:SWI48 0 "register_operand" "=r")
12094 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12097 (clobber (reg:CC FLAGS_REG))]
12099 "blsr\t{%1, %0|%0, %1}"
12100 [(set_attr "type" "bitmanip")
12101 (set_attr "mode" "<MODE>")])
12103 ;; TBM instructions.
12104 (define_insn "tbm_bextri_<mode>"
12105 [(set (match_operand:SWI48 0 "register_operand" "=r")
12106 (zero_extract:SWI48
12107 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12108 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12109 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12110 (clobber (reg:CC FLAGS_REG))]
12113 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12114 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12116 [(set_attr "type" "bitmanip")
12117 (set_attr "mode" "<MODE>")])
12119 (define_insn "*tbm_blcfill_<mode>"
12120 [(set (match_operand:SWI48 0 "register_operand" "=r")
12123 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12126 (clobber (reg:CC FLAGS_REG))]
12128 "blcfill\t{%1, %0|%0, %1}"
12129 [(set_attr "type" "bitmanip")
12130 (set_attr "mode" "<MODE>")])
12132 (define_insn "*tbm_blci_<mode>"
12133 [(set (match_operand:SWI48 0 "register_operand" "=r")
12137 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12140 (clobber (reg:CC FLAGS_REG))]
12142 "blci\t{%1, %0|%0, %1}"
12143 [(set_attr "type" "bitmanip")
12144 (set_attr "mode" "<MODE>")])
12146 (define_insn "*tbm_blcic_<mode>"
12147 [(set (match_operand:SWI48 0 "register_operand" "=r")
12150 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12154 (clobber (reg:CC FLAGS_REG))]
12156 "blcic\t{%1, %0|%0, %1}"
12157 [(set_attr "type" "bitmanip")
12158 (set_attr "mode" "<MODE>")])
12160 (define_insn "*tbm_blcmsk_<mode>"
12161 [(set (match_operand:SWI48 0 "register_operand" "=r")
12164 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12167 (clobber (reg:CC FLAGS_REG))]
12169 "blcmsk\t{%1, %0|%0, %1}"
12170 [(set_attr "type" "bitmanip")
12171 (set_attr "mode" "<MODE>")])
12173 (define_insn "*tbm_blcs_<mode>"
12174 [(set (match_operand:SWI48 0 "register_operand" "=r")
12177 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12180 (clobber (reg:CC FLAGS_REG))]
12182 "blcs\t{%1, %0|%0, %1}"
12183 [(set_attr "type" "bitmanip")
12184 (set_attr "mode" "<MODE>")])
12186 (define_insn "*tbm_blsfill_<mode>"
12187 [(set (match_operand:SWI48 0 "register_operand" "=r")
12190 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12193 (clobber (reg:CC FLAGS_REG))]
12195 "blsfill\t{%1, %0|%0, %1}"
12196 [(set_attr "type" "bitmanip")
12197 (set_attr "mode" "<MODE>")])
12199 (define_insn "*tbm_blsic_<mode>"
12200 [(set (match_operand:SWI48 0 "register_operand" "=r")
12203 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12207 (clobber (reg:CC FLAGS_REG))]
12209 "blsic\t{%1, %0|%0, %1}"
12210 [(set_attr "type" "bitmanip")
12211 (set_attr "mode" "<MODE>")])
12213 (define_insn "*tbm_t1mskc_<mode>"
12214 [(set (match_operand:SWI48 0 "register_operand" "=r")
12217 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12221 (clobber (reg:CC FLAGS_REG))]
12223 "t1mskc\t{%1, %0|%0, %1}"
12224 [(set_attr "type" "bitmanip")
12225 (set_attr "mode" "<MODE>")])
12227 (define_insn "*tbm_tzmsk_<mode>"
12228 [(set (match_operand:SWI48 0 "register_operand" "=r")
12231 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12235 (clobber (reg:CC FLAGS_REG))]
12237 "tzmsk\t{%1, %0|%0, %1}"
12238 [(set_attr "type" "bitmanip")
12239 (set_attr "mode" "<MODE>")])
12241 (define_insn "bsr_rex64"
12242 [(set (match_operand:DI 0 "register_operand" "=r")
12243 (minus:DI (const_int 63)
12244 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12245 (clobber (reg:CC FLAGS_REG))]
12247 "bsr{q}\t{%1, %0|%0, %1}"
12248 [(set_attr "type" "alu1")
12249 (set_attr "prefix_0f" "1")
12250 (set_attr "mode" "DI")])
12253 [(set (match_operand:SI 0 "register_operand" "=r")
12254 (minus:SI (const_int 31)
12255 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12256 (clobber (reg:CC FLAGS_REG))]
12258 "bsr{l}\t{%1, %0|%0, %1}"
12259 [(set_attr "type" "alu1")
12260 (set_attr "prefix_0f" "1")
12261 (set_attr "mode" "SI")])
12263 (define_insn "*bsrhi"
12264 [(set (match_operand:HI 0 "register_operand" "=r")
12265 (minus:HI (const_int 15)
12266 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12267 (clobber (reg:CC FLAGS_REG))]
12269 "bsr{w}\t{%1, %0|%0, %1}"
12270 [(set_attr "type" "alu1")
12271 (set_attr "prefix_0f" "1")
12272 (set_attr "mode" "HI")])
12274 (define_insn "popcount<mode>2"
12275 [(set (match_operand:SWI248 0 "register_operand" "=r")
12277 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12278 (clobber (reg:CC FLAGS_REG))]
12282 return "popcnt\t{%1, %0|%0, %1}";
12284 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12287 [(set_attr "prefix_rep" "1")
12288 (set_attr "type" "bitmanip")
12289 (set_attr "mode" "<MODE>")])
12291 (define_insn "*popcount<mode>2_cmp"
12292 [(set (reg FLAGS_REG)
12295 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12297 (set (match_operand:SWI248 0 "register_operand" "=r")
12298 (popcount:SWI248 (match_dup 1)))]
12299 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12302 return "popcnt\t{%1, %0|%0, %1}";
12304 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12307 [(set_attr "prefix_rep" "1")
12308 (set_attr "type" "bitmanip")
12309 (set_attr "mode" "<MODE>")])
12311 (define_insn "*popcountsi2_cmp_zext"
12312 [(set (reg FLAGS_REG)
12314 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12316 (set (match_operand:DI 0 "register_operand" "=r")
12317 (zero_extend:DI(popcount:SI (match_dup 1))))]
12318 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12321 return "popcnt\t{%1, %0|%0, %1}";
12323 return "popcnt{l}\t{%1, %0|%0, %1}";
12326 [(set_attr "prefix_rep" "1")
12327 (set_attr "type" "bitmanip")
12328 (set_attr "mode" "SI")])
12330 (define_expand "bswap<mode>2"
12331 [(set (match_operand:SWI48 0 "register_operand" "")
12332 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12335 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12337 rtx x = operands[0];
12339 emit_move_insn (x, operands[1]);
12340 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12341 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12342 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12347 (define_insn "*bswap<mode>2_movbe"
12348 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12349 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12351 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12354 movbe\t{%1, %0|%0, %1}
12355 movbe\t{%1, %0|%0, %1}"
12356 [(set_attr "type" "bitmanip,imov,imov")
12357 (set_attr "modrm" "0,1,1")
12358 (set_attr "prefix_0f" "*,1,1")
12359 (set_attr "prefix_extra" "*,1,1")
12360 (set_attr "mode" "<MODE>")])
12362 (define_insn "*bswap<mode>2_1"
12363 [(set (match_operand:SWI48 0 "register_operand" "=r")
12364 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12367 [(set_attr "type" "bitmanip")
12368 (set_attr "modrm" "0")
12369 (set_attr "mode" "<MODE>")])
12371 (define_insn "*bswaphi_lowpart_1"
12372 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12373 (bswap:HI (match_dup 0)))
12374 (clobber (reg:CC FLAGS_REG))]
12375 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12377 xchg{b}\t{%h0, %b0|%b0, %h0}
12378 rol{w}\t{$8, %0|%0, 8}"
12379 [(set_attr "length" "2,4")
12380 (set_attr "mode" "QI,HI")])
12382 (define_insn "bswaphi_lowpart"
12383 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12384 (bswap:HI (match_dup 0)))
12385 (clobber (reg:CC FLAGS_REG))]
12387 "rol{w}\t{$8, %0|%0, 8}"
12388 [(set_attr "length" "4")
12389 (set_attr "mode" "HI")])
12391 (define_expand "paritydi2"
12392 [(set (match_operand:DI 0 "register_operand" "")
12393 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12396 rtx scratch = gen_reg_rtx (QImode);
12399 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12400 NULL_RTX, operands[1]));
12402 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12403 gen_rtx_REG (CCmode, FLAGS_REG),
12405 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12408 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12411 rtx tmp = gen_reg_rtx (SImode);
12413 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12414 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12419 (define_expand "paritysi2"
12420 [(set (match_operand:SI 0 "register_operand" "")
12421 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12424 rtx scratch = gen_reg_rtx (QImode);
12427 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12429 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12430 gen_rtx_REG (CCmode, FLAGS_REG),
12432 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12434 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12438 (define_insn_and_split "paritydi2_cmp"
12439 [(set (reg:CC FLAGS_REG)
12440 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12442 (clobber (match_scratch:DI 0 "=r"))
12443 (clobber (match_scratch:SI 1 "=&r"))
12444 (clobber (match_scratch:HI 2 "=Q"))]
12447 "&& reload_completed"
12449 [(set (match_dup 1)
12450 (xor:SI (match_dup 1) (match_dup 4)))
12451 (clobber (reg:CC FLAGS_REG))])
12453 [(set (reg:CC FLAGS_REG)
12454 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12455 (clobber (match_dup 1))
12456 (clobber (match_dup 2))])]
12458 operands[4] = gen_lowpart (SImode, operands[3]);
12462 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12463 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12466 operands[1] = gen_highpart (SImode, operands[3]);
12469 (define_insn_and_split "paritysi2_cmp"
12470 [(set (reg:CC FLAGS_REG)
12471 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12473 (clobber (match_scratch:SI 0 "=r"))
12474 (clobber (match_scratch:HI 1 "=&Q"))]
12477 "&& reload_completed"
12479 [(set (match_dup 1)
12480 (xor:HI (match_dup 1) (match_dup 3)))
12481 (clobber (reg:CC FLAGS_REG))])
12483 [(set (reg:CC FLAGS_REG)
12484 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12485 (clobber (match_dup 1))])]
12487 operands[3] = gen_lowpart (HImode, operands[2]);
12489 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12490 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12493 (define_insn "*parityhi2_cmp"
12494 [(set (reg:CC FLAGS_REG)
12495 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12497 (clobber (match_scratch:HI 0 "=Q"))]
12499 "xor{b}\t{%h0, %b0|%b0, %h0}"
12500 [(set_attr "length" "2")
12501 (set_attr "mode" "HI")])
12503 ;; Thread-local storage patterns for ELF.
12505 ;; Note that these code sequences must appear exactly as shown
12506 ;; in order to allow linker relaxation.
12508 (define_insn "*tls_global_dynamic_32_gnu"
12509 [(set (match_operand:SI 0 "register_operand" "=a")
12510 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12511 (match_operand:SI 2 "tls_symbolic_operand" "")
12512 (match_operand:SI 3 "call_insn_operand" "")]
12514 (clobber (match_scratch:SI 4 "=d"))
12515 (clobber (match_scratch:SI 5 "=c"))
12516 (clobber (reg:CC FLAGS_REG))]
12517 "!TARGET_64BIT && TARGET_GNU_TLS"
12518 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12519 [(set_attr "type" "multi")
12520 (set_attr "length" "12")])
12522 (define_expand "tls_global_dynamic_32"
12523 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12526 (match_operand:SI 1 "tls_symbolic_operand" "")
12529 (clobber (match_scratch:SI 4 ""))
12530 (clobber (match_scratch:SI 5 ""))
12531 (clobber (reg:CC FLAGS_REG))])]
12535 operands[2] = pic_offset_table_rtx;
12538 operands[2] = gen_reg_rtx (Pmode);
12539 emit_insn (gen_set_got (operands[2]));
12541 if (TARGET_GNU2_TLS)
12543 emit_insn (gen_tls_dynamic_gnu2_32
12544 (operands[0], operands[1], operands[2]));
12547 operands[3] = ix86_tls_get_addr ();
12550 (define_insn "*tls_global_dynamic_64"
12551 [(set (match_operand:DI 0 "register_operand" "=a")
12552 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12553 (match_operand:DI 3 "" "")))
12554 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12557 { 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"; }
12558 [(set_attr "type" "multi")
12559 (set_attr "length" "16")])
12561 (define_expand "tls_global_dynamic_64"
12562 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12563 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12564 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12568 if (TARGET_GNU2_TLS)
12570 emit_insn (gen_tls_dynamic_gnu2_64
12571 (operands[0], operands[1]));
12574 operands[2] = ix86_tls_get_addr ();
12577 (define_insn "*tls_local_dynamic_base_32_gnu"
12578 [(set (match_operand:SI 0 "register_operand" "=a")
12579 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12580 (match_operand:SI 2 "call_insn_operand" "")]
12581 UNSPEC_TLS_LD_BASE))
12582 (clobber (match_scratch:SI 3 "=d"))
12583 (clobber (match_scratch:SI 4 "=c"))
12584 (clobber (reg:CC FLAGS_REG))]
12585 "!TARGET_64BIT && TARGET_GNU_TLS"
12586 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12587 [(set_attr "type" "multi")
12588 (set_attr "length" "11")])
12590 (define_expand "tls_local_dynamic_base_32"
12591 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12592 (unspec:SI [(match_dup 1) (match_dup 2)]
12593 UNSPEC_TLS_LD_BASE))
12594 (clobber (match_scratch:SI 3 ""))
12595 (clobber (match_scratch:SI 4 ""))
12596 (clobber (reg:CC FLAGS_REG))])]
12600 operands[1] = pic_offset_table_rtx;
12603 operands[1] = gen_reg_rtx (Pmode);
12604 emit_insn (gen_set_got (operands[1]));
12606 if (TARGET_GNU2_TLS)
12608 emit_insn (gen_tls_dynamic_gnu2_32
12609 (operands[0], ix86_tls_module_base (), operands[1]));
12612 operands[2] = ix86_tls_get_addr ();
12615 (define_insn "*tls_local_dynamic_base_64"
12616 [(set (match_operand:DI 0 "register_operand" "=a")
12617 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12618 (match_operand:DI 2 "" "")))
12619 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12621 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12622 [(set_attr "type" "multi")
12623 (set_attr "length" "12")])
12625 (define_expand "tls_local_dynamic_base_64"
12626 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12627 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12628 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12631 if (TARGET_GNU2_TLS)
12633 emit_insn (gen_tls_dynamic_gnu2_64
12634 (operands[0], ix86_tls_module_base ()));
12637 operands[1] = ix86_tls_get_addr ();
12640 ;; Local dynamic of a single variable is a lose. Show combine how
12641 ;; to convert that back to global dynamic.
12643 (define_insn_and_split "*tls_local_dynamic_32_once"
12644 [(set (match_operand:SI 0 "register_operand" "=a")
12645 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12646 (match_operand:SI 2 "call_insn_operand" "")]
12647 UNSPEC_TLS_LD_BASE)
12648 (const:SI (unspec:SI
12649 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12651 (clobber (match_scratch:SI 4 "=d"))
12652 (clobber (match_scratch:SI 5 "=c"))
12653 (clobber (reg:CC FLAGS_REG))]
12657 [(parallel [(set (match_dup 0)
12658 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12660 (clobber (match_dup 4))
12661 (clobber (match_dup 5))
12662 (clobber (reg:CC FLAGS_REG))])])
12664 ;; Segment register for the thread base ptr load
12665 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12667 ;; Load and add the thread base pointer from %gs:0.
12668 (define_insn "*load_tp_<mode>"
12669 [(set (match_operand:P 0 "register_operand" "=r")
12670 (unspec:P [(const_int 0)] UNSPEC_TP))]
12672 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12673 [(set_attr "type" "imov")
12674 (set_attr "modrm" "0")
12675 (set_attr "length" "7")
12676 (set_attr "memory" "load")
12677 (set_attr "imm_disp" "false")])
12679 (define_insn "*add_tp_<mode>"
12680 [(set (match_operand:P 0 "register_operand" "=r")
12681 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12682 (match_operand:P 1 "register_operand" "0")))
12683 (clobber (reg:CC FLAGS_REG))]
12685 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12686 [(set_attr "type" "alu")
12687 (set_attr "modrm" "0")
12688 (set_attr "length" "7")
12689 (set_attr "memory" "load")
12690 (set_attr "imm_disp" "false")])
12692 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12693 ;; %rax as destination of the initial executable code sequence.
12694 (define_insn "tls_initial_exec_64_sun"
12695 [(set (match_operand:DI 0 "register_operand" "=a")
12697 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12698 UNSPEC_TLS_IE_SUN))
12699 (clobber (reg:CC FLAGS_REG))]
12700 "TARGET_64BIT && TARGET_SUN_TLS"
12701 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}\n\tadd{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"
12702 [(set_attr "type" "multi")])
12704 ;; GNU2 TLS patterns can be split.
12706 (define_expand "tls_dynamic_gnu2_32"
12707 [(set (match_dup 3)
12708 (plus:SI (match_operand:SI 2 "register_operand" "")
12710 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12713 [(set (match_operand:SI 0 "register_operand" "")
12714 (unspec:SI [(match_dup 1) (match_dup 3)
12715 (match_dup 2) (reg:SI SP_REG)]
12717 (clobber (reg:CC FLAGS_REG))])]
12718 "!TARGET_64BIT && TARGET_GNU2_TLS"
12720 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12721 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12724 (define_insn "*tls_dynamic_lea_32"
12725 [(set (match_operand:SI 0 "register_operand" "=r")
12726 (plus:SI (match_operand:SI 1 "register_operand" "b")
12728 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12729 UNSPEC_TLSDESC))))]
12730 "!TARGET_64BIT && TARGET_GNU2_TLS"
12731 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12732 [(set_attr "type" "lea")
12733 (set_attr "mode" "SI")
12734 (set_attr "length" "6")
12735 (set_attr "length_address" "4")])
12737 (define_insn "*tls_dynamic_call_32"
12738 [(set (match_operand:SI 0 "register_operand" "=a")
12739 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12740 (match_operand:SI 2 "register_operand" "0")
12741 ;; we have to make sure %ebx still points to the GOT
12742 (match_operand:SI 3 "register_operand" "b")
12745 (clobber (reg:CC FLAGS_REG))]
12746 "!TARGET_64BIT && TARGET_GNU2_TLS"
12747 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12748 [(set_attr "type" "call")
12749 (set_attr "length" "2")
12750 (set_attr "length_address" "0")])
12752 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12753 [(set (match_operand:SI 0 "register_operand" "=&a")
12755 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12756 (match_operand:SI 4 "" "")
12757 (match_operand:SI 2 "register_operand" "b")
12760 (const:SI (unspec:SI
12761 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12763 (clobber (reg:CC FLAGS_REG))]
12764 "!TARGET_64BIT && TARGET_GNU2_TLS"
12767 [(set (match_dup 0) (match_dup 5))]
12769 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12770 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12773 (define_expand "tls_dynamic_gnu2_64"
12774 [(set (match_dup 2)
12775 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12778 [(set (match_operand:DI 0 "register_operand" "")
12779 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12781 (clobber (reg:CC FLAGS_REG))])]
12782 "TARGET_64BIT && TARGET_GNU2_TLS"
12784 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12785 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12788 (define_insn "*tls_dynamic_lea_64"
12789 [(set (match_operand:DI 0 "register_operand" "=r")
12790 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12792 "TARGET_64BIT && TARGET_GNU2_TLS"
12793 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12794 [(set_attr "type" "lea")
12795 (set_attr "mode" "DI")
12796 (set_attr "length" "7")
12797 (set_attr "length_address" "4")])
12799 (define_insn "*tls_dynamic_call_64"
12800 [(set (match_operand:DI 0 "register_operand" "=a")
12801 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12802 (match_operand:DI 2 "register_operand" "0")
12805 (clobber (reg:CC FLAGS_REG))]
12806 "TARGET_64BIT && TARGET_GNU2_TLS"
12807 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12808 [(set_attr "type" "call")
12809 (set_attr "length" "2")
12810 (set_attr "length_address" "0")])
12812 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12813 [(set (match_operand:DI 0 "register_operand" "=&a")
12815 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12816 (match_operand:DI 3 "" "")
12819 (const:DI (unspec:DI
12820 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12822 (clobber (reg:CC FLAGS_REG))]
12823 "TARGET_64BIT && TARGET_GNU2_TLS"
12826 [(set (match_dup 0) (match_dup 4))]
12828 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12829 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12832 ;; These patterns match the binary 387 instructions for addM3, subM3,
12833 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12834 ;; SFmode. The first is the normal insn, the second the same insn but
12835 ;; with one operand a conversion, and the third the same insn but with
12836 ;; the other operand a conversion. The conversion may be SFmode or
12837 ;; SImode if the target mode DFmode, but only SImode if the target mode
12840 ;; Gcc is slightly more smart about handling normal two address instructions
12841 ;; so use special patterns for add and mull.
12843 (define_insn "*fop_<mode>_comm_mixed_avx"
12844 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12845 (match_operator:MODEF 3 "binary_fp_operator"
12846 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12847 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12848 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12849 && COMMUTATIVE_ARITH_P (operands[3])
12850 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12851 "* return output_387_binary_op (insn, operands);"
12852 [(set (attr "type")
12853 (if_then_else (eq_attr "alternative" "1")
12854 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12855 (const_string "ssemul")
12856 (const_string "sseadd"))
12857 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12858 (const_string "fmul")
12859 (const_string "fop"))))
12860 (set_attr "prefix" "orig,maybe_vex")
12861 (set_attr "mode" "<MODE>")])
12863 (define_insn "*fop_<mode>_comm_mixed"
12864 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12865 (match_operator:MODEF 3 "binary_fp_operator"
12866 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12867 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12868 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12869 && COMMUTATIVE_ARITH_P (operands[3])
12870 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12871 "* return output_387_binary_op (insn, operands);"
12872 [(set (attr "type")
12873 (if_then_else (eq_attr "alternative" "1")
12874 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12875 (const_string "ssemul")
12876 (const_string "sseadd"))
12877 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12878 (const_string "fmul")
12879 (const_string "fop"))))
12880 (set_attr "mode" "<MODE>")])
12882 (define_insn "*fop_<mode>_comm_avx"
12883 [(set (match_operand:MODEF 0 "register_operand" "=x")
12884 (match_operator:MODEF 3 "binary_fp_operator"
12885 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12886 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12887 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12888 && COMMUTATIVE_ARITH_P (operands[3])
12889 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12890 "* return output_387_binary_op (insn, operands);"
12891 [(set (attr "type")
12892 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12893 (const_string "ssemul")
12894 (const_string "sseadd")))
12895 (set_attr "prefix" "vex")
12896 (set_attr "mode" "<MODE>")])
12898 (define_insn "*fop_<mode>_comm_sse"
12899 [(set (match_operand:MODEF 0 "register_operand" "=x")
12900 (match_operator:MODEF 3 "binary_fp_operator"
12901 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12902 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12903 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12904 && COMMUTATIVE_ARITH_P (operands[3])
12905 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12906 "* return output_387_binary_op (insn, operands);"
12907 [(set (attr "type")
12908 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12909 (const_string "ssemul")
12910 (const_string "sseadd")))
12911 (set_attr "mode" "<MODE>")])
12913 (define_insn "*fop_<mode>_comm_i387"
12914 [(set (match_operand:MODEF 0 "register_operand" "=f")
12915 (match_operator:MODEF 3 "binary_fp_operator"
12916 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12917 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12918 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12919 && COMMUTATIVE_ARITH_P (operands[3])
12920 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12921 "* return output_387_binary_op (insn, operands);"
12922 [(set (attr "type")
12923 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12924 (const_string "fmul")
12925 (const_string "fop")))
12926 (set_attr "mode" "<MODE>")])
12928 (define_insn "*fop_<mode>_1_mixed_avx"
12929 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12930 (match_operator:MODEF 3 "binary_fp_operator"
12931 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12932 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12933 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12934 && !COMMUTATIVE_ARITH_P (operands[3])
12935 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12936 "* return output_387_binary_op (insn, operands);"
12937 [(set (attr "type")
12938 (cond [(and (eq_attr "alternative" "2")
12939 (match_operand:MODEF 3 "mult_operator" ""))
12940 (const_string "ssemul")
12941 (and (eq_attr "alternative" "2")
12942 (match_operand:MODEF 3 "div_operator" ""))
12943 (const_string "ssediv")
12944 (eq_attr "alternative" "2")
12945 (const_string "sseadd")
12946 (match_operand:MODEF 3 "mult_operator" "")
12947 (const_string "fmul")
12948 (match_operand:MODEF 3 "div_operator" "")
12949 (const_string "fdiv")
12951 (const_string "fop")))
12952 (set_attr "prefix" "orig,orig,maybe_vex")
12953 (set_attr "mode" "<MODE>")])
12955 (define_insn "*fop_<mode>_1_mixed"
12956 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12957 (match_operator:MODEF 3 "binary_fp_operator"
12958 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12959 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12960 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12961 && !COMMUTATIVE_ARITH_P (operands[3])
12962 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12963 "* return output_387_binary_op (insn, operands);"
12964 [(set (attr "type")
12965 (cond [(and (eq_attr "alternative" "2")
12966 (match_operand:MODEF 3 "mult_operator" ""))
12967 (const_string "ssemul")
12968 (and (eq_attr "alternative" "2")
12969 (match_operand:MODEF 3 "div_operator" ""))
12970 (const_string "ssediv")
12971 (eq_attr "alternative" "2")
12972 (const_string "sseadd")
12973 (match_operand:MODEF 3 "mult_operator" "")
12974 (const_string "fmul")
12975 (match_operand:MODEF 3 "div_operator" "")
12976 (const_string "fdiv")
12978 (const_string "fop")))
12979 (set_attr "mode" "<MODE>")])
12981 (define_insn "*rcpsf2_sse"
12982 [(set (match_operand:SF 0 "register_operand" "=x")
12983 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12986 "%vrcpss\t{%1, %d0|%d0, %1}"
12987 [(set_attr "type" "sse")
12988 (set_attr "atom_sse_attr" "rcp")
12989 (set_attr "prefix" "maybe_vex")
12990 (set_attr "mode" "SF")])
12992 (define_insn "*fop_<mode>_1_avx"
12993 [(set (match_operand:MODEF 0 "register_operand" "=x")
12994 (match_operator:MODEF 3 "binary_fp_operator"
12995 [(match_operand:MODEF 1 "register_operand" "x")
12996 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12997 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12998 && !COMMUTATIVE_ARITH_P (operands[3])"
12999 "* return output_387_binary_op (insn, operands);"
13000 [(set (attr "type")
13001 (cond [(match_operand:MODEF 3 "mult_operator" "")
13002 (const_string "ssemul")
13003 (match_operand:MODEF 3 "div_operator" "")
13004 (const_string "ssediv")
13006 (const_string "sseadd")))
13007 (set_attr "prefix" "vex")
13008 (set_attr "mode" "<MODE>")])
13010 (define_insn "*fop_<mode>_1_sse"
13011 [(set (match_operand:MODEF 0 "register_operand" "=x")
13012 (match_operator:MODEF 3 "binary_fp_operator"
13013 [(match_operand:MODEF 1 "register_operand" "0")
13014 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13015 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13016 && !COMMUTATIVE_ARITH_P (operands[3])"
13017 "* return output_387_binary_op (insn, operands);"
13018 [(set (attr "type")
13019 (cond [(match_operand:MODEF 3 "mult_operator" "")
13020 (const_string "ssemul")
13021 (match_operand:MODEF 3 "div_operator" "")
13022 (const_string "ssediv")
13024 (const_string "sseadd")))
13025 (set_attr "mode" "<MODE>")])
13027 ;; This pattern is not fully shadowed by the pattern above.
13028 (define_insn "*fop_<mode>_1_i387"
13029 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13030 (match_operator:MODEF 3 "binary_fp_operator"
13031 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13032 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13033 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13034 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13035 && !COMMUTATIVE_ARITH_P (operands[3])
13036 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13037 "* return output_387_binary_op (insn, operands);"
13038 [(set (attr "type")
13039 (cond [(match_operand:MODEF 3 "mult_operator" "")
13040 (const_string "fmul")
13041 (match_operand:MODEF 3 "div_operator" "")
13042 (const_string "fdiv")
13044 (const_string "fop")))
13045 (set_attr "mode" "<MODE>")])
13047 ;; ??? Add SSE splitters for these!
13048 (define_insn "*fop_<MODEF:mode>_2_i387"
13049 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13050 (match_operator:MODEF 3 "binary_fp_operator"
13052 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13053 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13054 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13055 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13056 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13057 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13058 [(set (attr "type")
13059 (cond [(match_operand:MODEF 3 "mult_operator" "")
13060 (const_string "fmul")
13061 (match_operand:MODEF 3 "div_operator" "")
13062 (const_string "fdiv")
13064 (const_string "fop")))
13065 (set_attr "fp_int_src" "true")
13066 (set_attr "mode" "<X87MODEI12:MODE>")])
13068 (define_insn "*fop_<MODEF:mode>_3_i387"
13069 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13070 (match_operator:MODEF 3 "binary_fp_operator"
13071 [(match_operand:MODEF 1 "register_operand" "0,0")
13073 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13074 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13075 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13076 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13077 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13078 [(set (attr "type")
13079 (cond [(match_operand:MODEF 3 "mult_operator" "")
13080 (const_string "fmul")
13081 (match_operand:MODEF 3 "div_operator" "")
13082 (const_string "fdiv")
13084 (const_string "fop")))
13085 (set_attr "fp_int_src" "true")
13086 (set_attr "mode" "<MODE>")])
13088 (define_insn "*fop_df_4_i387"
13089 [(set (match_operand:DF 0 "register_operand" "=f,f")
13090 (match_operator:DF 3 "binary_fp_operator"
13092 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13093 (match_operand:DF 2 "register_operand" "0,f")]))]
13094 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13095 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13096 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13097 "* return output_387_binary_op (insn, operands);"
13098 [(set (attr "type")
13099 (cond [(match_operand:DF 3 "mult_operator" "")
13100 (const_string "fmul")
13101 (match_operand:DF 3 "div_operator" "")
13102 (const_string "fdiv")
13104 (const_string "fop")))
13105 (set_attr "mode" "SF")])
13107 (define_insn "*fop_df_5_i387"
13108 [(set (match_operand:DF 0 "register_operand" "=f,f")
13109 (match_operator:DF 3 "binary_fp_operator"
13110 [(match_operand:DF 1 "register_operand" "0,f")
13112 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13113 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13114 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13115 "* return output_387_binary_op (insn, operands);"
13116 [(set (attr "type")
13117 (cond [(match_operand:DF 3 "mult_operator" "")
13118 (const_string "fmul")
13119 (match_operand:DF 3 "div_operator" "")
13120 (const_string "fdiv")
13122 (const_string "fop")))
13123 (set_attr "mode" "SF")])
13125 (define_insn "*fop_df_6_i387"
13126 [(set (match_operand:DF 0 "register_operand" "=f,f")
13127 (match_operator:DF 3 "binary_fp_operator"
13129 (match_operand:SF 1 "register_operand" "0,f"))
13131 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13132 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13133 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13134 "* return output_387_binary_op (insn, operands);"
13135 [(set (attr "type")
13136 (cond [(match_operand:DF 3 "mult_operator" "")
13137 (const_string "fmul")
13138 (match_operand:DF 3 "div_operator" "")
13139 (const_string "fdiv")
13141 (const_string "fop")))
13142 (set_attr "mode" "SF")])
13144 (define_insn "*fop_xf_comm_i387"
13145 [(set (match_operand:XF 0 "register_operand" "=f")
13146 (match_operator:XF 3 "binary_fp_operator"
13147 [(match_operand:XF 1 "register_operand" "%0")
13148 (match_operand:XF 2 "register_operand" "f")]))]
13150 && COMMUTATIVE_ARITH_P (operands[3])"
13151 "* return output_387_binary_op (insn, operands);"
13152 [(set (attr "type")
13153 (if_then_else (match_operand:XF 3 "mult_operator" "")
13154 (const_string "fmul")
13155 (const_string "fop")))
13156 (set_attr "mode" "XF")])
13158 (define_insn "*fop_xf_1_i387"
13159 [(set (match_operand:XF 0 "register_operand" "=f,f")
13160 (match_operator:XF 3 "binary_fp_operator"
13161 [(match_operand:XF 1 "register_operand" "0,f")
13162 (match_operand:XF 2 "register_operand" "f,0")]))]
13164 && !COMMUTATIVE_ARITH_P (operands[3])"
13165 "* return output_387_binary_op (insn, operands);"
13166 [(set (attr "type")
13167 (cond [(match_operand:XF 3 "mult_operator" "")
13168 (const_string "fmul")
13169 (match_operand:XF 3 "div_operator" "")
13170 (const_string "fdiv")
13172 (const_string "fop")))
13173 (set_attr "mode" "XF")])
13175 (define_insn "*fop_xf_2_i387"
13176 [(set (match_operand:XF 0 "register_operand" "=f,f")
13177 (match_operator:XF 3 "binary_fp_operator"
13179 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13180 (match_operand:XF 2 "register_operand" "0,0")]))]
13181 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13182 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13183 [(set (attr "type")
13184 (cond [(match_operand:XF 3 "mult_operator" "")
13185 (const_string "fmul")
13186 (match_operand:XF 3 "div_operator" "")
13187 (const_string "fdiv")
13189 (const_string "fop")))
13190 (set_attr "fp_int_src" "true")
13191 (set_attr "mode" "<MODE>")])
13193 (define_insn "*fop_xf_3_i387"
13194 [(set (match_operand:XF 0 "register_operand" "=f,f")
13195 (match_operator:XF 3 "binary_fp_operator"
13196 [(match_operand:XF 1 "register_operand" "0,0")
13198 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13199 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13200 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13201 [(set (attr "type")
13202 (cond [(match_operand:XF 3 "mult_operator" "")
13203 (const_string "fmul")
13204 (match_operand:XF 3 "div_operator" "")
13205 (const_string "fdiv")
13207 (const_string "fop")))
13208 (set_attr "fp_int_src" "true")
13209 (set_attr "mode" "<MODE>")])
13211 (define_insn "*fop_xf_4_i387"
13212 [(set (match_operand:XF 0 "register_operand" "=f,f")
13213 (match_operator:XF 3 "binary_fp_operator"
13215 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13216 (match_operand:XF 2 "register_operand" "0,f")]))]
13218 "* return output_387_binary_op (insn, operands);"
13219 [(set (attr "type")
13220 (cond [(match_operand:XF 3 "mult_operator" "")
13221 (const_string "fmul")
13222 (match_operand:XF 3 "div_operator" "")
13223 (const_string "fdiv")
13225 (const_string "fop")))
13226 (set_attr "mode" "<MODE>")])
13228 (define_insn "*fop_xf_5_i387"
13229 [(set (match_operand:XF 0 "register_operand" "=f,f")
13230 (match_operator:XF 3 "binary_fp_operator"
13231 [(match_operand:XF 1 "register_operand" "0,f")
13233 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13235 "* return output_387_binary_op (insn, operands);"
13236 [(set (attr "type")
13237 (cond [(match_operand:XF 3 "mult_operator" "")
13238 (const_string "fmul")
13239 (match_operand:XF 3 "div_operator" "")
13240 (const_string "fdiv")
13242 (const_string "fop")))
13243 (set_attr "mode" "<MODE>")])
13245 (define_insn "*fop_xf_6_i387"
13246 [(set (match_operand:XF 0 "register_operand" "=f,f")
13247 (match_operator:XF 3 "binary_fp_operator"
13249 (match_operand:MODEF 1 "register_operand" "0,f"))
13251 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13253 "* return output_387_binary_op (insn, operands);"
13254 [(set (attr "type")
13255 (cond [(match_operand:XF 3 "mult_operator" "")
13256 (const_string "fmul")
13257 (match_operand:XF 3 "div_operator" "")
13258 (const_string "fdiv")
13260 (const_string "fop")))
13261 (set_attr "mode" "<MODE>")])
13264 [(set (match_operand 0 "register_operand" "")
13265 (match_operator 3 "binary_fp_operator"
13266 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13267 (match_operand 2 "register_operand" "")]))]
13269 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13270 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13273 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13274 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13275 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13276 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13277 GET_MODE (operands[3]),
13280 ix86_free_from_memory (GET_MODE (operands[1]));
13285 [(set (match_operand 0 "register_operand" "")
13286 (match_operator 3 "binary_fp_operator"
13287 [(match_operand 1 "register_operand" "")
13288 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13290 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13291 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13294 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13295 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13296 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13297 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13298 GET_MODE (operands[3]),
13301 ix86_free_from_memory (GET_MODE (operands[2]));
13305 ;; FPU special functions.
13307 ;; This pattern implements a no-op XFmode truncation for
13308 ;; all fancy i386 XFmode math functions.
13310 (define_insn "truncxf<mode>2_i387_noop_unspec"
13311 [(set (match_operand:MODEF 0 "register_operand" "=f")
13312 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13313 UNSPEC_TRUNC_NOOP))]
13314 "TARGET_USE_FANCY_MATH_387"
13315 "* return output_387_reg_move (insn, operands);"
13316 [(set_attr "type" "fmov")
13317 (set_attr "mode" "<MODE>")])
13319 (define_insn "sqrtxf2"
13320 [(set (match_operand:XF 0 "register_operand" "=f")
13321 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13322 "TARGET_USE_FANCY_MATH_387"
13324 [(set_attr "type" "fpspc")
13325 (set_attr "mode" "XF")
13326 (set_attr "athlon_decode" "direct")
13327 (set_attr "amdfam10_decode" "direct")
13328 (set_attr "bdver1_decode" "direct")])
13330 (define_insn "sqrt_extend<mode>xf2_i387"
13331 [(set (match_operand:XF 0 "register_operand" "=f")
13334 (match_operand:MODEF 1 "register_operand" "0"))))]
13335 "TARGET_USE_FANCY_MATH_387"
13337 [(set_attr "type" "fpspc")
13338 (set_attr "mode" "XF")
13339 (set_attr "athlon_decode" "direct")
13340 (set_attr "amdfam10_decode" "direct")
13341 (set_attr "bdver1_decode" "direct")])
13343 (define_insn "*rsqrtsf2_sse"
13344 [(set (match_operand:SF 0 "register_operand" "=x")
13345 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13348 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13349 [(set_attr "type" "sse")
13350 (set_attr "atom_sse_attr" "rcp")
13351 (set_attr "prefix" "maybe_vex")
13352 (set_attr "mode" "SF")])
13354 (define_expand "rsqrtsf2"
13355 [(set (match_operand:SF 0 "register_operand" "")
13356 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13360 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13364 (define_insn "*sqrt<mode>2_sse"
13365 [(set (match_operand:MODEF 0 "register_operand" "=x")
13367 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13368 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13369 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13370 [(set_attr "type" "sse")
13371 (set_attr "atom_sse_attr" "sqrt")
13372 (set_attr "prefix" "maybe_vex")
13373 (set_attr "mode" "<MODE>")
13374 (set_attr "athlon_decode" "*")
13375 (set_attr "amdfam10_decode" "*")
13376 (set_attr "bdver1_decode" "*")])
13378 (define_expand "sqrt<mode>2"
13379 [(set (match_operand:MODEF 0 "register_operand" "")
13381 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13382 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13383 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13385 if (<MODE>mode == SFmode
13386 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13387 && flag_finite_math_only && !flag_trapping_math
13388 && flag_unsafe_math_optimizations)
13390 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13394 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13396 rtx op0 = gen_reg_rtx (XFmode);
13397 rtx op1 = force_reg (<MODE>mode, operands[1]);
13399 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13400 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13405 (define_insn "fpremxf4_i387"
13406 [(set (match_operand:XF 0 "register_operand" "=f")
13407 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13408 (match_operand:XF 3 "register_operand" "1")]
13410 (set (match_operand:XF 1 "register_operand" "=u")
13411 (unspec:XF [(match_dup 2) (match_dup 3)]
13413 (set (reg:CCFP FPSR_REG)
13414 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13416 "TARGET_USE_FANCY_MATH_387"
13418 [(set_attr "type" "fpspc")
13419 (set_attr "mode" "XF")])
13421 (define_expand "fmodxf3"
13422 [(use (match_operand:XF 0 "register_operand" ""))
13423 (use (match_operand:XF 1 "general_operand" ""))
13424 (use (match_operand:XF 2 "general_operand" ""))]
13425 "TARGET_USE_FANCY_MATH_387"
13427 rtx label = gen_label_rtx ();
13429 rtx op1 = gen_reg_rtx (XFmode);
13430 rtx op2 = gen_reg_rtx (XFmode);
13432 emit_move_insn (op2, operands[2]);
13433 emit_move_insn (op1, operands[1]);
13435 emit_label (label);
13436 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13437 ix86_emit_fp_unordered_jump (label);
13438 LABEL_NUSES (label) = 1;
13440 emit_move_insn (operands[0], op1);
13444 (define_expand "fmod<mode>3"
13445 [(use (match_operand:MODEF 0 "register_operand" ""))
13446 (use (match_operand:MODEF 1 "general_operand" ""))
13447 (use (match_operand:MODEF 2 "general_operand" ""))]
13448 "TARGET_USE_FANCY_MATH_387"
13450 rtx (*gen_truncxf) (rtx, rtx);
13452 rtx label = gen_label_rtx ();
13454 rtx op1 = gen_reg_rtx (XFmode);
13455 rtx op2 = gen_reg_rtx (XFmode);
13457 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13458 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13460 emit_label (label);
13461 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13462 ix86_emit_fp_unordered_jump (label);
13463 LABEL_NUSES (label) = 1;
13465 /* Truncate the result properly for strict SSE math. */
13466 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13467 && !TARGET_MIX_SSE_I387)
13468 gen_truncxf = gen_truncxf<mode>2;
13470 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13472 emit_insn (gen_truncxf (operands[0], op1));
13476 (define_insn "fprem1xf4_i387"
13477 [(set (match_operand:XF 0 "register_operand" "=f")
13478 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13479 (match_operand:XF 3 "register_operand" "1")]
13481 (set (match_operand:XF 1 "register_operand" "=u")
13482 (unspec:XF [(match_dup 2) (match_dup 3)]
13484 (set (reg:CCFP FPSR_REG)
13485 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13487 "TARGET_USE_FANCY_MATH_387"
13489 [(set_attr "type" "fpspc")
13490 (set_attr "mode" "XF")])
13492 (define_expand "remainderxf3"
13493 [(use (match_operand:XF 0 "register_operand" ""))
13494 (use (match_operand:XF 1 "general_operand" ""))
13495 (use (match_operand:XF 2 "general_operand" ""))]
13496 "TARGET_USE_FANCY_MATH_387"
13498 rtx label = gen_label_rtx ();
13500 rtx op1 = gen_reg_rtx (XFmode);
13501 rtx op2 = gen_reg_rtx (XFmode);
13503 emit_move_insn (op2, operands[2]);
13504 emit_move_insn (op1, operands[1]);
13506 emit_label (label);
13507 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13508 ix86_emit_fp_unordered_jump (label);
13509 LABEL_NUSES (label) = 1;
13511 emit_move_insn (operands[0], op1);
13515 (define_expand "remainder<mode>3"
13516 [(use (match_operand:MODEF 0 "register_operand" ""))
13517 (use (match_operand:MODEF 1 "general_operand" ""))
13518 (use (match_operand:MODEF 2 "general_operand" ""))]
13519 "TARGET_USE_FANCY_MATH_387"
13521 rtx (*gen_truncxf) (rtx, rtx);
13523 rtx label = gen_label_rtx ();
13525 rtx op1 = gen_reg_rtx (XFmode);
13526 rtx op2 = gen_reg_rtx (XFmode);
13528 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13529 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13531 emit_label (label);
13533 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13534 ix86_emit_fp_unordered_jump (label);
13535 LABEL_NUSES (label) = 1;
13537 /* Truncate the result properly for strict SSE math. */
13538 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13539 && !TARGET_MIX_SSE_I387)
13540 gen_truncxf = gen_truncxf<mode>2;
13542 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13544 emit_insn (gen_truncxf (operands[0], op1));
13548 (define_insn "*sinxf2_i387"
13549 [(set (match_operand:XF 0 "register_operand" "=f")
13550 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13551 "TARGET_USE_FANCY_MATH_387
13552 && flag_unsafe_math_optimizations"
13554 [(set_attr "type" "fpspc")
13555 (set_attr "mode" "XF")])
13557 (define_insn "*sin_extend<mode>xf2_i387"
13558 [(set (match_operand:XF 0 "register_operand" "=f")
13559 (unspec:XF [(float_extend:XF
13560 (match_operand:MODEF 1 "register_operand" "0"))]
13562 "TARGET_USE_FANCY_MATH_387
13563 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13564 || TARGET_MIX_SSE_I387)
13565 && flag_unsafe_math_optimizations"
13567 [(set_attr "type" "fpspc")
13568 (set_attr "mode" "XF")])
13570 (define_insn "*cosxf2_i387"
13571 [(set (match_operand:XF 0 "register_operand" "=f")
13572 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13573 "TARGET_USE_FANCY_MATH_387
13574 && flag_unsafe_math_optimizations"
13576 [(set_attr "type" "fpspc")
13577 (set_attr "mode" "XF")])
13579 (define_insn "*cos_extend<mode>xf2_i387"
13580 [(set (match_operand:XF 0 "register_operand" "=f")
13581 (unspec:XF [(float_extend:XF
13582 (match_operand:MODEF 1 "register_operand" "0"))]
13584 "TARGET_USE_FANCY_MATH_387
13585 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13586 || TARGET_MIX_SSE_I387)
13587 && flag_unsafe_math_optimizations"
13589 [(set_attr "type" "fpspc")
13590 (set_attr "mode" "XF")])
13592 ;; When sincos pattern is defined, sin and cos builtin functions will be
13593 ;; expanded to sincos pattern with one of its outputs left unused.
13594 ;; CSE pass will figure out if two sincos patterns can be combined,
13595 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13596 ;; depending on the unused output.
13598 (define_insn "sincosxf3"
13599 [(set (match_operand:XF 0 "register_operand" "=f")
13600 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13601 UNSPEC_SINCOS_COS))
13602 (set (match_operand:XF 1 "register_operand" "=u")
13603 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13604 "TARGET_USE_FANCY_MATH_387
13605 && flag_unsafe_math_optimizations"
13607 [(set_attr "type" "fpspc")
13608 (set_attr "mode" "XF")])
13611 [(set (match_operand:XF 0 "register_operand" "")
13612 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13613 UNSPEC_SINCOS_COS))
13614 (set (match_operand:XF 1 "register_operand" "")
13615 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13616 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13617 && !(reload_completed || reload_in_progress)"
13618 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13621 [(set (match_operand:XF 0 "register_operand" "")
13622 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13623 UNSPEC_SINCOS_COS))
13624 (set (match_operand:XF 1 "register_operand" "")
13625 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13626 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13627 && !(reload_completed || reload_in_progress)"
13628 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13630 (define_insn "sincos_extend<mode>xf3_i387"
13631 [(set (match_operand:XF 0 "register_operand" "=f")
13632 (unspec:XF [(float_extend:XF
13633 (match_operand:MODEF 2 "register_operand" "0"))]
13634 UNSPEC_SINCOS_COS))
13635 (set (match_operand:XF 1 "register_operand" "=u")
13636 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13637 "TARGET_USE_FANCY_MATH_387
13638 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13639 || TARGET_MIX_SSE_I387)
13640 && flag_unsafe_math_optimizations"
13642 [(set_attr "type" "fpspc")
13643 (set_attr "mode" "XF")])
13646 [(set (match_operand:XF 0 "register_operand" "")
13647 (unspec:XF [(float_extend:XF
13648 (match_operand:MODEF 2 "register_operand" ""))]
13649 UNSPEC_SINCOS_COS))
13650 (set (match_operand:XF 1 "register_operand" "")
13651 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13652 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13653 && !(reload_completed || reload_in_progress)"
13654 [(set (match_dup 1)
13655 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13658 [(set (match_operand:XF 0 "register_operand" "")
13659 (unspec:XF [(float_extend:XF
13660 (match_operand:MODEF 2 "register_operand" ""))]
13661 UNSPEC_SINCOS_COS))
13662 (set (match_operand:XF 1 "register_operand" "")
13663 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13664 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13665 && !(reload_completed || reload_in_progress)"
13666 [(set (match_dup 0)
13667 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13669 (define_expand "sincos<mode>3"
13670 [(use (match_operand:MODEF 0 "register_operand" ""))
13671 (use (match_operand:MODEF 1 "register_operand" ""))
13672 (use (match_operand:MODEF 2 "register_operand" ""))]
13673 "TARGET_USE_FANCY_MATH_387
13674 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13675 || TARGET_MIX_SSE_I387)
13676 && flag_unsafe_math_optimizations"
13678 rtx op0 = gen_reg_rtx (XFmode);
13679 rtx op1 = gen_reg_rtx (XFmode);
13681 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13682 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13683 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13687 (define_insn "fptanxf4_i387"
13688 [(set (match_operand:XF 0 "register_operand" "=f")
13689 (match_operand:XF 3 "const_double_operand" "F"))
13690 (set (match_operand:XF 1 "register_operand" "=u")
13691 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13693 "TARGET_USE_FANCY_MATH_387
13694 && flag_unsafe_math_optimizations
13695 && standard_80387_constant_p (operands[3]) == 2"
13697 [(set_attr "type" "fpspc")
13698 (set_attr "mode" "XF")])
13700 (define_insn "fptan_extend<mode>xf4_i387"
13701 [(set (match_operand:MODEF 0 "register_operand" "=f")
13702 (match_operand:MODEF 3 "const_double_operand" "F"))
13703 (set (match_operand:XF 1 "register_operand" "=u")
13704 (unspec:XF [(float_extend:XF
13705 (match_operand:MODEF 2 "register_operand" "0"))]
13707 "TARGET_USE_FANCY_MATH_387
13708 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13709 || TARGET_MIX_SSE_I387)
13710 && flag_unsafe_math_optimizations
13711 && standard_80387_constant_p (operands[3]) == 2"
13713 [(set_attr "type" "fpspc")
13714 (set_attr "mode" "XF")])
13716 (define_expand "tanxf2"
13717 [(use (match_operand:XF 0 "register_operand" ""))
13718 (use (match_operand:XF 1 "register_operand" ""))]
13719 "TARGET_USE_FANCY_MATH_387
13720 && flag_unsafe_math_optimizations"
13722 rtx one = gen_reg_rtx (XFmode);
13723 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13725 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13729 (define_expand "tan<mode>2"
13730 [(use (match_operand:MODEF 0 "register_operand" ""))
13731 (use (match_operand:MODEF 1 "register_operand" ""))]
13732 "TARGET_USE_FANCY_MATH_387
13733 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13734 || TARGET_MIX_SSE_I387)
13735 && flag_unsafe_math_optimizations"
13737 rtx op0 = gen_reg_rtx (XFmode);
13739 rtx one = gen_reg_rtx (<MODE>mode);
13740 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13742 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13743 operands[1], op2));
13744 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13748 (define_insn "*fpatanxf3_i387"
13749 [(set (match_operand:XF 0 "register_operand" "=f")
13750 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13751 (match_operand:XF 2 "register_operand" "u")]
13753 (clobber (match_scratch:XF 3 "=2"))]
13754 "TARGET_USE_FANCY_MATH_387
13755 && flag_unsafe_math_optimizations"
13757 [(set_attr "type" "fpspc")
13758 (set_attr "mode" "XF")])
13760 (define_insn "fpatan_extend<mode>xf3_i387"
13761 [(set (match_operand:XF 0 "register_operand" "=f")
13762 (unspec:XF [(float_extend:XF
13763 (match_operand:MODEF 1 "register_operand" "0"))
13765 (match_operand:MODEF 2 "register_operand" "u"))]
13767 (clobber (match_scratch:XF 3 "=2"))]
13768 "TARGET_USE_FANCY_MATH_387
13769 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13770 || TARGET_MIX_SSE_I387)
13771 && flag_unsafe_math_optimizations"
13773 [(set_attr "type" "fpspc")
13774 (set_attr "mode" "XF")])
13776 (define_expand "atan2xf3"
13777 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13778 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13779 (match_operand:XF 1 "register_operand" "")]
13781 (clobber (match_scratch:XF 3 ""))])]
13782 "TARGET_USE_FANCY_MATH_387
13783 && flag_unsafe_math_optimizations")
13785 (define_expand "atan2<mode>3"
13786 [(use (match_operand:MODEF 0 "register_operand" ""))
13787 (use (match_operand:MODEF 1 "register_operand" ""))
13788 (use (match_operand:MODEF 2 "register_operand" ""))]
13789 "TARGET_USE_FANCY_MATH_387
13790 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13791 || TARGET_MIX_SSE_I387)
13792 && flag_unsafe_math_optimizations"
13794 rtx op0 = gen_reg_rtx (XFmode);
13796 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13797 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13801 (define_expand "atanxf2"
13802 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13803 (unspec:XF [(match_dup 2)
13804 (match_operand:XF 1 "register_operand" "")]
13806 (clobber (match_scratch:XF 3 ""))])]
13807 "TARGET_USE_FANCY_MATH_387
13808 && flag_unsafe_math_optimizations"
13810 operands[2] = gen_reg_rtx (XFmode);
13811 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13814 (define_expand "atan<mode>2"
13815 [(use (match_operand:MODEF 0 "register_operand" ""))
13816 (use (match_operand:MODEF 1 "register_operand" ""))]
13817 "TARGET_USE_FANCY_MATH_387
13818 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13819 || TARGET_MIX_SSE_I387)
13820 && flag_unsafe_math_optimizations"
13822 rtx op0 = gen_reg_rtx (XFmode);
13824 rtx op2 = gen_reg_rtx (<MODE>mode);
13825 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13827 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13828 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13832 (define_expand "asinxf2"
13833 [(set (match_dup 2)
13834 (mult:XF (match_operand:XF 1 "register_operand" "")
13836 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13837 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13838 (parallel [(set (match_operand:XF 0 "register_operand" "")
13839 (unspec:XF [(match_dup 5) (match_dup 1)]
13841 (clobber (match_scratch:XF 6 ""))])]
13842 "TARGET_USE_FANCY_MATH_387
13843 && flag_unsafe_math_optimizations"
13847 if (optimize_insn_for_size_p ())
13850 for (i = 2; i < 6; i++)
13851 operands[i] = gen_reg_rtx (XFmode);
13853 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13856 (define_expand "asin<mode>2"
13857 [(use (match_operand:MODEF 0 "register_operand" ""))
13858 (use (match_operand:MODEF 1 "general_operand" ""))]
13859 "TARGET_USE_FANCY_MATH_387
13860 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13861 || TARGET_MIX_SSE_I387)
13862 && flag_unsafe_math_optimizations"
13864 rtx op0 = gen_reg_rtx (XFmode);
13865 rtx op1 = gen_reg_rtx (XFmode);
13867 if (optimize_insn_for_size_p ())
13870 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13871 emit_insn (gen_asinxf2 (op0, op1));
13872 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13876 (define_expand "acosxf2"
13877 [(set (match_dup 2)
13878 (mult:XF (match_operand:XF 1 "register_operand" "")
13880 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13881 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13882 (parallel [(set (match_operand:XF 0 "register_operand" "")
13883 (unspec:XF [(match_dup 1) (match_dup 5)]
13885 (clobber (match_scratch:XF 6 ""))])]
13886 "TARGET_USE_FANCY_MATH_387
13887 && flag_unsafe_math_optimizations"
13891 if (optimize_insn_for_size_p ())
13894 for (i = 2; i < 6; i++)
13895 operands[i] = gen_reg_rtx (XFmode);
13897 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13900 (define_expand "acos<mode>2"
13901 [(use (match_operand:MODEF 0 "register_operand" ""))
13902 (use (match_operand:MODEF 1 "general_operand" ""))]
13903 "TARGET_USE_FANCY_MATH_387
13904 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13905 || TARGET_MIX_SSE_I387)
13906 && flag_unsafe_math_optimizations"
13908 rtx op0 = gen_reg_rtx (XFmode);
13909 rtx op1 = gen_reg_rtx (XFmode);
13911 if (optimize_insn_for_size_p ())
13914 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13915 emit_insn (gen_acosxf2 (op0, op1));
13916 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13920 (define_insn "fyl2xxf3_i387"
13921 [(set (match_operand:XF 0 "register_operand" "=f")
13922 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13923 (match_operand:XF 2 "register_operand" "u")]
13925 (clobber (match_scratch:XF 3 "=2"))]
13926 "TARGET_USE_FANCY_MATH_387
13927 && flag_unsafe_math_optimizations"
13929 [(set_attr "type" "fpspc")
13930 (set_attr "mode" "XF")])
13932 (define_insn "fyl2x_extend<mode>xf3_i387"
13933 [(set (match_operand:XF 0 "register_operand" "=f")
13934 (unspec:XF [(float_extend:XF
13935 (match_operand:MODEF 1 "register_operand" "0"))
13936 (match_operand:XF 2 "register_operand" "u")]
13938 (clobber (match_scratch:XF 3 "=2"))]
13939 "TARGET_USE_FANCY_MATH_387
13940 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13941 || TARGET_MIX_SSE_I387)
13942 && flag_unsafe_math_optimizations"
13944 [(set_attr "type" "fpspc")
13945 (set_attr "mode" "XF")])
13947 (define_expand "logxf2"
13948 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13949 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13950 (match_dup 2)] UNSPEC_FYL2X))
13951 (clobber (match_scratch:XF 3 ""))])]
13952 "TARGET_USE_FANCY_MATH_387
13953 && flag_unsafe_math_optimizations"
13955 operands[2] = gen_reg_rtx (XFmode);
13956 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13959 (define_expand "log<mode>2"
13960 [(use (match_operand:MODEF 0 "register_operand" ""))
13961 (use (match_operand:MODEF 1 "register_operand" ""))]
13962 "TARGET_USE_FANCY_MATH_387
13963 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13964 || TARGET_MIX_SSE_I387)
13965 && flag_unsafe_math_optimizations"
13967 rtx op0 = gen_reg_rtx (XFmode);
13969 rtx op2 = gen_reg_rtx (XFmode);
13970 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13972 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13973 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13977 (define_expand "log10xf2"
13978 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13979 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13980 (match_dup 2)] UNSPEC_FYL2X))
13981 (clobber (match_scratch:XF 3 ""))])]
13982 "TARGET_USE_FANCY_MATH_387
13983 && flag_unsafe_math_optimizations"
13985 operands[2] = gen_reg_rtx (XFmode);
13986 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13989 (define_expand "log10<mode>2"
13990 [(use (match_operand:MODEF 0 "register_operand" ""))
13991 (use (match_operand:MODEF 1 "register_operand" ""))]
13992 "TARGET_USE_FANCY_MATH_387
13993 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13994 || TARGET_MIX_SSE_I387)
13995 && flag_unsafe_math_optimizations"
13997 rtx op0 = gen_reg_rtx (XFmode);
13999 rtx op2 = gen_reg_rtx (XFmode);
14000 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14002 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14003 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14007 (define_expand "log2xf2"
14008 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14009 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14010 (match_dup 2)] UNSPEC_FYL2X))
14011 (clobber (match_scratch:XF 3 ""))])]
14012 "TARGET_USE_FANCY_MATH_387
14013 && flag_unsafe_math_optimizations"
14015 operands[2] = gen_reg_rtx (XFmode);
14016 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14019 (define_expand "log2<mode>2"
14020 [(use (match_operand:MODEF 0 "register_operand" ""))
14021 (use (match_operand:MODEF 1 "register_operand" ""))]
14022 "TARGET_USE_FANCY_MATH_387
14023 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14024 || TARGET_MIX_SSE_I387)
14025 && flag_unsafe_math_optimizations"
14027 rtx op0 = gen_reg_rtx (XFmode);
14029 rtx op2 = gen_reg_rtx (XFmode);
14030 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14032 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14033 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14037 (define_insn "fyl2xp1xf3_i387"
14038 [(set (match_operand:XF 0 "register_operand" "=f")
14039 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14040 (match_operand:XF 2 "register_operand" "u")]
14042 (clobber (match_scratch:XF 3 "=2"))]
14043 "TARGET_USE_FANCY_MATH_387
14044 && flag_unsafe_math_optimizations"
14046 [(set_attr "type" "fpspc")
14047 (set_attr "mode" "XF")])
14049 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14050 [(set (match_operand:XF 0 "register_operand" "=f")
14051 (unspec:XF [(float_extend:XF
14052 (match_operand:MODEF 1 "register_operand" "0"))
14053 (match_operand:XF 2 "register_operand" "u")]
14055 (clobber (match_scratch:XF 3 "=2"))]
14056 "TARGET_USE_FANCY_MATH_387
14057 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14058 || TARGET_MIX_SSE_I387)
14059 && flag_unsafe_math_optimizations"
14061 [(set_attr "type" "fpspc")
14062 (set_attr "mode" "XF")])
14064 (define_expand "log1pxf2"
14065 [(use (match_operand:XF 0 "register_operand" ""))
14066 (use (match_operand:XF 1 "register_operand" ""))]
14067 "TARGET_USE_FANCY_MATH_387
14068 && flag_unsafe_math_optimizations"
14070 if (optimize_insn_for_size_p ())
14073 ix86_emit_i387_log1p (operands[0], operands[1]);
14077 (define_expand "log1p<mode>2"
14078 [(use (match_operand:MODEF 0 "register_operand" ""))
14079 (use (match_operand:MODEF 1 "register_operand" ""))]
14080 "TARGET_USE_FANCY_MATH_387
14081 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14082 || TARGET_MIX_SSE_I387)
14083 && flag_unsafe_math_optimizations"
14087 if (optimize_insn_for_size_p ())
14090 op0 = gen_reg_rtx (XFmode);
14092 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14094 ix86_emit_i387_log1p (op0, operands[1]);
14095 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14099 (define_insn "fxtractxf3_i387"
14100 [(set (match_operand:XF 0 "register_operand" "=f")
14101 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14102 UNSPEC_XTRACT_FRACT))
14103 (set (match_operand:XF 1 "register_operand" "=u")
14104 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14105 "TARGET_USE_FANCY_MATH_387
14106 && flag_unsafe_math_optimizations"
14108 [(set_attr "type" "fpspc")
14109 (set_attr "mode" "XF")])
14111 (define_insn "fxtract_extend<mode>xf3_i387"
14112 [(set (match_operand:XF 0 "register_operand" "=f")
14113 (unspec:XF [(float_extend:XF
14114 (match_operand:MODEF 2 "register_operand" "0"))]
14115 UNSPEC_XTRACT_FRACT))
14116 (set (match_operand:XF 1 "register_operand" "=u")
14117 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14118 "TARGET_USE_FANCY_MATH_387
14119 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14120 || TARGET_MIX_SSE_I387)
14121 && flag_unsafe_math_optimizations"
14123 [(set_attr "type" "fpspc")
14124 (set_attr "mode" "XF")])
14126 (define_expand "logbxf2"
14127 [(parallel [(set (match_dup 2)
14128 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14129 UNSPEC_XTRACT_FRACT))
14130 (set (match_operand:XF 0 "register_operand" "")
14131 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14132 "TARGET_USE_FANCY_MATH_387
14133 && flag_unsafe_math_optimizations"
14134 "operands[2] = gen_reg_rtx (XFmode);")
14136 (define_expand "logb<mode>2"
14137 [(use (match_operand:MODEF 0 "register_operand" ""))
14138 (use (match_operand:MODEF 1 "register_operand" ""))]
14139 "TARGET_USE_FANCY_MATH_387
14140 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14141 || TARGET_MIX_SSE_I387)
14142 && flag_unsafe_math_optimizations"
14144 rtx op0 = gen_reg_rtx (XFmode);
14145 rtx op1 = gen_reg_rtx (XFmode);
14147 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14148 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14152 (define_expand "ilogbxf2"
14153 [(use (match_operand:SI 0 "register_operand" ""))
14154 (use (match_operand:XF 1 "register_operand" ""))]
14155 "TARGET_USE_FANCY_MATH_387
14156 && flag_unsafe_math_optimizations"
14160 if (optimize_insn_for_size_p ())
14163 op0 = gen_reg_rtx (XFmode);
14164 op1 = gen_reg_rtx (XFmode);
14166 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14167 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14171 (define_expand "ilogb<mode>2"
14172 [(use (match_operand:SI 0 "register_operand" ""))
14173 (use (match_operand:MODEF 1 "register_operand" ""))]
14174 "TARGET_USE_FANCY_MATH_387
14175 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14176 || TARGET_MIX_SSE_I387)
14177 && flag_unsafe_math_optimizations"
14181 if (optimize_insn_for_size_p ())
14184 op0 = gen_reg_rtx (XFmode);
14185 op1 = gen_reg_rtx (XFmode);
14187 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14188 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14192 (define_insn "*f2xm1xf2_i387"
14193 [(set (match_operand:XF 0 "register_operand" "=f")
14194 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14196 "TARGET_USE_FANCY_MATH_387
14197 && flag_unsafe_math_optimizations"
14199 [(set_attr "type" "fpspc")
14200 (set_attr "mode" "XF")])
14202 (define_insn "*fscalexf4_i387"
14203 [(set (match_operand:XF 0 "register_operand" "=f")
14204 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14205 (match_operand:XF 3 "register_operand" "1")]
14206 UNSPEC_FSCALE_FRACT))
14207 (set (match_operand:XF 1 "register_operand" "=u")
14208 (unspec:XF [(match_dup 2) (match_dup 3)]
14209 UNSPEC_FSCALE_EXP))]
14210 "TARGET_USE_FANCY_MATH_387
14211 && flag_unsafe_math_optimizations"
14213 [(set_attr "type" "fpspc")
14214 (set_attr "mode" "XF")])
14216 (define_expand "expNcorexf3"
14217 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14218 (match_operand:XF 2 "register_operand" "")))
14219 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14220 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14221 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14222 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14223 (parallel [(set (match_operand:XF 0 "register_operand" "")
14224 (unspec:XF [(match_dup 8) (match_dup 4)]
14225 UNSPEC_FSCALE_FRACT))
14227 (unspec:XF [(match_dup 8) (match_dup 4)]
14228 UNSPEC_FSCALE_EXP))])]
14229 "TARGET_USE_FANCY_MATH_387
14230 && flag_unsafe_math_optimizations"
14234 if (optimize_insn_for_size_p ())
14237 for (i = 3; i < 10; i++)
14238 operands[i] = gen_reg_rtx (XFmode);
14240 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14243 (define_expand "expxf2"
14244 [(use (match_operand:XF 0 "register_operand" ""))
14245 (use (match_operand:XF 1 "register_operand" ""))]
14246 "TARGET_USE_FANCY_MATH_387
14247 && flag_unsafe_math_optimizations"
14251 if (optimize_insn_for_size_p ())
14254 op2 = gen_reg_rtx (XFmode);
14255 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14257 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14261 (define_expand "exp<mode>2"
14262 [(use (match_operand:MODEF 0 "register_operand" ""))
14263 (use (match_operand:MODEF 1 "general_operand" ""))]
14264 "TARGET_USE_FANCY_MATH_387
14265 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14266 || TARGET_MIX_SSE_I387)
14267 && flag_unsafe_math_optimizations"
14271 if (optimize_insn_for_size_p ())
14274 op0 = gen_reg_rtx (XFmode);
14275 op1 = gen_reg_rtx (XFmode);
14277 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14278 emit_insn (gen_expxf2 (op0, op1));
14279 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14283 (define_expand "exp10xf2"
14284 [(use (match_operand:XF 0 "register_operand" ""))
14285 (use (match_operand:XF 1 "register_operand" ""))]
14286 "TARGET_USE_FANCY_MATH_387
14287 && flag_unsafe_math_optimizations"
14291 if (optimize_insn_for_size_p ())
14294 op2 = gen_reg_rtx (XFmode);
14295 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14297 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14301 (define_expand "exp10<mode>2"
14302 [(use (match_operand:MODEF 0 "register_operand" ""))
14303 (use (match_operand:MODEF 1 "general_operand" ""))]
14304 "TARGET_USE_FANCY_MATH_387
14305 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14306 || TARGET_MIX_SSE_I387)
14307 && flag_unsafe_math_optimizations"
14311 if (optimize_insn_for_size_p ())
14314 op0 = gen_reg_rtx (XFmode);
14315 op1 = gen_reg_rtx (XFmode);
14317 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14318 emit_insn (gen_exp10xf2 (op0, op1));
14319 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14323 (define_expand "exp2xf2"
14324 [(use (match_operand:XF 0 "register_operand" ""))
14325 (use (match_operand:XF 1 "register_operand" ""))]
14326 "TARGET_USE_FANCY_MATH_387
14327 && flag_unsafe_math_optimizations"
14331 if (optimize_insn_for_size_p ())
14334 op2 = gen_reg_rtx (XFmode);
14335 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14337 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14341 (define_expand "exp2<mode>2"
14342 [(use (match_operand:MODEF 0 "register_operand" ""))
14343 (use (match_operand:MODEF 1 "general_operand" ""))]
14344 "TARGET_USE_FANCY_MATH_387
14345 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14346 || TARGET_MIX_SSE_I387)
14347 && flag_unsafe_math_optimizations"
14351 if (optimize_insn_for_size_p ())
14354 op0 = gen_reg_rtx (XFmode);
14355 op1 = gen_reg_rtx (XFmode);
14357 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14358 emit_insn (gen_exp2xf2 (op0, op1));
14359 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14363 (define_expand "expm1xf2"
14364 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14366 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14367 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14368 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14369 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14370 (parallel [(set (match_dup 7)
14371 (unspec:XF [(match_dup 6) (match_dup 4)]
14372 UNSPEC_FSCALE_FRACT))
14374 (unspec:XF [(match_dup 6) (match_dup 4)]
14375 UNSPEC_FSCALE_EXP))])
14376 (parallel [(set (match_dup 10)
14377 (unspec:XF [(match_dup 9) (match_dup 8)]
14378 UNSPEC_FSCALE_FRACT))
14379 (set (match_dup 11)
14380 (unspec:XF [(match_dup 9) (match_dup 8)]
14381 UNSPEC_FSCALE_EXP))])
14382 (set (match_dup 12) (minus:XF (match_dup 10)
14383 (float_extend:XF (match_dup 13))))
14384 (set (match_operand:XF 0 "register_operand" "")
14385 (plus:XF (match_dup 12) (match_dup 7)))]
14386 "TARGET_USE_FANCY_MATH_387
14387 && flag_unsafe_math_optimizations"
14391 if (optimize_insn_for_size_p ())
14394 for (i = 2; i < 13; i++)
14395 operands[i] = gen_reg_rtx (XFmode);
14398 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14400 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14403 (define_expand "expm1<mode>2"
14404 [(use (match_operand:MODEF 0 "register_operand" ""))
14405 (use (match_operand:MODEF 1 "general_operand" ""))]
14406 "TARGET_USE_FANCY_MATH_387
14407 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14408 || TARGET_MIX_SSE_I387)
14409 && flag_unsafe_math_optimizations"
14413 if (optimize_insn_for_size_p ())
14416 op0 = gen_reg_rtx (XFmode);
14417 op1 = gen_reg_rtx (XFmode);
14419 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14420 emit_insn (gen_expm1xf2 (op0, op1));
14421 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14425 (define_expand "ldexpxf3"
14426 [(set (match_dup 3)
14427 (float:XF (match_operand:SI 2 "register_operand" "")))
14428 (parallel [(set (match_operand:XF 0 " register_operand" "")
14429 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14431 UNSPEC_FSCALE_FRACT))
14433 (unspec:XF [(match_dup 1) (match_dup 3)]
14434 UNSPEC_FSCALE_EXP))])]
14435 "TARGET_USE_FANCY_MATH_387
14436 && flag_unsafe_math_optimizations"
14438 if (optimize_insn_for_size_p ())
14441 operands[3] = gen_reg_rtx (XFmode);
14442 operands[4] = gen_reg_rtx (XFmode);
14445 (define_expand "ldexp<mode>3"
14446 [(use (match_operand:MODEF 0 "register_operand" ""))
14447 (use (match_operand:MODEF 1 "general_operand" ""))
14448 (use (match_operand:SI 2 "register_operand" ""))]
14449 "TARGET_USE_FANCY_MATH_387
14450 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14451 || TARGET_MIX_SSE_I387)
14452 && flag_unsafe_math_optimizations"
14456 if (optimize_insn_for_size_p ())
14459 op0 = gen_reg_rtx (XFmode);
14460 op1 = gen_reg_rtx (XFmode);
14462 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14463 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14464 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14468 (define_expand "scalbxf3"
14469 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14470 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14471 (match_operand:XF 2 "register_operand" "")]
14472 UNSPEC_FSCALE_FRACT))
14474 (unspec:XF [(match_dup 1) (match_dup 2)]
14475 UNSPEC_FSCALE_EXP))])]
14476 "TARGET_USE_FANCY_MATH_387
14477 && flag_unsafe_math_optimizations"
14479 if (optimize_insn_for_size_p ())
14482 operands[3] = gen_reg_rtx (XFmode);
14485 (define_expand "scalb<mode>3"
14486 [(use (match_operand:MODEF 0 "register_operand" ""))
14487 (use (match_operand:MODEF 1 "general_operand" ""))
14488 (use (match_operand:MODEF 2 "general_operand" ""))]
14489 "TARGET_USE_FANCY_MATH_387
14490 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14491 || TARGET_MIX_SSE_I387)
14492 && flag_unsafe_math_optimizations"
14496 if (optimize_insn_for_size_p ())
14499 op0 = gen_reg_rtx (XFmode);
14500 op1 = gen_reg_rtx (XFmode);
14501 op2 = gen_reg_rtx (XFmode);
14503 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14504 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14505 emit_insn (gen_scalbxf3 (op0, op1, op2));
14506 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14510 (define_expand "significandxf2"
14511 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14512 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14513 UNSPEC_XTRACT_FRACT))
14515 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14516 "TARGET_USE_FANCY_MATH_387
14517 && flag_unsafe_math_optimizations"
14518 "operands[2] = gen_reg_rtx (XFmode);")
14520 (define_expand "significand<mode>2"
14521 [(use (match_operand:MODEF 0 "register_operand" ""))
14522 (use (match_operand:MODEF 1 "register_operand" ""))]
14523 "TARGET_USE_FANCY_MATH_387
14524 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14525 || TARGET_MIX_SSE_I387)
14526 && flag_unsafe_math_optimizations"
14528 rtx op0 = gen_reg_rtx (XFmode);
14529 rtx op1 = gen_reg_rtx (XFmode);
14531 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14532 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14537 (define_insn "sse4_1_round<mode>2"
14538 [(set (match_operand:MODEF 0 "register_operand" "=x")
14539 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14540 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14543 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14544 [(set_attr "type" "ssecvt")
14545 (set_attr "prefix_extra" "1")
14546 (set_attr "prefix" "maybe_vex")
14547 (set_attr "mode" "<MODE>")])
14549 (define_insn "rintxf2"
14550 [(set (match_operand:XF 0 "register_operand" "=f")
14551 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14553 "TARGET_USE_FANCY_MATH_387
14554 && flag_unsafe_math_optimizations"
14556 [(set_attr "type" "fpspc")
14557 (set_attr "mode" "XF")])
14559 (define_expand "rint<mode>2"
14560 [(use (match_operand:MODEF 0 "register_operand" ""))
14561 (use (match_operand:MODEF 1 "register_operand" ""))]
14562 "(TARGET_USE_FANCY_MATH_387
14563 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14564 || TARGET_MIX_SSE_I387)
14565 && flag_unsafe_math_optimizations)
14566 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14567 && !flag_trapping_math)"
14569 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14570 && !flag_trapping_math)
14572 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14575 emit_insn (gen_sse4_1_round<mode>2
14576 (operands[0], operands[1], GEN_INT (0x04)));
14578 ix86_expand_rint (operand0, operand1);
14582 rtx op0 = gen_reg_rtx (XFmode);
14583 rtx op1 = gen_reg_rtx (XFmode);
14585 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14586 emit_insn (gen_rintxf2 (op0, op1));
14588 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14593 (define_expand "round<mode>2"
14594 [(match_operand:MODEF 0 "register_operand" "")
14595 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14596 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14597 && !flag_trapping_math && !flag_rounding_math"
14599 if (optimize_insn_for_size_p ())
14601 if (TARGET_64BIT || (<MODE>mode != DFmode))
14602 ix86_expand_round (operand0, operand1);
14604 ix86_expand_rounddf_32 (operand0, operand1);
14608 (define_insn_and_split "*fistdi2_1"
14609 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14610 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14612 "TARGET_USE_FANCY_MATH_387
14613 && can_create_pseudo_p ()"
14618 if (memory_operand (operands[0], VOIDmode))
14619 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14622 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14623 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14628 [(set_attr "type" "fpspc")
14629 (set_attr "mode" "DI")])
14631 (define_insn "fistdi2"
14632 [(set (match_operand:DI 0 "memory_operand" "=m")
14633 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14635 (clobber (match_scratch:XF 2 "=&1f"))]
14636 "TARGET_USE_FANCY_MATH_387"
14637 "* return output_fix_trunc (insn, operands, 0);"
14638 [(set_attr "type" "fpspc")
14639 (set_attr "mode" "DI")])
14641 (define_insn "fistdi2_with_temp"
14642 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14643 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14645 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14646 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14647 "TARGET_USE_FANCY_MATH_387"
14649 [(set_attr "type" "fpspc")
14650 (set_attr "mode" "DI")])
14653 [(set (match_operand:DI 0 "register_operand" "")
14654 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14656 (clobber (match_operand:DI 2 "memory_operand" ""))
14657 (clobber (match_scratch 3 ""))]
14659 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14660 (clobber (match_dup 3))])
14661 (set (match_dup 0) (match_dup 2))])
14664 [(set (match_operand:DI 0 "memory_operand" "")
14665 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14667 (clobber (match_operand:DI 2 "memory_operand" ""))
14668 (clobber (match_scratch 3 ""))]
14670 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14671 (clobber (match_dup 3))])])
14673 (define_insn_and_split "*fist<mode>2_1"
14674 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14675 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14677 "TARGET_USE_FANCY_MATH_387
14678 && can_create_pseudo_p ()"
14683 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14684 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14688 [(set_attr "type" "fpspc")
14689 (set_attr "mode" "<MODE>")])
14691 (define_insn "fist<mode>2"
14692 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14693 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14695 "TARGET_USE_FANCY_MATH_387"
14696 "* return output_fix_trunc (insn, operands, 0);"
14697 [(set_attr "type" "fpspc")
14698 (set_attr "mode" "<MODE>")])
14700 (define_insn "fist<mode>2_with_temp"
14701 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14702 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14704 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14705 "TARGET_USE_FANCY_MATH_387"
14707 [(set_attr "type" "fpspc")
14708 (set_attr "mode" "<MODE>")])
14711 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14712 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14714 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14716 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14717 (set (match_dup 0) (match_dup 2))])
14720 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14721 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14723 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14725 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14727 (define_expand "lrintxf<mode>2"
14728 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14729 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14731 "TARGET_USE_FANCY_MATH_387")
14733 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14734 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14735 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14736 UNSPEC_FIX_NOTRUNC))]
14737 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14738 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14740 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14741 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14742 (match_operand:MODEF 1 "register_operand" "")]
14743 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14744 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14745 && !flag_trapping_math && !flag_rounding_math"
14747 if (optimize_insn_for_size_p ())
14749 ix86_expand_lround (operand0, operand1);
14753 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14754 (define_insn_and_split "frndintxf2_floor"
14755 [(set (match_operand:XF 0 "register_operand" "")
14756 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14757 UNSPEC_FRNDINT_FLOOR))
14758 (clobber (reg:CC FLAGS_REG))]
14759 "TARGET_USE_FANCY_MATH_387
14760 && flag_unsafe_math_optimizations
14761 && can_create_pseudo_p ()"
14766 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14768 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14769 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14771 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14772 operands[2], operands[3]));
14775 [(set_attr "type" "frndint")
14776 (set_attr "i387_cw" "floor")
14777 (set_attr "mode" "XF")])
14779 (define_insn "frndintxf2_floor_i387"
14780 [(set (match_operand:XF 0 "register_operand" "=f")
14781 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14782 UNSPEC_FRNDINT_FLOOR))
14783 (use (match_operand:HI 2 "memory_operand" "m"))
14784 (use (match_operand:HI 3 "memory_operand" "m"))]
14785 "TARGET_USE_FANCY_MATH_387
14786 && flag_unsafe_math_optimizations"
14787 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14788 [(set_attr "type" "frndint")
14789 (set_attr "i387_cw" "floor")
14790 (set_attr "mode" "XF")])
14792 (define_expand "floorxf2"
14793 [(use (match_operand:XF 0 "register_operand" ""))
14794 (use (match_operand:XF 1 "register_operand" ""))]
14795 "TARGET_USE_FANCY_MATH_387
14796 && flag_unsafe_math_optimizations"
14798 if (optimize_insn_for_size_p ())
14800 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14804 (define_expand "floor<mode>2"
14805 [(use (match_operand:MODEF 0 "register_operand" ""))
14806 (use (match_operand:MODEF 1 "register_operand" ""))]
14807 "(TARGET_USE_FANCY_MATH_387
14808 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14809 || TARGET_MIX_SSE_I387)
14810 && flag_unsafe_math_optimizations)
14811 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14812 && !flag_trapping_math)"
14814 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14815 && !flag_trapping_math
14816 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14818 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14821 emit_insn (gen_sse4_1_round<mode>2
14822 (operands[0], operands[1], GEN_INT (0x01)));
14823 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14824 ix86_expand_floorceil (operand0, operand1, true);
14826 ix86_expand_floorceildf_32 (operand0, operand1, true);
14832 if (optimize_insn_for_size_p ())
14835 op0 = gen_reg_rtx (XFmode);
14836 op1 = gen_reg_rtx (XFmode);
14837 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14838 emit_insn (gen_frndintxf2_floor (op0, op1));
14840 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14845 (define_insn_and_split "*fist<mode>2_floor_1"
14846 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14847 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14848 UNSPEC_FIST_FLOOR))
14849 (clobber (reg:CC FLAGS_REG))]
14850 "TARGET_USE_FANCY_MATH_387
14851 && flag_unsafe_math_optimizations
14852 && can_create_pseudo_p ()"
14857 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14859 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14860 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14861 if (memory_operand (operands[0], VOIDmode))
14862 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14863 operands[2], operands[3]));
14866 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14867 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14868 operands[2], operands[3],
14873 [(set_attr "type" "fistp")
14874 (set_attr "i387_cw" "floor")
14875 (set_attr "mode" "<MODE>")])
14877 (define_insn "fistdi2_floor"
14878 [(set (match_operand:DI 0 "memory_operand" "=m")
14879 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14880 UNSPEC_FIST_FLOOR))
14881 (use (match_operand:HI 2 "memory_operand" "m"))
14882 (use (match_operand:HI 3 "memory_operand" "m"))
14883 (clobber (match_scratch:XF 4 "=&1f"))]
14884 "TARGET_USE_FANCY_MATH_387
14885 && flag_unsafe_math_optimizations"
14886 "* return output_fix_trunc (insn, operands, 0);"
14887 [(set_attr "type" "fistp")
14888 (set_attr "i387_cw" "floor")
14889 (set_attr "mode" "DI")])
14891 (define_insn "fistdi2_floor_with_temp"
14892 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14893 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14894 UNSPEC_FIST_FLOOR))
14895 (use (match_operand:HI 2 "memory_operand" "m,m"))
14896 (use (match_operand:HI 3 "memory_operand" "m,m"))
14897 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14898 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14899 "TARGET_USE_FANCY_MATH_387
14900 && flag_unsafe_math_optimizations"
14902 [(set_attr "type" "fistp")
14903 (set_attr "i387_cw" "floor")
14904 (set_attr "mode" "DI")])
14907 [(set (match_operand:DI 0 "register_operand" "")
14908 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14909 UNSPEC_FIST_FLOOR))
14910 (use (match_operand:HI 2 "memory_operand" ""))
14911 (use (match_operand:HI 3 "memory_operand" ""))
14912 (clobber (match_operand:DI 4 "memory_operand" ""))
14913 (clobber (match_scratch 5 ""))]
14915 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14916 (use (match_dup 2))
14917 (use (match_dup 3))
14918 (clobber (match_dup 5))])
14919 (set (match_dup 0) (match_dup 4))])
14922 [(set (match_operand:DI 0 "memory_operand" "")
14923 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14924 UNSPEC_FIST_FLOOR))
14925 (use (match_operand:HI 2 "memory_operand" ""))
14926 (use (match_operand:HI 3 "memory_operand" ""))
14927 (clobber (match_operand:DI 4 "memory_operand" ""))
14928 (clobber (match_scratch 5 ""))]
14930 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14931 (use (match_dup 2))
14932 (use (match_dup 3))
14933 (clobber (match_dup 5))])])
14935 (define_insn "fist<mode>2_floor"
14936 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14937 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14938 UNSPEC_FIST_FLOOR))
14939 (use (match_operand:HI 2 "memory_operand" "m"))
14940 (use (match_operand:HI 3 "memory_operand" "m"))]
14941 "TARGET_USE_FANCY_MATH_387
14942 && flag_unsafe_math_optimizations"
14943 "* return output_fix_trunc (insn, operands, 0);"
14944 [(set_attr "type" "fistp")
14945 (set_attr "i387_cw" "floor")
14946 (set_attr "mode" "<MODE>")])
14948 (define_insn "fist<mode>2_floor_with_temp"
14949 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14950 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14951 UNSPEC_FIST_FLOOR))
14952 (use (match_operand:HI 2 "memory_operand" "m,m"))
14953 (use (match_operand:HI 3 "memory_operand" "m,m"))
14954 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14955 "TARGET_USE_FANCY_MATH_387
14956 && flag_unsafe_math_optimizations"
14958 [(set_attr "type" "fistp")
14959 (set_attr "i387_cw" "floor")
14960 (set_attr "mode" "<MODE>")])
14963 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14964 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14965 UNSPEC_FIST_FLOOR))
14966 (use (match_operand:HI 2 "memory_operand" ""))
14967 (use (match_operand:HI 3 "memory_operand" ""))
14968 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14970 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14971 UNSPEC_FIST_FLOOR))
14972 (use (match_dup 2))
14973 (use (match_dup 3))])
14974 (set (match_dup 0) (match_dup 4))])
14977 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14978 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14979 UNSPEC_FIST_FLOOR))
14980 (use (match_operand:HI 2 "memory_operand" ""))
14981 (use (match_operand:HI 3 "memory_operand" ""))
14982 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14984 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14985 UNSPEC_FIST_FLOOR))
14986 (use (match_dup 2))
14987 (use (match_dup 3))])])
14989 (define_expand "lfloorxf<mode>2"
14990 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14991 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14992 UNSPEC_FIST_FLOOR))
14993 (clobber (reg:CC FLAGS_REG))])]
14994 "TARGET_USE_FANCY_MATH_387
14995 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14996 && flag_unsafe_math_optimizations")
14998 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14999 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15000 (match_operand:MODEF 1 "register_operand" "")]
15001 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15002 && !flag_trapping_math"
15004 if (TARGET_64BIT && optimize_insn_for_size_p ())
15006 ix86_expand_lfloorceil (operand0, operand1, true);
15010 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15011 (define_insn_and_split "frndintxf2_ceil"
15012 [(set (match_operand:XF 0 "register_operand" "")
15013 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15014 UNSPEC_FRNDINT_CEIL))
15015 (clobber (reg:CC FLAGS_REG))]
15016 "TARGET_USE_FANCY_MATH_387
15017 && flag_unsafe_math_optimizations
15018 && can_create_pseudo_p ()"
15023 ix86_optimize_mode_switching[I387_CEIL] = 1;
15025 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15026 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15028 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15029 operands[2], operands[3]));
15032 [(set_attr "type" "frndint")
15033 (set_attr "i387_cw" "ceil")
15034 (set_attr "mode" "XF")])
15036 (define_insn "frndintxf2_ceil_i387"
15037 [(set (match_operand:XF 0 "register_operand" "=f")
15038 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15039 UNSPEC_FRNDINT_CEIL))
15040 (use (match_operand:HI 2 "memory_operand" "m"))
15041 (use (match_operand:HI 3 "memory_operand" "m"))]
15042 "TARGET_USE_FANCY_MATH_387
15043 && flag_unsafe_math_optimizations"
15044 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15045 [(set_attr "type" "frndint")
15046 (set_attr "i387_cw" "ceil")
15047 (set_attr "mode" "XF")])
15049 (define_expand "ceilxf2"
15050 [(use (match_operand:XF 0 "register_operand" ""))
15051 (use (match_operand:XF 1 "register_operand" ""))]
15052 "TARGET_USE_FANCY_MATH_387
15053 && flag_unsafe_math_optimizations"
15055 if (optimize_insn_for_size_p ())
15057 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15061 (define_expand "ceil<mode>2"
15062 [(use (match_operand:MODEF 0 "register_operand" ""))
15063 (use (match_operand:MODEF 1 "register_operand" ""))]
15064 "(TARGET_USE_FANCY_MATH_387
15065 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15066 || TARGET_MIX_SSE_I387)
15067 && flag_unsafe_math_optimizations)
15068 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15069 && !flag_trapping_math)"
15071 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15072 && !flag_trapping_math
15073 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15076 emit_insn (gen_sse4_1_round<mode>2
15077 (operands[0], operands[1], GEN_INT (0x02)));
15078 else if (optimize_insn_for_size_p ())
15080 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15081 ix86_expand_floorceil (operand0, operand1, false);
15083 ix86_expand_floorceildf_32 (operand0, operand1, false);
15089 if (optimize_insn_for_size_p ())
15092 op0 = gen_reg_rtx (XFmode);
15093 op1 = gen_reg_rtx (XFmode);
15094 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15095 emit_insn (gen_frndintxf2_ceil (op0, op1));
15097 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15102 (define_insn_and_split "*fist<mode>2_ceil_1"
15103 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15104 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15106 (clobber (reg:CC FLAGS_REG))]
15107 "TARGET_USE_FANCY_MATH_387
15108 && flag_unsafe_math_optimizations
15109 && can_create_pseudo_p ()"
15114 ix86_optimize_mode_switching[I387_CEIL] = 1;
15116 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15117 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15118 if (memory_operand (operands[0], VOIDmode))
15119 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15120 operands[2], operands[3]));
15123 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15124 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15125 operands[2], operands[3],
15130 [(set_attr "type" "fistp")
15131 (set_attr "i387_cw" "ceil")
15132 (set_attr "mode" "<MODE>")])
15134 (define_insn "fistdi2_ceil"
15135 [(set (match_operand:DI 0 "memory_operand" "=m")
15136 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15138 (use (match_operand:HI 2 "memory_operand" "m"))
15139 (use (match_operand:HI 3 "memory_operand" "m"))
15140 (clobber (match_scratch:XF 4 "=&1f"))]
15141 "TARGET_USE_FANCY_MATH_387
15142 && flag_unsafe_math_optimizations"
15143 "* return output_fix_trunc (insn, operands, 0);"
15144 [(set_attr "type" "fistp")
15145 (set_attr "i387_cw" "ceil")
15146 (set_attr "mode" "DI")])
15148 (define_insn "fistdi2_ceil_with_temp"
15149 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15150 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15152 (use (match_operand:HI 2 "memory_operand" "m,m"))
15153 (use (match_operand:HI 3 "memory_operand" "m,m"))
15154 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15155 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15156 "TARGET_USE_FANCY_MATH_387
15157 && flag_unsafe_math_optimizations"
15159 [(set_attr "type" "fistp")
15160 (set_attr "i387_cw" "ceil")
15161 (set_attr "mode" "DI")])
15164 [(set (match_operand:DI 0 "register_operand" "")
15165 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15167 (use (match_operand:HI 2 "memory_operand" ""))
15168 (use (match_operand:HI 3 "memory_operand" ""))
15169 (clobber (match_operand:DI 4 "memory_operand" ""))
15170 (clobber (match_scratch 5 ""))]
15172 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15173 (use (match_dup 2))
15174 (use (match_dup 3))
15175 (clobber (match_dup 5))])
15176 (set (match_dup 0) (match_dup 4))])
15179 [(set (match_operand:DI 0 "memory_operand" "")
15180 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15182 (use (match_operand:HI 2 "memory_operand" ""))
15183 (use (match_operand:HI 3 "memory_operand" ""))
15184 (clobber (match_operand:DI 4 "memory_operand" ""))
15185 (clobber (match_scratch 5 ""))]
15187 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15188 (use (match_dup 2))
15189 (use (match_dup 3))
15190 (clobber (match_dup 5))])])
15192 (define_insn "fist<mode>2_ceil"
15193 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15194 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15196 (use (match_operand:HI 2 "memory_operand" "m"))
15197 (use (match_operand:HI 3 "memory_operand" "m"))]
15198 "TARGET_USE_FANCY_MATH_387
15199 && flag_unsafe_math_optimizations"
15200 "* return output_fix_trunc (insn, operands, 0);"
15201 [(set_attr "type" "fistp")
15202 (set_attr "i387_cw" "ceil")
15203 (set_attr "mode" "<MODE>")])
15205 (define_insn "fist<mode>2_ceil_with_temp"
15206 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15207 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15209 (use (match_operand:HI 2 "memory_operand" "m,m"))
15210 (use (match_operand:HI 3 "memory_operand" "m,m"))
15211 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15212 "TARGET_USE_FANCY_MATH_387
15213 && flag_unsafe_math_optimizations"
15215 [(set_attr "type" "fistp")
15216 (set_attr "i387_cw" "ceil")
15217 (set_attr "mode" "<MODE>")])
15220 [(set (match_operand:X87MODEI12 0 "register_operand" "")
15221 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15223 (use (match_operand:HI 2 "memory_operand" ""))
15224 (use (match_operand:HI 3 "memory_operand" ""))
15225 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15227 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15229 (use (match_dup 2))
15230 (use (match_dup 3))])
15231 (set (match_dup 0) (match_dup 4))])
15234 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15235 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15237 (use (match_operand:HI 2 "memory_operand" ""))
15238 (use (match_operand:HI 3 "memory_operand" ""))
15239 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15241 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15243 (use (match_dup 2))
15244 (use (match_dup 3))])])
15246 (define_expand "lceilxf<mode>2"
15247 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15248 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15250 (clobber (reg:CC FLAGS_REG))])]
15251 "TARGET_USE_FANCY_MATH_387
15252 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15253 && flag_unsafe_math_optimizations")
15255 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15256 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15257 (match_operand:MODEF 1 "register_operand" "")]
15258 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15259 && !flag_trapping_math"
15261 ix86_expand_lfloorceil (operand0, operand1, false);
15265 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15266 (define_insn_and_split "frndintxf2_trunc"
15267 [(set (match_operand:XF 0 "register_operand" "")
15268 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15269 UNSPEC_FRNDINT_TRUNC))
15270 (clobber (reg:CC FLAGS_REG))]
15271 "TARGET_USE_FANCY_MATH_387
15272 && flag_unsafe_math_optimizations
15273 && can_create_pseudo_p ()"
15278 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15280 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15281 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15283 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15284 operands[2], operands[3]));
15287 [(set_attr "type" "frndint")
15288 (set_attr "i387_cw" "trunc")
15289 (set_attr "mode" "XF")])
15291 (define_insn "frndintxf2_trunc_i387"
15292 [(set (match_operand:XF 0 "register_operand" "=f")
15293 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15294 UNSPEC_FRNDINT_TRUNC))
15295 (use (match_operand:HI 2 "memory_operand" "m"))
15296 (use (match_operand:HI 3 "memory_operand" "m"))]
15297 "TARGET_USE_FANCY_MATH_387
15298 && flag_unsafe_math_optimizations"
15299 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15300 [(set_attr "type" "frndint")
15301 (set_attr "i387_cw" "trunc")
15302 (set_attr "mode" "XF")])
15304 (define_expand "btruncxf2"
15305 [(use (match_operand:XF 0 "register_operand" ""))
15306 (use (match_operand:XF 1 "register_operand" ""))]
15307 "TARGET_USE_FANCY_MATH_387
15308 && flag_unsafe_math_optimizations"
15310 if (optimize_insn_for_size_p ())
15312 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15316 (define_expand "btrunc<mode>2"
15317 [(use (match_operand:MODEF 0 "register_operand" ""))
15318 (use (match_operand:MODEF 1 "register_operand" ""))]
15319 "(TARGET_USE_FANCY_MATH_387
15320 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15321 || TARGET_MIX_SSE_I387)
15322 && flag_unsafe_math_optimizations)
15323 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15324 && !flag_trapping_math)"
15326 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15327 && !flag_trapping_math
15328 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15331 emit_insn (gen_sse4_1_round<mode>2
15332 (operands[0], operands[1], GEN_INT (0x03)));
15333 else if (optimize_insn_for_size_p ())
15335 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15336 ix86_expand_trunc (operand0, operand1);
15338 ix86_expand_truncdf_32 (operand0, operand1);
15344 if (optimize_insn_for_size_p ())
15347 op0 = gen_reg_rtx (XFmode);
15348 op1 = gen_reg_rtx (XFmode);
15349 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15350 emit_insn (gen_frndintxf2_trunc (op0, op1));
15352 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15357 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15358 (define_insn_and_split "frndintxf2_mask_pm"
15359 [(set (match_operand:XF 0 "register_operand" "")
15360 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15361 UNSPEC_FRNDINT_MASK_PM))
15362 (clobber (reg:CC FLAGS_REG))]
15363 "TARGET_USE_FANCY_MATH_387
15364 && flag_unsafe_math_optimizations
15365 && can_create_pseudo_p ()"
15370 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15372 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15373 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15375 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15376 operands[2], operands[3]));
15379 [(set_attr "type" "frndint")
15380 (set_attr "i387_cw" "mask_pm")
15381 (set_attr "mode" "XF")])
15383 (define_insn "frndintxf2_mask_pm_i387"
15384 [(set (match_operand:XF 0 "register_operand" "=f")
15385 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15386 UNSPEC_FRNDINT_MASK_PM))
15387 (use (match_operand:HI 2 "memory_operand" "m"))
15388 (use (match_operand:HI 3 "memory_operand" "m"))]
15389 "TARGET_USE_FANCY_MATH_387
15390 && flag_unsafe_math_optimizations"
15391 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15392 [(set_attr "type" "frndint")
15393 (set_attr "i387_cw" "mask_pm")
15394 (set_attr "mode" "XF")])
15396 (define_expand "nearbyintxf2"
15397 [(use (match_operand:XF 0 "register_operand" ""))
15398 (use (match_operand:XF 1 "register_operand" ""))]
15399 "TARGET_USE_FANCY_MATH_387
15400 && flag_unsafe_math_optimizations"
15402 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15406 (define_expand "nearbyint<mode>2"
15407 [(use (match_operand:MODEF 0 "register_operand" ""))
15408 (use (match_operand:MODEF 1 "register_operand" ""))]
15409 "TARGET_USE_FANCY_MATH_387
15410 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15411 || TARGET_MIX_SSE_I387)
15412 && flag_unsafe_math_optimizations"
15414 rtx op0 = gen_reg_rtx (XFmode);
15415 rtx op1 = gen_reg_rtx (XFmode);
15417 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15418 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15420 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15424 (define_insn "fxam<mode>2_i387"
15425 [(set (match_operand:HI 0 "register_operand" "=a")
15427 [(match_operand:X87MODEF 1 "register_operand" "f")]
15429 "TARGET_USE_FANCY_MATH_387"
15430 "fxam\n\tfnstsw\t%0"
15431 [(set_attr "type" "multi")
15432 (set_attr "length" "4")
15433 (set_attr "unit" "i387")
15434 (set_attr "mode" "<MODE>")])
15436 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15437 [(set (match_operand:HI 0 "register_operand" "")
15439 [(match_operand:MODEF 1 "memory_operand" "")]
15441 "TARGET_USE_FANCY_MATH_387
15442 && can_create_pseudo_p ()"
15445 [(set (match_dup 2)(match_dup 1))
15447 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15449 operands[2] = gen_reg_rtx (<MODE>mode);
15451 MEM_VOLATILE_P (operands[1]) = 1;
15453 [(set_attr "type" "multi")
15454 (set_attr "unit" "i387")
15455 (set_attr "mode" "<MODE>")])
15457 (define_expand "isinfxf2"
15458 [(use (match_operand:SI 0 "register_operand" ""))
15459 (use (match_operand:XF 1 "register_operand" ""))]
15460 "TARGET_USE_FANCY_MATH_387
15461 && TARGET_C99_FUNCTIONS"
15463 rtx mask = GEN_INT (0x45);
15464 rtx val = GEN_INT (0x05);
15468 rtx scratch = gen_reg_rtx (HImode);
15469 rtx res = gen_reg_rtx (QImode);
15471 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15473 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15474 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15475 cond = gen_rtx_fmt_ee (EQ, QImode,
15476 gen_rtx_REG (CCmode, FLAGS_REG),
15478 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15479 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15483 (define_expand "isinf<mode>2"
15484 [(use (match_operand:SI 0 "register_operand" ""))
15485 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15486 "TARGET_USE_FANCY_MATH_387
15487 && TARGET_C99_FUNCTIONS
15488 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15490 rtx mask = GEN_INT (0x45);
15491 rtx val = GEN_INT (0x05);
15495 rtx scratch = gen_reg_rtx (HImode);
15496 rtx res = gen_reg_rtx (QImode);
15498 /* Remove excess precision by forcing value through memory. */
15499 if (memory_operand (operands[1], VOIDmode))
15500 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15503 enum ix86_stack_slot slot = (virtuals_instantiated
15506 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15508 emit_move_insn (temp, operands[1]);
15509 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15512 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15513 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15514 cond = gen_rtx_fmt_ee (EQ, QImode,
15515 gen_rtx_REG (CCmode, FLAGS_REG),
15517 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15518 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15522 (define_expand "signbitxf2"
15523 [(use (match_operand:SI 0 "register_operand" ""))
15524 (use (match_operand:XF 1 "register_operand" ""))]
15525 "TARGET_USE_FANCY_MATH_387"
15527 rtx scratch = gen_reg_rtx (HImode);
15529 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15530 emit_insn (gen_andsi3 (operands[0],
15531 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15535 (define_insn "movmsk_df"
15536 [(set (match_operand:SI 0 "register_operand" "=r")
15538 [(match_operand:DF 1 "register_operand" "x")]
15540 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15541 "%vmovmskpd\t{%1, %0|%0, %1}"
15542 [(set_attr "type" "ssemov")
15543 (set_attr "prefix" "maybe_vex")
15544 (set_attr "mode" "DF")])
15546 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15547 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15548 (define_expand "signbitdf2"
15549 [(use (match_operand:SI 0 "register_operand" ""))
15550 (use (match_operand:DF 1 "register_operand" ""))]
15551 "TARGET_USE_FANCY_MATH_387
15552 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15554 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15556 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15557 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15561 rtx scratch = gen_reg_rtx (HImode);
15563 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15564 emit_insn (gen_andsi3 (operands[0],
15565 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15570 (define_expand "signbitsf2"
15571 [(use (match_operand:SI 0 "register_operand" ""))
15572 (use (match_operand:SF 1 "register_operand" ""))]
15573 "TARGET_USE_FANCY_MATH_387
15574 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15576 rtx scratch = gen_reg_rtx (HImode);
15578 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15579 emit_insn (gen_andsi3 (operands[0],
15580 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15584 ;; Block operation instructions
15587 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15590 [(set_attr "length" "1")
15591 (set_attr "length_immediate" "0")
15592 (set_attr "modrm" "0")])
15594 (define_expand "movmem<mode>"
15595 [(use (match_operand:BLK 0 "memory_operand" ""))
15596 (use (match_operand:BLK 1 "memory_operand" ""))
15597 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15598 (use (match_operand:SWI48 3 "const_int_operand" ""))
15599 (use (match_operand:SI 4 "const_int_operand" ""))
15600 (use (match_operand:SI 5 "const_int_operand" ""))]
15603 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15604 operands[4], operands[5]))
15610 ;; Most CPUs don't like single string operations
15611 ;; Handle this case here to simplify previous expander.
15613 (define_expand "strmov"
15614 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15615 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15616 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15617 (clobber (reg:CC FLAGS_REG))])
15618 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15619 (clobber (reg:CC FLAGS_REG))])]
15622 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15624 /* If .md ever supports :P for Pmode, these can be directly
15625 in the pattern above. */
15626 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15627 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15629 /* Can't use this if the user has appropriated esi or edi. */
15630 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15631 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15633 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15634 operands[2], operands[3],
15635 operands[5], operands[6]));
15639 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15642 (define_expand "strmov_singleop"
15643 [(parallel [(set (match_operand 1 "memory_operand" "")
15644 (match_operand 3 "memory_operand" ""))
15645 (set (match_operand 0 "register_operand" "")
15646 (match_operand 4 "" ""))
15647 (set (match_operand 2 "register_operand" "")
15648 (match_operand 5 "" ""))])]
15650 "ix86_current_function_needs_cld = 1;")
15652 (define_insn "*strmovdi_rex_1"
15653 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15654 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15655 (set (match_operand:DI 0 "register_operand" "=D")
15656 (plus:DI (match_dup 2)
15658 (set (match_operand:DI 1 "register_operand" "=S")
15659 (plus:DI (match_dup 3)
15663 [(set_attr "type" "str")
15664 (set_attr "memory" "both")
15665 (set_attr "mode" "DI")])
15667 (define_insn "*strmovsi_1"
15668 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15669 (mem:SI (match_operand:P 3 "register_operand" "1")))
15670 (set (match_operand:P 0 "register_operand" "=D")
15671 (plus:P (match_dup 2)
15673 (set (match_operand:P 1 "register_operand" "=S")
15674 (plus:P (match_dup 3)
15678 [(set_attr "type" "str")
15679 (set_attr "memory" "both")
15680 (set_attr "mode" "SI")])
15682 (define_insn "*strmovhi_1"
15683 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15684 (mem:HI (match_operand:P 3 "register_operand" "1")))
15685 (set (match_operand:P 0 "register_operand" "=D")
15686 (plus:P (match_dup 2)
15688 (set (match_operand:P 1 "register_operand" "=S")
15689 (plus:P (match_dup 3)
15693 [(set_attr "type" "str")
15694 (set_attr "memory" "both")
15695 (set_attr "mode" "HI")])
15697 (define_insn "*strmovqi_1"
15698 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15699 (mem:QI (match_operand:P 3 "register_operand" "1")))
15700 (set (match_operand:P 0 "register_operand" "=D")
15701 (plus:P (match_dup 2)
15703 (set (match_operand:P 1 "register_operand" "=S")
15704 (plus:P (match_dup 3)
15708 [(set_attr "type" "str")
15709 (set_attr "memory" "both")
15710 (set (attr "prefix_rex")
15712 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15714 (const_string "*")))
15715 (set_attr "mode" "QI")])
15717 (define_expand "rep_mov"
15718 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15719 (set (match_operand 0 "register_operand" "")
15720 (match_operand 5 "" ""))
15721 (set (match_operand 2 "register_operand" "")
15722 (match_operand 6 "" ""))
15723 (set (match_operand 1 "memory_operand" "")
15724 (match_operand 3 "memory_operand" ""))
15725 (use (match_dup 4))])]
15727 "ix86_current_function_needs_cld = 1;")
15729 (define_insn "*rep_movdi_rex64"
15730 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15731 (set (match_operand:DI 0 "register_operand" "=D")
15732 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15734 (match_operand:DI 3 "register_operand" "0")))
15735 (set (match_operand:DI 1 "register_operand" "=S")
15736 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15737 (match_operand:DI 4 "register_operand" "1")))
15738 (set (mem:BLK (match_dup 3))
15739 (mem:BLK (match_dup 4)))
15740 (use (match_dup 5))]
15743 [(set_attr "type" "str")
15744 (set_attr "prefix_rep" "1")
15745 (set_attr "memory" "both")
15746 (set_attr "mode" "DI")])
15748 (define_insn "*rep_movsi"
15749 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15750 (set (match_operand:P 0 "register_operand" "=D")
15751 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15753 (match_operand:P 3 "register_operand" "0")))
15754 (set (match_operand:P 1 "register_operand" "=S")
15755 (plus:P (ashift:P (match_dup 5) (const_int 2))
15756 (match_operand:P 4 "register_operand" "1")))
15757 (set (mem:BLK (match_dup 3))
15758 (mem:BLK (match_dup 4)))
15759 (use (match_dup 5))]
15761 "rep{%;} movs{l|d}"
15762 [(set_attr "type" "str")
15763 (set_attr "prefix_rep" "1")
15764 (set_attr "memory" "both")
15765 (set_attr "mode" "SI")])
15767 (define_insn "*rep_movqi"
15768 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15769 (set (match_operand:P 0 "register_operand" "=D")
15770 (plus:P (match_operand:P 3 "register_operand" "0")
15771 (match_operand:P 5 "register_operand" "2")))
15772 (set (match_operand:P 1 "register_operand" "=S")
15773 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15774 (set (mem:BLK (match_dup 3))
15775 (mem:BLK (match_dup 4)))
15776 (use (match_dup 5))]
15779 [(set_attr "type" "str")
15780 (set_attr "prefix_rep" "1")
15781 (set_attr "memory" "both")
15782 (set_attr "mode" "QI")])
15784 (define_expand "setmem<mode>"
15785 [(use (match_operand:BLK 0 "memory_operand" ""))
15786 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15787 (use (match_operand 2 "const_int_operand" ""))
15788 (use (match_operand 3 "const_int_operand" ""))
15789 (use (match_operand:SI 4 "const_int_operand" ""))
15790 (use (match_operand:SI 5 "const_int_operand" ""))]
15793 if (ix86_expand_setmem (operands[0], operands[1],
15794 operands[2], operands[3],
15795 operands[4], operands[5]))
15801 ;; Most CPUs don't like single string operations
15802 ;; Handle this case here to simplify previous expander.
15804 (define_expand "strset"
15805 [(set (match_operand 1 "memory_operand" "")
15806 (match_operand 2 "register_operand" ""))
15807 (parallel [(set (match_operand 0 "register_operand" "")
15809 (clobber (reg:CC FLAGS_REG))])]
15812 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15813 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15815 /* If .md ever supports :P for Pmode, this can be directly
15816 in the pattern above. */
15817 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15818 GEN_INT (GET_MODE_SIZE (GET_MODE
15820 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15822 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15828 (define_expand "strset_singleop"
15829 [(parallel [(set (match_operand 1 "memory_operand" "")
15830 (match_operand 2 "register_operand" ""))
15831 (set (match_operand 0 "register_operand" "")
15832 (match_operand 3 "" ""))])]
15834 "ix86_current_function_needs_cld = 1;")
15836 (define_insn "*strsetdi_rex_1"
15837 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15838 (match_operand:DI 2 "register_operand" "a"))
15839 (set (match_operand:DI 0 "register_operand" "=D")
15840 (plus:DI (match_dup 1)
15844 [(set_attr "type" "str")
15845 (set_attr "memory" "store")
15846 (set_attr "mode" "DI")])
15848 (define_insn "*strsetsi_1"
15849 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15850 (match_operand:SI 2 "register_operand" "a"))
15851 (set (match_operand:P 0 "register_operand" "=D")
15852 (plus:P (match_dup 1)
15856 [(set_attr "type" "str")
15857 (set_attr "memory" "store")
15858 (set_attr "mode" "SI")])
15860 (define_insn "*strsethi_1"
15861 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15862 (match_operand:HI 2 "register_operand" "a"))
15863 (set (match_operand:P 0 "register_operand" "=D")
15864 (plus:P (match_dup 1)
15868 [(set_attr "type" "str")
15869 (set_attr "memory" "store")
15870 (set_attr "mode" "HI")])
15872 (define_insn "*strsetqi_1"
15873 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15874 (match_operand:QI 2 "register_operand" "a"))
15875 (set (match_operand:P 0 "register_operand" "=D")
15876 (plus:P (match_dup 1)
15880 [(set_attr "type" "str")
15881 (set_attr "memory" "store")
15882 (set (attr "prefix_rex")
15884 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15886 (const_string "*")))
15887 (set_attr "mode" "QI")])
15889 (define_expand "rep_stos"
15890 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15891 (set (match_operand 0 "register_operand" "")
15892 (match_operand 4 "" ""))
15893 (set (match_operand 2 "memory_operand" "") (const_int 0))
15894 (use (match_operand 3 "register_operand" ""))
15895 (use (match_dup 1))])]
15897 "ix86_current_function_needs_cld = 1;")
15899 (define_insn "*rep_stosdi_rex64"
15900 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15901 (set (match_operand:DI 0 "register_operand" "=D")
15902 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15904 (match_operand:DI 3 "register_operand" "0")))
15905 (set (mem:BLK (match_dup 3))
15907 (use (match_operand:DI 2 "register_operand" "a"))
15908 (use (match_dup 4))]
15911 [(set_attr "type" "str")
15912 (set_attr "prefix_rep" "1")
15913 (set_attr "memory" "store")
15914 (set_attr "mode" "DI")])
15916 (define_insn "*rep_stossi"
15917 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15918 (set (match_operand:P 0 "register_operand" "=D")
15919 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15921 (match_operand:P 3 "register_operand" "0")))
15922 (set (mem:BLK (match_dup 3))
15924 (use (match_operand:SI 2 "register_operand" "a"))
15925 (use (match_dup 4))]
15927 "rep{%;} stos{l|d}"
15928 [(set_attr "type" "str")
15929 (set_attr "prefix_rep" "1")
15930 (set_attr "memory" "store")
15931 (set_attr "mode" "SI")])
15933 (define_insn "*rep_stosqi"
15934 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15935 (set (match_operand:P 0 "register_operand" "=D")
15936 (plus:P (match_operand:P 3 "register_operand" "0")
15937 (match_operand:P 4 "register_operand" "1")))
15938 (set (mem:BLK (match_dup 3))
15940 (use (match_operand:QI 2 "register_operand" "a"))
15941 (use (match_dup 4))]
15944 [(set_attr "type" "str")
15945 (set_attr "prefix_rep" "1")
15946 (set_attr "memory" "store")
15947 (set (attr "prefix_rex")
15949 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15951 (const_string "*")))
15952 (set_attr "mode" "QI")])
15954 (define_expand "cmpstrnsi"
15955 [(set (match_operand:SI 0 "register_operand" "")
15956 (compare:SI (match_operand:BLK 1 "general_operand" "")
15957 (match_operand:BLK 2 "general_operand" "")))
15958 (use (match_operand 3 "general_operand" ""))
15959 (use (match_operand 4 "immediate_operand" ""))]
15962 rtx addr1, addr2, out, outlow, count, countreg, align;
15964 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15967 /* Can't use this if the user has appropriated esi or edi. */
15968 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15973 out = gen_reg_rtx (SImode);
15975 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15976 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15977 if (addr1 != XEXP (operands[1], 0))
15978 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15979 if (addr2 != XEXP (operands[2], 0))
15980 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15982 count = operands[3];
15983 countreg = ix86_zero_extend_to_Pmode (count);
15985 /* %%% Iff we are testing strict equality, we can use known alignment
15986 to good advantage. This may be possible with combine, particularly
15987 once cc0 is dead. */
15988 align = operands[4];
15990 if (CONST_INT_P (count))
15992 if (INTVAL (count) == 0)
15994 emit_move_insn (operands[0], const0_rtx);
15997 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15998 operands[1], operands[2]));
16002 rtx (*gen_cmp) (rtx, rtx);
16004 gen_cmp = (TARGET_64BIT
16005 ? gen_cmpdi_1 : gen_cmpsi_1);
16007 emit_insn (gen_cmp (countreg, countreg));
16008 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16009 operands[1], operands[2]));
16012 outlow = gen_lowpart (QImode, out);
16013 emit_insn (gen_cmpintqi (outlow));
16014 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16016 if (operands[0] != out)
16017 emit_move_insn (operands[0], out);
16022 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16024 (define_expand "cmpintqi"
16025 [(set (match_dup 1)
16026 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16028 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16029 (parallel [(set (match_operand:QI 0 "register_operand" "")
16030 (minus:QI (match_dup 1)
16032 (clobber (reg:CC FLAGS_REG))])]
16035 operands[1] = gen_reg_rtx (QImode);
16036 operands[2] = gen_reg_rtx (QImode);
16039 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16040 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16042 (define_expand "cmpstrnqi_nz_1"
16043 [(parallel [(set (reg:CC FLAGS_REG)
16044 (compare:CC (match_operand 4 "memory_operand" "")
16045 (match_operand 5 "memory_operand" "")))
16046 (use (match_operand 2 "register_operand" ""))
16047 (use (match_operand:SI 3 "immediate_operand" ""))
16048 (clobber (match_operand 0 "register_operand" ""))
16049 (clobber (match_operand 1 "register_operand" ""))
16050 (clobber (match_dup 2))])]
16052 "ix86_current_function_needs_cld = 1;")
16054 (define_insn "*cmpstrnqi_nz_1"
16055 [(set (reg:CC FLAGS_REG)
16056 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16057 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16058 (use (match_operand:P 6 "register_operand" "2"))
16059 (use (match_operand:SI 3 "immediate_operand" "i"))
16060 (clobber (match_operand:P 0 "register_operand" "=S"))
16061 (clobber (match_operand:P 1 "register_operand" "=D"))
16062 (clobber (match_operand:P 2 "register_operand" "=c"))]
16065 [(set_attr "type" "str")
16066 (set_attr "mode" "QI")
16067 (set (attr "prefix_rex")
16069 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16071 (const_string "*")))
16072 (set_attr "prefix_rep" "1")])
16074 ;; The same, but the count is not known to not be zero.
16076 (define_expand "cmpstrnqi_1"
16077 [(parallel [(set (reg:CC FLAGS_REG)
16078 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16080 (compare:CC (match_operand 4 "memory_operand" "")
16081 (match_operand 5 "memory_operand" ""))
16083 (use (match_operand:SI 3 "immediate_operand" ""))
16084 (use (reg:CC FLAGS_REG))
16085 (clobber (match_operand 0 "register_operand" ""))
16086 (clobber (match_operand 1 "register_operand" ""))
16087 (clobber (match_dup 2))])]
16089 "ix86_current_function_needs_cld = 1;")
16091 (define_insn "*cmpstrnqi_1"
16092 [(set (reg:CC FLAGS_REG)
16093 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16095 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16096 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16098 (use (match_operand:SI 3 "immediate_operand" "i"))
16099 (use (reg:CC FLAGS_REG))
16100 (clobber (match_operand:P 0 "register_operand" "=S"))
16101 (clobber (match_operand:P 1 "register_operand" "=D"))
16102 (clobber (match_operand:P 2 "register_operand" "=c"))]
16105 [(set_attr "type" "str")
16106 (set_attr "mode" "QI")
16107 (set (attr "prefix_rex")
16109 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16111 (const_string "*")))
16112 (set_attr "prefix_rep" "1")])
16114 (define_expand "strlen<mode>"
16115 [(set (match_operand:SWI48x 0 "register_operand" "")
16116 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
16117 (match_operand:QI 2 "immediate_operand" "")
16118 (match_operand 3 "immediate_operand" "")]
16122 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16128 (define_expand "strlenqi_1"
16129 [(parallel [(set (match_operand 0 "register_operand" "")
16130 (match_operand 2 "" ""))
16131 (clobber (match_operand 1 "register_operand" ""))
16132 (clobber (reg:CC FLAGS_REG))])]
16134 "ix86_current_function_needs_cld = 1;")
16136 (define_insn "*strlenqi_1"
16137 [(set (match_operand:P 0 "register_operand" "=&c")
16138 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16139 (match_operand:QI 2 "register_operand" "a")
16140 (match_operand:P 3 "immediate_operand" "i")
16141 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16142 (clobber (match_operand:P 1 "register_operand" "=D"))
16143 (clobber (reg:CC FLAGS_REG))]
16146 [(set_attr "type" "str")
16147 (set_attr "mode" "QI")
16148 (set (attr "prefix_rex")
16150 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
16152 (const_string "*")))
16153 (set_attr "prefix_rep" "1")])
16155 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16156 ;; handled in combine, but it is not currently up to the task.
16157 ;; When used for their truth value, the cmpstrn* expanders generate
16166 ;; The intermediate three instructions are unnecessary.
16168 ;; This one handles cmpstrn*_nz_1...
16171 (set (reg:CC FLAGS_REG)
16172 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16173 (mem:BLK (match_operand 5 "register_operand" ""))))
16174 (use (match_operand 6 "register_operand" ""))
16175 (use (match_operand:SI 3 "immediate_operand" ""))
16176 (clobber (match_operand 0 "register_operand" ""))
16177 (clobber (match_operand 1 "register_operand" ""))
16178 (clobber (match_operand 2 "register_operand" ""))])
16179 (set (match_operand:QI 7 "register_operand" "")
16180 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16181 (set (match_operand:QI 8 "register_operand" "")
16182 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16183 (set (reg FLAGS_REG)
16184 (compare (match_dup 7) (match_dup 8)))
16186 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16188 (set (reg:CC FLAGS_REG)
16189 (compare:CC (mem:BLK (match_dup 4))
16190 (mem:BLK (match_dup 5))))
16191 (use (match_dup 6))
16192 (use (match_dup 3))
16193 (clobber (match_dup 0))
16194 (clobber (match_dup 1))
16195 (clobber (match_dup 2))])])
16197 ;; ...and this one handles cmpstrn*_1.
16200 (set (reg:CC FLAGS_REG)
16201 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16203 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16204 (mem:BLK (match_operand 5 "register_operand" "")))
16206 (use (match_operand:SI 3 "immediate_operand" ""))
16207 (use (reg:CC FLAGS_REG))
16208 (clobber (match_operand 0 "register_operand" ""))
16209 (clobber (match_operand 1 "register_operand" ""))
16210 (clobber (match_operand 2 "register_operand" ""))])
16211 (set (match_operand:QI 7 "register_operand" "")
16212 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16213 (set (match_operand:QI 8 "register_operand" "")
16214 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16215 (set (reg FLAGS_REG)
16216 (compare (match_dup 7) (match_dup 8)))
16218 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16220 (set (reg:CC FLAGS_REG)
16221 (if_then_else:CC (ne (match_dup 6)
16223 (compare:CC (mem:BLK (match_dup 4))
16224 (mem:BLK (match_dup 5)))
16226 (use (match_dup 3))
16227 (use (reg:CC FLAGS_REG))
16228 (clobber (match_dup 0))
16229 (clobber (match_dup 1))
16230 (clobber (match_dup 2))])])
16232 ;; Conditional move instructions.
16234 (define_expand "mov<mode>cc"
16235 [(set (match_operand:SWIM 0 "register_operand" "")
16236 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16237 (match_operand:SWIM 2 "general_operand" "")
16238 (match_operand:SWIM 3 "general_operand" "")))]
16240 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16242 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16243 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16244 ;; So just document what we're doing explicitly.
16246 (define_expand "x86_mov<mode>cc_0_m1"
16248 [(set (match_operand:SWI48 0 "register_operand" "")
16249 (if_then_else:SWI48
16250 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16251 [(match_operand 1 "flags_reg_operand" "")
16255 (clobber (reg:CC FLAGS_REG))])])
16257 (define_insn "*x86_mov<mode>cc_0_m1"
16258 [(set (match_operand:SWI48 0 "register_operand" "=r")
16259 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16260 [(reg FLAGS_REG) (const_int 0)])
16263 (clobber (reg:CC FLAGS_REG))]
16265 "sbb{<imodesuffix>}\t%0, %0"
16266 ; Since we don't have the proper number of operands for an alu insn,
16267 ; fill in all the blanks.
16268 [(set_attr "type" "alu")
16269 (set_attr "use_carry" "1")
16270 (set_attr "pent_pair" "pu")
16271 (set_attr "memory" "none")
16272 (set_attr "imm_disp" "false")
16273 (set_attr "mode" "<MODE>")
16274 (set_attr "length_immediate" "0")])
16276 (define_insn "*x86_mov<mode>cc_0_m1_se"
16277 [(set (match_operand:SWI48 0 "register_operand" "=r")
16278 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16279 [(reg FLAGS_REG) (const_int 0)])
16282 (clobber (reg:CC FLAGS_REG))]
16284 "sbb{<imodesuffix>}\t%0, %0"
16285 [(set_attr "type" "alu")
16286 (set_attr "use_carry" "1")
16287 (set_attr "pent_pair" "pu")
16288 (set_attr "memory" "none")
16289 (set_attr "imm_disp" "false")
16290 (set_attr "mode" "<MODE>")
16291 (set_attr "length_immediate" "0")])
16293 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16294 [(set (match_operand:SWI48 0 "register_operand" "=r")
16295 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16296 [(reg FLAGS_REG) (const_int 0)])))]
16298 "sbb{<imodesuffix>}\t%0, %0"
16299 [(set_attr "type" "alu")
16300 (set_attr "use_carry" "1")
16301 (set_attr "pent_pair" "pu")
16302 (set_attr "memory" "none")
16303 (set_attr "imm_disp" "false")
16304 (set_attr "mode" "<MODE>")
16305 (set_attr "length_immediate" "0")])
16307 (define_insn "*mov<mode>cc_noc"
16308 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16309 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16310 [(reg FLAGS_REG) (const_int 0)])
16311 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16312 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16313 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16315 cmov%O2%C1\t{%2, %0|%0, %2}
16316 cmov%O2%c1\t{%3, %0|%0, %3}"
16317 [(set_attr "type" "icmov")
16318 (set_attr "mode" "<MODE>")])
16320 (define_insn_and_split "*movqicc_noc"
16321 [(set (match_operand:QI 0 "register_operand" "=r,r")
16322 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16323 [(match_operand 4 "flags_reg_operand" "")
16325 (match_operand:QI 2 "register_operand" "r,0")
16326 (match_operand:QI 3 "register_operand" "0,r")))]
16327 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16329 "&& reload_completed"
16330 [(set (match_dup 0)
16331 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16334 "operands[0] = gen_lowpart (SImode, operands[0]);
16335 operands[2] = gen_lowpart (SImode, operands[2]);
16336 operands[3] = gen_lowpart (SImode, operands[3]);"
16337 [(set_attr "type" "icmov")
16338 (set_attr "mode" "SI")])
16340 (define_expand "mov<mode>cc"
16341 [(set (match_operand:X87MODEF 0 "register_operand" "")
16342 (if_then_else:X87MODEF
16343 (match_operand 1 "ix86_fp_comparison_operator" "")
16344 (match_operand:X87MODEF 2 "register_operand" "")
16345 (match_operand:X87MODEF 3 "register_operand" "")))]
16346 "(TARGET_80387 && TARGET_CMOVE)
16347 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16348 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16350 (define_insn "*movxfcc_1"
16351 [(set (match_operand:XF 0 "register_operand" "=f,f")
16352 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16353 [(reg FLAGS_REG) (const_int 0)])
16354 (match_operand:XF 2 "register_operand" "f,0")
16355 (match_operand:XF 3 "register_operand" "0,f")))]
16356 "TARGET_80387 && TARGET_CMOVE"
16358 fcmov%F1\t{%2, %0|%0, %2}
16359 fcmov%f1\t{%3, %0|%0, %3}"
16360 [(set_attr "type" "fcmov")
16361 (set_attr "mode" "XF")])
16363 (define_insn "*movdfcc_1_rex64"
16364 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16365 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16366 [(reg FLAGS_REG) (const_int 0)])
16367 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16368 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16369 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16370 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16372 fcmov%F1\t{%2, %0|%0, %2}
16373 fcmov%f1\t{%3, %0|%0, %3}
16374 cmov%O2%C1\t{%2, %0|%0, %2}
16375 cmov%O2%c1\t{%3, %0|%0, %3}"
16376 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16377 (set_attr "mode" "DF,DF,DI,DI")])
16379 (define_insn "*movdfcc_1"
16380 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16381 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16382 [(reg FLAGS_REG) (const_int 0)])
16383 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16384 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16385 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16386 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16388 fcmov%F1\t{%2, %0|%0, %2}
16389 fcmov%f1\t{%3, %0|%0, %3}
16392 [(set_attr "type" "fcmov,fcmov,multi,multi")
16393 (set_attr "mode" "DF,DF,DI,DI")])
16396 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16397 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16398 [(match_operand 4 "flags_reg_operand" "")
16400 (match_operand:DF 2 "nonimmediate_operand" "")
16401 (match_operand:DF 3 "nonimmediate_operand" "")))]
16402 "!TARGET_64BIT && reload_completed"
16403 [(set (match_dup 2)
16404 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16408 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16412 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16413 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16416 (define_insn "*movsfcc_1_387"
16417 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16418 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16419 [(reg FLAGS_REG) (const_int 0)])
16420 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16421 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16422 "TARGET_80387 && TARGET_CMOVE
16423 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16425 fcmov%F1\t{%2, %0|%0, %2}
16426 fcmov%f1\t{%3, %0|%0, %3}
16427 cmov%O2%C1\t{%2, %0|%0, %2}
16428 cmov%O2%c1\t{%3, %0|%0, %3}"
16429 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16430 (set_attr "mode" "SF,SF,SI,SI")])
16432 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16433 ;; the scalar versions to have only XMM registers as operands.
16435 ;; XOP conditional move
16436 (define_insn "*xop_pcmov_<mode>"
16437 [(set (match_operand:MODEF 0 "register_operand" "=x")
16438 (if_then_else:MODEF
16439 (match_operand:MODEF 1 "register_operand" "x")
16440 (match_operand:MODEF 2 "register_operand" "x")
16441 (match_operand:MODEF 3 "register_operand" "x")))]
16443 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16444 [(set_attr "type" "sse4arg")])
16446 ;; These versions of the min/max patterns are intentionally ignorant of
16447 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16448 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16449 ;; are undefined in this condition, we're certain this is correct.
16451 (define_insn "*avx_<code><mode>3"
16452 [(set (match_operand:MODEF 0 "register_operand" "=x")
16454 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16455 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16456 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16457 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16458 [(set_attr "type" "sseadd")
16459 (set_attr "prefix" "vex")
16460 (set_attr "mode" "<MODE>")])
16462 (define_insn "<code><mode>3"
16463 [(set (match_operand:MODEF 0 "register_operand" "=x")
16465 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16466 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16467 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16468 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16469 [(set_attr "type" "sseadd")
16470 (set_attr "mode" "<MODE>")])
16472 ;; These versions of the min/max patterns implement exactly the operations
16473 ;; min = (op1 < op2 ? op1 : op2)
16474 ;; max = (!(op1 < op2) ? op1 : op2)
16475 ;; Their operands are not commutative, and thus they may be used in the
16476 ;; presence of -0.0 and NaN.
16478 (define_insn "*avx_ieee_smin<mode>3"
16479 [(set (match_operand:MODEF 0 "register_operand" "=x")
16481 [(match_operand:MODEF 1 "register_operand" "x")
16482 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16484 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16485 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16486 [(set_attr "type" "sseadd")
16487 (set_attr "prefix" "vex")
16488 (set_attr "mode" "<MODE>")])
16490 (define_insn "*ieee_smin<mode>3"
16491 [(set (match_operand:MODEF 0 "register_operand" "=x")
16493 [(match_operand:MODEF 1 "register_operand" "0")
16494 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16496 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16497 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16498 [(set_attr "type" "sseadd")
16499 (set_attr "mode" "<MODE>")])
16501 (define_insn "*avx_ieee_smax<mode>3"
16502 [(set (match_operand:MODEF 0 "register_operand" "=x")
16504 [(match_operand:MODEF 1 "register_operand" "0")
16505 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16507 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16508 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16509 [(set_attr "type" "sseadd")
16510 (set_attr "prefix" "vex")
16511 (set_attr "mode" "<MODE>")])
16513 (define_insn "*ieee_smax<mode>3"
16514 [(set (match_operand:MODEF 0 "register_operand" "=x")
16516 [(match_operand:MODEF 1 "register_operand" "0")
16517 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16519 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16520 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16521 [(set_attr "type" "sseadd")
16522 (set_attr "mode" "<MODE>")])
16524 ;; Make two stack loads independent:
16526 ;; fld %st(0) -> fld bb
16527 ;; fmul bb fmul %st(1), %st
16529 ;; Actually we only match the last two instructions for simplicity.
16531 [(set (match_operand 0 "fp_register_operand" "")
16532 (match_operand 1 "fp_register_operand" ""))
16534 (match_operator 2 "binary_fp_operator"
16536 (match_operand 3 "memory_operand" "")]))]
16537 "REGNO (operands[0]) != REGNO (operands[1])"
16538 [(set (match_dup 0) (match_dup 3))
16539 (set (match_dup 0) (match_dup 4))]
16541 ;; The % modifier is not operational anymore in peephole2's, so we have to
16542 ;; swap the operands manually in the case of addition and multiplication.
16543 "if (COMMUTATIVE_ARITH_P (operands[2]))
16544 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16545 GET_MODE (operands[2]),
16546 operands[0], operands[1]);
16548 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16549 GET_MODE (operands[2]),
16550 operands[1], operands[0]);")
16552 ;; Conditional addition patterns
16553 (define_expand "add<mode>cc"
16554 [(match_operand:SWI 0 "register_operand" "")
16555 (match_operand 1 "ordered_comparison_operator" "")
16556 (match_operand:SWI 2 "register_operand" "")
16557 (match_operand:SWI 3 "const_int_operand" "")]
16559 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16561 ;; Misc patterns (?)
16563 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16564 ;; Otherwise there will be nothing to keep
16566 ;; [(set (reg ebp) (reg esp))]
16567 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16568 ;; (clobber (eflags)]
16569 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16571 ;; in proper program order.
16573 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16574 [(set (match_operand:P 0 "register_operand" "=r,r")
16575 (plus:P (match_operand:P 1 "register_operand" "0,r")
16576 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16577 (clobber (reg:CC FLAGS_REG))
16578 (clobber (mem:BLK (scratch)))]
16581 switch (get_attr_type (insn))
16584 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16587 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16588 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16589 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16591 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16594 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16595 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16598 [(set (attr "type")
16599 (cond [(and (eq_attr "alternative" "0")
16600 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16601 (const_string "alu")
16602 (match_operand:<MODE> 2 "const0_operand" "")
16603 (const_string "imov")
16605 (const_string "lea")))
16606 (set (attr "length_immediate")
16607 (cond [(eq_attr "type" "imov")
16609 (and (eq_attr "type" "alu")
16610 (match_operand 2 "const128_operand" ""))
16613 (const_string "*")))
16614 (set_attr "mode" "<MODE>")])
16616 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16617 [(set (match_operand:P 0 "register_operand" "=r")
16618 (minus:P (match_operand:P 1 "register_operand" "0")
16619 (match_operand:P 2 "register_operand" "r")))
16620 (clobber (reg:CC FLAGS_REG))
16621 (clobber (mem:BLK (scratch)))]
16623 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16624 [(set_attr "type" "alu")
16625 (set_attr "mode" "<MODE>")])
16627 (define_insn "allocate_stack_worker_probe_<mode>"
16628 [(set (match_operand:P 0 "register_operand" "=a")
16629 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16630 UNSPECV_STACK_PROBE))
16631 (clobber (reg:CC FLAGS_REG))]
16632 "ix86_target_stack_probe ()"
16633 "call\t___chkstk_ms"
16634 [(set_attr "type" "multi")
16635 (set_attr "length" "5")])
16637 (define_expand "allocate_stack"
16638 [(match_operand 0 "register_operand" "")
16639 (match_operand 1 "general_operand" "")]
16640 "ix86_target_stack_probe ()"
16644 #ifndef CHECK_STACK_LIMIT
16645 #define CHECK_STACK_LIMIT 0
16648 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16649 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16651 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16652 stack_pointer_rtx, 0, OPTAB_DIRECT);
16653 if (x != stack_pointer_rtx)
16654 emit_move_insn (stack_pointer_rtx, x);
16658 x = copy_to_mode_reg (Pmode, operands[1]);
16660 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16662 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16663 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16664 stack_pointer_rtx, 0, OPTAB_DIRECT);
16665 if (x != stack_pointer_rtx)
16666 emit_move_insn (stack_pointer_rtx, x);
16669 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16673 ;; Use IOR for stack probes, this is shorter.
16674 (define_expand "probe_stack"
16675 [(match_operand 0 "memory_operand" "")]
16678 rtx (*gen_ior3) (rtx, rtx, rtx);
16680 gen_ior3 = (GET_MODE (operands[0]) == DImode
16681 ? gen_iordi3 : gen_iorsi3);
16683 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16687 (define_insn "adjust_stack_and_probe<mode>"
16688 [(set (match_operand:P 0 "register_operand" "=r")
16689 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16690 UNSPECV_PROBE_STACK_RANGE))
16691 (set (reg:P SP_REG)
16692 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16693 (clobber (reg:CC FLAGS_REG))
16694 (clobber (mem:BLK (scratch)))]
16696 "* return output_adjust_stack_and_probe (operands[0]);"
16697 [(set_attr "type" "multi")])
16699 (define_insn "probe_stack_range<mode>"
16700 [(set (match_operand:P 0 "register_operand" "=r")
16701 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16702 (match_operand:P 2 "const_int_operand" "n")]
16703 UNSPECV_PROBE_STACK_RANGE))
16704 (clobber (reg:CC FLAGS_REG))]
16706 "* return output_probe_stack_range (operands[0], operands[2]);"
16707 [(set_attr "type" "multi")])
16709 (define_expand "builtin_setjmp_receiver"
16710 [(label_ref (match_operand 0 "" ""))]
16711 "!TARGET_64BIT && flag_pic"
16717 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16718 rtx label_rtx = gen_label_rtx ();
16719 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16720 xops[0] = xops[1] = picreg;
16721 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16722 ix86_expand_binary_operator (MINUS, SImode, xops);
16726 emit_insn (gen_set_got (pic_offset_table_rtx));
16730 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16733 [(set (match_operand 0 "register_operand" "")
16734 (match_operator 3 "promotable_binary_operator"
16735 [(match_operand 1 "register_operand" "")
16736 (match_operand 2 "aligned_operand" "")]))
16737 (clobber (reg:CC FLAGS_REG))]
16738 "! TARGET_PARTIAL_REG_STALL && reload_completed
16739 && ((GET_MODE (operands[0]) == HImode
16740 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16741 /* ??? next two lines just !satisfies_constraint_K (...) */
16742 || !CONST_INT_P (operands[2])
16743 || satisfies_constraint_K (operands[2])))
16744 || (GET_MODE (operands[0]) == QImode
16745 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16746 [(parallel [(set (match_dup 0)
16747 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16748 (clobber (reg:CC FLAGS_REG))])]
16749 "operands[0] = gen_lowpart (SImode, operands[0]);
16750 operands[1] = gen_lowpart (SImode, operands[1]);
16751 if (GET_CODE (operands[3]) != ASHIFT)
16752 operands[2] = gen_lowpart (SImode, operands[2]);
16753 PUT_MODE (operands[3], SImode);")
16755 ; Promote the QImode tests, as i386 has encoding of the AND
16756 ; instruction with 32-bit sign-extended immediate and thus the
16757 ; instruction size is unchanged, except in the %eax case for
16758 ; which it is increased by one byte, hence the ! optimize_size.
16760 [(set (match_operand 0 "flags_reg_operand" "")
16761 (match_operator 2 "compare_operator"
16762 [(and (match_operand 3 "aligned_operand" "")
16763 (match_operand 4 "const_int_operand" ""))
16765 (set (match_operand 1 "register_operand" "")
16766 (and (match_dup 3) (match_dup 4)))]
16767 "! TARGET_PARTIAL_REG_STALL && reload_completed
16768 && optimize_insn_for_speed_p ()
16769 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16770 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16771 /* Ensure that the operand will remain sign-extended immediate. */
16772 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16773 [(parallel [(set (match_dup 0)
16774 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16777 (and:SI (match_dup 3) (match_dup 4)))])]
16780 = gen_int_mode (INTVAL (operands[4])
16781 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16782 operands[1] = gen_lowpart (SImode, operands[1]);
16783 operands[3] = gen_lowpart (SImode, operands[3]);
16786 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16787 ; the TEST instruction with 32-bit sign-extended immediate and thus
16788 ; the instruction size would at least double, which is not what we
16789 ; want even with ! optimize_size.
16791 [(set (match_operand 0 "flags_reg_operand" "")
16792 (match_operator 1 "compare_operator"
16793 [(and (match_operand:HI 2 "aligned_operand" "")
16794 (match_operand:HI 3 "const_int_operand" ""))
16796 "! TARGET_PARTIAL_REG_STALL && reload_completed
16797 && ! TARGET_FAST_PREFIX
16798 && optimize_insn_for_speed_p ()
16799 /* Ensure that the operand will remain sign-extended immediate. */
16800 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16801 [(set (match_dup 0)
16802 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16806 = gen_int_mode (INTVAL (operands[3])
16807 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16808 operands[2] = gen_lowpart (SImode, operands[2]);
16812 [(set (match_operand 0 "register_operand" "")
16813 (neg (match_operand 1 "register_operand" "")))
16814 (clobber (reg:CC FLAGS_REG))]
16815 "! TARGET_PARTIAL_REG_STALL && reload_completed
16816 && (GET_MODE (operands[0]) == HImode
16817 || (GET_MODE (operands[0]) == QImode
16818 && (TARGET_PROMOTE_QImode
16819 || optimize_insn_for_size_p ())))"
16820 [(parallel [(set (match_dup 0)
16821 (neg:SI (match_dup 1)))
16822 (clobber (reg:CC FLAGS_REG))])]
16823 "operands[0] = gen_lowpart (SImode, operands[0]);
16824 operands[1] = gen_lowpart (SImode, operands[1]);")
16827 [(set (match_operand 0 "register_operand" "")
16828 (not (match_operand 1 "register_operand" "")))]
16829 "! TARGET_PARTIAL_REG_STALL && reload_completed
16830 && (GET_MODE (operands[0]) == HImode
16831 || (GET_MODE (operands[0]) == QImode
16832 && (TARGET_PROMOTE_QImode
16833 || optimize_insn_for_size_p ())))"
16834 [(set (match_dup 0)
16835 (not:SI (match_dup 1)))]
16836 "operands[0] = gen_lowpart (SImode, operands[0]);
16837 operands[1] = gen_lowpart (SImode, operands[1]);")
16840 [(set (match_operand 0 "register_operand" "")
16841 (if_then_else (match_operator 1 "ordered_comparison_operator"
16842 [(reg FLAGS_REG) (const_int 0)])
16843 (match_operand 2 "register_operand" "")
16844 (match_operand 3 "register_operand" "")))]
16845 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16846 && (GET_MODE (operands[0]) == HImode
16847 || (GET_MODE (operands[0]) == QImode
16848 && (TARGET_PROMOTE_QImode
16849 || optimize_insn_for_size_p ())))"
16850 [(set (match_dup 0)
16851 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16852 "operands[0] = gen_lowpart (SImode, operands[0]);
16853 operands[2] = gen_lowpart (SImode, operands[2]);
16854 operands[3] = gen_lowpart (SImode, operands[3]);")
16856 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16857 ;; transform a complex memory operation into two memory to register operations.
16859 ;; Don't push memory operands
16861 [(set (match_operand:SWI 0 "push_operand" "")
16862 (match_operand:SWI 1 "memory_operand" ""))
16863 (match_scratch:SWI 2 "<r>")]
16864 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16865 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16866 [(set (match_dup 2) (match_dup 1))
16867 (set (match_dup 0) (match_dup 2))])
16869 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16872 [(set (match_operand:SF 0 "push_operand" "")
16873 (match_operand:SF 1 "memory_operand" ""))
16874 (match_scratch:SF 2 "r")]
16875 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16876 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16877 [(set (match_dup 2) (match_dup 1))
16878 (set (match_dup 0) (match_dup 2))])
16880 ;; Don't move an immediate directly to memory when the instruction
16883 [(match_scratch:SWI124 1 "<r>")
16884 (set (match_operand:SWI124 0 "memory_operand" "")
16886 "optimize_insn_for_speed_p ()
16887 && !TARGET_USE_MOV0
16888 && TARGET_SPLIT_LONG_MOVES
16889 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16890 && peep2_regno_dead_p (0, FLAGS_REG)"
16891 [(parallel [(set (match_dup 2) (const_int 0))
16892 (clobber (reg:CC FLAGS_REG))])
16893 (set (match_dup 0) (match_dup 1))]
16894 "operands[2] = gen_lowpart (SImode, operands[1]);")
16897 [(match_scratch:SWI124 2 "<r>")
16898 (set (match_operand:SWI124 0 "memory_operand" "")
16899 (match_operand:SWI124 1 "immediate_operand" ""))]
16900 "optimize_insn_for_speed_p ()
16901 && TARGET_SPLIT_LONG_MOVES
16902 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16903 [(set (match_dup 2) (match_dup 1))
16904 (set (match_dup 0) (match_dup 2))])
16906 ;; Don't compare memory with zero, load and use a test instead.
16908 [(set (match_operand 0 "flags_reg_operand" "")
16909 (match_operator 1 "compare_operator"
16910 [(match_operand:SI 2 "memory_operand" "")
16912 (match_scratch:SI 3 "r")]
16913 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16914 [(set (match_dup 3) (match_dup 2))
16915 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16917 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16918 ;; Don't split NOTs with a displacement operand, because resulting XOR
16919 ;; will not be pairable anyway.
16921 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16922 ;; represented using a modRM byte. The XOR replacement is long decoded,
16923 ;; so this split helps here as well.
16925 ;; Note: Can't do this as a regular split because we can't get proper
16926 ;; lifetime information then.
16929 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16930 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16931 "optimize_insn_for_speed_p ()
16932 && ((TARGET_NOT_UNPAIRABLE
16933 && (!MEM_P (operands[0])
16934 || !memory_displacement_operand (operands[0], <MODE>mode)))
16935 || (TARGET_NOT_VECTORMODE
16936 && long_memory_operand (operands[0], <MODE>mode)))
16937 && peep2_regno_dead_p (0, FLAGS_REG)"
16938 [(parallel [(set (match_dup 0)
16939 (xor:SWI124 (match_dup 1) (const_int -1)))
16940 (clobber (reg:CC FLAGS_REG))])])
16942 ;; Non pairable "test imm, reg" instructions can be translated to
16943 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16944 ;; byte opcode instead of two, have a short form for byte operands),
16945 ;; so do it for other CPUs as well. Given that the value was dead,
16946 ;; this should not create any new dependencies. Pass on the sub-word
16947 ;; versions if we're concerned about partial register stalls.
16950 [(set (match_operand 0 "flags_reg_operand" "")
16951 (match_operator 1 "compare_operator"
16952 [(and:SI (match_operand:SI 2 "register_operand" "")
16953 (match_operand:SI 3 "immediate_operand" ""))
16955 "ix86_match_ccmode (insn, CCNOmode)
16956 && (true_regnum (operands[2]) != AX_REG
16957 || satisfies_constraint_K (operands[3]))
16958 && peep2_reg_dead_p (1, operands[2])"
16960 [(set (match_dup 0)
16961 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16964 (and:SI (match_dup 2) (match_dup 3)))])])
16966 ;; We don't need to handle HImode case, because it will be promoted to SImode
16967 ;; on ! TARGET_PARTIAL_REG_STALL
16970 [(set (match_operand 0 "flags_reg_operand" "")
16971 (match_operator 1 "compare_operator"
16972 [(and:QI (match_operand:QI 2 "register_operand" "")
16973 (match_operand:QI 3 "immediate_operand" ""))
16975 "! TARGET_PARTIAL_REG_STALL
16976 && ix86_match_ccmode (insn, CCNOmode)
16977 && true_regnum (operands[2]) != AX_REG
16978 && peep2_reg_dead_p (1, operands[2])"
16980 [(set (match_dup 0)
16981 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16984 (and:QI (match_dup 2) (match_dup 3)))])])
16987 [(set (match_operand 0 "flags_reg_operand" "")
16988 (match_operator 1 "compare_operator"
16991 (match_operand 2 "ext_register_operand" "")
16994 (match_operand 3 "const_int_operand" ""))
16996 "! TARGET_PARTIAL_REG_STALL
16997 && ix86_match_ccmode (insn, CCNOmode)
16998 && true_regnum (operands[2]) != AX_REG
16999 && peep2_reg_dead_p (1, operands[2])"
17000 [(parallel [(set (match_dup 0)
17009 (set (zero_extract:SI (match_dup 2)
17017 (match_dup 3)))])])
17019 ;; Don't do logical operations with memory inputs.
17021 [(match_scratch:SI 2 "r")
17022 (parallel [(set (match_operand:SI 0 "register_operand" "")
17023 (match_operator:SI 3 "arith_or_logical_operator"
17025 (match_operand:SI 1 "memory_operand" "")]))
17026 (clobber (reg:CC FLAGS_REG))])]
17027 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17028 [(set (match_dup 2) (match_dup 1))
17029 (parallel [(set (match_dup 0)
17030 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17031 (clobber (reg:CC FLAGS_REG))])])
17034 [(match_scratch:SI 2 "r")
17035 (parallel [(set (match_operand:SI 0 "register_operand" "")
17036 (match_operator:SI 3 "arith_or_logical_operator"
17037 [(match_operand:SI 1 "memory_operand" "")
17039 (clobber (reg:CC FLAGS_REG))])]
17040 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17041 [(set (match_dup 2) (match_dup 1))
17042 (parallel [(set (match_dup 0)
17043 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17044 (clobber (reg:CC FLAGS_REG))])])
17046 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17047 ;; refers to the destination of the load!
17050 [(set (match_operand:SI 0 "register_operand" "")
17051 (match_operand:SI 1 "register_operand" ""))
17052 (parallel [(set (match_dup 0)
17053 (match_operator:SI 3 "commutative_operator"
17055 (match_operand:SI 2 "memory_operand" "")]))
17056 (clobber (reg:CC FLAGS_REG))])]
17057 "REGNO (operands[0]) != REGNO (operands[1])
17058 && GENERAL_REGNO_P (REGNO (operands[0]))
17059 && GENERAL_REGNO_P (REGNO (operands[1]))"
17060 [(set (match_dup 0) (match_dup 4))
17061 (parallel [(set (match_dup 0)
17062 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17063 (clobber (reg:CC FLAGS_REG))])]
17064 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17067 [(set (match_operand 0 "register_operand" "")
17068 (match_operand 1 "register_operand" ""))
17070 (match_operator 3 "commutative_operator"
17072 (match_operand 2 "memory_operand" "")]))]
17073 "REGNO (operands[0]) != REGNO (operands[1])
17074 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17075 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17076 [(set (match_dup 0) (match_dup 2))
17078 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17080 ; Don't do logical operations with memory outputs
17082 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17083 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17084 ; the same decoder scheduling characteristics as the original.
17087 [(match_scratch:SI 2 "r")
17088 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17089 (match_operator:SI 3 "arith_or_logical_operator"
17091 (match_operand:SI 1 "nonmemory_operand" "")]))
17092 (clobber (reg:CC FLAGS_REG))])]
17093 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17094 /* Do not split stack checking probes. */
17095 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17096 [(set (match_dup 2) (match_dup 0))
17097 (parallel [(set (match_dup 2)
17098 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17099 (clobber (reg:CC FLAGS_REG))])
17100 (set (match_dup 0) (match_dup 2))])
17103 [(match_scratch:SI 2 "r")
17104 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17105 (match_operator:SI 3 "arith_or_logical_operator"
17106 [(match_operand:SI 1 "nonmemory_operand" "")
17108 (clobber (reg:CC FLAGS_REG))])]
17109 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17110 /* Do not split stack checking probes. */
17111 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17112 [(set (match_dup 2) (match_dup 0))
17113 (parallel [(set (match_dup 2)
17114 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17115 (clobber (reg:CC FLAGS_REG))])
17116 (set (match_dup 0) (match_dup 2))])
17118 ;; Attempt to always use XOR for zeroing registers.
17120 [(set (match_operand 0 "register_operand" "")
17121 (match_operand 1 "const0_operand" ""))]
17122 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17123 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17124 && GENERAL_REG_P (operands[0])
17125 && peep2_regno_dead_p (0, FLAGS_REG)"
17126 [(parallel [(set (match_dup 0) (const_int 0))
17127 (clobber (reg:CC FLAGS_REG))])]
17128 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17131 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17133 "(GET_MODE (operands[0]) == QImode
17134 || GET_MODE (operands[0]) == HImode)
17135 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17136 && peep2_regno_dead_p (0, FLAGS_REG)"
17137 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17138 (clobber (reg:CC FLAGS_REG))])])
17140 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17142 [(set (match_operand:SWI248 0 "register_operand" "")
17144 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17145 && peep2_regno_dead_p (0, FLAGS_REG)"
17146 [(parallel [(set (match_dup 0) (const_int -1))
17147 (clobber (reg:CC FLAGS_REG))])]
17149 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17150 operands[0] = gen_lowpart (SImode, operands[0]);
17153 ;; Attempt to convert simple lea to add/shift.
17154 ;; These can be created by move expanders.
17157 [(set (match_operand:SWI48 0 "register_operand" "")
17158 (plus:SWI48 (match_dup 0)
17159 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17160 "peep2_regno_dead_p (0, FLAGS_REG)"
17161 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17162 (clobber (reg:CC FLAGS_REG))])])
17165 [(set (match_operand:SI 0 "register_operand" "")
17166 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17167 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17169 && peep2_regno_dead_p (0, FLAGS_REG)
17170 && REGNO (operands[0]) == REGNO (operands[1])"
17171 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17172 (clobber (reg:CC FLAGS_REG))])]
17173 "operands[2] = gen_lowpart (SImode, operands[2]);")
17176 [(set (match_operand:SWI48 0 "register_operand" "")
17177 (mult:SWI48 (match_dup 0)
17178 (match_operand:SWI48 1 "const_int_operand" "")))]
17179 "exact_log2 (INTVAL (operands[1])) >= 0
17180 && peep2_regno_dead_p (0, FLAGS_REG)"
17181 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17182 (clobber (reg:CC FLAGS_REG))])]
17183 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17186 [(set (match_operand:SI 0 "register_operand" "")
17187 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17188 (match_operand:DI 2 "const_int_operand" "")) 0))]
17190 && exact_log2 (INTVAL (operands[2])) >= 0
17191 && REGNO (operands[0]) == REGNO (operands[1])
17192 && peep2_regno_dead_p (0, FLAGS_REG)"
17193 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17194 (clobber (reg:CC FLAGS_REG))])]
17195 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17197 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17198 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17199 ;; On many CPUs it is also faster, since special hardware to avoid esp
17200 ;; dependencies is present.
17202 ;; While some of these conversions may be done using splitters, we use
17203 ;; peepholes in order to allow combine_stack_adjustments pass to see
17204 ;; nonobfuscated RTL.
17206 ;; Convert prologue esp subtractions to push.
17207 ;; We need register to push. In order to keep verify_flow_info happy we have
17209 ;; - use scratch and clobber it in order to avoid dependencies
17210 ;; - use already live register
17211 ;; We can't use the second way right now, since there is no reliable way how to
17212 ;; verify that given register is live. First choice will also most likely in
17213 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17214 ;; call clobbered registers are dead. We may want to use base pointer as an
17215 ;; alternative when no register is available later.
17218 [(match_scratch:P 1 "r")
17219 (parallel [(set (reg:P SP_REG)
17220 (plus:P (reg:P SP_REG)
17221 (match_operand:P 0 "const_int_operand" "")))
17222 (clobber (reg:CC FLAGS_REG))
17223 (clobber (mem:BLK (scratch)))])]
17224 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17225 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17226 [(clobber (match_dup 1))
17227 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17228 (clobber (mem:BLK (scratch)))])])
17231 [(match_scratch:P 1 "r")
17232 (parallel [(set (reg:P SP_REG)
17233 (plus:P (reg:P SP_REG)
17234 (match_operand:P 0 "const_int_operand" "")))
17235 (clobber (reg:CC FLAGS_REG))
17236 (clobber (mem:BLK (scratch)))])]
17237 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17238 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17239 [(clobber (match_dup 1))
17240 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17241 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17242 (clobber (mem:BLK (scratch)))])])
17244 ;; Convert esp subtractions to push.
17246 [(match_scratch:P 1 "r")
17247 (parallel [(set (reg:P SP_REG)
17248 (plus:P (reg:P SP_REG)
17249 (match_operand:P 0 "const_int_operand" "")))
17250 (clobber (reg:CC FLAGS_REG))])]
17251 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17252 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17253 [(clobber (match_dup 1))
17254 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17257 [(match_scratch:P 1 "r")
17258 (parallel [(set (reg:P SP_REG)
17259 (plus:P (reg:P SP_REG)
17260 (match_operand:P 0 "const_int_operand" "")))
17261 (clobber (reg:CC FLAGS_REG))])]
17262 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17263 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17264 [(clobber (match_dup 1))
17265 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17266 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17268 ;; Convert epilogue deallocator to pop.
17270 [(match_scratch:P 1 "r")
17271 (parallel [(set (reg:P SP_REG)
17272 (plus:P (reg:P SP_REG)
17273 (match_operand:P 0 "const_int_operand" "")))
17274 (clobber (reg:CC FLAGS_REG))
17275 (clobber (mem:BLK (scratch)))])]
17276 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17277 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17278 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17279 (clobber (mem:BLK (scratch)))])])
17281 ;; Two pops case is tricky, since pop causes dependency
17282 ;; on destination register. We use two registers if available.
17284 [(match_scratch:P 1 "r")
17285 (match_scratch:P 2 "r")
17286 (parallel [(set (reg:P SP_REG)
17287 (plus:P (reg:P SP_REG)
17288 (match_operand:P 0 "const_int_operand" "")))
17289 (clobber (reg:CC FLAGS_REG))
17290 (clobber (mem:BLK (scratch)))])]
17291 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17292 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17293 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17294 (clobber (mem:BLK (scratch)))])
17295 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17298 [(match_scratch:P 1 "r")
17299 (parallel [(set (reg:P SP_REG)
17300 (plus:P (reg:P SP_REG)
17301 (match_operand:P 0 "const_int_operand" "")))
17302 (clobber (reg:CC FLAGS_REG))
17303 (clobber (mem:BLK (scratch)))])]
17304 "optimize_insn_for_size_p ()
17305 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17306 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17307 (clobber (mem:BLK (scratch)))])
17308 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17310 ;; Convert esp additions to pop.
17312 [(match_scratch:P 1 "r")
17313 (parallel [(set (reg:P SP_REG)
17314 (plus:P (reg:P SP_REG)
17315 (match_operand:P 0 "const_int_operand" "")))
17316 (clobber (reg:CC FLAGS_REG))])]
17317 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17318 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17320 ;; Two pops case is tricky, since pop causes dependency
17321 ;; on destination register. We use two registers if available.
17323 [(match_scratch:P 1 "r")
17324 (match_scratch:P 2 "r")
17325 (parallel [(set (reg:P SP_REG)
17326 (plus:P (reg:P SP_REG)
17327 (match_operand:P 0 "const_int_operand" "")))
17328 (clobber (reg:CC FLAGS_REG))])]
17329 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17330 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17331 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17334 [(match_scratch:P 1 "r")
17335 (parallel [(set (reg:P SP_REG)
17336 (plus:P (reg:P SP_REG)
17337 (match_operand:P 0 "const_int_operand" "")))
17338 (clobber (reg:CC FLAGS_REG))])]
17339 "optimize_insn_for_size_p ()
17340 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17341 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17342 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17344 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17345 ;; required and register dies. Similarly for 128 to -128.
17347 [(set (match_operand 0 "flags_reg_operand" "")
17348 (match_operator 1 "compare_operator"
17349 [(match_operand 2 "register_operand" "")
17350 (match_operand 3 "const_int_operand" "")]))]
17351 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17352 && incdec_operand (operands[3], GET_MODE (operands[3])))
17353 || (!TARGET_FUSE_CMP_AND_BRANCH
17354 && INTVAL (operands[3]) == 128))
17355 && ix86_match_ccmode (insn, CCGCmode)
17356 && peep2_reg_dead_p (1, operands[2])"
17357 [(parallel [(set (match_dup 0)
17358 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17359 (clobber (match_dup 2))])])
17361 ;; Convert imul by three, five and nine into lea
17364 [(set (match_operand:SWI48 0 "register_operand" "")
17365 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17366 (match_operand:SWI48 2 "const_int_operand" "")))
17367 (clobber (reg:CC FLAGS_REG))])]
17368 "INTVAL (operands[2]) == 3
17369 || INTVAL (operands[2]) == 5
17370 || INTVAL (operands[2]) == 9"
17371 [(set (match_dup 0)
17372 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17374 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17378 [(set (match_operand:SWI48 0 "register_operand" "")
17379 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17380 (match_operand:SWI48 2 "const_int_operand" "")))
17381 (clobber (reg:CC FLAGS_REG))])]
17382 "optimize_insn_for_speed_p ()
17383 && (INTVAL (operands[2]) == 3
17384 || INTVAL (operands[2]) == 5
17385 || INTVAL (operands[2]) == 9)"
17386 [(set (match_dup 0) (match_dup 1))
17388 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17390 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17392 ;; imul $32bit_imm, mem, reg is vector decoded, while
17393 ;; imul $32bit_imm, reg, reg is direct decoded.
17395 [(match_scratch:SWI48 3 "r")
17396 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17397 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17398 (match_operand:SWI48 2 "immediate_operand" "")))
17399 (clobber (reg:CC FLAGS_REG))])]
17400 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17401 && !satisfies_constraint_K (operands[2])"
17402 [(set (match_dup 3) (match_dup 1))
17403 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17404 (clobber (reg:CC FLAGS_REG))])])
17407 [(match_scratch:SI 3 "r")
17408 (parallel [(set (match_operand:DI 0 "register_operand" "")
17410 (mult:SI (match_operand:SI 1 "memory_operand" "")
17411 (match_operand:SI 2 "immediate_operand" ""))))
17412 (clobber (reg:CC FLAGS_REG))])]
17414 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17415 && !satisfies_constraint_K (operands[2])"
17416 [(set (match_dup 3) (match_dup 1))
17417 (parallel [(set (match_dup 0)
17418 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17419 (clobber (reg:CC FLAGS_REG))])])
17421 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17422 ;; Convert it into imul reg, reg
17423 ;; It would be better to force assembler to encode instruction using long
17424 ;; immediate, but there is apparently no way to do so.
17426 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17428 (match_operand:SWI248 1 "nonimmediate_operand" "")
17429 (match_operand:SWI248 2 "const_int_operand" "")))
17430 (clobber (reg:CC FLAGS_REG))])
17431 (match_scratch:SWI248 3 "r")]
17432 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17433 && satisfies_constraint_K (operands[2])"
17434 [(set (match_dup 3) (match_dup 2))
17435 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17436 (clobber (reg:CC FLAGS_REG))])]
17438 if (!rtx_equal_p (operands[0], operands[1]))
17439 emit_move_insn (operands[0], operands[1]);
17442 ;; After splitting up read-modify operations, array accesses with memory
17443 ;; operands might end up in form:
17445 ;; movl 4(%esp), %edx
17447 ;; instead of pre-splitting:
17449 ;; addl 4(%esp), %eax
17451 ;; movl 4(%esp), %edx
17452 ;; leal (%edx,%eax,4), %eax
17455 [(match_scratch:P 5 "r")
17456 (parallel [(set (match_operand 0 "register_operand" "")
17457 (ashift (match_operand 1 "register_operand" "")
17458 (match_operand 2 "const_int_operand" "")))
17459 (clobber (reg:CC FLAGS_REG))])
17460 (parallel [(set (match_operand 3 "register_operand" "")
17461 (plus (match_dup 0)
17462 (match_operand 4 "x86_64_general_operand" "")))
17463 (clobber (reg:CC FLAGS_REG))])]
17464 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17465 /* Validate MODE for lea. */
17466 && ((!TARGET_PARTIAL_REG_STALL
17467 && (GET_MODE (operands[0]) == QImode
17468 || GET_MODE (operands[0]) == HImode))
17469 || GET_MODE (operands[0]) == SImode
17470 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17471 && (rtx_equal_p (operands[0], operands[3])
17472 || peep2_reg_dead_p (2, operands[0]))
17473 /* We reorder load and the shift. */
17474 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17475 [(set (match_dup 5) (match_dup 4))
17476 (set (match_dup 0) (match_dup 1))]
17478 enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17479 int scale = 1 << INTVAL (operands[2]);
17480 rtx index = gen_lowpart (Pmode, operands[1]);
17481 rtx base = gen_lowpart (Pmode, operands[5]);
17482 rtx dest = gen_lowpart (mode, operands[3]);
17484 operands[1] = gen_rtx_PLUS (Pmode, base,
17485 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17486 operands[5] = base;
17489 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17490 operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17492 operands[0] = dest;
17495 ;; Call-value patterns last so that the wildcard operand does not
17496 ;; disrupt insn-recog's switch tables.
17498 (define_insn_and_split "*call_value_pop_0_vzeroupper"
17500 [(set (match_operand 0 "" "")
17501 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17502 (match_operand:SI 2 "" "")))
17503 (set (reg:SI SP_REG)
17504 (plus:SI (reg:SI SP_REG)
17505 (match_operand:SI 3 "immediate_operand" "")))])
17506 (unspec [(match_operand 4 "const_int_operand" "")]
17507 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17508 "TARGET_VZEROUPPER && !TARGET_64BIT"
17510 "&& reload_completed"
17512 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17513 [(set_attr "type" "callv")])
17515 (define_insn "*call_value_pop_0"
17516 [(set (match_operand 0 "" "")
17517 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17518 (match_operand:SI 2 "" "")))
17519 (set (reg:SI SP_REG)
17520 (plus:SI (reg:SI SP_REG)
17521 (match_operand:SI 3 "immediate_operand" "")))]
17523 { return ix86_output_call_insn (insn, operands[1], 1); }
17524 [(set_attr "type" "callv")])
17526 (define_insn_and_split "*call_value_pop_1_vzeroupper"
17528 [(set (match_operand 0 "" "")
17529 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17530 (match_operand:SI 2 "" "")))
17531 (set (reg:SI SP_REG)
17532 (plus:SI (reg:SI SP_REG)
17533 (match_operand:SI 3 "immediate_operand" "i")))])
17534 (unspec [(match_operand 4 "const_int_operand" "")]
17535 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17536 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17538 "&& reload_completed"
17540 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17541 [(set_attr "type" "callv")])
17543 (define_insn "*call_value_pop_1"
17544 [(set (match_operand 0 "" "")
17545 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17546 (match_operand:SI 2 "" "")))
17547 (set (reg:SI SP_REG)
17548 (plus:SI (reg:SI SP_REG)
17549 (match_operand:SI 3 "immediate_operand" "i")))]
17550 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17551 { return ix86_output_call_insn (insn, operands[1], 1); }
17552 [(set_attr "type" "callv")])
17554 (define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
17556 [(set (match_operand 0 "" "")
17557 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17558 (match_operand:SI 2 "" "")))
17559 (set (reg:SI SP_REG)
17560 (plus:SI (reg:SI SP_REG)
17561 (match_operand:SI 3 "immediate_operand" "i,i")))])
17562 (unspec [(match_operand 4 "const_int_operand" "")]
17563 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17564 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17566 "&& reload_completed"
17568 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
17569 [(set_attr "type" "callv")])
17571 (define_insn "*sibcall_value_pop_1"
17572 [(set (match_operand 0 "" "")
17573 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17574 (match_operand:SI 2 "" "")))
17575 (set (reg:SI SP_REG)
17576 (plus:SI (reg:SI SP_REG)
17577 (match_operand:SI 3 "immediate_operand" "i,i")))]
17578 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17579 { return ix86_output_call_insn (insn, operands[1], 1); }
17580 [(set_attr "type" "callv")])
17582 (define_insn_and_split "*call_value_0_vzeroupper"
17583 [(set (match_operand 0 "" "")
17584 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17585 (match_operand:SI 2 "" "")))
17586 (unspec [(match_operand 3 "const_int_operand" "")]
17587 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17588 "TARGET_VZEROUPPER && !TARGET_64BIT"
17590 "&& reload_completed"
17592 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17593 [(set_attr "type" "callv")])
17595 (define_insn "*call_value_0"
17596 [(set (match_operand 0 "" "")
17597 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17598 (match_operand:SI 2 "" "")))]
17600 { return ix86_output_call_insn (insn, operands[1], 1); }
17601 [(set_attr "type" "callv")])
17603 (define_insn_and_split "*call_value_0_rex64_vzeroupper"
17604 [(set (match_operand 0 "" "")
17605 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17606 (match_operand:DI 2 "const_int_operand" "")))
17607 (unspec [(match_operand 3 "const_int_operand" "")]
17608 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17609 "TARGET_VZEROUPPER && TARGET_64BIT"
17611 "&& reload_completed"
17613 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17614 [(set_attr "type" "callv")])
17616 (define_insn "*call_value_0_rex64"
17617 [(set (match_operand 0 "" "")
17618 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17619 (match_operand:DI 2 "const_int_operand" "")))]
17621 { return ix86_output_call_insn (insn, operands[1], 1); }
17622 [(set_attr "type" "callv")])
17624 (define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper"
17626 [(set (match_operand 0 "" "")
17627 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17628 (match_operand:DI 2 "const_int_operand" "")))
17629 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17630 (clobber (reg:TI XMM6_REG))
17631 (clobber (reg:TI XMM7_REG))
17632 (clobber (reg:TI XMM8_REG))
17633 (clobber (reg:TI XMM9_REG))
17634 (clobber (reg:TI XMM10_REG))
17635 (clobber (reg:TI XMM11_REG))
17636 (clobber (reg:TI XMM12_REG))
17637 (clobber (reg:TI XMM13_REG))
17638 (clobber (reg:TI XMM14_REG))
17639 (clobber (reg:TI XMM15_REG))
17640 (clobber (reg:DI SI_REG))
17641 (clobber (reg:DI DI_REG))])
17642 (unspec [(match_operand 3 "const_int_operand" "")]
17643 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17644 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17646 "&& reload_completed"
17648 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17649 [(set_attr "type" "callv")])
17651 (define_insn "*call_value_0_rex64_ms_sysv"
17652 [(set (match_operand 0 "" "")
17653 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17654 (match_operand:DI 2 "const_int_operand" "")))
17655 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17656 (clobber (reg:TI XMM6_REG))
17657 (clobber (reg:TI XMM7_REG))
17658 (clobber (reg:TI XMM8_REG))
17659 (clobber (reg:TI XMM9_REG))
17660 (clobber (reg:TI XMM10_REG))
17661 (clobber (reg:TI XMM11_REG))
17662 (clobber (reg:TI XMM12_REG))
17663 (clobber (reg:TI XMM13_REG))
17664 (clobber (reg:TI XMM14_REG))
17665 (clobber (reg:TI XMM15_REG))
17666 (clobber (reg:DI SI_REG))
17667 (clobber (reg:DI DI_REG))]
17668 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17669 { return ix86_output_call_insn (insn, operands[1], 1); }
17670 [(set_attr "type" "callv")])
17672 (define_insn_and_split "*call_value_1_vzeroupper"
17673 [(set (match_operand 0 "" "")
17674 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17675 (match_operand:SI 2 "" "")))
17676 (unspec [(match_operand 3 "const_int_operand" "")]
17677 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17678 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17680 "&& reload_completed"
17682 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17683 [(set_attr "type" "callv")])
17685 (define_insn "*call_value_1"
17686 [(set (match_operand 0 "" "")
17687 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17688 (match_operand:SI 2 "" "")))]
17689 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17690 { return ix86_output_call_insn (insn, operands[1], 1); }
17691 [(set_attr "type" "callv")])
17693 (define_insn_and_split "*sibcall_value_1_vzeroupper"
17694 [(set (match_operand 0 "" "")
17695 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17696 (match_operand:SI 2 "" "")))
17697 (unspec [(match_operand 3 "const_int_operand" "")]
17698 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17699 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17701 "&& reload_completed"
17703 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17704 [(set_attr "type" "callv")])
17706 (define_insn "*sibcall_value_1"
17707 [(set (match_operand 0 "" "")
17708 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17709 (match_operand:SI 2 "" "")))]
17710 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17711 { return ix86_output_call_insn (insn, operands[1], 1); }
17712 [(set_attr "type" "callv")])
17714 (define_insn_and_split "*call_value_1_rex64_vzeroupper"
17715 [(set (match_operand 0 "" "")
17716 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17717 (match_operand:DI 2 "" "")))
17718 (unspec [(match_operand 3 "const_int_operand" "")]
17719 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17720 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
17721 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17723 "&& reload_completed"
17725 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17726 [(set_attr "type" "callv")])
17728 (define_insn "*call_value_1_rex64"
17729 [(set (match_operand 0 "" "")
17730 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17731 (match_operand:DI 2 "" "")))]
17732 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17733 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17734 { return ix86_output_call_insn (insn, operands[1], 1); }
17735 [(set_attr "type" "callv")])
17737 (define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
17739 [(set (match_operand 0 "" "")
17740 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17741 (match_operand:DI 2 "" "")))
17742 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17743 (clobber (reg:TI XMM6_REG))
17744 (clobber (reg:TI XMM7_REG))
17745 (clobber (reg:TI XMM8_REG))
17746 (clobber (reg:TI XMM9_REG))
17747 (clobber (reg:TI XMM10_REG))
17748 (clobber (reg:TI XMM11_REG))
17749 (clobber (reg:TI XMM12_REG))
17750 (clobber (reg:TI XMM13_REG))
17751 (clobber (reg:TI XMM14_REG))
17752 (clobber (reg:TI XMM15_REG))
17753 (clobber (reg:DI SI_REG))
17754 (clobber (reg:DI DI_REG))])
17755 (unspec [(match_operand 3 "const_int_operand" "")]
17756 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17757 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17759 "&& reload_completed"
17761 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17762 [(set_attr "type" "callv")])
17764 (define_insn "*call_value_1_rex64_ms_sysv"
17765 [(set (match_operand 0 "" "")
17766 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17767 (match_operand:DI 2 "" "")))
17768 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17769 (clobber (reg:TI XMM6_REG))
17770 (clobber (reg:TI XMM7_REG))
17771 (clobber (reg:TI XMM8_REG))
17772 (clobber (reg:TI XMM9_REG))
17773 (clobber (reg:TI XMM10_REG))
17774 (clobber (reg:TI XMM11_REG))
17775 (clobber (reg:TI XMM12_REG))
17776 (clobber (reg:TI XMM13_REG))
17777 (clobber (reg:TI XMM14_REG))
17778 (clobber (reg:TI XMM15_REG))
17779 (clobber (reg:DI SI_REG))
17780 (clobber (reg:DI DI_REG))]
17781 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17782 { return ix86_output_call_insn (insn, operands[1], 1); }
17783 [(set_attr "type" "callv")])
17785 (define_insn_and_split "*call_value_1_rex64_large_vzeroupper"
17786 [(set (match_operand 0 "" "")
17787 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17788 (match_operand:DI 2 "" "")))
17789 (unspec [(match_operand 3 "const_int_operand" "")]
17790 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17791 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17793 "&& reload_completed"
17795 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17796 [(set_attr "type" "callv")])
17798 (define_insn "*call_value_1_rex64_large"
17799 [(set (match_operand 0 "" "")
17800 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17801 (match_operand:DI 2 "" "")))]
17802 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17803 { return ix86_output_call_insn (insn, operands[1], 1); }
17804 [(set_attr "type" "callv")])
17806 (define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
17807 [(set (match_operand 0 "" "")
17808 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17809 (match_operand:DI 2 "" "")))
17810 (unspec [(match_operand 3 "const_int_operand" "")]
17811 UNSPEC_CALL_NEEDS_VZEROUPPER)]
17812 "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
17814 "&& reload_completed"
17816 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17817 [(set_attr "type" "callv")])
17819 (define_insn "*sibcall_value_1_rex64"
17820 [(set (match_operand 0 "" "")
17821 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17822 (match_operand:DI 2 "" "")))]
17823 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17824 { return ix86_output_call_insn (insn, operands[1], 1); }
17825 [(set_attr "type" "callv")])
17827 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17828 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17829 ;; caught for use by garbage collectors and the like. Using an insn that
17830 ;; maps to SIGILL makes it more likely the program will rightfully die.
17831 ;; Keeping with tradition, "6" is in honor of #UD.
17832 (define_insn "trap"
17833 [(trap_if (const_int 1) (const_int 6))]
17835 { return ASM_SHORT "0x0b0f"; }
17836 [(set_attr "length" "2")])
17838 (define_expand "prefetch"
17839 [(prefetch (match_operand 0 "address_operand" "")
17840 (match_operand:SI 1 "const_int_operand" "")
17841 (match_operand:SI 2 "const_int_operand" ""))]
17842 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17844 int rw = INTVAL (operands[1]);
17845 int locality = INTVAL (operands[2]);
17847 gcc_assert (rw == 0 || rw == 1);
17848 gcc_assert (locality >= 0 && locality <= 3);
17849 gcc_assert (GET_MODE (operands[0]) == Pmode
17850 || GET_MODE (operands[0]) == VOIDmode);
17852 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17853 supported by SSE counterpart or the SSE prefetch is not available
17854 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17856 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17857 operands[2] = GEN_INT (3);
17859 operands[1] = const0_rtx;
17862 (define_insn "*prefetch_sse_<mode>"
17863 [(prefetch (match_operand:P 0 "address_operand" "p")
17865 (match_operand:SI 1 "const_int_operand" ""))]
17866 "TARGET_PREFETCH_SSE"
17868 static const char * const patterns[4] = {
17869 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17872 int locality = INTVAL (operands[1]);
17873 gcc_assert (locality >= 0 && locality <= 3);
17875 return patterns[locality];
17877 [(set_attr "type" "sse")
17878 (set_attr "atom_sse_attr" "prefetch")
17879 (set (attr "length_address")
17880 (symbol_ref "memory_address_length (operands[0])"))
17881 (set_attr "memory" "none")])
17883 (define_insn "*prefetch_3dnow_<mode>"
17884 [(prefetch (match_operand:P 0 "address_operand" "p")
17885 (match_operand:SI 1 "const_int_operand" "n")
17889 if (INTVAL (operands[1]) == 0)
17890 return "prefetch\t%a0";
17892 return "prefetchw\t%a0";
17894 [(set_attr "type" "mmx")
17895 (set (attr "length_address")
17896 (symbol_ref "memory_address_length (operands[0])"))
17897 (set_attr "memory" "none")])
17899 (define_expand "stack_protect_set"
17900 [(match_operand 0 "memory_operand" "")
17901 (match_operand 1 "memory_operand" "")]
17904 rtx (*insn)(rtx, rtx);
17906 #ifdef TARGET_THREAD_SSP_OFFSET
17907 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17908 insn = (TARGET_64BIT
17909 ? gen_stack_tls_protect_set_di
17910 : gen_stack_tls_protect_set_si);
17912 insn = (TARGET_64BIT
17913 ? gen_stack_protect_set_di
17914 : gen_stack_protect_set_si);
17917 emit_insn (insn (operands[0], operands[1]));
17921 (define_insn "stack_protect_set_<mode>"
17922 [(set (match_operand:P 0 "memory_operand" "=m")
17923 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17924 (set (match_scratch:P 2 "=&r") (const_int 0))
17925 (clobber (reg:CC FLAGS_REG))]
17927 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17928 [(set_attr "type" "multi")])
17930 (define_insn "stack_tls_protect_set_<mode>"
17931 [(set (match_operand:P 0 "memory_operand" "=m")
17932 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17933 UNSPEC_SP_TLS_SET))
17934 (set (match_scratch:P 2 "=&r") (const_int 0))
17935 (clobber (reg:CC FLAGS_REG))]
17937 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17938 [(set_attr "type" "multi")])
17940 (define_expand "stack_protect_test"
17941 [(match_operand 0 "memory_operand" "")
17942 (match_operand 1 "memory_operand" "")
17943 (match_operand 2 "" "")]
17946 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17948 rtx (*insn)(rtx, rtx, rtx);
17950 #ifdef TARGET_THREAD_SSP_OFFSET
17951 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17952 insn = (TARGET_64BIT
17953 ? gen_stack_tls_protect_test_di
17954 : gen_stack_tls_protect_test_si);
17956 insn = (TARGET_64BIT
17957 ? gen_stack_protect_test_di
17958 : gen_stack_protect_test_si);
17961 emit_insn (insn (flags, operands[0], operands[1]));
17963 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17964 flags, const0_rtx, operands[2]));
17968 (define_insn "stack_protect_test_<mode>"
17969 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17970 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17971 (match_operand:P 2 "memory_operand" "m")]
17973 (clobber (match_scratch:P 3 "=&r"))]
17975 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17976 [(set_attr "type" "multi")])
17978 (define_insn "stack_tls_protect_test_<mode>"
17979 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17980 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17981 (match_operand:P 2 "const_int_operand" "i")]
17982 UNSPEC_SP_TLS_TEST))
17983 (clobber (match_scratch:P 3 "=r"))]
17985 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17986 [(set_attr "type" "multi")])
17988 (define_insn "sse4_2_crc32<mode>"
17989 [(set (match_operand:SI 0 "register_operand" "=r")
17991 [(match_operand:SI 1 "register_operand" "0")
17992 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17994 "TARGET_SSE4_2 || TARGET_CRC32"
17995 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17996 [(set_attr "type" "sselog1")
17997 (set_attr "prefix_rep" "1")
17998 (set_attr "prefix_extra" "1")
17999 (set (attr "prefix_data16")
18000 (if_then_else (match_operand:HI 2 "" "")
18002 (const_string "*")))
18003 (set (attr "prefix_rex")
18004 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18006 (const_string "*")))
18007 (set_attr "mode" "SI")])
18009 (define_insn "sse4_2_crc32di"
18010 [(set (match_operand:DI 0 "register_operand" "=r")
18012 [(match_operand:DI 1 "register_operand" "0")
18013 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18015 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18016 "crc32{q}\t{%2, %0|%0, %2}"
18017 [(set_attr "type" "sselog1")
18018 (set_attr "prefix_rep" "1")
18019 (set_attr "prefix_extra" "1")
18020 (set_attr "mode" "DI")])
18022 (define_expand "rdpmc"
18023 [(match_operand:DI 0 "register_operand" "")
18024 (match_operand:SI 1 "register_operand" "")]
18027 rtx reg = gen_reg_rtx (DImode);
18030 /* Force operand 1 into ECX. */
18031 rtx ecx = gen_rtx_REG (SImode, CX_REG);
18032 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18033 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18038 rtvec vec = rtvec_alloc (2);
18039 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18040 rtx upper = gen_reg_rtx (DImode);
18041 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18042 gen_rtvec (1, const0_rtx),
18044 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18045 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18047 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18048 NULL, 1, OPTAB_DIRECT);
18049 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18053 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18054 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18058 (define_insn "*rdpmc"
18059 [(set (match_operand:DI 0 "register_operand" "=A")
18060 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18064 [(set_attr "type" "other")
18065 (set_attr "length" "2")])
18067 (define_insn "*rdpmc_rex64"
18068 [(set (match_operand:DI 0 "register_operand" "=a")
18069 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18071 (set (match_operand:DI 1 "register_operand" "=d")
18072 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18075 [(set_attr "type" "other")
18076 (set_attr "length" "2")])
18078 (define_expand "rdtsc"
18079 [(set (match_operand:DI 0 "register_operand" "")
18080 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18085 rtvec vec = rtvec_alloc (2);
18086 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18087 rtx upper = gen_reg_rtx (DImode);
18088 rtx lower = gen_reg_rtx (DImode);
18089 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18090 gen_rtvec (1, const0_rtx),
18092 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18093 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18095 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18096 NULL, 1, OPTAB_DIRECT);
18097 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18099 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18104 (define_insn "*rdtsc"
18105 [(set (match_operand:DI 0 "register_operand" "=A")
18106 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18109 [(set_attr "type" "other")
18110 (set_attr "length" "2")])
18112 (define_insn "*rdtsc_rex64"
18113 [(set (match_operand:DI 0 "register_operand" "=a")
18114 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18115 (set (match_operand:DI 1 "register_operand" "=d")
18116 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18119 [(set_attr "type" "other")
18120 (set_attr "length" "2")])
18122 (define_expand "rdtscp"
18123 [(match_operand:DI 0 "register_operand" "")
18124 (match_operand:SI 1 "memory_operand" "")]
18127 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18128 gen_rtvec (1, const0_rtx),
18130 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18131 gen_rtvec (1, const0_rtx),
18133 rtx reg = gen_reg_rtx (DImode);
18134 rtx tmp = gen_reg_rtx (SImode);
18138 rtvec vec = rtvec_alloc (3);
18139 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18140 rtx upper = gen_reg_rtx (DImode);
18141 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18142 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18143 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18145 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18146 NULL, 1, OPTAB_DIRECT);
18147 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18152 rtvec vec = rtvec_alloc (2);
18153 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18154 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18155 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18158 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18159 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18163 (define_insn "*rdtscp"
18164 [(set (match_operand:DI 0 "register_operand" "=A")
18165 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18166 (set (match_operand:SI 1 "register_operand" "=c")
18167 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18170 [(set_attr "type" "other")
18171 (set_attr "length" "3")])
18173 (define_insn "*rdtscp_rex64"
18174 [(set (match_operand:DI 0 "register_operand" "=a")
18175 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18176 (set (match_operand:DI 1 "register_operand" "=d")
18177 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18178 (set (match_operand:SI 2 "register_operand" "=c")
18179 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18182 [(set_attr "type" "other")
18183 (set_attr "length" "3")])
18185 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18187 ;; LWP instructions
18189 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18191 (define_expand "lwp_llwpcb"
18192 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18193 UNSPECV_LLWP_INTRINSIC)]
18196 (define_insn "*lwp_llwpcb<mode>1"
18197 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18198 UNSPECV_LLWP_INTRINSIC)]
18201 [(set_attr "type" "lwp")
18202 (set_attr "mode" "<MODE>")
18203 (set_attr "length" "5")])
18205 (define_expand "lwp_slwpcb"
18206 [(set (match_operand 0 "register_operand" "=r")
18207 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18211 emit_insn (gen_lwp_slwpcbdi (operands[0]));
18213 emit_insn (gen_lwp_slwpcbsi (operands[0]));
18217 (define_insn "lwp_slwpcb<mode>"
18218 [(set (match_operand:P 0 "register_operand" "=r")
18219 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18222 [(set_attr "type" "lwp")
18223 (set_attr "mode" "<MODE>")
18224 (set_attr "length" "5")])
18226 (define_expand "lwp_lwpval<mode>3"
18227 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18228 (match_operand:SI 2 "nonimmediate_operand" "rm")
18229 (match_operand:SI 3 "const_int_operand" "i")]
18230 UNSPECV_LWPVAL_INTRINSIC)]
18232 "/* Avoid unused variable warning. */
18235 (define_insn "*lwp_lwpval<mode>3_1"
18236 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18237 (match_operand:SI 1 "nonimmediate_operand" "rm")
18238 (match_operand:SI 2 "const_int_operand" "i")]
18239 UNSPECV_LWPVAL_INTRINSIC)]
18241 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18242 [(set_attr "type" "lwp")
18243 (set_attr "mode" "<MODE>")
18244 (set (attr "length")
18245 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18247 (define_expand "lwp_lwpins<mode>3"
18248 [(set (reg:CCC FLAGS_REG)
18249 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18250 (match_operand:SI 2 "nonimmediate_operand" "rm")
18251 (match_operand:SI 3 "const_int_operand" "i")]
18252 UNSPECV_LWPINS_INTRINSIC))
18253 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18254 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18257 (define_insn "*lwp_lwpins<mode>3_1"
18258 [(set (reg:CCC FLAGS_REG)
18259 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18260 (match_operand:SI 1 "nonimmediate_operand" "rm")
18261 (match_operand:SI 2 "const_int_operand" "i")]
18262 UNSPECV_LWPINS_INTRINSIC))]
18264 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18265 [(set_attr "type" "lwp")
18266 (set_attr "mode" "<MODE>")
18267 (set (attr "length")
18268 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18270 (define_insn "rdfsbase<mode>"
18271 [(set (match_operand:SWI48 0 "register_operand" "=r")
18272 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18273 "TARGET_64BIT && TARGET_FSGSBASE"
18275 [(set_attr "type" "other")
18276 (set_attr "prefix_extra" "2")])
18278 (define_insn "rdgsbase<mode>"
18279 [(set (match_operand:SWI48 0 "register_operand" "=r")
18280 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18281 "TARGET_64BIT && TARGET_FSGSBASE"
18283 [(set_attr "type" "other")
18284 (set_attr "prefix_extra" "2")])
18286 (define_insn "wrfsbase<mode>"
18287 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18289 "TARGET_64BIT && TARGET_FSGSBASE"
18291 [(set_attr "type" "other")
18292 (set_attr "prefix_extra" "2")])
18294 (define_insn "wrgsbase<mode>"
18295 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18297 "TARGET_64BIT && TARGET_FSGSBASE"
18299 [(set_attr "type" "other")
18300 (set_attr "prefix_extra" "2")])
18302 (define_insn "rdrand<mode>_1"
18303 [(set (match_operand:SWI248 0 "register_operand" "=r")
18304 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18305 (set (reg:CCC FLAGS_REG)
18306 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18309 [(set_attr "type" "other")
18310 (set_attr "prefix_extra" "1")])
18314 (include "sync.md")