1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
65 (define_c_enum "unspec" [
66 ;; Relocation specifiers
77 UNSPEC_MACHOPIC_OFFSET
82 UNSPEC_SSE_PROLOGUE_SAVE
87 UNSPEC_MEMORY_BLOCKAGE
88 UNSPEC_SSE_PROLOGUE_SAVE_LOW
96 ;; Other random patterns
105 UNSPEC_LD_MPIC ; load_macho_picbase
108 ;; For SSE/MMX support:
126 UNSPEC_MS_TO_SYSV_CALL
128 ;; Generic math support
130 UNSPEC_IEEE_MIN ; not commutative
131 UNSPEC_IEEE_MAX ; not commutative
133 ;; x87 Floating point
149 UNSPEC_FRNDINT_MASK_PM
153 ;; x87 Double output FP
185 ;; For SSE4.1 support
195 ;; For SSE4.2 support
201 UNSPEC_FMA4_INTRINSIC
204 UNSPEC_XOP_UNSIGNED_CMP
215 UNSPEC_AESKEYGENASSIST
217 ;; For PCLMUL support
231 (define_c_enum "unspecv" [
253 UNSPECV_LLWP_INTRINSIC
254 UNSPECV_SLWP_INTRINSIC
255 UNSPECV_LWPVAL_INTRINSIC
256 UNSPECV_LWPINS_INTRINSIC
259 ;; Constants to represent pcomtrue/pcomfalse variants
269 ;; Constants used in the XOP pperm instruction
271 [(PPERM_SRC 0x00) /* copy source */
272 (PPERM_INVERT 0x20) /* invert source */
273 (PPERM_REVERSE 0x40) /* bit reverse source */
274 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
275 (PPERM_ZERO 0x80) /* all 0's */
276 (PPERM_ONES 0xa0) /* all 1's */
277 (PPERM_SIGN 0xc0) /* propagate sign bit */
278 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
279 (PPERM_SRC1 0x00) /* use first source byte */
280 (PPERM_SRC2 0x10) /* use second source byte */
283 ;; Registers by name.
336 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
339 ;; In C guard expressions, put expressions which may be compile-time
340 ;; constants first. This allows for better optimization. For
341 ;; example, write "TARGET_64BIT && reload_completed", not
342 ;; "reload_completed && TARGET_64BIT".
346 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
347 generic64,amdfam10,bdver1"
348 (const (symbol_ref "ix86_schedule")))
350 ;; A basic instruction type. Refinements due to arguments to be
351 ;; provided in other attributes.
354 alu,alu1,negnot,imov,imovx,lea,
355 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
356 icmp,test,ibr,setcc,icmov,
357 push,pop,call,callv,leave,
359 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
360 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
361 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
362 ssemuladd,sse4arg,lwp,
363 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
364 (const_string "other"))
366 ;; Main data type used by the insn
368 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
369 (const_string "unknown"))
371 ;; The CPU unit operations uses.
372 (define_attr "unit" "integer,i387,sse,mmx,unknown"
373 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
374 (const_string "i387")
375 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
376 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
377 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
379 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
381 (eq_attr "type" "other")
382 (const_string "unknown")]
383 (const_string "integer")))
385 ;; The (bounding maximum) length of an instruction immediate.
386 (define_attr "length_immediate" ""
387 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
390 (eq_attr "unit" "i387,sse,mmx")
392 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
394 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
395 (eq_attr "type" "imov,test")
396 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
397 (eq_attr "type" "call")
398 (if_then_else (match_operand 0 "constant_call_address_operand" "")
401 (eq_attr "type" "callv")
402 (if_then_else (match_operand 1 "constant_call_address_operand" "")
405 ;; We don't know the size before shorten_branches. Expect
406 ;; the instruction to fit for better scheduling.
407 (eq_attr "type" "ibr")
410 (symbol_ref "/* Update immediate_length and other attributes! */
411 gcc_unreachable (),1")))
413 ;; The (bounding maximum) length of an instruction address.
414 (define_attr "length_address" ""
415 (cond [(eq_attr "type" "str,other,multi,fxch")
417 (and (eq_attr "type" "call")
418 (match_operand 0 "constant_call_address_operand" ""))
420 (and (eq_attr "type" "callv")
421 (match_operand 1 "constant_call_address_operand" ""))
424 (symbol_ref "ix86_attr_length_address_default (insn)")))
426 ;; Set when length prefix is used.
427 (define_attr "prefix_data16" ""
428 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
430 (eq_attr "mode" "HI")
432 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
437 ;; Set when string REP prefix is used.
438 (define_attr "prefix_rep" ""
439 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
441 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
446 ;; Set when 0f opcode prefix is used.
447 (define_attr "prefix_0f" ""
449 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
450 (eq_attr "unit" "sse,mmx"))
454 ;; Set when REX opcode prefix is used.
455 (define_attr "prefix_rex" ""
456 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
458 (and (eq_attr "mode" "DI")
459 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
460 (eq_attr "unit" "!mmx")))
462 (and (eq_attr "mode" "QI")
463 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
466 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
469 (and (eq_attr "type" "imovx")
470 (match_operand:QI 1 "ext_QIreg_operand" ""))
475 ;; There are also additional prefixes in 3DNOW, SSSE3.
476 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
477 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
478 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
479 (define_attr "prefix_extra" ""
480 (cond [(eq_attr "type" "ssemuladd,sse4arg")
482 (eq_attr "type" "sseiadd1,ssecvt1")
487 ;; Prefix used: original, VEX or maybe VEX.
488 (define_attr "prefix" "orig,vex,maybe_vex"
489 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
491 (const_string "orig")))
493 ;; VEX W bit is used.
494 (define_attr "prefix_vex_w" "" (const_int 0))
496 ;; The length of VEX prefix
497 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
498 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
499 ;; still prefix_0f 1, with prefix_extra 1.
500 (define_attr "length_vex" ""
501 (if_then_else (and (eq_attr "prefix_0f" "1")
502 (eq_attr "prefix_extra" "0"))
503 (if_then_else (eq_attr "prefix_vex_w" "1")
504 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
505 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
506 (if_then_else (eq_attr "prefix_vex_w" "1")
507 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
508 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
510 ;; Set when modrm byte is used.
511 (define_attr "modrm" ""
512 (cond [(eq_attr "type" "str,leave")
514 (eq_attr "unit" "i387")
516 (and (eq_attr "type" "incdec")
517 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
518 (ior (match_operand:SI 1 "register_operand" "")
519 (match_operand:HI 1 "register_operand" ""))))
521 (and (eq_attr "type" "push")
522 (not (match_operand 1 "memory_operand" "")))
524 (and (eq_attr "type" "pop")
525 (not (match_operand 0 "memory_operand" "")))
527 (and (eq_attr "type" "imov")
528 (and (not (eq_attr "mode" "DI"))
529 (ior (and (match_operand 0 "register_operand" "")
530 (match_operand 1 "immediate_operand" ""))
531 (ior (and (match_operand 0 "ax_reg_operand" "")
532 (match_operand 1 "memory_displacement_only_operand" ""))
533 (and (match_operand 0 "memory_displacement_only_operand" "")
534 (match_operand 1 "ax_reg_operand" ""))))))
536 (and (eq_attr "type" "call")
537 (match_operand 0 "constant_call_address_operand" ""))
539 (and (eq_attr "type" "callv")
540 (match_operand 1 "constant_call_address_operand" ""))
542 (and (eq_attr "type" "alu,alu1,icmp,test")
543 (match_operand 0 "ax_reg_operand" ""))
544 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
548 ;; The (bounding maximum) length of an instruction in bytes.
549 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
550 ;; Later we may want to split them and compute proper length as for
552 (define_attr "length" ""
553 (cond [(eq_attr "type" "other,multi,fistp,frndint")
555 (eq_attr "type" "fcmp")
557 (eq_attr "unit" "i387")
559 (plus (attr "prefix_data16")
560 (attr "length_address")))
561 (ior (eq_attr "prefix" "vex")
562 (and (eq_attr "prefix" "maybe_vex")
563 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
564 (plus (attr "length_vex")
565 (plus (attr "length_immediate")
567 (attr "length_address"))))]
568 (plus (plus (attr "modrm")
569 (plus (attr "prefix_0f")
570 (plus (attr "prefix_rex")
571 (plus (attr "prefix_extra")
573 (plus (attr "prefix_rep")
574 (plus (attr "prefix_data16")
575 (plus (attr "length_immediate")
576 (attr "length_address")))))))
578 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
579 ;; `store' if there is a simple memory reference therein, or `unknown'
580 ;; if the instruction is complex.
582 (define_attr "memory" "none,load,store,both,unknown"
583 (cond [(eq_attr "type" "other,multi,str,lwp")
584 (const_string "unknown")
585 (eq_attr "type" "lea,fcmov,fpspc")
586 (const_string "none")
587 (eq_attr "type" "fistp,leave")
588 (const_string "both")
589 (eq_attr "type" "frndint")
590 (const_string "load")
591 (eq_attr "type" "push")
592 (if_then_else (match_operand 1 "memory_operand" "")
593 (const_string "both")
594 (const_string "store"))
595 (eq_attr "type" "pop")
596 (if_then_else (match_operand 0 "memory_operand" "")
597 (const_string "both")
598 (const_string "load"))
599 (eq_attr "type" "setcc")
600 (if_then_else (match_operand 0 "memory_operand" "")
601 (const_string "store")
602 (const_string "none"))
603 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
604 (if_then_else (ior (match_operand 0 "memory_operand" "")
605 (match_operand 1 "memory_operand" ""))
606 (const_string "load")
607 (const_string "none"))
608 (eq_attr "type" "ibr")
609 (if_then_else (match_operand 0 "memory_operand" "")
610 (const_string "load")
611 (const_string "none"))
612 (eq_attr "type" "call")
613 (if_then_else (match_operand 0 "constant_call_address_operand" "")
614 (const_string "none")
615 (const_string "load"))
616 (eq_attr "type" "callv")
617 (if_then_else (match_operand 1 "constant_call_address_operand" "")
618 (const_string "none")
619 (const_string "load"))
620 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
621 (match_operand 1 "memory_operand" ""))
622 (const_string "both")
623 (and (match_operand 0 "memory_operand" "")
624 (match_operand 1 "memory_operand" ""))
625 (const_string "both")
626 (match_operand 0 "memory_operand" "")
627 (const_string "store")
628 (match_operand 1 "memory_operand" "")
629 (const_string "load")
631 "!alu1,negnot,ishift1,
632 imov,imovx,icmp,test,bitmanip,
634 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
635 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
636 (match_operand 2 "memory_operand" ""))
637 (const_string "load")
638 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
639 (match_operand 3 "memory_operand" ""))
640 (const_string "load")
642 (const_string "none")))
644 ;; Indicates if an instruction has both an immediate and a displacement.
646 (define_attr "imm_disp" "false,true,unknown"
647 (cond [(eq_attr "type" "other,multi")
648 (const_string "unknown")
649 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
650 (and (match_operand 0 "memory_displacement_operand" "")
651 (match_operand 1 "immediate_operand" "")))
652 (const_string "true")
653 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
654 (and (match_operand 0 "memory_displacement_operand" "")
655 (match_operand 2 "immediate_operand" "")))
656 (const_string "true")
658 (const_string "false")))
660 ;; Indicates if an FP operation has an integer source.
662 (define_attr "fp_int_src" "false,true"
663 (const_string "false"))
665 ;; Defines rounding mode of an FP operation.
667 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
668 (const_string "any"))
670 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
671 (define_attr "use_carry" "0,1" (const_string "0"))
673 ;; Define attribute to indicate unaligned ssemov insns
674 (define_attr "movu" "0,1" (const_string "0"))
676 ;; Describe a user's asm statement.
677 (define_asm_attributes
678 [(set_attr "length" "128")
679 (set_attr "type" "multi")])
681 ;; All integer comparison codes.
682 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
684 ;; All floating-point comparison codes.
685 (define_code_iterator fp_cond [unordered ordered
686 uneq unge ungt unle unlt ltgt])
688 (define_code_iterator plusminus [plus minus])
690 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
692 ;; Base name for define_insn
693 (define_code_attr plusminus_insn
694 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
695 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
697 ;; Base name for insn mnemonic.
698 (define_code_attr plusminus_mnemonic
699 [(plus "add") (ss_plus "adds") (us_plus "addus")
700 (minus "sub") (ss_minus "subs") (us_minus "subus")])
701 (define_code_attr plusminus_carry_mnemonic
702 [(plus "adc") (minus "sbb")])
704 ;; Mark commutative operators as such in constraints.
705 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
706 (minus "") (ss_minus "") (us_minus "")])
708 ;; Mapping of signed max and min
709 (define_code_iterator smaxmin [smax smin])
711 ;; Mapping of unsigned max and min
712 (define_code_iterator umaxmin [umax umin])
714 ;; Mapping of signed/unsigned max and min
715 (define_code_iterator maxmin [smax smin umax umin])
717 ;; Base name for integer and FP insn mnemonic
718 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
719 (umax "maxu") (umin "minu")])
720 (define_code_attr maxmin_float [(smax "max") (smin "min")])
722 ;; Mapping of logic operators
723 (define_code_iterator any_logic [and ior xor])
724 (define_code_iterator any_or [ior xor])
726 ;; Base name for insn mnemonic.
727 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
729 ;; Mapping of shift-right operators
730 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
732 ;; Base name for define_insn
733 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
735 ;; Base name for insn mnemonic.
736 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
738 ;; Mapping of rotate operators
739 (define_code_iterator any_rotate [rotate rotatert])
741 ;; Base name for define_insn
742 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
744 ;; Base name for insn mnemonic.
745 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
747 ;; Mapping of abs neg operators
748 (define_code_iterator absneg [abs neg])
750 ;; Base name for x87 insn mnemonic.
751 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
753 ;; Used in signed and unsigned widening multiplications.
754 (define_code_iterator any_extend [sign_extend zero_extend])
756 ;; Various insn prefixes for signed and unsigned operations.
757 (define_code_attr u [(sign_extend "") (zero_extend "u")
758 (div "") (udiv "u")])
759 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
761 ;; Used in signed and unsigned divisions.
762 (define_code_iterator any_div [div udiv])
764 ;; Instruction prefix for signed and unsigned operations.
765 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
766 (div "i") (udiv "")])
768 ;; All single word integer modes.
769 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
771 ;; Single word integer modes without DImode.
772 (define_mode_iterator SWI124 [QI HI SI])
774 ;; Single word integer modes without QImode.
775 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
777 ;; Single word integer modes without QImode and HImode.
778 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
780 ;; All math-dependant single and double word integer modes.
781 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
782 (HI "TARGET_HIMODE_MATH")
783 SI DI (TI "TARGET_64BIT")])
785 ;; Math-dependant single word integer modes.
786 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
787 (HI "TARGET_HIMODE_MATH")
788 SI (DI "TARGET_64BIT")])
790 ;; Math-dependant single word integer modes without DImode.
791 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
792 (HI "TARGET_HIMODE_MATH")
795 ;; Math-dependant single word integer modes without QImode.
796 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
797 SI (DI "TARGET_64BIT")])
799 ;; Double word integer modes.
800 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
801 (TI "TARGET_64BIT")])
803 ;; Double word integer modes as mode attribute.
804 (define_mode_attr DWI [(SI "DI") (DI "TI")])
805 (define_mode_attr dwi [(SI "di") (DI "ti")])
807 ;; Half mode for double word integer modes.
808 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
809 (DI "TARGET_64BIT")])
811 ;; Instruction suffix for integer modes.
812 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
814 ;; Register class for integer modes.
815 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
817 ;; Immediate operand constraint for integer modes.
818 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
820 ;; General operand constraint for word modes.
821 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
823 ;; Immediate operand constraint for double integer modes.
824 (define_mode_attr di [(SI "iF") (DI "e")])
826 ;; Immediate operand constraint for shifts.
827 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
829 ;; General operand predicate for integer modes.
830 (define_mode_attr general_operand
831 [(QI "general_operand")
832 (HI "general_operand")
833 (SI "general_operand")
834 (DI "x86_64_general_operand")
835 (TI "x86_64_general_operand")])
837 ;; General sign/zero extend operand predicate for integer modes.
838 (define_mode_attr general_szext_operand
839 [(QI "general_operand")
840 (HI "general_operand")
841 (SI "general_operand")
842 (DI "x86_64_szext_general_operand")])
844 ;; Operand predicate for shifts.
845 (define_mode_attr shift_operand
846 [(QI "nonimmediate_operand")
847 (HI "nonimmediate_operand")
848 (SI "nonimmediate_operand")
849 (DI "shiftdi_operand")
850 (TI "register_operand")])
852 ;; Operand predicate for shift argument.
853 (define_mode_attr shift_immediate_operand
854 [(QI "const_1_to_31_operand")
855 (HI "const_1_to_31_operand")
856 (SI "const_1_to_31_operand")
857 (DI "const_1_to_63_operand")])
859 ;; Input operand predicate for arithmetic left shifts.
860 (define_mode_attr ashl_input_operand
861 [(QI "nonimmediate_operand")
862 (HI "nonimmediate_operand")
863 (SI "nonimmediate_operand")
864 (DI "ashldi_input_operand")
865 (TI "reg_or_pm1_operand")])
867 ;; SSE and x87 SFmode and DFmode floating point modes
868 (define_mode_iterator MODEF [SF DF])
870 ;; All x87 floating point modes
871 (define_mode_iterator X87MODEF [SF DF XF])
873 ;; All integer modes handled by x87 fisttp operator.
874 (define_mode_iterator X87MODEI [HI SI DI])
876 ;; All integer modes handled by integer x87 operators.
877 (define_mode_iterator X87MODEI12 [HI SI])
879 ;; All integer modes handled by SSE cvtts?2si* operators.
880 (define_mode_iterator SSEMODEI24 [SI DI])
882 ;; SSE asm suffix for floating point modes
883 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
885 ;; SSE vector mode corresponding to a scalar mode
886 (define_mode_attr ssevecmode
887 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
889 ;; Instruction suffix for REX 64bit operators.
890 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
892 ;; This mode iterator allows :P to be used for patterns that operate on
893 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
894 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
896 ;; Scheduling descriptions
898 (include "pentium.md")
901 (include "athlon.md")
906 ;; Operand and operator predicates and constraints
908 (include "predicates.md")
909 (include "constraints.md")
912 ;; Compare and branch/compare and store instructions.
914 (define_expand "cbranch<mode>4"
915 [(set (reg:CC FLAGS_REG)
916 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
917 (match_operand:SDWIM 2 "<general_operand>" "")))
918 (set (pc) (if_then_else
919 (match_operator 0 "comparison_operator"
920 [(reg:CC FLAGS_REG) (const_int 0)])
921 (label_ref (match_operand 3 "" ""))
925 if (MEM_P (operands[1]) && MEM_P (operands[2]))
926 operands[1] = force_reg (<MODE>mode, operands[1]);
927 ix86_compare_op0 = operands[1];
928 ix86_compare_op1 = operands[2];
929 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
933 (define_expand "cstore<mode>4"
934 [(set (reg:CC FLAGS_REG)
935 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
936 (match_operand:SWIM 3 "<general_operand>" "")))
937 (set (match_operand:QI 0 "register_operand" "")
938 (match_operator 1 "comparison_operator"
939 [(reg:CC FLAGS_REG) (const_int 0)]))]
942 if (MEM_P (operands[2]) && MEM_P (operands[3]))
943 operands[2] = force_reg (<MODE>mode, operands[2]);
944 ix86_compare_op0 = operands[2];
945 ix86_compare_op1 = operands[3];
946 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
950 (define_expand "cmp<mode>_1"
951 [(set (reg:CC FLAGS_REG)
952 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
953 (match_operand:SWI48 1 "<general_operand>" "")))]
957 (define_insn "*cmp<mode>_ccno_1"
958 [(set (reg FLAGS_REG)
959 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
960 (match_operand:SWI 1 "const0_operand" "")))]
961 "ix86_match_ccmode (insn, CCNOmode)"
963 test{<imodesuffix>}\t%0, %0
964 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
965 [(set_attr "type" "test,icmp")
966 (set_attr "length_immediate" "0,1")
967 (set_attr "mode" "<MODE>")])
969 (define_insn "*cmp<mode>_1"
970 [(set (reg FLAGS_REG)
971 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
972 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
973 "ix86_match_ccmode (insn, CCmode)"
974 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
975 [(set_attr "type" "icmp")
976 (set_attr "mode" "<MODE>")])
978 (define_insn "*cmp<mode>_minus_1"
979 [(set (reg FLAGS_REG)
981 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
982 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
984 "ix86_match_ccmode (insn, CCGOCmode)"
985 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
986 [(set_attr "type" "icmp")
987 (set_attr "mode" "<MODE>")])
989 (define_insn "*cmpqi_ext_1"
990 [(set (reg FLAGS_REG)
992 (match_operand:QI 0 "general_operand" "Qm")
995 (match_operand 1 "ext_register_operand" "Q")
998 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
999 "cmp{b}\t{%h1, %0|%0, %h1}"
1000 [(set_attr "type" "icmp")
1001 (set_attr "mode" "QI")])
1003 (define_insn "*cmpqi_ext_1_rex64"
1004 [(set (reg FLAGS_REG)
1006 (match_operand:QI 0 "register_operand" "Q")
1009 (match_operand 1 "ext_register_operand" "Q")
1011 (const_int 8)) 0)))]
1012 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1013 "cmp{b}\t{%h1, %0|%0, %h1}"
1014 [(set_attr "type" "icmp")
1015 (set_attr "mode" "QI")])
1017 (define_insn "*cmpqi_ext_2"
1018 [(set (reg FLAGS_REG)
1022 (match_operand 0 "ext_register_operand" "Q")
1025 (match_operand:QI 1 "const0_operand" "")))]
1026 "ix86_match_ccmode (insn, CCNOmode)"
1028 [(set_attr "type" "test")
1029 (set_attr "length_immediate" "0")
1030 (set_attr "mode" "QI")])
1032 (define_expand "cmpqi_ext_3"
1033 [(set (reg:CC FLAGS_REG)
1037 (match_operand 0 "ext_register_operand" "")
1040 (match_operand:QI 1 "immediate_operand" "")))]
1044 (define_insn "*cmpqi_ext_3_insn"
1045 [(set (reg FLAGS_REG)
1049 (match_operand 0 "ext_register_operand" "Q")
1052 (match_operand:QI 1 "general_operand" "Qmn")))]
1053 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1054 "cmp{b}\t{%1, %h0|%h0, %1}"
1055 [(set_attr "type" "icmp")
1056 (set_attr "modrm" "1")
1057 (set_attr "mode" "QI")])
1059 (define_insn "*cmpqi_ext_3_insn_rex64"
1060 [(set (reg FLAGS_REG)
1064 (match_operand 0 "ext_register_operand" "Q")
1067 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1068 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1069 "cmp{b}\t{%1, %h0|%h0, %1}"
1070 [(set_attr "type" "icmp")
1071 (set_attr "modrm" "1")
1072 (set_attr "mode" "QI")])
1074 (define_insn "*cmpqi_ext_4"
1075 [(set (reg FLAGS_REG)
1079 (match_operand 0 "ext_register_operand" "Q")
1084 (match_operand 1 "ext_register_operand" "Q")
1086 (const_int 8)) 0)))]
1087 "ix86_match_ccmode (insn, CCmode)"
1088 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1089 [(set_attr "type" "icmp")
1090 (set_attr "mode" "QI")])
1092 ;; These implement float point compares.
1093 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1094 ;; which would allow mix and match FP modes on the compares. Which is what
1095 ;; the old patterns did, but with many more of them.
1097 (define_expand "cbranchxf4"
1098 [(set (reg:CC FLAGS_REG)
1099 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1100 (match_operand:XF 2 "nonmemory_operand" "")))
1101 (set (pc) (if_then_else
1102 (match_operator 0 "ix86_fp_comparison_operator"
1105 (label_ref (match_operand 3 "" ""))
1109 ix86_compare_op0 = operands[1];
1110 ix86_compare_op1 = operands[2];
1111 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1115 (define_expand "cstorexf4"
1116 [(set (reg:CC FLAGS_REG)
1117 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1118 (match_operand:XF 3 "nonmemory_operand" "")))
1119 (set (match_operand:QI 0 "register_operand" "")
1120 (match_operator 1 "ix86_fp_comparison_operator"
1125 ix86_compare_op0 = operands[2];
1126 ix86_compare_op1 = operands[3];
1127 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1131 (define_expand "cbranch<mode>4"
1132 [(set (reg:CC FLAGS_REG)
1133 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1134 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1135 (set (pc) (if_then_else
1136 (match_operator 0 "ix86_fp_comparison_operator"
1139 (label_ref (match_operand 3 "" ""))
1141 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1143 ix86_compare_op0 = operands[1];
1144 ix86_compare_op1 = operands[2];
1145 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1149 (define_expand "cstore<mode>4"
1150 [(set (reg:CC FLAGS_REG)
1151 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1152 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1153 (set (match_operand:QI 0 "register_operand" "")
1154 (match_operator 1 "ix86_fp_comparison_operator"
1157 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1159 ix86_compare_op0 = operands[2];
1160 ix86_compare_op1 = operands[3];
1161 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1165 (define_expand "cbranchcc4"
1166 [(set (pc) (if_then_else
1167 (match_operator 0 "comparison_operator"
1168 [(match_operand 1 "flags_reg_operand" "")
1169 (match_operand 2 "const0_operand" "")])
1170 (label_ref (match_operand 3 "" ""))
1174 ix86_compare_op0 = operands[1];
1175 ix86_compare_op1 = operands[2];
1176 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1180 (define_expand "cstorecc4"
1181 [(set (match_operand:QI 0 "register_operand" "")
1182 (match_operator 1 "comparison_operator"
1183 [(match_operand 2 "flags_reg_operand" "")
1184 (match_operand 3 "const0_operand" "")]))]
1187 ix86_compare_op0 = operands[2];
1188 ix86_compare_op1 = operands[3];
1189 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1194 ;; FP compares, step 1:
1195 ;; Set the FP condition codes.
1197 ;; CCFPmode compare with exceptions
1198 ;; CCFPUmode compare with no exceptions
1200 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1201 ;; used to manage the reg stack popping would not be preserved.
1203 (define_insn "*cmpfp_0"
1204 [(set (match_operand:HI 0 "register_operand" "=a")
1207 (match_operand 1 "register_operand" "f")
1208 (match_operand 2 "const0_operand" ""))]
1210 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1211 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1212 "* return output_fp_compare (insn, operands, 0, 0);"
1213 [(set_attr "type" "multi")
1214 (set_attr "unit" "i387")
1216 (cond [(match_operand:SF 1 "" "")
1218 (match_operand:DF 1 "" "")
1221 (const_string "XF")))])
1223 (define_insn_and_split "*cmpfp_0_cc"
1224 [(set (reg:CCFP FLAGS_REG)
1226 (match_operand 1 "register_operand" "f")
1227 (match_operand 2 "const0_operand" "")))
1228 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1229 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1230 && TARGET_SAHF && !TARGET_CMOVE
1231 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1233 "&& reload_completed"
1236 [(compare:CCFP (match_dup 1)(match_dup 2))]
1238 (set (reg:CC FLAGS_REG)
1239 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
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 "*cmpfp_xf"
1252 [(set (match_operand:HI 0 "register_operand" "=a")
1255 (match_operand:XF 1 "register_operand" "f")
1256 (match_operand:XF 2 "register_operand" "f"))]
1259 "* return output_fp_compare (insn, operands, 0, 0);"
1260 [(set_attr "type" "multi")
1261 (set_attr "unit" "i387")
1262 (set_attr "mode" "XF")])
1264 (define_insn_and_split "*cmpfp_xf_cc"
1265 [(set (reg:CCFP FLAGS_REG)
1267 (match_operand:XF 1 "register_operand" "f")
1268 (match_operand:XF 2 "register_operand" "f")))
1269 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1271 && TARGET_SAHF && !TARGET_CMOVE"
1273 "&& reload_completed"
1276 [(compare:CCFP (match_dup 1)(match_dup 2))]
1278 (set (reg:CC FLAGS_REG)
1279 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1281 [(set_attr "type" "multi")
1282 (set_attr "unit" "i387")
1283 (set_attr "mode" "XF")])
1285 (define_insn "*cmpfp_<mode>"
1286 [(set (match_operand:HI 0 "register_operand" "=a")
1289 (match_operand:MODEF 1 "register_operand" "f")
1290 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1293 "* return output_fp_compare (insn, operands, 0, 0);"
1294 [(set_attr "type" "multi")
1295 (set_attr "unit" "i387")
1296 (set_attr "mode" "<MODE>")])
1298 (define_insn_and_split "*cmpfp_<mode>_cc"
1299 [(set (reg:CCFP FLAGS_REG)
1301 (match_operand:MODEF 1 "register_operand" "f")
1302 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1303 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1305 && TARGET_SAHF && !TARGET_CMOVE"
1307 "&& reload_completed"
1310 [(compare:CCFP (match_dup 1)(match_dup 2))]
1312 (set (reg:CC FLAGS_REG)
1313 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1315 [(set_attr "type" "multi")
1316 (set_attr "unit" "i387")
1317 (set_attr "mode" "<MODE>")])
1319 (define_insn "*cmpfp_u"
1320 [(set (match_operand:HI 0 "register_operand" "=a")
1323 (match_operand 1 "register_operand" "f")
1324 (match_operand 2 "register_operand" "f"))]
1326 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1327 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1328 "* return output_fp_compare (insn, operands, 0, 1);"
1329 [(set_attr "type" "multi")
1330 (set_attr "unit" "i387")
1332 (cond [(match_operand:SF 1 "" "")
1334 (match_operand:DF 1 "" "")
1337 (const_string "XF")))])
1339 (define_insn_and_split "*cmpfp_u_cc"
1340 [(set (reg:CCFPU FLAGS_REG)
1342 (match_operand 1 "register_operand" "f")
1343 (match_operand 2 "register_operand" "f")))
1344 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1345 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1346 && TARGET_SAHF && !TARGET_CMOVE
1347 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1349 "&& reload_completed"
1352 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1354 (set (reg:CC FLAGS_REG)
1355 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
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 "*cmpfp_<mode>"
1368 [(set (match_operand:HI 0 "register_operand" "=a")
1371 (match_operand 1 "register_operand" "f")
1372 (match_operator 3 "float_operator"
1373 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1375 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1376 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1377 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1378 "* return output_fp_compare (insn, operands, 0, 0);"
1379 [(set_attr "type" "multi")
1380 (set_attr "unit" "i387")
1381 (set_attr "fp_int_src" "true")
1382 (set_attr "mode" "<MODE>")])
1384 (define_insn_and_split "*cmpfp_<mode>_cc"
1385 [(set (reg:CCFP FLAGS_REG)
1387 (match_operand 1 "register_operand" "f")
1388 (match_operator 3 "float_operator"
1389 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1390 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1391 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1392 && TARGET_SAHF && !TARGET_CMOVE
1393 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1394 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1396 "&& reload_completed"
1401 (match_op_dup 3 [(match_dup 2)]))]
1403 (set (reg:CC FLAGS_REG)
1404 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1406 [(set_attr "type" "multi")
1407 (set_attr "unit" "i387")
1408 (set_attr "fp_int_src" "true")
1409 (set_attr "mode" "<MODE>")])
1411 ;; FP compares, step 2
1412 ;; Move the fpsw to ax.
1414 (define_insn "x86_fnstsw_1"
1415 [(set (match_operand:HI 0 "register_operand" "=a")
1416 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1419 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1420 (set_attr "mode" "SI")
1421 (set_attr "unit" "i387")])
1423 ;; FP compares, step 3
1424 ;; Get ax into flags, general case.
1426 (define_insn "x86_sahf_1"
1427 [(set (reg:CC FLAGS_REG)
1428 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1432 #ifndef HAVE_AS_IX86_SAHF
1434 return ASM_BYTE "0x9e";
1439 [(set_attr "length" "1")
1440 (set_attr "athlon_decode" "vector")
1441 (set_attr "amdfam10_decode" "direct")
1442 (set_attr "mode" "SI")])
1444 ;; Pentium Pro can do steps 1 through 3 in one go.
1445 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1446 (define_insn "*cmpfp_i_mixed"
1447 [(set (reg:CCFP FLAGS_REG)
1448 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1449 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1450 "TARGET_MIX_SSE_I387
1451 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1452 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1453 "* return output_fp_compare (insn, operands, 1, 0);"
1454 [(set_attr "type" "fcmp,ssecomi")
1455 (set_attr "prefix" "orig,maybe_vex")
1457 (if_then_else (match_operand:SF 1 "" "")
1459 (const_string "DF")))
1460 (set (attr "prefix_rep")
1461 (if_then_else (eq_attr "type" "ssecomi")
1463 (const_string "*")))
1464 (set (attr "prefix_data16")
1465 (cond [(eq_attr "type" "fcmp")
1467 (eq_attr "mode" "DF")
1470 (const_string "0")))
1471 (set_attr "athlon_decode" "vector")
1472 (set_attr "amdfam10_decode" "direct")])
1474 (define_insn "*cmpfp_i_sse"
1475 [(set (reg:CCFP FLAGS_REG)
1476 (compare:CCFP (match_operand 0 "register_operand" "x")
1477 (match_operand 1 "nonimmediate_operand" "xm")))]
1479 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1480 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1481 "* return output_fp_compare (insn, operands, 1, 0);"
1482 [(set_attr "type" "ssecomi")
1483 (set_attr "prefix" "maybe_vex")
1485 (if_then_else (match_operand:SF 1 "" "")
1487 (const_string "DF")))
1488 (set_attr "prefix_rep" "0")
1489 (set (attr "prefix_data16")
1490 (if_then_else (eq_attr "mode" "DF")
1492 (const_string "0")))
1493 (set_attr "athlon_decode" "vector")
1494 (set_attr "amdfam10_decode" "direct")])
1496 (define_insn "*cmpfp_i_i387"
1497 [(set (reg:CCFP FLAGS_REG)
1498 (compare:CCFP (match_operand 0 "register_operand" "f")
1499 (match_operand 1 "register_operand" "f")))]
1500 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1502 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1503 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1504 "* return output_fp_compare (insn, operands, 1, 0);"
1505 [(set_attr "type" "fcmp")
1507 (cond [(match_operand:SF 1 "" "")
1509 (match_operand:DF 1 "" "")
1512 (const_string "XF")))
1513 (set_attr "athlon_decode" "vector")
1514 (set_attr "amdfam10_decode" "direct")])
1516 (define_insn "*cmpfp_iu_mixed"
1517 [(set (reg:CCFPU FLAGS_REG)
1518 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1519 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1520 "TARGET_MIX_SSE_I387
1521 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1522 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1523 "* return output_fp_compare (insn, operands, 1, 1);"
1524 [(set_attr "type" "fcmp,ssecomi")
1525 (set_attr "prefix" "orig,maybe_vex")
1527 (if_then_else (match_operand:SF 1 "" "")
1529 (const_string "DF")))
1530 (set (attr "prefix_rep")
1531 (if_then_else (eq_attr "type" "ssecomi")
1533 (const_string "*")))
1534 (set (attr "prefix_data16")
1535 (cond [(eq_attr "type" "fcmp")
1537 (eq_attr "mode" "DF")
1540 (const_string "0")))
1541 (set_attr "athlon_decode" "vector")
1542 (set_attr "amdfam10_decode" "direct")])
1544 (define_insn "*cmpfp_iu_sse"
1545 [(set (reg:CCFPU FLAGS_REG)
1546 (compare:CCFPU (match_operand 0 "register_operand" "x")
1547 (match_operand 1 "nonimmediate_operand" "xm")))]
1549 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1550 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1551 "* return output_fp_compare (insn, operands, 1, 1);"
1552 [(set_attr "type" "ssecomi")
1553 (set_attr "prefix" "maybe_vex")
1555 (if_then_else (match_operand:SF 1 "" "")
1557 (const_string "DF")))
1558 (set_attr "prefix_rep" "0")
1559 (set (attr "prefix_data16")
1560 (if_then_else (eq_attr "mode" "DF")
1562 (const_string "0")))
1563 (set_attr "athlon_decode" "vector")
1564 (set_attr "amdfam10_decode" "direct")])
1566 (define_insn "*cmpfp_iu_387"
1567 [(set (reg:CCFPU FLAGS_REG)
1568 (compare:CCFPU (match_operand 0 "register_operand" "f")
1569 (match_operand 1 "register_operand" "f")))]
1570 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1572 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1573 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1574 "* return output_fp_compare (insn, operands, 1, 1);"
1575 [(set_attr "type" "fcmp")
1577 (cond [(match_operand:SF 1 "" "")
1579 (match_operand:DF 1 "" "")
1582 (const_string "XF")))
1583 (set_attr "athlon_decode" "vector")
1584 (set_attr "amdfam10_decode" "direct")])
1586 ;; Move instructions.
1588 ;; General case of fullword move.
1590 (define_expand "movsi"
1591 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1592 (match_operand:SI 1 "general_operand" ""))]
1594 "ix86_expand_move (SImode, operands); DONE;")
1596 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1599 ;; %%% We don't use a post-inc memory reference because x86 is not a
1600 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1601 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1602 ;; targets without our curiosities, and it is just as easy to represent
1603 ;; this differently.
1605 (define_insn "*pushsi2"
1606 [(set (match_operand:SI 0 "push_operand" "=<")
1607 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1610 [(set_attr "type" "push")
1611 (set_attr "mode" "SI")])
1613 ;; For 64BIT abi we always round up to 8 bytes.
1614 (define_insn "*pushsi2_rex64"
1615 [(set (match_operand:SI 0 "push_operand" "=X")
1616 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1619 [(set_attr "type" "push")
1620 (set_attr "mode" "SI")])
1622 (define_insn "*pushsi2_prologue"
1623 [(set (match_operand:SI 0 "push_operand" "=<")
1624 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1625 (clobber (mem:BLK (scratch)))]
1628 [(set_attr "type" "push")
1629 (set_attr "mode" "SI")])
1631 (define_insn "*popsi1_epilogue"
1632 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1633 (mem:SI (reg:SI SP_REG)))
1634 (set (reg:SI SP_REG)
1635 (plus:SI (reg:SI SP_REG) (const_int 4)))
1636 (clobber (mem:BLK (scratch)))]
1639 [(set_attr "type" "pop")
1640 (set_attr "mode" "SI")])
1642 (define_insn "popsi1"
1643 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1644 (mem:SI (reg:SI SP_REG)))
1645 (set (reg:SI SP_REG)
1646 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1649 [(set_attr "type" "pop")
1650 (set_attr "mode" "SI")])
1652 (define_insn "*movsi_xor"
1653 [(set (match_operand:SI 0 "register_operand" "=r")
1654 (match_operand:SI 1 "const0_operand" ""))
1655 (clobber (reg:CC FLAGS_REG))]
1658 [(set_attr "type" "alu1")
1659 (set_attr "mode" "SI")
1660 (set_attr "length_immediate" "0")])
1662 (define_insn "*movsi_or"
1663 [(set (match_operand:SI 0 "register_operand" "=r")
1664 (match_operand:SI 1 "immediate_operand" "i"))
1665 (clobber (reg:CC FLAGS_REG))]
1667 && operands[1] == constm1_rtx"
1669 operands[1] = constm1_rtx;
1670 return "or{l}\t{%1, %0|%0, %1}";
1672 [(set_attr "type" "alu1")
1673 (set_attr "mode" "SI")
1674 (set_attr "length_immediate" "1")])
1676 (define_insn "*movsi_1"
1677 [(set (match_operand:SI 0 "nonimmediate_operand"
1678 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1679 (match_operand:SI 1 "general_operand"
1680 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1681 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1683 switch (get_attr_type (insn))
1686 if (get_attr_mode (insn) == MODE_TI)
1687 return "%vpxor\t%0, %d0";
1688 return "%vxorps\t%0, %d0";
1691 switch (get_attr_mode (insn))
1694 return "%vmovdqa\t{%1, %0|%0, %1}";
1696 return "%vmovaps\t{%1, %0|%0, %1}";
1698 return "%vmovd\t{%1, %0|%0, %1}";
1700 return "%vmovss\t{%1, %0|%0, %1}";
1706 return "pxor\t%0, %0";
1709 if (get_attr_mode (insn) == MODE_DI)
1710 return "movq\t{%1, %0|%0, %1}";
1711 return "movd\t{%1, %0|%0, %1}";
1714 return "lea{l}\t{%a1, %0|%0, %a1}";
1717 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1718 return "mov{l}\t{%1, %0|%0, %1}";
1722 (cond [(eq_attr "alternative" "2")
1723 (const_string "mmx")
1724 (eq_attr "alternative" "3,4,5")
1725 (const_string "mmxmov")
1726 (eq_attr "alternative" "6")
1727 (const_string "sselog1")
1728 (eq_attr "alternative" "7,8,9,10,11")
1729 (const_string "ssemov")
1730 (match_operand:DI 1 "pic_32bit_operand" "")
1731 (const_string "lea")
1733 (const_string "imov")))
1734 (set (attr "prefix")
1735 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1736 (const_string "orig")
1737 (const_string "maybe_vex")))
1738 (set (attr "prefix_data16")
1739 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1741 (const_string "*")))
1743 (cond [(eq_attr "alternative" "2,3")
1745 (eq_attr "alternative" "6,7")
1747 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1748 (const_string "V4SF")
1749 (const_string "TI"))
1750 (and (eq_attr "alternative" "8,9,10,11")
1751 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1754 (const_string "SI")))])
1756 ;; Stores and loads of ax to arbitrary constant address.
1757 ;; We fake an second form of instruction to force reload to load address
1758 ;; into register when rax is not available
1759 (define_insn "*movabssi_1_rex64"
1760 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1761 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1762 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1764 movabs{l}\t{%1, %P0|%P0, %1}
1765 mov{l}\t{%1, %a0|%a0, %1}"
1766 [(set_attr "type" "imov")
1767 (set_attr "modrm" "0,*")
1768 (set_attr "length_address" "8,0")
1769 (set_attr "length_immediate" "0,*")
1770 (set_attr "memory" "store")
1771 (set_attr "mode" "SI")])
1773 (define_insn "*movabssi_2_rex64"
1774 [(set (match_operand:SI 0 "register_operand" "=a,r")
1775 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1776 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1778 movabs{l}\t{%P1, %0|%0, %P1}
1779 mov{l}\t{%a1, %0|%0, %a1}"
1780 [(set_attr "type" "imov")
1781 (set_attr "modrm" "0,*")
1782 (set_attr "length_address" "8,0")
1783 (set_attr "length_immediate" "0")
1784 (set_attr "memory" "load")
1785 (set_attr "mode" "SI")])
1787 (define_insn "*swapsi"
1788 [(set (match_operand:SI 0 "register_operand" "+r")
1789 (match_operand:SI 1 "register_operand" "+r"))
1794 [(set_attr "type" "imov")
1795 (set_attr "mode" "SI")
1796 (set_attr "pent_pair" "np")
1797 (set_attr "athlon_decode" "vector")
1798 (set_attr "amdfam10_decode" "double")])
1800 (define_expand "movhi"
1801 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1802 (match_operand:HI 1 "general_operand" ""))]
1804 "ix86_expand_move (HImode, operands); DONE;")
1806 (define_insn "*pushhi2"
1807 [(set (match_operand:HI 0 "push_operand" "=X")
1808 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1811 [(set_attr "type" "push")
1812 (set_attr "mode" "SI")])
1814 ;; For 64BIT abi we always round up to 8 bytes.
1815 (define_insn "*pushhi2_rex64"
1816 [(set (match_operand:HI 0 "push_operand" "=X")
1817 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1820 [(set_attr "type" "push")
1821 (set_attr "mode" "DI")])
1823 (define_insn "*movhi_1"
1824 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1825 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1826 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1828 switch (get_attr_type (insn))
1831 /* movzwl is faster than movw on p2 due to partial word stalls,
1832 though not as fast as an aligned movl. */
1833 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1835 if (get_attr_mode (insn) == MODE_SI)
1836 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1838 return "mov{w}\t{%1, %0|%0, %1}";
1842 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1843 (const_string "imov")
1844 (and (eq_attr "alternative" "0")
1845 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1847 (eq (symbol_ref "TARGET_HIMODE_MATH")
1849 (const_string "imov")
1850 (and (eq_attr "alternative" "1,2")
1851 (match_operand:HI 1 "aligned_operand" ""))
1852 (const_string "imov")
1853 (and (ne (symbol_ref "TARGET_MOVX")
1855 (eq_attr "alternative" "0,2"))
1856 (const_string "imovx")
1858 (const_string "imov")))
1860 (cond [(eq_attr "type" "imovx")
1862 (and (eq_attr "alternative" "1,2")
1863 (match_operand:HI 1 "aligned_operand" ""))
1865 (and (eq_attr "alternative" "0")
1866 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1868 (eq (symbol_ref "TARGET_HIMODE_MATH")
1872 (const_string "HI")))])
1874 ;; Stores and loads of ax to arbitrary constant address.
1875 ;; We fake an second form of instruction to force reload to load address
1876 ;; into register when rax is not available
1877 (define_insn "*movabshi_1_rex64"
1878 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1879 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1880 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1882 movabs{w}\t{%1, %P0|%P0, %1}
1883 mov{w}\t{%1, %a0|%a0, %1}"
1884 [(set_attr "type" "imov")
1885 (set_attr "modrm" "0,*")
1886 (set_attr "length_address" "8,0")
1887 (set_attr "length_immediate" "0,*")
1888 (set_attr "memory" "store")
1889 (set_attr "mode" "HI")])
1891 (define_insn "*movabshi_2_rex64"
1892 [(set (match_operand:HI 0 "register_operand" "=a,r")
1893 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1894 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1896 movabs{w}\t{%P1, %0|%0, %P1}
1897 mov{w}\t{%a1, %0|%0, %a1}"
1898 [(set_attr "type" "imov")
1899 (set_attr "modrm" "0,*")
1900 (set_attr "length_address" "8,0")
1901 (set_attr "length_immediate" "0")
1902 (set_attr "memory" "load")
1903 (set_attr "mode" "HI")])
1905 (define_insn "*swaphi_1"
1906 [(set (match_operand:HI 0 "register_operand" "+r")
1907 (match_operand:HI 1 "register_operand" "+r"))
1910 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1912 [(set_attr "type" "imov")
1913 (set_attr "mode" "SI")
1914 (set_attr "pent_pair" "np")
1915 (set_attr "athlon_decode" "vector")
1916 (set_attr "amdfam10_decode" "double")])
1918 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1919 (define_insn "*swaphi_2"
1920 [(set (match_operand:HI 0 "register_operand" "+r")
1921 (match_operand:HI 1 "register_operand" "+r"))
1924 "TARGET_PARTIAL_REG_STALL"
1926 [(set_attr "type" "imov")
1927 (set_attr "mode" "HI")
1928 (set_attr "pent_pair" "np")
1929 (set_attr "athlon_decode" "vector")])
1931 (define_expand "movstricthi"
1932 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1933 (match_operand:HI 1 "general_operand" ""))]
1936 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1938 /* Don't generate memory->memory moves, go through a register */
1939 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1940 operands[1] = force_reg (HImode, operands[1]);
1943 (define_insn "*movstricthi_1"
1944 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1945 (match_operand:HI 1 "general_operand" "rn,m"))]
1946 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1947 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1948 "mov{w}\t{%1, %0|%0, %1}"
1949 [(set_attr "type" "imov")
1950 (set_attr "mode" "HI")])
1952 (define_insn "*movstricthi_xor"
1953 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1954 (match_operand:HI 1 "const0_operand" ""))
1955 (clobber (reg:CC FLAGS_REG))]
1958 [(set_attr "type" "alu1")
1959 (set_attr "mode" "HI")
1960 (set_attr "length_immediate" "0")])
1962 (define_expand "movqi"
1963 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1964 (match_operand:QI 1 "general_operand" ""))]
1966 "ix86_expand_move (QImode, operands); DONE;")
1968 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1969 ;; "push a byte". But actually we use pushl, which has the effect
1970 ;; of rounding the amount pushed up to a word.
1972 (define_insn "*pushqi2"
1973 [(set (match_operand:QI 0 "push_operand" "=X")
1974 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1977 [(set_attr "type" "push")
1978 (set_attr "mode" "SI")])
1980 ;; For 64BIT abi we always round up to 8 bytes.
1981 (define_insn "*pushqi2_rex64"
1982 [(set (match_operand:QI 0 "push_operand" "=X")
1983 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1986 [(set_attr "type" "push")
1987 (set_attr "mode" "DI")])
1989 ;; Situation is quite tricky about when to choose full sized (SImode) move
1990 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1991 ;; partial register dependency machines (such as AMD Athlon), where QImode
1992 ;; moves issue extra dependency and for partial register stalls machines
1993 ;; that don't use QImode patterns (and QImode move cause stall on the next
1996 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1997 ;; register stall machines with, where we use QImode instructions, since
1998 ;; partial register stall can be caused there. Then we use movzx.
1999 (define_insn "*movqi_1"
2000 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2001 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2002 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2004 switch (get_attr_type (insn))
2007 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2008 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2010 if (get_attr_mode (insn) == MODE_SI)
2011 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2013 return "mov{b}\t{%1, %0|%0, %1}";
2017 (cond [(and (eq_attr "alternative" "5")
2018 (not (match_operand:QI 1 "aligned_operand" "")))
2019 (const_string "imovx")
2020 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2021 (const_string "imov")
2022 (and (eq_attr "alternative" "3")
2023 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2025 (eq (symbol_ref "TARGET_QIMODE_MATH")
2027 (const_string "imov")
2028 (eq_attr "alternative" "3,5")
2029 (const_string "imovx")
2030 (and (ne (symbol_ref "TARGET_MOVX")
2032 (eq_attr "alternative" "2"))
2033 (const_string "imovx")
2035 (const_string "imov")))
2037 (cond [(eq_attr "alternative" "3,4,5")
2039 (eq_attr "alternative" "6")
2041 (eq_attr "type" "imovx")
2043 (and (eq_attr "type" "imov")
2044 (and (eq_attr "alternative" "0,1")
2045 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2047 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2049 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2052 ;; Avoid partial register stalls when not using QImode arithmetic
2053 (and (eq_attr "type" "imov")
2054 (and (eq_attr "alternative" "0,1")
2055 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2057 (eq (symbol_ref "TARGET_QIMODE_MATH")
2061 (const_string "QI")))])
2063 (define_insn "*swapqi_1"
2064 [(set (match_operand:QI 0 "register_operand" "+r")
2065 (match_operand:QI 1 "register_operand" "+r"))
2068 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2070 [(set_attr "type" "imov")
2071 (set_attr "mode" "SI")
2072 (set_attr "pent_pair" "np")
2073 (set_attr "athlon_decode" "vector")
2074 (set_attr "amdfam10_decode" "vector")])
2076 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2077 (define_insn "*swapqi_2"
2078 [(set (match_operand:QI 0 "register_operand" "+q")
2079 (match_operand:QI 1 "register_operand" "+q"))
2082 "TARGET_PARTIAL_REG_STALL"
2084 [(set_attr "type" "imov")
2085 (set_attr "mode" "QI")
2086 (set_attr "pent_pair" "np")
2087 (set_attr "athlon_decode" "vector")])
2089 (define_expand "movstrictqi"
2090 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2091 (match_operand:QI 1 "general_operand" ""))]
2094 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2096 /* Don't generate memory->memory moves, go through a register. */
2097 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2098 operands[1] = force_reg (QImode, operands[1]);
2101 (define_insn "*movstrictqi_1"
2102 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2103 (match_operand:QI 1 "general_operand" "*qn,m"))]
2104 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2105 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2106 "mov{b}\t{%1, %0|%0, %1}"
2107 [(set_attr "type" "imov")
2108 (set_attr "mode" "QI")])
2110 (define_insn "*movstrictqi_xor"
2111 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2112 (match_operand:QI 1 "const0_operand" ""))
2113 (clobber (reg:CC FLAGS_REG))]
2116 [(set_attr "type" "alu1")
2117 (set_attr "mode" "QI")
2118 (set_attr "length_immediate" "0")])
2120 (define_insn "*movsi_extv_1"
2121 [(set (match_operand:SI 0 "register_operand" "=R")
2122 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2126 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2127 [(set_attr "type" "imovx")
2128 (set_attr "mode" "SI")])
2130 (define_insn "*movhi_extv_1"
2131 [(set (match_operand:HI 0 "register_operand" "=R")
2132 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2136 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2137 [(set_attr "type" "imovx")
2138 (set_attr "mode" "SI")])
2140 (define_insn "*movqi_extv_1"
2141 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2142 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2147 switch (get_attr_type (insn))
2150 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2152 return "mov{b}\t{%h1, %0|%0, %h1}";
2156 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2157 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2158 (ne (symbol_ref "TARGET_MOVX")
2160 (const_string "imovx")
2161 (const_string "imov")))
2163 (if_then_else (eq_attr "type" "imovx")
2165 (const_string "QI")))])
2167 (define_insn "*movqi_extv_1_rex64"
2168 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2169 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2174 switch (get_attr_type (insn))
2177 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2179 return "mov{b}\t{%h1, %0|%0, %h1}";
2183 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2184 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2185 (ne (symbol_ref "TARGET_MOVX")
2187 (const_string "imovx")
2188 (const_string "imov")))
2190 (if_then_else (eq_attr "type" "imovx")
2192 (const_string "QI")))])
2194 ;; Stores and loads of ax to arbitrary constant address.
2195 ;; We fake an second form of instruction to force reload to load address
2196 ;; into register when rax is not available
2197 (define_insn "*movabsqi_1_rex64"
2198 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2199 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2200 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2202 movabs{b}\t{%1, %P0|%P0, %1}
2203 mov{b}\t{%1, %a0|%a0, %1}"
2204 [(set_attr "type" "imov")
2205 (set_attr "modrm" "0,*")
2206 (set_attr "length_address" "8,0")
2207 (set_attr "length_immediate" "0,*")
2208 (set_attr "memory" "store")
2209 (set_attr "mode" "QI")])
2211 (define_insn "*movabsqi_2_rex64"
2212 [(set (match_operand:QI 0 "register_operand" "=a,r")
2213 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2214 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2216 movabs{b}\t{%P1, %0|%0, %P1}
2217 mov{b}\t{%a1, %0|%0, %a1}"
2218 [(set_attr "type" "imov")
2219 (set_attr "modrm" "0,*")
2220 (set_attr "length_address" "8,0")
2221 (set_attr "length_immediate" "0")
2222 (set_attr "memory" "load")
2223 (set_attr "mode" "QI")])
2225 (define_insn "*movdi_extzv_1"
2226 [(set (match_operand:DI 0 "register_operand" "=R")
2227 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2231 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2232 [(set_attr "type" "imovx")
2233 (set_attr "mode" "SI")])
2235 (define_insn "*movsi_extzv_1"
2236 [(set (match_operand:SI 0 "register_operand" "=R")
2237 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2241 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2242 [(set_attr "type" "imovx")
2243 (set_attr "mode" "SI")])
2245 (define_insn "*movqi_extzv_2"
2246 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2247 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2252 switch (get_attr_type (insn))
2255 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2257 return "mov{b}\t{%h1, %0|%0, %h1}";
2261 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2262 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2263 (ne (symbol_ref "TARGET_MOVX")
2265 (const_string "imovx")
2266 (const_string "imov")))
2268 (if_then_else (eq_attr "type" "imovx")
2270 (const_string "QI")))])
2272 (define_insn "*movqi_extzv_2_rex64"
2273 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2274 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2279 switch (get_attr_type (insn))
2282 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2284 return "mov{b}\t{%h1, %0|%0, %h1}";
2288 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2289 (ne (symbol_ref "TARGET_MOVX")
2291 (const_string "imovx")
2292 (const_string "imov")))
2294 (if_then_else (eq_attr "type" "imovx")
2296 (const_string "QI")))])
2298 (define_insn "movsi_insv_1"
2299 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2302 (match_operand:SI 1 "general_operand" "Qmn"))]
2304 "mov{b}\t{%b1, %h0|%h0, %b1}"
2305 [(set_attr "type" "imov")
2306 (set_attr "mode" "QI")])
2308 (define_insn "*movsi_insv_1_rex64"
2309 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2312 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2314 "mov{b}\t{%b1, %h0|%h0, %b1}"
2315 [(set_attr "type" "imov")
2316 (set_attr "mode" "QI")])
2318 (define_insn "movdi_insv_1_rex64"
2319 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2322 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2324 "mov{b}\t{%b1, %h0|%h0, %b1}"
2325 [(set_attr "type" "imov")
2326 (set_attr "mode" "QI")])
2328 (define_insn "*movqi_insv_2"
2329 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2332 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2335 "mov{b}\t{%h1, %h0|%h0, %h1}"
2336 [(set_attr "type" "imov")
2337 (set_attr "mode" "QI")])
2339 (define_expand "movdi"
2340 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2341 (match_operand:DI 1 "general_operand" ""))]
2343 "ix86_expand_move (DImode, operands); DONE;")
2345 (define_insn "*pushdi"
2346 [(set (match_operand:DI 0 "push_operand" "=<")
2347 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2351 (define_insn "*pushdi2_rex64"
2352 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2353 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2358 [(set_attr "type" "push,multi")
2359 (set_attr "mode" "DI")])
2361 ;; Convert impossible pushes of immediate to existing instructions.
2362 ;; First try to get scratch register and go through it. In case this
2363 ;; fails, push sign extended lower part first and then overwrite
2364 ;; upper part by 32bit move.
2366 [(match_scratch:DI 2 "r")
2367 (set (match_operand:DI 0 "push_operand" "")
2368 (match_operand:DI 1 "immediate_operand" ""))]
2369 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2370 && !x86_64_immediate_operand (operands[1], DImode)"
2371 [(set (match_dup 2) (match_dup 1))
2372 (set (match_dup 0) (match_dup 2))]
2375 ;; We need to define this as both peepholer and splitter for case
2376 ;; peephole2 pass is not run.
2377 ;; "&& 1" is needed to keep it from matching the previous pattern.
2379 [(set (match_operand:DI 0 "push_operand" "")
2380 (match_operand:DI 1 "immediate_operand" ""))]
2381 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2382 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2383 [(set (match_dup 0) (match_dup 1))
2384 (set (match_dup 2) (match_dup 3))]
2386 split_di (&operands[1], 1, &operands[2], &operands[3]);
2388 operands[1] = gen_lowpart (DImode, operands[2]);
2389 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2394 [(set (match_operand:DI 0 "push_operand" "")
2395 (match_operand:DI 1 "immediate_operand" ""))]
2396 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2397 ? epilogue_completed : reload_completed)
2398 && !symbolic_operand (operands[1], DImode)
2399 && !x86_64_immediate_operand (operands[1], DImode)"
2400 [(set (match_dup 0) (match_dup 1))
2401 (set (match_dup 2) (match_dup 3))]
2403 split_di (&operands[1], 1, &operands[2], &operands[3]);
2405 operands[1] = gen_lowpart (DImode, operands[2]);
2406 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2410 (define_insn "*pushdi2_prologue_rex64"
2411 [(set (match_operand:DI 0 "push_operand" "=<")
2412 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2413 (clobber (mem:BLK (scratch)))]
2416 [(set_attr "type" "push")
2417 (set_attr "mode" "DI")])
2419 (define_insn "*popdi1_epilogue_rex64"
2420 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2421 (mem:DI (reg:DI SP_REG)))
2422 (set (reg:DI SP_REG)
2423 (plus:DI (reg:DI SP_REG) (const_int 8)))
2424 (clobber (mem:BLK (scratch)))]
2427 [(set_attr "type" "pop")
2428 (set_attr "mode" "DI")])
2430 (define_insn "popdi1"
2431 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2432 (mem:DI (reg:DI SP_REG)))
2433 (set (reg:DI SP_REG)
2434 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2437 [(set_attr "type" "pop")
2438 (set_attr "mode" "DI")])
2440 (define_insn "*movdi_xor_rex64"
2441 [(set (match_operand:DI 0 "register_operand" "=r")
2442 (match_operand:DI 1 "const0_operand" ""))
2443 (clobber (reg:CC FLAGS_REG))]
2445 && reload_completed"
2447 [(set_attr "type" "alu1")
2448 (set_attr "mode" "SI")
2449 (set_attr "length_immediate" "0")])
2451 (define_insn "*movdi_or_rex64"
2452 [(set (match_operand:DI 0 "register_operand" "=r")
2453 (match_operand:DI 1 "const_int_operand" "i"))
2454 (clobber (reg:CC FLAGS_REG))]
2457 && operands[1] == constm1_rtx"
2459 operands[1] = constm1_rtx;
2460 return "or{q}\t{%1, %0|%0, %1}";
2462 [(set_attr "type" "alu1")
2463 (set_attr "mode" "DI")
2464 (set_attr "length_immediate" "1")])
2466 (define_insn "*movdi_2"
2467 [(set (match_operand:DI 0 "nonimmediate_operand"
2468 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2469 (match_operand:DI 1 "general_operand"
2470 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2471 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2476 movq\t{%1, %0|%0, %1}
2477 movq\t{%1, %0|%0, %1}
2479 %vmovq\t{%1, %0|%0, %1}
2480 %vmovdqa\t{%1, %0|%0, %1}
2481 %vmovq\t{%1, %0|%0, %1}
2483 movlps\t{%1, %0|%0, %1}
2484 movaps\t{%1, %0|%0, %1}
2485 movlps\t{%1, %0|%0, %1}"
2486 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2487 (set (attr "prefix")
2488 (if_then_else (eq_attr "alternative" "5,6,7,8")
2489 (const_string "vex")
2490 (const_string "orig")))
2491 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2494 [(set (match_operand:DI 0 "push_operand" "")
2495 (match_operand:DI 1 "general_operand" ""))]
2496 "!TARGET_64BIT && reload_completed
2497 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2499 "ix86_split_long_move (operands); DONE;")
2501 ;; %%% This multiword shite has got to go.
2503 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2504 (match_operand:DI 1 "general_operand" ""))]
2505 "!TARGET_64BIT && reload_completed
2506 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2507 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2509 "ix86_split_long_move (operands); DONE;")
2511 (define_insn "*movdi_1_rex64"
2512 [(set (match_operand:DI 0 "nonimmediate_operand"
2513 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2514 (match_operand:DI 1 "general_operand"
2515 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2516 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2518 switch (get_attr_type (insn))
2521 if (SSE_REG_P (operands[0]))
2522 return "movq2dq\t{%1, %0|%0, %1}";
2524 return "movdq2q\t{%1, %0|%0, %1}";
2529 if (get_attr_mode (insn) == MODE_TI)
2530 return "vmovdqa\t{%1, %0|%0, %1}";
2532 return "vmovq\t{%1, %0|%0, %1}";
2535 if (get_attr_mode (insn) == MODE_TI)
2536 return "movdqa\t{%1, %0|%0, %1}";
2540 /* Moves from and into integer register is done using movd
2541 opcode with REX prefix. */
2542 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2543 return "movd\t{%1, %0|%0, %1}";
2544 return "movq\t{%1, %0|%0, %1}";
2547 return "%vpxor\t%0, %d0";
2550 return "pxor\t%0, %0";
2556 return "lea{q}\t{%a1, %0|%0, %a1}";
2559 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2560 if (get_attr_mode (insn) == MODE_SI)
2561 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2562 else if (which_alternative == 2)
2563 return "movabs{q}\t{%1, %0|%0, %1}";
2565 return "mov{q}\t{%1, %0|%0, %1}";
2569 (cond [(eq_attr "alternative" "5")
2570 (const_string "mmx")
2571 (eq_attr "alternative" "6,7,8,9,10")
2572 (const_string "mmxmov")
2573 (eq_attr "alternative" "11")
2574 (const_string "sselog1")
2575 (eq_attr "alternative" "12,13,14,15,16")
2576 (const_string "ssemov")
2577 (eq_attr "alternative" "17,18")
2578 (const_string "ssecvt")
2579 (eq_attr "alternative" "4")
2580 (const_string "multi")
2581 (match_operand:DI 1 "pic_32bit_operand" "")
2582 (const_string "lea")
2584 (const_string "imov")))
2587 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2589 (const_string "*")))
2590 (set (attr "length_immediate")
2592 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2594 (const_string "*")))
2595 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2596 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2597 (set (attr "prefix")
2598 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2599 (const_string "maybe_vex")
2600 (const_string "orig")))
2601 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2603 ;; Stores and loads of ax to arbitrary constant address.
2604 ;; We fake an second form of instruction to force reload to load address
2605 ;; into register when rax is not available
2606 (define_insn "*movabsdi_1_rex64"
2607 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2608 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2609 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2611 movabs{q}\t{%1, %P0|%P0, %1}
2612 mov{q}\t{%1, %a0|%a0, %1}"
2613 [(set_attr "type" "imov")
2614 (set_attr "modrm" "0,*")
2615 (set_attr "length_address" "8,0")
2616 (set_attr "length_immediate" "0,*")
2617 (set_attr "memory" "store")
2618 (set_attr "mode" "DI")])
2620 (define_insn "*movabsdi_2_rex64"
2621 [(set (match_operand:DI 0 "register_operand" "=a,r")
2622 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2623 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2625 movabs{q}\t{%P1, %0|%0, %P1}
2626 mov{q}\t{%a1, %0|%0, %a1}"
2627 [(set_attr "type" "imov")
2628 (set_attr "modrm" "0,*")
2629 (set_attr "length_address" "8,0")
2630 (set_attr "length_immediate" "0")
2631 (set_attr "memory" "load")
2632 (set_attr "mode" "DI")])
2634 ;; Convert impossible stores of immediate to existing instructions.
2635 ;; First try to get scratch register and go through it. In case this
2636 ;; fails, move by 32bit parts.
2638 [(match_scratch:DI 2 "r")
2639 (set (match_operand:DI 0 "memory_operand" "")
2640 (match_operand:DI 1 "immediate_operand" ""))]
2641 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2642 && !x86_64_immediate_operand (operands[1], DImode)"
2643 [(set (match_dup 2) (match_dup 1))
2644 (set (match_dup 0) (match_dup 2))]
2647 ;; We need to define this as both peepholer and splitter for case
2648 ;; peephole2 pass is not run.
2649 ;; "&& 1" is needed to keep it from matching the previous pattern.
2651 [(set (match_operand:DI 0 "memory_operand" "")
2652 (match_operand:DI 1 "immediate_operand" ""))]
2653 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2654 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2655 [(set (match_dup 2) (match_dup 3))
2656 (set (match_dup 4) (match_dup 5))]
2657 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2660 [(set (match_operand:DI 0 "memory_operand" "")
2661 (match_operand:DI 1 "immediate_operand" ""))]
2662 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2663 ? epilogue_completed : reload_completed)
2664 && !symbolic_operand (operands[1], DImode)
2665 && !x86_64_immediate_operand (operands[1], DImode)"
2666 [(set (match_dup 2) (match_dup 3))
2667 (set (match_dup 4) (match_dup 5))]
2668 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2670 (define_insn "*swapdi_rex64"
2671 [(set (match_operand:DI 0 "register_operand" "+r")
2672 (match_operand:DI 1 "register_operand" "+r"))
2677 [(set_attr "type" "imov")
2678 (set_attr "mode" "DI")
2679 (set_attr "pent_pair" "np")
2680 (set_attr "athlon_decode" "vector")
2681 (set_attr "amdfam10_decode" "double")])
2683 (define_expand "movoi"
2684 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2685 (match_operand:OI 1 "general_operand" ""))]
2687 "ix86_expand_move (OImode, operands); DONE;")
2689 (define_insn "*movoi_internal"
2690 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2691 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2693 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2695 switch (which_alternative)
2698 return "vxorps\t%0, %0, %0";
2701 if (misaligned_operand (operands[0], OImode)
2702 || misaligned_operand (operands[1], OImode))
2703 return "vmovdqu\t{%1, %0|%0, %1}";
2705 return "vmovdqa\t{%1, %0|%0, %1}";
2710 [(set_attr "type" "sselog1,ssemov,ssemov")
2711 (set_attr "prefix" "vex")
2712 (set_attr "mode" "OI")])
2714 (define_expand "movti"
2715 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2716 (match_operand:TI 1 "nonimmediate_operand" ""))]
2717 "TARGET_SSE || TARGET_64BIT"
2720 ix86_expand_move (TImode, operands);
2721 else if (push_operand (operands[0], TImode))
2722 ix86_expand_push (TImode, operands[1]);
2724 ix86_expand_vector_move (TImode, operands);
2728 (define_insn "*movti_internal"
2729 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2730 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2731 "TARGET_SSE && !TARGET_64BIT
2732 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2734 switch (which_alternative)
2737 if (get_attr_mode (insn) == MODE_V4SF)
2738 return "%vxorps\t%0, %d0";
2740 return "%vpxor\t%0, %d0";
2743 /* TDmode values are passed as TImode on the stack. Moving them
2744 to stack may result in unaligned memory access. */
2745 if (misaligned_operand (operands[0], TImode)
2746 || misaligned_operand (operands[1], TImode))
2748 if (get_attr_mode (insn) == MODE_V4SF)
2749 return "%vmovups\t{%1, %0|%0, %1}";
2751 return "%vmovdqu\t{%1, %0|%0, %1}";
2755 if (get_attr_mode (insn) == MODE_V4SF)
2756 return "%vmovaps\t{%1, %0|%0, %1}";
2758 return "%vmovdqa\t{%1, %0|%0, %1}";
2764 [(set_attr "type" "sselog1,ssemov,ssemov")
2765 (set_attr "prefix" "maybe_vex")
2767 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2768 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2769 (const_string "V4SF")
2770 (and (eq_attr "alternative" "2")
2771 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2773 (const_string "V4SF")]
2774 (const_string "TI")))])
2776 (define_insn "*movti_rex64"
2777 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2778 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2780 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2782 switch (which_alternative)
2788 if (get_attr_mode (insn) == MODE_V4SF)
2789 return "%vxorps\t%0, %d0";
2791 return "%vpxor\t%0, %d0";
2794 /* TDmode values are passed as TImode on the stack. Moving them
2795 to stack may result in unaligned memory access. */
2796 if (misaligned_operand (operands[0], TImode)
2797 || misaligned_operand (operands[1], TImode))
2799 if (get_attr_mode (insn) == MODE_V4SF)
2800 return "%vmovups\t{%1, %0|%0, %1}";
2802 return "%vmovdqu\t{%1, %0|%0, %1}";
2806 if (get_attr_mode (insn) == MODE_V4SF)
2807 return "%vmovaps\t{%1, %0|%0, %1}";
2809 return "%vmovdqa\t{%1, %0|%0, %1}";
2815 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2816 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2818 (cond [(eq_attr "alternative" "2,3")
2820 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2822 (const_string "V4SF")
2823 (const_string "TI"))
2824 (eq_attr "alternative" "4")
2826 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2828 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2830 (const_string "V4SF")
2831 (const_string "TI"))]
2832 (const_string "DI")))])
2835 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2836 (match_operand:TI 1 "general_operand" ""))]
2837 "reload_completed && !SSE_REG_P (operands[0])
2838 && !SSE_REG_P (operands[1])"
2840 "ix86_split_long_move (operands); DONE;")
2842 ;; This expands to what emit_move_complex would generate if we didn't
2843 ;; have a movti pattern. Having this avoids problems with reload on
2844 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2845 ;; to have around all the time.
2846 (define_expand "movcdi"
2847 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2848 (match_operand:CDI 1 "general_operand" ""))]
2851 if (push_operand (operands[0], CDImode))
2852 emit_move_complex_push (CDImode, operands[0], operands[1]);
2854 emit_move_complex_parts (operands[0], operands[1]);
2858 (define_expand "movsf"
2859 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2860 (match_operand:SF 1 "general_operand" ""))]
2862 "ix86_expand_move (SFmode, operands); DONE;")
2864 (define_insn "*pushsf"
2865 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2866 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2869 /* Anything else should be already split before reg-stack. */
2870 gcc_assert (which_alternative == 1);
2871 return "push{l}\t%1";
2873 [(set_attr "type" "multi,push,multi")
2874 (set_attr "unit" "i387,*,*")
2875 (set_attr "mode" "SF,SI,SF")])
2877 (define_insn "*pushsf_rex64"
2878 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2879 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2882 /* Anything else should be already split before reg-stack. */
2883 gcc_assert (which_alternative == 1);
2884 return "push{q}\t%q1";
2886 [(set_attr "type" "multi,push,multi")
2887 (set_attr "unit" "i387,*,*")
2888 (set_attr "mode" "SF,DI,SF")])
2891 [(set (match_operand:SF 0 "push_operand" "")
2892 (match_operand:SF 1 "memory_operand" ""))]
2894 && MEM_P (operands[1])
2895 && (operands[2] = find_constant_src (insn))"
2899 ;; %%% Kill this when call knows how to work this out.
2901 [(set (match_operand:SF 0 "push_operand" "")
2902 (match_operand:SF 1 "any_fp_register_operand" ""))]
2904 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2905 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2908 [(set (match_operand:SF 0 "push_operand" "")
2909 (match_operand:SF 1 "any_fp_register_operand" ""))]
2911 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2912 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2914 (define_insn "*movsf_1"
2915 [(set (match_operand:SF 0 "nonimmediate_operand"
2916 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2917 (match_operand:SF 1 "general_operand"
2918 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2919 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2920 && (reload_in_progress || reload_completed
2921 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2922 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2923 && standard_80387_constant_p (operands[1]))
2924 || GET_CODE (operands[1]) != CONST_DOUBLE
2925 || memory_operand (operands[0], SFmode))"
2927 switch (which_alternative)
2931 return output_387_reg_move (insn, operands);
2934 return standard_80387_constant_opcode (operands[1]);
2938 return "mov{l}\t{%1, %0|%0, %1}";
2940 if (get_attr_mode (insn) == MODE_TI)
2941 return "%vpxor\t%0, %d0";
2943 return "%vxorps\t%0, %d0";
2945 if (get_attr_mode (insn) == MODE_V4SF)
2946 return "%vmovaps\t{%1, %0|%0, %1}";
2948 return "%vmovss\t{%1, %d0|%d0, %1}";
2951 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2952 : "vmovss\t{%1, %0|%0, %1}";
2954 return "movss\t{%1, %0|%0, %1}";
2956 return "%vmovss\t{%1, %0|%0, %1}";
2958 case 9: case 10: case 14: case 15:
2959 return "movd\t{%1, %0|%0, %1}";
2961 return "%vmovd\t{%1, %0|%0, %1}";
2964 return "movq\t{%1, %0|%0, %1}";
2970 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2971 (set (attr "prefix")
2972 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2973 (const_string "maybe_vex")
2974 (const_string "orig")))
2976 (cond [(eq_attr "alternative" "3,4,9,10")
2978 (eq_attr "alternative" "5")
2980 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2982 (ne (symbol_ref "TARGET_SSE2")
2984 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2987 (const_string "V4SF"))
2988 /* For architectures resolving dependencies on
2989 whole SSE registers use APS move to break dependency
2990 chains, otherwise use short move to avoid extra work.
2992 Do the same for architectures resolving dependencies on
2993 the parts. While in DF mode it is better to always handle
2994 just register parts, the SF mode is different due to lack
2995 of instructions to load just part of the register. It is
2996 better to maintain the whole registers in single format
2997 to avoid problems on using packed logical operations. */
2998 (eq_attr "alternative" "6")
3000 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3002 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3004 (const_string "V4SF")
3005 (const_string "SF"))
3006 (eq_attr "alternative" "11")
3007 (const_string "DI")]
3008 (const_string "SF")))])
3010 (define_insn "*swapsf"
3011 [(set (match_operand:SF 0 "fp_register_operand" "+f")
3012 (match_operand:SF 1 "fp_register_operand" "+f"))
3015 "reload_completed || TARGET_80387"
3017 if (STACK_TOP_P (operands[0]))
3022 [(set_attr "type" "fxch")
3023 (set_attr "mode" "SF")])
3025 (define_expand "movdf"
3026 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3027 (match_operand:DF 1 "general_operand" ""))]
3029 "ix86_expand_move (DFmode, operands); DONE;")
3031 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3032 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3033 ;; On the average, pushdf using integers can be still shorter. Allow this
3034 ;; pattern for optimize_size too.
3036 (define_insn "*pushdf_nointeger"
3037 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3038 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3039 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3041 /* This insn should be already split before reg-stack. */
3044 [(set_attr "type" "multi")
3045 (set_attr "unit" "i387,*,*,*")
3046 (set_attr "mode" "DF,SI,SI,DF")])
3048 (define_insn "*pushdf_integer"
3049 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3050 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3051 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3053 /* This insn should be already split before reg-stack. */
3056 [(set_attr "type" "multi")
3057 (set_attr "unit" "i387,*,*")
3058 (set_attr "mode" "DF,SI,DF")])
3060 ;; %%% Kill this when call knows how to work this out.
3062 [(set (match_operand:DF 0 "push_operand" "")
3063 (match_operand:DF 1 "any_fp_register_operand" ""))]
3065 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3066 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3070 [(set (match_operand:DF 0 "push_operand" "")
3071 (match_operand:DF 1 "general_operand" ""))]
3074 "ix86_split_long_move (operands); DONE;")
3076 ;; Moving is usually shorter when only FP registers are used. This separate
3077 ;; movdf pattern avoids the use of integer registers for FP operations
3078 ;; when optimizing for size.
3080 (define_insn "*movdf_nointeger"
3081 [(set (match_operand:DF 0 "nonimmediate_operand"
3082 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3083 (match_operand:DF 1 "general_operand"
3084 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3085 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3086 && ((optimize_function_for_size_p (cfun)
3087 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3088 && (reload_in_progress || reload_completed
3089 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3090 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3091 && optimize_function_for_size_p (cfun)
3092 && !memory_operand (operands[0], DFmode)
3093 && standard_80387_constant_p (operands[1]))
3094 || GET_CODE (operands[1]) != CONST_DOUBLE
3095 || ((optimize_function_for_size_p (cfun)
3096 || !TARGET_MEMORY_MISMATCH_STALL
3097 || reload_in_progress || reload_completed)
3098 && memory_operand (operands[0], DFmode)))"
3100 switch (which_alternative)
3104 return output_387_reg_move (insn, operands);
3107 return standard_80387_constant_opcode (operands[1]);
3113 switch (get_attr_mode (insn))
3116 return "%vxorps\t%0, %d0";
3118 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3119 return "%vxorps\t%0, %d0";
3121 return "%vxorpd\t%0, %d0";
3123 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3124 return "%vxorps\t%0, %d0";
3126 return "%vpxor\t%0, %d0";
3133 switch (get_attr_mode (insn))
3136 return "%vmovaps\t{%1, %0|%0, %1}";
3138 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3139 return "%vmovaps\t{%1, %0|%0, %1}";
3141 return "%vmovapd\t{%1, %0|%0, %1}";
3143 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3144 return "%vmovaps\t{%1, %0|%0, %1}";
3146 return "%vmovdqa\t{%1, %0|%0, %1}";
3148 return "%vmovq\t{%1, %0|%0, %1}";
3152 if (REG_P (operands[0]) && REG_P (operands[1]))
3153 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3155 return "vmovsd\t{%1, %0|%0, %1}";
3158 return "movsd\t{%1, %0|%0, %1}";
3162 if (REG_P (operands[0]))
3163 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3165 return "vmovlpd\t{%1, %0|%0, %1}";
3168 return "movlpd\t{%1, %0|%0, %1}";
3172 if (REG_P (operands[0]))
3173 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3175 return "vmovlps\t{%1, %0|%0, %1}";
3178 return "movlps\t{%1, %0|%0, %1}";
3187 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3188 (set (attr "prefix")
3189 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3190 (const_string "orig")
3191 (const_string "maybe_vex")))
3192 (set (attr "prefix_data16")
3193 (if_then_else (eq_attr "mode" "V1DF")
3195 (const_string "*")))
3197 (cond [(eq_attr "alternative" "0,1,2")
3199 (eq_attr "alternative" "3,4")
3202 /* For SSE1, we have many fewer alternatives. */
3203 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3204 (cond [(eq_attr "alternative" "5,6")
3205 (const_string "V4SF")
3207 (const_string "V2SF"))
3209 /* xorps is one byte shorter. */
3210 (eq_attr "alternative" "5")
3211 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3213 (const_string "V4SF")
3214 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3218 (const_string "V2DF"))
3220 /* For architectures resolving dependencies on
3221 whole SSE registers use APD move to break dependency
3222 chains, otherwise use short move to avoid extra work.
3224 movaps encodes one byte shorter. */
3225 (eq_attr "alternative" "6")
3227 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3229 (const_string "V4SF")
3230 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3232 (const_string "V2DF")
3234 (const_string "DF"))
3235 /* For architectures resolving dependencies on register
3236 parts we may avoid extra work to zero out upper part
3238 (eq_attr "alternative" "7")
3240 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3242 (const_string "V1DF")
3243 (const_string "DF"))
3245 (const_string "DF")))])
3247 (define_insn "*movdf_integer_rex64"
3248 [(set (match_operand:DF 0 "nonimmediate_operand"
3249 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3250 (match_operand:DF 1 "general_operand"
3251 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3252 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3253 && (reload_in_progress || reload_completed
3254 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3255 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3256 && optimize_function_for_size_p (cfun)
3257 && standard_80387_constant_p (operands[1]))
3258 || GET_CODE (operands[1]) != CONST_DOUBLE
3259 || memory_operand (operands[0], DFmode))"
3261 switch (which_alternative)
3265 return output_387_reg_move (insn, operands);
3268 return standard_80387_constant_opcode (operands[1]);
3275 switch (get_attr_mode (insn))
3278 return "%vxorps\t%0, %d0";
3280 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3281 return "%vxorps\t%0, %d0";
3283 return "%vxorpd\t%0, %d0";
3285 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3286 return "%vxorps\t%0, %d0";
3288 return "%vpxor\t%0, %d0";
3295 switch (get_attr_mode (insn))
3298 return "%vmovaps\t{%1, %0|%0, %1}";
3300 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3301 return "%vmovaps\t{%1, %0|%0, %1}";
3303 return "%vmovapd\t{%1, %0|%0, %1}";
3305 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3306 return "%vmovaps\t{%1, %0|%0, %1}";
3308 return "%vmovdqa\t{%1, %0|%0, %1}";
3310 return "%vmovq\t{%1, %0|%0, %1}";
3314 if (REG_P (operands[0]) && REG_P (operands[1]))
3315 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3317 return "vmovsd\t{%1, %0|%0, %1}";
3320 return "movsd\t{%1, %0|%0, %1}";
3322 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3324 return "%vmovlps\t{%1, %d0|%d0, %1}";
3331 return "%vmovd\t{%1, %0|%0, %1}";
3337 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3338 (set (attr "prefix")
3339 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3340 (const_string "orig")
3341 (const_string "maybe_vex")))
3342 (set (attr "prefix_data16")
3343 (if_then_else (eq_attr "mode" "V1DF")
3345 (const_string "*")))
3347 (cond [(eq_attr "alternative" "0,1,2")
3349 (eq_attr "alternative" "3,4,9,10")
3352 /* For SSE1, we have many fewer alternatives. */
3353 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3354 (cond [(eq_attr "alternative" "5,6")
3355 (const_string "V4SF")
3357 (const_string "V2SF"))
3359 /* xorps is one byte shorter. */
3360 (eq_attr "alternative" "5")
3361 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3363 (const_string "V4SF")
3364 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3368 (const_string "V2DF"))
3370 /* For architectures resolving dependencies on
3371 whole SSE registers use APD move to break dependency
3372 chains, otherwise use short move to avoid extra work.
3374 movaps encodes one byte shorter. */
3375 (eq_attr "alternative" "6")
3377 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3379 (const_string "V4SF")
3380 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3382 (const_string "V2DF")
3384 (const_string "DF"))
3385 /* For architectures resolving dependencies on register
3386 parts we may avoid extra work to zero out upper part
3388 (eq_attr "alternative" "7")
3390 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3392 (const_string "V1DF")
3393 (const_string "DF"))
3395 (const_string "DF")))])
3397 (define_insn "*movdf_integer"
3398 [(set (match_operand:DF 0 "nonimmediate_operand"
3399 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3400 (match_operand:DF 1 "general_operand"
3401 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3402 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3403 && optimize_function_for_speed_p (cfun)
3404 && TARGET_INTEGER_DFMODE_MOVES
3405 && (reload_in_progress || reload_completed
3406 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3407 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3408 && optimize_function_for_size_p (cfun)
3409 && standard_80387_constant_p (operands[1]))
3410 || GET_CODE (operands[1]) != CONST_DOUBLE
3411 || memory_operand (operands[0], DFmode))"
3413 switch (which_alternative)
3417 return output_387_reg_move (insn, operands);
3420 return standard_80387_constant_opcode (operands[1]);
3427 switch (get_attr_mode (insn))
3430 return "xorps\t%0, %0";
3432 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3433 return "xorps\t%0, %0";
3435 return "xorpd\t%0, %0";
3437 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3438 return "xorps\t%0, %0";
3440 return "pxor\t%0, %0";
3447 switch (get_attr_mode (insn))
3450 return "movaps\t{%1, %0|%0, %1}";
3452 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3453 return "movaps\t{%1, %0|%0, %1}";
3455 return "movapd\t{%1, %0|%0, %1}";
3457 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3458 return "movaps\t{%1, %0|%0, %1}";
3460 return "movdqa\t{%1, %0|%0, %1}";
3462 return "movq\t{%1, %0|%0, %1}";
3464 return "movsd\t{%1, %0|%0, %1}";
3466 return "movlpd\t{%1, %0|%0, %1}";
3468 return "movlps\t{%1, %0|%0, %1}";
3477 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3478 (set (attr "prefix_data16")
3479 (if_then_else (eq_attr "mode" "V1DF")
3481 (const_string "*")))
3483 (cond [(eq_attr "alternative" "0,1,2")
3485 (eq_attr "alternative" "3,4")
3488 /* For SSE1, we have many fewer alternatives. */
3489 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3490 (cond [(eq_attr "alternative" "5,6")
3491 (const_string "V4SF")
3493 (const_string "V2SF"))
3495 /* xorps is one byte shorter. */
3496 (eq_attr "alternative" "5")
3497 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3499 (const_string "V4SF")
3500 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3504 (const_string "V2DF"))
3506 /* For architectures resolving dependencies on
3507 whole SSE registers use APD move to break dependency
3508 chains, otherwise use short move to avoid extra work.
3510 movaps encodes one byte shorter. */
3511 (eq_attr "alternative" "6")
3513 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3515 (const_string "V4SF")
3516 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3518 (const_string "V2DF")
3520 (const_string "DF"))
3521 /* For architectures resolving dependencies on register
3522 parts we may avoid extra work to zero out upper part
3524 (eq_attr "alternative" "7")
3526 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3528 (const_string "V1DF")
3529 (const_string "DF"))
3531 (const_string "DF")))])
3534 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3535 (match_operand:DF 1 "general_operand" ""))]
3537 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3538 && ! (ANY_FP_REG_P (operands[0]) ||
3539 (GET_CODE (operands[0]) == SUBREG
3540 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3541 && ! (ANY_FP_REG_P (operands[1]) ||
3542 (GET_CODE (operands[1]) == SUBREG
3543 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3545 "ix86_split_long_move (operands); DONE;")
3547 (define_insn "*swapdf"
3548 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3549 (match_operand:DF 1 "fp_register_operand" "+f"))
3552 "reload_completed || TARGET_80387"
3554 if (STACK_TOP_P (operands[0]))
3559 [(set_attr "type" "fxch")
3560 (set_attr "mode" "DF")])
3562 (define_expand "movxf"
3563 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3564 (match_operand:XF 1 "general_operand" ""))]
3566 "ix86_expand_move (XFmode, operands); DONE;")
3568 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3569 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3570 ;; Pushing using integer instructions is longer except for constants
3571 ;; and direct memory references.
3572 ;; (assuming that any given constant is pushed only once, but this ought to be
3573 ;; handled elsewhere).
3575 (define_insn "*pushxf_nointeger"
3576 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3577 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3578 "optimize_function_for_size_p (cfun)"
3580 /* This insn should be already split before reg-stack. */
3583 [(set_attr "type" "multi")
3584 (set_attr "unit" "i387,*,*")
3585 (set_attr "mode" "XF,SI,SI")])
3587 (define_insn "*pushxf_integer"
3588 [(set (match_operand:XF 0 "push_operand" "=<,<")
3589 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3590 "optimize_function_for_speed_p (cfun)"
3592 /* This insn should be already split before reg-stack. */
3595 [(set_attr "type" "multi")
3596 (set_attr "unit" "i387,*")
3597 (set_attr "mode" "XF,SI")])
3600 [(set (match_operand 0 "push_operand" "")
3601 (match_operand 1 "general_operand" ""))]
3603 && (GET_MODE (operands[0]) == XFmode
3604 || GET_MODE (operands[0]) == DFmode)
3605 && !ANY_FP_REG_P (operands[1])"
3607 "ix86_split_long_move (operands); DONE;")
3610 [(set (match_operand:XF 0 "push_operand" "")
3611 (match_operand:XF 1 "any_fp_register_operand" ""))]
3613 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3614 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3615 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3617 ;; Do not use integer registers when optimizing for size
3618 (define_insn "*movxf_nointeger"
3619 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3620 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3621 "optimize_function_for_size_p (cfun)
3622 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3623 && (reload_in_progress || reload_completed
3624 || standard_80387_constant_p (operands[1])
3625 || GET_CODE (operands[1]) != CONST_DOUBLE
3626 || memory_operand (operands[0], XFmode))"
3628 switch (which_alternative)
3632 return output_387_reg_move (insn, operands);
3635 return standard_80387_constant_opcode (operands[1]);
3643 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3644 (set_attr "mode" "XF,XF,XF,SI,SI")])
3646 (define_insn "*movxf_integer"
3647 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3648 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3649 "optimize_function_for_speed_p (cfun)
3650 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3651 && (reload_in_progress || reload_completed
3652 || GET_CODE (operands[1]) != CONST_DOUBLE
3653 || memory_operand (operands[0], XFmode))"
3655 switch (which_alternative)
3659 return output_387_reg_move (insn, operands);
3662 return standard_80387_constant_opcode (operands[1]);
3671 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3672 (set_attr "mode" "XF,XF,XF,SI,SI")])
3674 (define_expand "movtf"
3675 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3676 (match_operand:TF 1 "nonimmediate_operand" ""))]
3679 ix86_expand_move (TFmode, operands);
3683 (define_insn "*movtf_internal"
3684 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3685 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3687 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3689 switch (which_alternative)
3693 if (get_attr_mode (insn) == MODE_V4SF)
3694 return "%vmovaps\t{%1, %0|%0, %1}";
3696 return "%vmovdqa\t{%1, %0|%0, %1}";
3698 if (get_attr_mode (insn) == MODE_V4SF)
3699 return "%vxorps\t%0, %d0";
3701 return "%vpxor\t%0, %d0";
3709 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3710 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3712 (cond [(eq_attr "alternative" "0,2")
3714 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3716 (const_string "V4SF")
3717 (const_string "TI"))
3718 (eq_attr "alternative" "1")
3720 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3722 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3724 (const_string "V4SF")
3725 (const_string "TI"))]
3726 (const_string "DI")))])
3728 (define_insn "*pushtf_sse"
3729 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3730 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3733 /* This insn should be already split before reg-stack. */
3736 [(set_attr "type" "multi")
3737 (set_attr "unit" "sse,*,*")
3738 (set_attr "mode" "TF,SI,SI")])
3741 [(set (match_operand:TF 0 "push_operand" "")
3742 (match_operand:TF 1 "general_operand" ""))]
3743 "TARGET_SSE2 && reload_completed
3744 && !SSE_REG_P (operands[1])"
3746 "ix86_split_long_move (operands); DONE;")
3749 [(set (match_operand:TF 0 "push_operand" "")
3750 (match_operand:TF 1 "any_fp_register_operand" ""))]
3752 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3753 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3757 [(set (match_operand 0 "nonimmediate_operand" "")
3758 (match_operand 1 "general_operand" ""))]
3760 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3761 && GET_MODE (operands[0]) == XFmode
3762 && ! (ANY_FP_REG_P (operands[0]) ||
3763 (GET_CODE (operands[0]) == SUBREG
3764 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3765 && ! (ANY_FP_REG_P (operands[1]) ||
3766 (GET_CODE (operands[1]) == SUBREG
3767 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3769 "ix86_split_long_move (operands); DONE;")
3772 [(set (match_operand 0 "register_operand" "")
3773 (match_operand 1 "memory_operand" ""))]
3775 && MEM_P (operands[1])
3776 && (GET_MODE (operands[0]) == TFmode
3777 || GET_MODE (operands[0]) == XFmode
3778 || GET_MODE (operands[0]) == SFmode
3779 || GET_MODE (operands[0]) == DFmode)
3780 && (operands[2] = find_constant_src (insn))"
3781 [(set (match_dup 0) (match_dup 2))]
3783 rtx c = operands[2];
3784 rtx r = operands[0];
3786 if (GET_CODE (r) == SUBREG)
3791 if (!standard_sse_constant_p (c))
3794 else if (FP_REG_P (r))
3796 if (!standard_80387_constant_p (c))
3799 else if (MMX_REG_P (r))
3804 [(set (match_operand 0 "register_operand" "")
3805 (float_extend (match_operand 1 "memory_operand" "")))]
3807 && MEM_P (operands[1])
3808 && (GET_MODE (operands[0]) == TFmode
3809 || GET_MODE (operands[0]) == XFmode
3810 || GET_MODE (operands[0]) == SFmode
3811 || GET_MODE (operands[0]) == DFmode)
3812 && (operands[2] = find_constant_src (insn))"
3813 [(set (match_dup 0) (match_dup 2))]
3815 rtx c = operands[2];
3816 rtx r = operands[0];
3818 if (GET_CODE (r) == SUBREG)
3823 if (!standard_sse_constant_p (c))
3826 else if (FP_REG_P (r))
3828 if (!standard_80387_constant_p (c))
3831 else if (MMX_REG_P (r))
3835 (define_insn "swapxf"
3836 [(set (match_operand:XF 0 "register_operand" "+f")
3837 (match_operand:XF 1 "register_operand" "+f"))
3842 if (STACK_TOP_P (operands[0]))
3847 [(set_attr "type" "fxch")
3848 (set_attr "mode" "XF")])
3850 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3852 [(set (match_operand:X87MODEF 0 "register_operand" "")
3853 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3854 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3855 && (standard_80387_constant_p (operands[1]) == 8
3856 || standard_80387_constant_p (operands[1]) == 9)"
3857 [(set (match_dup 0)(match_dup 1))
3859 (neg:X87MODEF (match_dup 0)))]
3863 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3864 if (real_isnegzero (&r))
3865 operands[1] = CONST0_RTX (<MODE>mode);
3867 operands[1] = CONST1_RTX (<MODE>mode);
3871 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3872 (match_operand:TF 1 "general_operand" ""))]
3874 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3876 "ix86_split_long_move (operands); DONE;")
3878 ;; Zero extension instructions
3880 (define_expand "zero_extendhisi2"
3881 [(set (match_operand:SI 0 "register_operand" "")
3882 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3885 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3887 operands[1] = force_reg (HImode, operands[1]);
3888 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3893 (define_insn "zero_extendhisi2_and"
3894 [(set (match_operand:SI 0 "register_operand" "=r")
3895 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3896 (clobber (reg:CC FLAGS_REG))]
3897 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3899 [(set_attr "type" "alu1")
3900 (set_attr "mode" "SI")])
3903 [(set (match_operand:SI 0 "register_operand" "")
3904 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3905 (clobber (reg:CC FLAGS_REG))]
3906 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3907 && optimize_function_for_speed_p (cfun)"
3908 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3909 (clobber (reg:CC FLAGS_REG))])]
3912 (define_insn "*zero_extendhisi2_movzwl"
3913 [(set (match_operand:SI 0 "register_operand" "=r")
3914 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3915 "!TARGET_ZERO_EXTEND_WITH_AND
3916 || optimize_function_for_size_p (cfun)"
3917 "movz{wl|x}\t{%1, %0|%0, %1}"
3918 [(set_attr "type" "imovx")
3919 (set_attr "mode" "SI")])
3921 (define_expand "zero_extendqihi2"
3923 [(set (match_operand:HI 0 "register_operand" "")
3924 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3925 (clobber (reg:CC FLAGS_REG))])]
3929 (define_insn "*zero_extendqihi2_and"
3930 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3931 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3932 (clobber (reg:CC FLAGS_REG))]
3933 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3935 [(set_attr "type" "alu1")
3936 (set_attr "mode" "HI")])
3938 (define_insn "*zero_extendqihi2_movzbw_and"
3939 [(set (match_operand:HI 0 "register_operand" "=r,r")
3940 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3941 (clobber (reg:CC FLAGS_REG))]
3942 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3944 [(set_attr "type" "imovx,alu1")
3945 (set_attr "mode" "HI")])
3947 ; zero extend to SImode here to avoid partial register stalls
3948 (define_insn "*zero_extendqihi2_movzbl"
3949 [(set (match_operand:HI 0 "register_operand" "=r")
3950 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3951 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3952 && reload_completed"
3953 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3954 [(set_attr "type" "imovx")
3955 (set_attr "mode" "SI")])
3957 ;; For the movzbw case strip only the clobber
3959 [(set (match_operand:HI 0 "register_operand" "")
3960 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3961 (clobber (reg:CC FLAGS_REG))]
3963 && (!TARGET_ZERO_EXTEND_WITH_AND
3964 || optimize_function_for_size_p (cfun))
3965 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3966 [(set (match_operand:HI 0 "register_operand" "")
3967 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3969 ;; When source and destination does not overlap, clear destination
3970 ;; first and then do the movb
3972 [(set (match_operand:HI 0 "register_operand" "")
3973 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3974 (clobber (reg:CC FLAGS_REG))]
3976 && ANY_QI_REG_P (operands[0])
3977 && (TARGET_ZERO_EXTEND_WITH_AND
3978 && optimize_function_for_speed_p (cfun))
3979 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3980 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3982 operands[2] = gen_lowpart (QImode, operands[0]);
3983 ix86_expand_clear (operands[0]);
3986 ;; Rest is handled by single and.
3988 [(set (match_operand:HI 0 "register_operand" "")
3989 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3990 (clobber (reg:CC FLAGS_REG))]
3992 && true_regnum (operands[0]) == true_regnum (operands[1])"
3993 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3994 (clobber (reg:CC FLAGS_REG))])]
3997 (define_expand "zero_extendqisi2"
3999 [(set (match_operand:SI 0 "register_operand" "")
4000 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4001 (clobber (reg:CC FLAGS_REG))])]
4005 (define_insn "*zero_extendqisi2_and"
4006 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
4007 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4008 (clobber (reg:CC FLAGS_REG))]
4009 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4011 [(set_attr "type" "alu1")
4012 (set_attr "mode" "SI")])
4014 (define_insn "*zero_extendqisi2_movzbl_and"
4015 [(set (match_operand:SI 0 "register_operand" "=r,r")
4016 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4017 (clobber (reg:CC FLAGS_REG))]
4018 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4020 [(set_attr "type" "imovx,alu1")
4021 (set_attr "mode" "SI")])
4023 (define_insn "*zero_extendqisi2_movzbl"
4024 [(set (match_operand:SI 0 "register_operand" "=r")
4025 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4026 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4027 && reload_completed"
4028 "movz{bl|x}\t{%1, %0|%0, %1}"
4029 [(set_attr "type" "imovx")
4030 (set_attr "mode" "SI")])
4032 ;; For the movzbl case strip only the clobber
4034 [(set (match_operand:SI 0 "register_operand" "")
4035 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4036 (clobber (reg:CC FLAGS_REG))]
4038 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4039 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4041 (zero_extend:SI (match_dup 1)))])
4043 ;; When source and destination does not overlap, clear destination
4044 ;; first and then do the movb
4046 [(set (match_operand:SI 0 "register_operand" "")
4047 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4048 (clobber (reg:CC FLAGS_REG))]
4050 && ANY_QI_REG_P (operands[0])
4051 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4052 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4053 && !reg_overlap_mentioned_p (operands[0], operands[1])"
4054 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
4056 operands[2] = gen_lowpart (QImode, operands[0]);
4057 ix86_expand_clear (operands[0]);
4060 ;; Rest is handled by single and.
4062 [(set (match_operand:SI 0 "register_operand" "")
4063 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4064 (clobber (reg:CC FLAGS_REG))]
4066 && true_regnum (operands[0]) == true_regnum (operands[1])"
4067 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4068 (clobber (reg:CC FLAGS_REG))])]
4071 ;; %%% Kill me once multi-word ops are sane.
4072 (define_expand "zero_extendsidi2"
4073 [(set (match_operand:DI 0 "register_operand" "")
4074 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4079 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4084 (define_insn "zero_extendsidi2_32"
4085 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4087 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
4088 (clobber (reg:CC FLAGS_REG))]
4094 movd\t{%1, %0|%0, %1}
4095 movd\t{%1, %0|%0, %1}
4096 %vmovd\t{%1, %0|%0, %1}
4097 %vmovd\t{%1, %0|%0, %1}"
4098 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4099 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4100 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4102 (define_insn "zero_extendsidi2_rex64"
4103 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4105 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
4108 mov\t{%k1, %k0|%k0, %k1}
4110 movd\t{%1, %0|%0, %1}
4111 movd\t{%1, %0|%0, %1}
4112 %vmovd\t{%1, %0|%0, %1}
4113 %vmovd\t{%1, %0|%0, %1}"
4114 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4115 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4116 (set_attr "prefix_0f" "0,*,*,*,*,*")
4117 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4120 [(set (match_operand:DI 0 "memory_operand" "")
4121 (zero_extend:DI (match_dup 0)))]
4123 [(set (match_dup 4) (const_int 0))]
4124 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4127 [(set (match_operand:DI 0 "register_operand" "")
4128 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4129 (clobber (reg:CC FLAGS_REG))]
4130 "!TARGET_64BIT && reload_completed
4131 && true_regnum (operands[0]) == true_regnum (operands[1])"
4132 [(set (match_dup 4) (const_int 0))]
4133 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4136 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4137 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4138 (clobber (reg:CC FLAGS_REG))]
4139 "!TARGET_64BIT && reload_completed
4140 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4141 [(set (match_dup 3) (match_dup 1))
4142 (set (match_dup 4) (const_int 0))]
4143 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4145 (define_insn "zero_extendhidi2"
4146 [(set (match_operand:DI 0 "register_operand" "=r")
4147 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4149 "movz{wl|x}\t{%1, %k0|%k0, %1}"
4150 [(set_attr "type" "imovx")
4151 (set_attr "mode" "SI")])
4153 (define_insn "zero_extendqidi2"
4154 [(set (match_operand:DI 0 "register_operand" "=r")
4155 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4157 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4158 [(set_attr "type" "imovx")
4159 (set_attr "mode" "SI")])
4161 ;; Sign extension instructions
4163 (define_expand "extendsidi2"
4164 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4165 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4166 (clobber (reg:CC FLAGS_REG))
4167 (clobber (match_scratch:SI 2 ""))])]
4172 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4177 (define_insn "*extendsidi2_1"
4178 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4179 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4180 (clobber (reg:CC FLAGS_REG))
4181 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4185 (define_insn "extendsidi2_rex64"
4186 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4187 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4191 movs{lq|x}\t{%1, %0|%0, %1}"
4192 [(set_attr "type" "imovx")
4193 (set_attr "mode" "DI")
4194 (set_attr "prefix_0f" "0")
4195 (set_attr "modrm" "0,1")])
4197 (define_insn "extendhidi2"
4198 [(set (match_operand:DI 0 "register_operand" "=r")
4199 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4201 "movs{wq|x}\t{%1, %0|%0, %1}"
4202 [(set_attr "type" "imovx")
4203 (set_attr "mode" "DI")])
4205 (define_insn "extendqidi2"
4206 [(set (match_operand:DI 0 "register_operand" "=r")
4207 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4209 "movs{bq|x}\t{%1, %0|%0, %1}"
4210 [(set_attr "type" "imovx")
4211 (set_attr "mode" "DI")])
4213 ;; Extend to memory case when source register does die.
4215 [(set (match_operand:DI 0 "memory_operand" "")
4216 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4217 (clobber (reg:CC FLAGS_REG))
4218 (clobber (match_operand:SI 2 "register_operand" ""))]
4220 && dead_or_set_p (insn, operands[1])
4221 && !reg_mentioned_p (operands[1], operands[0]))"
4222 [(set (match_dup 3) (match_dup 1))
4223 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4224 (clobber (reg:CC FLAGS_REG))])
4225 (set (match_dup 4) (match_dup 1))]
4226 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4228 ;; Extend to memory case when source register does not die.
4230 [(set (match_operand:DI 0 "memory_operand" "")
4231 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4232 (clobber (reg:CC FLAGS_REG))
4233 (clobber (match_operand:SI 2 "register_operand" ""))]
4237 split_di (&operands[0], 1, &operands[3], &operands[4]);
4239 emit_move_insn (operands[3], operands[1]);
4241 /* Generate a cltd if possible and doing so it profitable. */
4242 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4243 && true_regnum (operands[1]) == AX_REG
4244 && true_regnum (operands[2]) == DX_REG)
4246 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4250 emit_move_insn (operands[2], operands[1]);
4251 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4253 emit_move_insn (operands[4], operands[2]);
4257 ;; Extend to register case. Optimize case where source and destination
4258 ;; registers match and cases where we can use cltd.
4260 [(set (match_operand:DI 0 "register_operand" "")
4261 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4262 (clobber (reg:CC FLAGS_REG))
4263 (clobber (match_scratch:SI 2 ""))]
4267 split_di (&operands[0], 1, &operands[3], &operands[4]);
4269 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4270 emit_move_insn (operands[3], operands[1]);
4272 /* Generate a cltd if possible and doing so it profitable. */
4273 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4274 && true_regnum (operands[3]) == AX_REG
4275 && true_regnum (operands[4]) == DX_REG)
4277 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4281 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4282 emit_move_insn (operands[4], operands[1]);
4284 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4288 (define_insn "extendhisi2"
4289 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4290 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4293 switch (get_attr_prefix_0f (insn))
4296 return "{cwtl|cwde}";
4298 return "movs{wl|x}\t{%1, %0|%0, %1}";
4301 [(set_attr "type" "imovx")
4302 (set_attr "mode" "SI")
4303 (set (attr "prefix_0f")
4304 ;; movsx is short decodable while cwtl is vector decoded.
4305 (if_then_else (and (eq_attr "cpu" "!k6")
4306 (eq_attr "alternative" "0"))
4308 (const_string "1")))
4310 (if_then_else (eq_attr "prefix_0f" "0")
4312 (const_string "1")))])
4314 (define_insn "*extendhisi2_zext"
4315 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4317 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4320 switch (get_attr_prefix_0f (insn))
4323 return "{cwtl|cwde}";
4325 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4328 [(set_attr "type" "imovx")
4329 (set_attr "mode" "SI")
4330 (set (attr "prefix_0f")
4331 ;; movsx is short decodable while cwtl is vector decoded.
4332 (if_then_else (and (eq_attr "cpu" "!k6")
4333 (eq_attr "alternative" "0"))
4335 (const_string "1")))
4337 (if_then_else (eq_attr "prefix_0f" "0")
4339 (const_string "1")))])
4341 (define_insn "extendqihi2"
4342 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4343 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4346 switch (get_attr_prefix_0f (insn))
4349 return "{cbtw|cbw}";
4351 return "movs{bw|x}\t{%1, %0|%0, %1}";
4354 [(set_attr "type" "imovx")
4355 (set_attr "mode" "HI")
4356 (set (attr "prefix_0f")
4357 ;; movsx is short decodable while cwtl is vector decoded.
4358 (if_then_else (and (eq_attr "cpu" "!k6")
4359 (eq_attr "alternative" "0"))
4361 (const_string "1")))
4363 (if_then_else (eq_attr "prefix_0f" "0")
4365 (const_string "1")))])
4367 (define_insn "extendqisi2"
4368 [(set (match_operand:SI 0 "register_operand" "=r")
4369 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4371 "movs{bl|x}\t{%1, %0|%0, %1}"
4372 [(set_attr "type" "imovx")
4373 (set_attr "mode" "SI")])
4375 (define_insn "*extendqisi2_zext"
4376 [(set (match_operand:DI 0 "register_operand" "=r")
4378 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4380 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4381 [(set_attr "type" "imovx")
4382 (set_attr "mode" "SI")])
4384 ;; Conversions between float and double.
4386 ;; These are all no-ops in the model used for the 80387. So just
4389 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4390 (define_insn "*dummy_extendsfdf2"
4391 [(set (match_operand:DF 0 "push_operand" "=<")
4392 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4397 [(set (match_operand:DF 0 "push_operand" "")
4398 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4400 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4401 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4403 (define_insn "*dummy_extendsfxf2"
4404 [(set (match_operand:XF 0 "push_operand" "=<")
4405 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4410 [(set (match_operand:XF 0 "push_operand" "")
4411 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4413 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4414 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4415 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4418 [(set (match_operand:XF 0 "push_operand" "")
4419 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4421 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4422 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4423 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4425 (define_expand "extendsfdf2"
4426 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4427 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4428 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4430 /* ??? Needed for compress_float_constant since all fp constants
4431 are LEGITIMATE_CONSTANT_P. */
4432 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4434 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4435 && standard_80387_constant_p (operands[1]) > 0)
4437 operands[1] = simplify_const_unary_operation
4438 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4439 emit_move_insn_1 (operands[0], operands[1]);
4442 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4446 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4448 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4450 We do the conversion post reload to avoid producing of 128bit spills
4451 that might lead to ICE on 32bit target. The sequence unlikely combine
4454 [(set (match_operand:DF 0 "register_operand" "")
4456 (match_operand:SF 1 "nonimmediate_operand" "")))]
4457 "TARGET_USE_VECTOR_FP_CONVERTS
4458 && optimize_insn_for_speed_p ()
4459 && reload_completed && SSE_REG_P (operands[0])"
4464 (parallel [(const_int 0) (const_int 1)]))))]
4466 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4467 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4468 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4469 Try to avoid move when unpacking can be done in source. */
4470 if (REG_P (operands[1]))
4472 /* If it is unsafe to overwrite upper half of source, we need
4473 to move to destination and unpack there. */
4474 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4475 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4476 && true_regnum (operands[0]) != true_regnum (operands[1]))
4478 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4479 emit_move_insn (tmp, operands[1]);
4482 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4483 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4487 emit_insn (gen_vec_setv4sf_0 (operands[3],
4488 CONST0_RTX (V4SFmode), operands[1]));
4491 (define_insn "*extendsfdf2_mixed"
4492 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4494 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4495 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4497 switch (which_alternative)
4501 return output_387_reg_move (insn, operands);
4504 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4510 [(set_attr "type" "fmov,fmov,ssecvt")
4511 (set_attr "prefix" "orig,orig,maybe_vex")
4512 (set_attr "mode" "SF,XF,DF")])
4514 (define_insn "*extendsfdf2_sse"
4515 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4516 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4517 "TARGET_SSE2 && TARGET_SSE_MATH"
4518 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4519 [(set_attr "type" "ssecvt")
4520 (set_attr "prefix" "maybe_vex")
4521 (set_attr "mode" "DF")])
4523 (define_insn "*extendsfdf2_i387"
4524 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4525 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4527 "* return output_387_reg_move (insn, operands);"
4528 [(set_attr "type" "fmov")
4529 (set_attr "mode" "SF,XF")])
4531 (define_expand "extend<mode>xf2"
4532 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4533 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4536 /* ??? Needed for compress_float_constant since all fp constants
4537 are LEGITIMATE_CONSTANT_P. */
4538 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4540 if (standard_80387_constant_p (operands[1]) > 0)
4542 operands[1] = simplify_const_unary_operation
4543 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4544 emit_move_insn_1 (operands[0], operands[1]);
4547 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4551 (define_insn "*extend<mode>xf2_i387"
4552 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4554 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4556 "* return output_387_reg_move (insn, operands);"
4557 [(set_attr "type" "fmov")
4558 (set_attr "mode" "<MODE>,XF")])
4560 ;; %%% This seems bad bad news.
4561 ;; This cannot output into an f-reg because there is no way to be sure
4562 ;; of truncating in that case. Otherwise this is just like a simple move
4563 ;; insn. So we pretend we can output to a reg in order to get better
4564 ;; register preferencing, but we really use a stack slot.
4566 ;; Conversion from DFmode to SFmode.
4568 (define_expand "truncdfsf2"
4569 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4571 (match_operand:DF 1 "nonimmediate_operand" "")))]
4572 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4574 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4576 else if (flag_unsafe_math_optimizations)
4580 enum ix86_stack_slot slot = (virtuals_instantiated
4583 rtx temp = assign_386_stack_local (SFmode, slot);
4584 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4589 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4591 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4593 We do the conversion post reload to avoid producing of 128bit spills
4594 that might lead to ICE on 32bit target. The sequence unlikely combine
4597 [(set (match_operand:SF 0 "register_operand" "")
4599 (match_operand:DF 1 "nonimmediate_operand" "")))]
4600 "TARGET_USE_VECTOR_FP_CONVERTS
4601 && optimize_insn_for_speed_p ()
4602 && reload_completed && SSE_REG_P (operands[0])"
4605 (float_truncate:V2SF
4609 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4610 operands[3] = CONST0_RTX (V2SFmode);
4611 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4612 /* Use movsd for loading from memory, unpcklpd for registers.
4613 Try to avoid move when unpacking can be done in source, or SSE3
4614 movddup is available. */
4615 if (REG_P (operands[1]))
4618 && true_regnum (operands[0]) != true_regnum (operands[1])
4619 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4620 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4622 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4623 emit_move_insn (tmp, operands[1]);
4626 else if (!TARGET_SSE3)
4627 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4628 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4631 emit_insn (gen_sse2_loadlpd (operands[4],
4632 CONST0_RTX (V2DFmode), operands[1]));
4635 (define_expand "truncdfsf2_with_temp"
4636 [(parallel [(set (match_operand:SF 0 "" "")
4637 (float_truncate:SF (match_operand:DF 1 "" "")))
4638 (clobber (match_operand:SF 2 "" ""))])]
4641 (define_insn "*truncdfsf_fast_mixed"
4642 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4644 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4645 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4647 switch (which_alternative)
4650 return output_387_reg_move (insn, operands);
4652 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4657 [(set_attr "type" "fmov,ssecvt")
4658 (set_attr "prefix" "orig,maybe_vex")
4659 (set_attr "mode" "SF")])
4661 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4662 ;; because nothing we do here is unsafe.
4663 (define_insn "*truncdfsf_fast_sse"
4664 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4666 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4667 "TARGET_SSE2 && TARGET_SSE_MATH"
4668 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4669 [(set_attr "type" "ssecvt")
4670 (set_attr "prefix" "maybe_vex")
4671 (set_attr "mode" "SF")])
4673 (define_insn "*truncdfsf_fast_i387"
4674 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4676 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4677 "TARGET_80387 && flag_unsafe_math_optimizations"
4678 "* return output_387_reg_move (insn, operands);"
4679 [(set_attr "type" "fmov")
4680 (set_attr "mode" "SF")])
4682 (define_insn "*truncdfsf_mixed"
4683 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4685 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4686 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4687 "TARGET_MIX_SSE_I387"
4689 switch (which_alternative)
4692 return output_387_reg_move (insn, operands);
4694 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4700 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4701 (set_attr "unit" "*,*,i387,i387,i387")
4702 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4703 (set_attr "mode" "SF")])
4705 (define_insn "*truncdfsf_i387"
4706 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4708 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4709 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4712 switch (which_alternative)
4715 return output_387_reg_move (insn, operands);
4721 [(set_attr "type" "fmov,multi,multi,multi")
4722 (set_attr "unit" "*,i387,i387,i387")
4723 (set_attr "mode" "SF")])
4725 (define_insn "*truncdfsf2_i387_1"
4726 [(set (match_operand:SF 0 "memory_operand" "=m")
4728 (match_operand:DF 1 "register_operand" "f")))]
4730 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4731 && !TARGET_MIX_SSE_I387"
4732 "* return output_387_reg_move (insn, operands);"
4733 [(set_attr "type" "fmov")
4734 (set_attr "mode" "SF")])
4737 [(set (match_operand:SF 0 "register_operand" "")
4739 (match_operand:DF 1 "fp_register_operand" "")))
4740 (clobber (match_operand 2 "" ""))]
4742 [(set (match_dup 2) (match_dup 1))
4743 (set (match_dup 0) (match_dup 2))]
4745 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4748 ;; Conversion from XFmode to {SF,DF}mode
4750 (define_expand "truncxf<mode>2"
4751 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4752 (float_truncate:MODEF
4753 (match_operand:XF 1 "register_operand" "")))
4754 (clobber (match_dup 2))])]
4757 if (flag_unsafe_math_optimizations)
4759 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4760 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4761 if (reg != operands[0])
4762 emit_move_insn (operands[0], reg);
4767 enum ix86_stack_slot slot = (virtuals_instantiated
4770 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4774 (define_insn "*truncxfsf2_mixed"
4775 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4777 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4778 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4781 gcc_assert (!which_alternative);
4782 return output_387_reg_move (insn, operands);
4784 [(set_attr "type" "fmov,multi,multi,multi")
4785 (set_attr "unit" "*,i387,i387,i387")
4786 (set_attr "mode" "SF")])
4788 (define_insn "*truncxfdf2_mixed"
4789 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4791 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4792 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4795 gcc_assert (!which_alternative);
4796 return output_387_reg_move (insn, operands);
4798 [(set_attr "type" "fmov,multi,multi,multi")
4799 (set_attr "unit" "*,i387,i387,i387")
4800 (set_attr "mode" "DF")])
4802 (define_insn "truncxf<mode>2_i387_noop"
4803 [(set (match_operand:MODEF 0 "register_operand" "=f")
4804 (float_truncate:MODEF
4805 (match_operand:XF 1 "register_operand" "f")))]
4806 "TARGET_80387 && flag_unsafe_math_optimizations"
4807 "* return output_387_reg_move (insn, operands);"
4808 [(set_attr "type" "fmov")
4809 (set_attr "mode" "<MODE>")])
4811 (define_insn "*truncxf<mode>2_i387"
4812 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4813 (float_truncate:MODEF
4814 (match_operand:XF 1 "register_operand" "f")))]
4816 "* return output_387_reg_move (insn, operands);"
4817 [(set_attr "type" "fmov")
4818 (set_attr "mode" "<MODE>")])
4821 [(set (match_operand:MODEF 0 "register_operand" "")
4822 (float_truncate:MODEF
4823 (match_operand:XF 1 "register_operand" "")))
4824 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4825 "TARGET_80387 && reload_completed"
4826 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4827 (set (match_dup 0) (match_dup 2))]
4831 [(set (match_operand:MODEF 0 "memory_operand" "")
4832 (float_truncate:MODEF
4833 (match_operand:XF 1 "register_operand" "")))
4834 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4836 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4839 ;; Signed conversion to DImode.
4841 (define_expand "fix_truncxfdi2"
4842 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4843 (fix:DI (match_operand:XF 1 "register_operand" "")))
4844 (clobber (reg:CC FLAGS_REG))])]
4849 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4854 (define_expand "fix_trunc<mode>di2"
4855 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4856 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4857 (clobber (reg:CC FLAGS_REG))])]
4858 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4861 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4863 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4866 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4868 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4869 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4870 if (out != operands[0])
4871 emit_move_insn (operands[0], out);
4876 ;; Signed conversion to SImode.
4878 (define_expand "fix_truncxfsi2"
4879 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4880 (fix:SI (match_operand:XF 1 "register_operand" "")))
4881 (clobber (reg:CC FLAGS_REG))])]
4886 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4891 (define_expand "fix_trunc<mode>si2"
4892 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4893 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4894 (clobber (reg:CC FLAGS_REG))])]
4895 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4898 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4900 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4903 if (SSE_FLOAT_MODE_P (<MODE>mode))
4905 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4906 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4907 if (out != operands[0])
4908 emit_move_insn (operands[0], out);
4913 ;; Signed conversion to HImode.
4915 (define_expand "fix_trunc<mode>hi2"
4916 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4917 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4918 (clobber (reg:CC FLAGS_REG))])]
4920 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4924 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4929 ;; Unsigned conversion to SImode.
4931 (define_expand "fixuns_trunc<mode>si2"
4933 [(set (match_operand:SI 0 "register_operand" "")
4935 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4937 (clobber (match_scratch:<ssevecmode> 3 ""))
4938 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4939 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4941 enum machine_mode mode = <MODE>mode;
4942 enum machine_mode vecmode = <ssevecmode>mode;
4943 REAL_VALUE_TYPE TWO31r;
4946 if (optimize_insn_for_size_p ())
4949 real_ldexp (&TWO31r, &dconst1, 31);
4950 two31 = const_double_from_real_value (TWO31r, mode);
4951 two31 = ix86_build_const_vector (mode, true, two31);
4952 operands[2] = force_reg (vecmode, two31);
4955 (define_insn_and_split "*fixuns_trunc<mode>_1"
4956 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4958 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4959 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4960 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4961 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4962 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4963 && optimize_function_for_speed_p (cfun)"
4965 "&& reload_completed"
4968 ix86_split_convert_uns_si_sse (operands);
4972 ;; Unsigned conversion to HImode.
4973 ;; Without these patterns, we'll try the unsigned SI conversion which
4974 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4976 (define_expand "fixuns_trunc<mode>hi2"
4978 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4979 (set (match_operand:HI 0 "nonimmediate_operand" "")
4980 (subreg:HI (match_dup 2) 0))]
4981 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4982 "operands[2] = gen_reg_rtx (SImode);")
4984 ;; When SSE is available, it is always faster to use it!
4985 (define_insn "fix_trunc<mode>di_sse"
4986 [(set (match_operand:DI 0 "register_operand" "=r,r")
4987 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4988 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4989 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4990 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4991 [(set_attr "type" "sseicvt")
4992 (set_attr "prefix" "maybe_vex")
4993 (set_attr "prefix_rex" "1")
4994 (set_attr "mode" "<MODE>")
4995 (set_attr "athlon_decode" "double,vector")
4996 (set_attr "amdfam10_decode" "double,double")])
4998 (define_insn "fix_trunc<mode>si_sse"
4999 [(set (match_operand:SI 0 "register_operand" "=r,r")
5000 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5001 "SSE_FLOAT_MODE_P (<MODE>mode)
5002 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5003 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
5004 [(set_attr "type" "sseicvt")
5005 (set_attr "prefix" "maybe_vex")
5006 (set_attr "mode" "<MODE>")
5007 (set_attr "athlon_decode" "double,vector")
5008 (set_attr "amdfam10_decode" "double,double")])
5010 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
5012 [(set (match_operand:MODEF 0 "register_operand" "")
5013 (match_operand:MODEF 1 "memory_operand" ""))
5014 (set (match_operand:SSEMODEI24 2 "register_operand" "")
5015 (fix:SSEMODEI24 (match_dup 0)))]
5016 "TARGET_SHORTEN_X87_SSE
5017 && peep2_reg_dead_p (2, operands[0])"
5018 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
5021 ;; Avoid vector decoded forms of the instruction.
5023 [(match_scratch:DF 2 "Y2")
5024 (set (match_operand:SSEMODEI24 0 "register_operand" "")
5025 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
5026 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5027 [(set (match_dup 2) (match_dup 1))
5028 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5032 [(match_scratch:SF 2 "x")
5033 (set (match_operand:SSEMODEI24 0 "register_operand" "")
5034 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
5035 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5036 [(set (match_dup 2) (match_dup 1))
5037 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5040 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5041 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5042 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5043 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5045 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5046 && (TARGET_64BIT || <MODE>mode != DImode))
5048 && can_create_pseudo_p ()"
5053 if (memory_operand (operands[0], VOIDmode))
5054 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5057 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5058 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5064 [(set_attr "type" "fisttp")
5065 (set_attr "mode" "<MODE>")])
5067 (define_insn "fix_trunc<mode>_i387_fisttp"
5068 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5069 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5070 (clobber (match_scratch:XF 2 "=&1f"))]
5071 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5073 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5074 && (TARGET_64BIT || <MODE>mode != DImode))
5075 && TARGET_SSE_MATH)"
5076 "* return output_fix_trunc (insn, operands, 1);"
5077 [(set_attr "type" "fisttp")
5078 (set_attr "mode" "<MODE>")])
5080 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5081 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5082 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5083 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5084 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5085 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5087 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5088 && (TARGET_64BIT || <MODE>mode != DImode))
5089 && TARGET_SSE_MATH)"
5091 [(set_attr "type" "fisttp")
5092 (set_attr "mode" "<MODE>")])
5095 [(set (match_operand:X87MODEI 0 "register_operand" "")
5096 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5097 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5098 (clobber (match_scratch 3 ""))]
5100 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5101 (clobber (match_dup 3))])
5102 (set (match_dup 0) (match_dup 2))]
5106 [(set (match_operand:X87MODEI 0 "memory_operand" "")
5107 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5108 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5109 (clobber (match_scratch 3 ""))]
5111 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5112 (clobber (match_dup 3))])]
5115 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5116 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5117 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5118 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5119 ;; function in i386.c.
5120 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5121 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5122 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5123 (clobber (reg:CC FLAGS_REG))]
5124 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5126 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5127 && (TARGET_64BIT || <MODE>mode != DImode))
5128 && can_create_pseudo_p ()"
5133 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5135 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5136 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5137 if (memory_operand (operands[0], VOIDmode))
5138 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5139 operands[2], operands[3]));
5142 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5143 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5144 operands[2], operands[3],
5149 [(set_attr "type" "fistp")
5150 (set_attr "i387_cw" "trunc")
5151 (set_attr "mode" "<MODE>")])
5153 (define_insn "fix_truncdi_i387"
5154 [(set (match_operand:DI 0 "memory_operand" "=m")
5155 (fix:DI (match_operand 1 "register_operand" "f")))
5156 (use (match_operand:HI 2 "memory_operand" "m"))
5157 (use (match_operand:HI 3 "memory_operand" "m"))
5158 (clobber (match_scratch:XF 4 "=&1f"))]
5159 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5161 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5162 "* return output_fix_trunc (insn, operands, 0);"
5163 [(set_attr "type" "fistp")
5164 (set_attr "i387_cw" "trunc")
5165 (set_attr "mode" "DI")])
5167 (define_insn "fix_truncdi_i387_with_temp"
5168 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5169 (fix:DI (match_operand 1 "register_operand" "f,f")))
5170 (use (match_operand:HI 2 "memory_operand" "m,m"))
5171 (use (match_operand:HI 3 "memory_operand" "m,m"))
5172 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5173 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5174 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5176 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5178 [(set_attr "type" "fistp")
5179 (set_attr "i387_cw" "trunc")
5180 (set_attr "mode" "DI")])
5183 [(set (match_operand:DI 0 "register_operand" "")
5184 (fix:DI (match_operand 1 "register_operand" "")))
5185 (use (match_operand:HI 2 "memory_operand" ""))
5186 (use (match_operand:HI 3 "memory_operand" ""))
5187 (clobber (match_operand:DI 4 "memory_operand" ""))
5188 (clobber (match_scratch 5 ""))]
5190 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5193 (clobber (match_dup 5))])
5194 (set (match_dup 0) (match_dup 4))]
5198 [(set (match_operand:DI 0 "memory_operand" "")
5199 (fix:DI (match_operand 1 "register_operand" "")))
5200 (use (match_operand:HI 2 "memory_operand" ""))
5201 (use (match_operand:HI 3 "memory_operand" ""))
5202 (clobber (match_operand:DI 4 "memory_operand" ""))
5203 (clobber (match_scratch 5 ""))]
5205 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5208 (clobber (match_dup 5))])]
5211 (define_insn "fix_trunc<mode>_i387"
5212 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5213 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5214 (use (match_operand:HI 2 "memory_operand" "m"))
5215 (use (match_operand:HI 3 "memory_operand" "m"))]
5216 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5218 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5219 "* return output_fix_trunc (insn, operands, 0);"
5220 [(set_attr "type" "fistp")
5221 (set_attr "i387_cw" "trunc")
5222 (set_attr "mode" "<MODE>")])
5224 (define_insn "fix_trunc<mode>_i387_with_temp"
5225 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5226 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5227 (use (match_operand:HI 2 "memory_operand" "m,m"))
5228 (use (match_operand:HI 3 "memory_operand" "m,m"))
5229 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5230 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5232 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5234 [(set_attr "type" "fistp")
5235 (set_attr "i387_cw" "trunc")
5236 (set_attr "mode" "<MODE>")])
5239 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5240 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5241 (use (match_operand:HI 2 "memory_operand" ""))
5242 (use (match_operand:HI 3 "memory_operand" ""))
5243 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5245 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5247 (use (match_dup 3))])
5248 (set (match_dup 0) (match_dup 4))]
5252 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5253 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5254 (use (match_operand:HI 2 "memory_operand" ""))
5255 (use (match_operand:HI 3 "memory_operand" ""))
5256 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5258 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5260 (use (match_dup 3))])]
5263 (define_insn "x86_fnstcw_1"
5264 [(set (match_operand:HI 0 "memory_operand" "=m")
5265 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5268 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5269 (set_attr "mode" "HI")
5270 (set_attr "unit" "i387")])
5272 (define_insn "x86_fldcw_1"
5273 [(set (reg:HI FPCR_REG)
5274 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5277 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5278 (set_attr "mode" "HI")
5279 (set_attr "unit" "i387")
5280 (set_attr "athlon_decode" "vector")
5281 (set_attr "amdfam10_decode" "vector")])
5283 ;; Conversion between fixed point and floating point.
5285 ;; Even though we only accept memory inputs, the backend _really_
5286 ;; wants to be able to do this between registers.
5288 (define_expand "floathi<mode>2"
5289 [(set (match_operand:X87MODEF 0 "register_operand" "")
5290 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5292 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5293 || TARGET_MIX_SSE_I387)"
5296 ;; Pre-reload splitter to add memory clobber to the pattern.
5297 (define_insn_and_split "*floathi<mode>2_1"
5298 [(set (match_operand:X87MODEF 0 "register_operand" "")
5299 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5301 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5302 || TARGET_MIX_SSE_I387)
5303 && can_create_pseudo_p ()"
5306 [(parallel [(set (match_dup 0)
5307 (float:X87MODEF (match_dup 1)))
5308 (clobber (match_dup 2))])]
5309 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5311 (define_insn "*floathi<mode>2_i387_with_temp"
5312 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5313 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5314 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5316 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5317 || TARGET_MIX_SSE_I387)"
5319 [(set_attr "type" "fmov,multi")
5320 (set_attr "mode" "<MODE>")
5321 (set_attr "unit" "*,i387")
5322 (set_attr "fp_int_src" "true")])
5324 (define_insn "*floathi<mode>2_i387"
5325 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5326 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5328 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5329 || TARGET_MIX_SSE_I387)"
5331 [(set_attr "type" "fmov")
5332 (set_attr "mode" "<MODE>")
5333 (set_attr "fp_int_src" "true")])
5336 [(set (match_operand:X87MODEF 0 "register_operand" "")
5337 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5338 (clobber (match_operand:HI 2 "memory_operand" ""))]
5340 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5341 || TARGET_MIX_SSE_I387)
5342 && reload_completed"
5343 [(set (match_dup 2) (match_dup 1))
5344 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5348 [(set (match_operand:X87MODEF 0 "register_operand" "")
5349 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5350 (clobber (match_operand:HI 2 "memory_operand" ""))]
5352 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5353 || TARGET_MIX_SSE_I387)
5354 && reload_completed"
5355 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5358 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5359 [(set (match_operand:X87MODEF 0 "register_operand" "")
5361 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5363 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5364 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5366 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5367 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5368 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5370 rtx reg = gen_reg_rtx (XFmode);
5373 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5375 if (<X87MODEF:MODE>mode == SFmode)
5376 insn = gen_truncxfsf2 (operands[0], reg);
5377 else if (<X87MODEF:MODE>mode == DFmode)
5378 insn = gen_truncxfdf2 (operands[0], reg);
5387 ;; Pre-reload splitter to add memory clobber to the pattern.
5388 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5389 [(set (match_operand:X87MODEF 0 "register_operand" "")
5390 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5392 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5393 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5394 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5395 || TARGET_MIX_SSE_I387))
5396 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5397 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5398 && ((<SSEMODEI24:MODE>mode == SImode
5399 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5400 && optimize_function_for_speed_p (cfun)
5401 && flag_trapping_math)
5402 || !(TARGET_INTER_UNIT_CONVERSIONS
5403 || optimize_function_for_size_p (cfun)))))
5404 && can_create_pseudo_p ()"
5407 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5408 (clobber (match_dup 2))])]
5410 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5412 /* Avoid store forwarding (partial memory) stall penalty
5413 by passing DImode value through XMM registers. */
5414 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5415 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5416 && optimize_function_for_speed_p (cfun))
5418 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5425 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5426 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5428 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5429 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5430 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5431 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5433 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5434 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5435 (set_attr "unit" "*,i387,*,*,*")
5436 (set_attr "athlon_decode" "*,*,double,direct,double")
5437 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5438 (set_attr "fp_int_src" "true")])
5440 (define_insn "*floatsi<mode>2_vector_mixed"
5441 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5442 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5443 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5444 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5448 [(set_attr "type" "fmov,sseicvt")
5449 (set_attr "mode" "<MODE>,<ssevecmode>")
5450 (set_attr "unit" "i387,*")
5451 (set_attr "athlon_decode" "*,direct")
5452 (set_attr "amdfam10_decode" "*,double")
5453 (set_attr "fp_int_src" "true")])
5455 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5456 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5458 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5459 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5460 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5461 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5463 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5464 (set_attr "mode" "<MODEF:MODE>")
5465 (set_attr "unit" "*,i387,*,*")
5466 (set_attr "athlon_decode" "*,*,double,direct")
5467 (set_attr "amdfam10_decode" "*,*,vector,double")
5468 (set_attr "fp_int_src" "true")])
5471 [(set (match_operand:MODEF 0 "register_operand" "")
5472 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5473 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5474 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5475 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5476 && TARGET_INTER_UNIT_CONVERSIONS
5478 && (SSE_REG_P (operands[0])
5479 || (GET_CODE (operands[0]) == SUBREG
5480 && SSE_REG_P (operands[0])))"
5481 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5485 [(set (match_operand:MODEF 0 "register_operand" "")
5486 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5487 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5488 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5489 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5490 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5492 && (SSE_REG_P (operands[0])
5493 || (GET_CODE (operands[0]) == SUBREG
5494 && SSE_REG_P (operands[0])))"
5495 [(set (match_dup 2) (match_dup 1))
5496 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5499 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5500 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5502 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5503 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5504 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5505 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5508 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5509 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5510 [(set_attr "type" "fmov,sseicvt,sseicvt")
5511 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5512 (set_attr "mode" "<MODEF:MODE>")
5513 (set (attr "prefix_rex")
5515 (and (eq_attr "prefix" "maybe_vex")
5516 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5518 (const_string "*")))
5519 (set_attr "unit" "i387,*,*")
5520 (set_attr "athlon_decode" "*,double,direct")
5521 (set_attr "amdfam10_decode" "*,vector,double")
5522 (set_attr "fp_int_src" "true")])
5524 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5525 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5527 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5528 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5529 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5530 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5533 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5534 [(set_attr "type" "fmov,sseicvt")
5535 (set_attr "prefix" "orig,maybe_vex")
5536 (set_attr "mode" "<MODEF:MODE>")
5537 (set (attr "prefix_rex")
5539 (and (eq_attr "prefix" "maybe_vex")
5540 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5542 (const_string "*")))
5543 (set_attr "athlon_decode" "*,direct")
5544 (set_attr "amdfam10_decode" "*,double")
5545 (set_attr "fp_int_src" "true")])
5547 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5548 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5550 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5551 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5552 "TARGET_SSE2 && TARGET_SSE_MATH
5553 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5555 [(set_attr "type" "sseicvt")
5556 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5557 (set_attr "athlon_decode" "double,direct,double")
5558 (set_attr "amdfam10_decode" "vector,double,double")
5559 (set_attr "fp_int_src" "true")])
5561 (define_insn "*floatsi<mode>2_vector_sse"
5562 [(set (match_operand:MODEF 0 "register_operand" "=x")
5563 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5564 "TARGET_SSE2 && TARGET_SSE_MATH
5565 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5567 [(set_attr "type" "sseicvt")
5568 (set_attr "mode" "<MODE>")
5569 (set_attr "athlon_decode" "direct")
5570 (set_attr "amdfam10_decode" "double")
5571 (set_attr "fp_int_src" "true")])
5574 [(set (match_operand:MODEF 0 "register_operand" "")
5575 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5576 (clobber (match_operand:SI 2 "memory_operand" ""))]
5577 "TARGET_SSE2 && TARGET_SSE_MATH
5578 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5580 && (SSE_REG_P (operands[0])
5581 || (GET_CODE (operands[0]) == SUBREG
5582 && SSE_REG_P (operands[0])))"
5585 rtx op1 = operands[1];
5587 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5589 if (GET_CODE (op1) == SUBREG)
5590 op1 = SUBREG_REG (op1);
5592 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5594 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5595 emit_insn (gen_sse2_loadld (operands[4],
5596 CONST0_RTX (V4SImode), operands[1]));
5598 /* We can ignore possible trapping value in the
5599 high part of SSE register for non-trapping math. */
5600 else if (SSE_REG_P (op1) && !flag_trapping_math)
5601 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5604 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5605 emit_move_insn (operands[2], operands[1]);
5606 emit_insn (gen_sse2_loadld (operands[4],
5607 CONST0_RTX (V4SImode), operands[2]));
5610 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5615 [(set (match_operand:MODEF 0 "register_operand" "")
5616 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5617 (clobber (match_operand:SI 2 "memory_operand" ""))]
5618 "TARGET_SSE2 && TARGET_SSE_MATH
5619 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5621 && (SSE_REG_P (operands[0])
5622 || (GET_CODE (operands[0]) == SUBREG
5623 && SSE_REG_P (operands[0])))"
5626 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5628 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5630 emit_insn (gen_sse2_loadld (operands[4],
5631 CONST0_RTX (V4SImode), operands[1]));
5633 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5638 [(set (match_operand:MODEF 0 "register_operand" "")
5639 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5640 "TARGET_SSE2 && TARGET_SSE_MATH
5641 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5643 && (SSE_REG_P (operands[0])
5644 || (GET_CODE (operands[0]) == SUBREG
5645 && SSE_REG_P (operands[0])))"
5648 rtx op1 = operands[1];
5650 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5652 if (GET_CODE (op1) == SUBREG)
5653 op1 = SUBREG_REG (op1);
5655 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5657 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5658 emit_insn (gen_sse2_loadld (operands[4],
5659 CONST0_RTX (V4SImode), operands[1]));
5661 /* We can ignore possible trapping value in the
5662 high part of SSE register for non-trapping math. */
5663 else if (SSE_REG_P (op1) && !flag_trapping_math)
5664 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5668 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5673 [(set (match_operand:MODEF 0 "register_operand" "")
5674 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5675 "TARGET_SSE2 && TARGET_SSE_MATH
5676 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5678 && (SSE_REG_P (operands[0])
5679 || (GET_CODE (operands[0]) == SUBREG
5680 && SSE_REG_P (operands[0])))"
5683 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5685 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5687 emit_insn (gen_sse2_loadld (operands[4],
5688 CONST0_RTX (V4SImode), operands[1]));
5690 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5694 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5695 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5697 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5698 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5699 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5700 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5702 [(set_attr "type" "sseicvt")
5703 (set_attr "mode" "<MODEF:MODE>")
5704 (set_attr "athlon_decode" "double,direct")
5705 (set_attr "amdfam10_decode" "vector,double")
5706 (set_attr "fp_int_src" "true")])
5708 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5709 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5711 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5712 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5713 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5714 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5715 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5716 [(set_attr "type" "sseicvt")
5717 (set_attr "prefix" "maybe_vex")
5718 (set_attr "mode" "<MODEF:MODE>")
5719 (set (attr "prefix_rex")
5721 (and (eq_attr "prefix" "maybe_vex")
5722 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5724 (const_string "*")))
5725 (set_attr "athlon_decode" "double,direct")
5726 (set_attr "amdfam10_decode" "vector,double")
5727 (set_attr "fp_int_src" "true")])
5730 [(set (match_operand:MODEF 0 "register_operand" "")
5731 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5732 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5733 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5734 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5735 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5737 && (SSE_REG_P (operands[0])
5738 || (GET_CODE (operands[0]) == SUBREG
5739 && SSE_REG_P (operands[0])))"
5740 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5743 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5744 [(set (match_operand:MODEF 0 "register_operand" "=x")
5746 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5747 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5748 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5749 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5750 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5751 [(set_attr "type" "sseicvt")
5752 (set_attr "prefix" "maybe_vex")
5753 (set_attr "mode" "<MODEF:MODE>")
5754 (set (attr "prefix_rex")
5756 (and (eq_attr "prefix" "maybe_vex")
5757 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5759 (const_string "*")))
5760 (set_attr "athlon_decode" "direct")
5761 (set_attr "amdfam10_decode" "double")
5762 (set_attr "fp_int_src" "true")])
5765 [(set (match_operand:MODEF 0 "register_operand" "")
5766 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5767 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5768 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5769 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5770 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5772 && (SSE_REG_P (operands[0])
5773 || (GET_CODE (operands[0]) == SUBREG
5774 && SSE_REG_P (operands[0])))"
5775 [(set (match_dup 2) (match_dup 1))
5776 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5780 [(set (match_operand:MODEF 0 "register_operand" "")
5781 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5782 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5783 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5784 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5786 && (SSE_REG_P (operands[0])
5787 || (GET_CODE (operands[0]) == SUBREG
5788 && SSE_REG_P (operands[0])))"
5789 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5792 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5793 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5795 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5796 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5798 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5802 [(set_attr "type" "fmov,multi")
5803 (set_attr "mode" "<X87MODEF:MODE>")
5804 (set_attr "unit" "*,i387")
5805 (set_attr "fp_int_src" "true")])
5807 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5808 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5810 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5812 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5814 [(set_attr "type" "fmov")
5815 (set_attr "mode" "<X87MODEF:MODE>")
5816 (set_attr "fp_int_src" "true")])
5819 [(set (match_operand:X87MODEF 0 "register_operand" "")
5820 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5821 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5823 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5825 && FP_REG_P (operands[0])"
5826 [(set (match_dup 2) (match_dup 1))
5827 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5831 [(set (match_operand:X87MODEF 0 "register_operand" "")
5832 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5833 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5835 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5837 && FP_REG_P (operands[0])"
5838 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5841 ;; Avoid store forwarding (partial memory) stall penalty
5842 ;; by passing DImode value through XMM registers. */
5844 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5845 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5847 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5848 (clobber (match_scratch:V4SI 3 "=X,x"))
5849 (clobber (match_scratch:V4SI 4 "=X,x"))
5850 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5851 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5852 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5853 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5855 [(set_attr "type" "multi")
5856 (set_attr "mode" "<X87MODEF:MODE>")
5857 (set_attr "unit" "i387")
5858 (set_attr "fp_int_src" "true")])
5861 [(set (match_operand:X87MODEF 0 "register_operand" "")
5862 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5863 (clobber (match_scratch:V4SI 3 ""))
5864 (clobber (match_scratch:V4SI 4 ""))
5865 (clobber (match_operand:DI 2 "memory_operand" ""))]
5866 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5867 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5868 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5870 && FP_REG_P (operands[0])"
5871 [(set (match_dup 2) (match_dup 3))
5872 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5874 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5875 Assemble the 64-bit DImode value in an xmm register. */
5876 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5877 gen_rtx_SUBREG (SImode, operands[1], 0)));
5878 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5879 gen_rtx_SUBREG (SImode, operands[1], 4)));
5880 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5883 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5887 [(set (match_operand:X87MODEF 0 "register_operand" "")
5888 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5889 (clobber (match_scratch:V4SI 3 ""))
5890 (clobber (match_scratch:V4SI 4 ""))
5891 (clobber (match_operand:DI 2 "memory_operand" ""))]
5892 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5893 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5894 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5896 && FP_REG_P (operands[0])"
5897 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5900 ;; Avoid store forwarding (partial memory) stall penalty by extending
5901 ;; SImode value to DImode through XMM register instead of pushing two
5902 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5903 ;; targets benefit from this optimization. Also note that fild
5904 ;; loads from memory only.
5906 (define_insn "*floatunssi<mode>2_1"
5907 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5908 (unsigned_float:X87MODEF
5909 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5910 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5911 (clobber (match_scratch:SI 3 "=X,x"))]
5913 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5916 [(set_attr "type" "multi")
5917 (set_attr "mode" "<MODE>")])
5920 [(set (match_operand:X87MODEF 0 "register_operand" "")
5921 (unsigned_float:X87MODEF
5922 (match_operand:SI 1 "register_operand" "")))
5923 (clobber (match_operand:DI 2 "memory_operand" ""))
5924 (clobber (match_scratch:SI 3 ""))]
5926 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5928 && reload_completed"
5929 [(set (match_dup 2) (match_dup 1))
5931 (float:X87MODEF (match_dup 2)))]
5932 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5935 [(set (match_operand:X87MODEF 0 "register_operand" "")
5936 (unsigned_float:X87MODEF
5937 (match_operand:SI 1 "memory_operand" "")))
5938 (clobber (match_operand:DI 2 "memory_operand" ""))
5939 (clobber (match_scratch:SI 3 ""))]
5941 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5943 && reload_completed"
5944 [(set (match_dup 2) (match_dup 3))
5946 (float:X87MODEF (match_dup 2)))]
5948 emit_move_insn (operands[3], operands[1]);
5949 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5952 (define_expand "floatunssi<mode>2"
5954 [(set (match_operand:X87MODEF 0 "register_operand" "")
5955 (unsigned_float:X87MODEF
5956 (match_operand:SI 1 "nonimmediate_operand" "")))
5957 (clobber (match_dup 2))
5958 (clobber (match_scratch:SI 3 ""))])]
5960 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5962 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5964 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5966 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5971 enum ix86_stack_slot slot = (virtuals_instantiated
5974 operands[2] = assign_386_stack_local (DImode, slot);
5978 (define_expand "floatunsdisf2"
5979 [(use (match_operand:SF 0 "register_operand" ""))
5980 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5981 "TARGET_64BIT && TARGET_SSE_MATH"
5982 "x86_emit_floatuns (operands); DONE;")
5984 (define_expand "floatunsdidf2"
5985 [(use (match_operand:DF 0 "register_operand" ""))
5986 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5987 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5988 && TARGET_SSE2 && TARGET_SSE_MATH"
5991 x86_emit_floatuns (operands);
5993 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5999 (define_expand "add<mode>3"
6000 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6001 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6002 (match_operand:SDWIM 2 "<general_operand>" "")))]
6004 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6006 (define_insn_and_split "*add<dwi>3_doubleword"
6007 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6009 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6010 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6011 (clobber (reg:CC FLAGS_REG))]
6012 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6015 [(parallel [(set (reg:CC FLAGS_REG)
6016 (unspec:CC [(match_dup 1) (match_dup 2)]
6019 (plus:DWIH (match_dup 1) (match_dup 2)))])
6020 (parallel [(set (match_dup 3)
6024 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6026 (clobber (reg:CC FLAGS_REG))])]
6027 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6029 (define_insn "*add<mode>3_cc"
6030 [(set (reg:CC FLAGS_REG)
6032 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6033 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
6035 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
6036 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6037 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6038 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6039 [(set_attr "type" "alu")
6040 (set_attr "mode" "<MODE>")])
6042 (define_insn "addqi3_cc"
6043 [(set (reg:CC FLAGS_REG)
6045 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6046 (match_operand:QI 2 "general_operand" "qn,qm")]
6048 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6049 (plus:QI (match_dup 1) (match_dup 2)))]
6050 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6051 "add{b}\t{%2, %0|%0, %2}"
6052 [(set_attr "type" "alu")
6053 (set_attr "mode" "QI")])
6055 (define_insn "*lea_1"
6056 [(set (match_operand:DWIH 0 "register_operand" "=r")
6057 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
6059 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
6060 [(set_attr "type" "lea")
6061 (set_attr "mode" "<MODE>")])
6063 (define_insn "*lea_2"
6064 [(set (match_operand:SI 0 "register_operand" "=r")
6065 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6067 "lea{l}\t{%a1, %0|%0, %a1}"
6068 [(set_attr "type" "lea")
6069 (set_attr "mode" "SI")])
6071 (define_insn "*lea_2_zext"
6072 [(set (match_operand:DI 0 "register_operand" "=r")
6074 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6076 "lea{l}\t{%a1, %k0|%k0, %a1}"
6077 [(set_attr "type" "lea")
6078 (set_attr "mode" "SI")])
6080 (define_insn "*add<mode>_1"
6081 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6083 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6084 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6085 (clobber (reg:CC FLAGS_REG))]
6086 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6088 switch (get_attr_type (insn))
6091 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6092 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6095 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6096 if (operands[2] == const1_rtx)
6097 return "inc{<imodesuffix>}\t%0";
6100 gcc_assert (operands[2] == constm1_rtx);
6101 return "dec{<imodesuffix>}\t%0";
6105 /* Use add as much as possible to replace lea for AGU optimization. */
6106 if (which_alternative == 2 && TARGET_OPT_AGU)
6107 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6109 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6110 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6111 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6113 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6117 (cond [(and (eq_attr "alternative" "2")
6118 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6119 (const_string "lea")
6120 (eq_attr "alternative" "3")
6121 (const_string "lea")
6122 (match_operand:SWI48 2 "incdec_operand" "")
6123 (const_string "incdec")
6125 (const_string "alu")))
6126 (set (attr "length_immediate")
6128 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6130 (const_string "*")))
6131 (set_attr "mode" "<MODE>")])
6133 ;; It may seem that nonimmediate operand is proper one for operand 1.
6134 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6135 ;; we take care in ix86_binary_operator_ok to not allow two memory
6136 ;; operands so proper swapping will be done in reload. This allow
6137 ;; patterns constructed from addsi_1 to match.
6139 (define_insn "*addsi_1_zext"
6140 [(set (match_operand:DI 0 "register_operand" "=r,r")
6142 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6143 (match_operand:SI 2 "general_operand" "g,li"))))
6144 (clobber (reg:CC FLAGS_REG))]
6145 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6147 switch (get_attr_type (insn))
6150 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6151 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6154 if (operands[2] == const1_rtx)
6155 return "inc{l}\t%k0";
6158 gcc_assert (operands[2] == constm1_rtx);
6159 return "dec{l}\t%k0";
6163 if (x86_maybe_negate_const_int (&operands[2], SImode))
6164 return "sub{l}\t{%2, %k0|%k0, %2}";
6166 return "add{l}\t{%2, %k0|%k0, %2}";
6170 (cond [(eq_attr "alternative" "1")
6171 (const_string "lea")
6172 (match_operand:SI 2 "incdec_operand" "")
6173 (const_string "incdec")
6175 (const_string "alu")))
6176 (set (attr "length_immediate")
6178 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6180 (const_string "*")))
6181 (set_attr "mode" "SI")])
6183 (define_insn "*addhi_1"
6184 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6185 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6186 (match_operand:HI 2 "general_operand" "rn,rm")))
6187 (clobber (reg:CC FLAGS_REG))]
6188 "TARGET_PARTIAL_REG_STALL
6189 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6191 switch (get_attr_type (insn))
6194 if (operands[2] == const1_rtx)
6195 return "inc{w}\t%0";
6198 gcc_assert (operands[2] == constm1_rtx);
6199 return "dec{w}\t%0";
6203 if (x86_maybe_negate_const_int (&operands[2], HImode))
6204 return "sub{w}\t{%2, %0|%0, %2}";
6206 return "add{w}\t{%2, %0|%0, %2}";
6210 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6211 (const_string "incdec")
6212 (const_string "alu")))
6213 (set (attr "length_immediate")
6215 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6217 (const_string "*")))
6218 (set_attr "mode" "HI")])
6220 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6221 ;; type optimizations enabled by define-splits. This is not important
6222 ;; for PII, and in fact harmful because of partial register stalls.
6224 (define_insn "*addhi_1_lea"
6225 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6226 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6227 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6228 (clobber (reg:CC FLAGS_REG))]
6229 "!TARGET_PARTIAL_REG_STALL
6230 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6232 switch (get_attr_type (insn))
6238 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6239 if (operands[2] == const1_rtx)
6240 return "inc{w}\t%0";
6243 gcc_assert (operands[2] == constm1_rtx);
6244 return "dec{w}\t%0";
6248 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6249 if (x86_maybe_negate_const_int (&operands[2], HImode))
6250 return "sub{w}\t{%2, %0|%0, %2}";
6252 return "add{w}\t{%2, %0|%0, %2}";
6256 (if_then_else (eq_attr "alternative" "2")
6257 (const_string "lea")
6258 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6259 (const_string "incdec")
6260 (const_string "alu"))))
6261 (set (attr "length_immediate")
6263 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6265 (const_string "*")))
6266 (set_attr "mode" "HI,HI,SI")])
6268 (define_insn "*addqi_1"
6269 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6270 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6271 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6272 (clobber (reg:CC FLAGS_REG))]
6273 "TARGET_PARTIAL_REG_STALL
6274 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6276 int widen = (which_alternative == 2);
6277 switch (get_attr_type (insn))
6280 if (operands[2] == const1_rtx)
6281 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6284 gcc_assert (operands[2] == constm1_rtx);
6285 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6289 if (x86_maybe_negate_const_int (&operands[2], QImode))
6292 return "sub{l}\t{%2, %k0|%k0, %2}";
6294 return "sub{b}\t{%2, %0|%0, %2}";
6297 return "add{l}\t{%k2, %k0|%k0, %k2}";
6299 return "add{b}\t{%2, %0|%0, %2}";
6303 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6304 (const_string "incdec")
6305 (const_string "alu")))
6306 (set (attr "length_immediate")
6308 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6310 (const_string "*")))
6311 (set_attr "mode" "QI,QI,SI")])
6313 ;; %%% Potential partial reg stall on alternative 2. What to do?
6314 (define_insn "*addqi_1_lea"
6315 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6316 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6317 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6318 (clobber (reg:CC FLAGS_REG))]
6319 "!TARGET_PARTIAL_REG_STALL
6320 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6322 int widen = (which_alternative == 2);
6323 switch (get_attr_type (insn))
6329 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6330 if (operands[2] == const1_rtx)
6331 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6334 gcc_assert (operands[2] == constm1_rtx);
6335 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6339 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6340 if (x86_maybe_negate_const_int (&operands[2], QImode))
6343 return "sub{l}\t{%2, %k0|%k0, %2}";
6345 return "sub{b}\t{%2, %0|%0, %2}";
6348 return "add{l}\t{%k2, %k0|%k0, %k2}";
6350 return "add{b}\t{%2, %0|%0, %2}";
6354 (if_then_else (eq_attr "alternative" "3")
6355 (const_string "lea")
6356 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6357 (const_string "incdec")
6358 (const_string "alu"))))
6359 (set (attr "length_immediate")
6361 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6363 (const_string "*")))
6364 (set_attr "mode" "QI,QI,SI,SI")])
6366 (define_insn "*addqi_1_slp"
6367 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6368 (plus:QI (match_dup 0)
6369 (match_operand:QI 1 "general_operand" "qn,qnm")))
6370 (clobber (reg:CC FLAGS_REG))]
6371 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6372 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6374 switch (get_attr_type (insn))
6377 if (operands[1] == const1_rtx)
6378 return "inc{b}\t%0";
6381 gcc_assert (operands[1] == constm1_rtx);
6382 return "dec{b}\t%0";
6386 if (x86_maybe_negate_const_int (&operands[1], QImode))
6387 return "sub{b}\t{%1, %0|%0, %1}";
6389 return "add{b}\t{%1, %0|%0, %1}";
6393 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6394 (const_string "incdec")
6395 (const_string "alu1")))
6396 (set (attr "memory")
6397 (if_then_else (match_operand 1 "memory_operand" "")
6398 (const_string "load")
6399 (const_string "none")))
6400 (set_attr "mode" "QI")])
6402 (define_insn "*add<mode>_2"
6403 [(set (reg FLAGS_REG)
6406 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6407 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6409 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6410 (plus:SWI (match_dup 1) (match_dup 2)))]
6411 "ix86_match_ccmode (insn, CCGOCmode)
6412 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6414 switch (get_attr_type (insn))
6417 if (operands[2] == const1_rtx)
6418 return "inc{<imodesuffix>}\t%0";
6421 gcc_assert (operands[2] == constm1_rtx);
6422 return "dec{<imodesuffix>}\t%0";
6426 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6427 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6429 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6433 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6434 (const_string "incdec")
6435 (const_string "alu")))
6436 (set (attr "length_immediate")
6438 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6440 (const_string "*")))
6441 (set_attr "mode" "<MODE>")])
6443 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6444 (define_insn "*addsi_2_zext"
6445 [(set (reg FLAGS_REG)
6447 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6448 (match_operand:SI 2 "general_operand" "g"))
6450 (set (match_operand:DI 0 "register_operand" "=r")
6451 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6452 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6453 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6455 switch (get_attr_type (insn))
6458 if (operands[2] == const1_rtx)
6459 return "inc{l}\t%k0";
6462 gcc_assert (operands[2] == constm1_rtx);
6463 return "dec{l}\t%k0";
6467 if (x86_maybe_negate_const_int (&operands[2], SImode))
6468 return "sub{l}\t{%2, %k0|%k0, %2}";
6470 return "add{l}\t{%2, %k0|%k0, %2}";
6474 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6475 (const_string "incdec")
6476 (const_string "alu")))
6477 (set (attr "length_immediate")
6479 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6481 (const_string "*")))
6482 (set_attr "mode" "SI")])
6484 (define_insn "*add<mode>_3"
6485 [(set (reg FLAGS_REG)
6487 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6488 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6489 (clobber (match_scratch:SWI 0 "=<r>"))]
6490 "ix86_match_ccmode (insn, CCZmode)
6491 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6493 switch (get_attr_type (insn))
6496 if (operands[2] == const1_rtx)
6497 return "inc{<imodesuffix>}\t%0";
6500 gcc_assert (operands[2] == constm1_rtx);
6501 return "dec{<imodesuffix>}\t%0";
6505 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6506 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6508 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6512 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6513 (const_string "incdec")
6514 (const_string "alu")))
6515 (set (attr "length_immediate")
6517 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6519 (const_string "*")))
6520 (set_attr "mode" "<MODE>")])
6522 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6523 (define_insn "*addsi_3_zext"
6524 [(set (reg FLAGS_REG)
6526 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6527 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6528 (set (match_operand:DI 0 "register_operand" "=r")
6529 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6530 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6531 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6533 switch (get_attr_type (insn))
6536 if (operands[2] == const1_rtx)
6537 return "inc{l}\t%k0";
6540 gcc_assert (operands[2] == constm1_rtx);
6541 return "dec{l}\t%k0";
6545 if (x86_maybe_negate_const_int (&operands[2], SImode))
6546 return "sub{l}\t{%2, %k0|%k0, %2}";
6548 return "add{l}\t{%2, %k0|%k0, %2}";
6552 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6553 (const_string "incdec")
6554 (const_string "alu")))
6555 (set (attr "length_immediate")
6557 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6559 (const_string "*")))
6560 (set_attr "mode" "SI")])
6562 ; For comparisons against 1, -1 and 128, we may generate better code
6563 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6564 ; is matched then. We can't accept general immediate, because for
6565 ; case of overflows, the result is messed up.
6566 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6567 ; only for comparisons not depending on it.
6569 (define_insn "*adddi_4"
6570 [(set (reg FLAGS_REG)
6572 (match_operand:DI 1 "nonimmediate_operand" "0")
6573 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6574 (clobber (match_scratch:DI 0 "=rm"))]
6576 && ix86_match_ccmode (insn, CCGCmode)"
6578 switch (get_attr_type (insn))
6581 if (operands[2] == constm1_rtx)
6582 return "inc{q}\t%0";
6585 gcc_assert (operands[2] == const1_rtx);
6586 return "dec{q}\t%0";
6590 if (x86_maybe_negate_const_int (&operands[2], DImode))
6591 return "add{q}\t{%2, %0|%0, %2}";
6593 return "sub{q}\t{%2, %0|%0, %2}";
6597 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6598 (const_string "incdec")
6599 (const_string "alu")))
6600 (set (attr "length_immediate")
6602 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6604 (const_string "*")))
6605 (set_attr "mode" "DI")])
6607 ; For comparisons against 1, -1 and 128, we may generate better code
6608 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6609 ; is matched then. We can't accept general immediate, because for
6610 ; case of overflows, the result is messed up.
6611 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6612 ; only for comparisons not depending on it.
6614 (define_insn "*add<mode>_4"
6615 [(set (reg FLAGS_REG)
6617 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6618 (match_operand:SWI124 2 "const_int_operand" "n")))
6619 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6620 "ix86_match_ccmode (insn, CCGCmode)"
6622 switch (get_attr_type (insn))
6625 if (operands[2] == constm1_rtx)
6626 return "inc{<imodesuffix>}\t%0";
6629 gcc_assert (operands[2] == const1_rtx);
6630 return "dec{<imodesuffix>}\t%0";
6634 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6635 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6637 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6641 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6642 (const_string "incdec")
6643 (const_string "alu")))
6644 (set (attr "length_immediate")
6646 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6648 (const_string "*")))
6649 (set_attr "mode" "<MODE>")])
6651 (define_insn "*add<mode>_5"
6652 [(set (reg FLAGS_REG)
6655 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6656 (match_operand:SWI 2 "<general_operand>" "<g>"))
6658 (clobber (match_scratch:SWI 0 "=<r>"))]
6659 "ix86_match_ccmode (insn, CCGOCmode)
6660 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6662 switch (get_attr_type (insn))
6665 if (operands[2] == const1_rtx)
6666 return "inc{<imodesuffix>}\t%0";
6669 gcc_assert (operands[2] == constm1_rtx);
6670 return "dec{<imodesuffix>}\t%0";
6674 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6675 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6677 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6681 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6682 (const_string "incdec")
6683 (const_string "alu")))
6684 (set (attr "length_immediate")
6686 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6688 (const_string "*")))
6689 (set_attr "mode" "<MODE>")])
6691 (define_insn "*addqi_ext_1_rex64"
6692 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6697 (match_operand 1 "ext_register_operand" "0")
6700 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6701 (clobber (reg:CC FLAGS_REG))]
6704 switch (get_attr_type (insn))
6707 if (operands[2] == const1_rtx)
6708 return "inc{b}\t%h0";
6711 gcc_assert (operands[2] == constm1_rtx);
6712 return "dec{b}\t%h0";
6716 return "add{b}\t{%2, %h0|%h0, %2}";
6720 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6721 (const_string "incdec")
6722 (const_string "alu")))
6723 (set_attr "modrm" "1")
6724 (set_attr "mode" "QI")])
6726 (define_insn "addqi_ext_1"
6727 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6732 (match_operand 1 "ext_register_operand" "0")
6735 (match_operand:QI 2 "general_operand" "Qmn")))
6736 (clobber (reg:CC FLAGS_REG))]
6739 switch (get_attr_type (insn))
6742 if (operands[2] == const1_rtx)
6743 return "inc{b}\t%h0";
6746 gcc_assert (operands[2] == constm1_rtx);
6747 return "dec{b}\t%h0";
6751 return "add{b}\t{%2, %h0|%h0, %2}";
6755 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6756 (const_string "incdec")
6757 (const_string "alu")))
6758 (set_attr "modrm" "1")
6759 (set_attr "mode" "QI")])
6761 (define_insn "*addqi_ext_2"
6762 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6767 (match_operand 1 "ext_register_operand" "%0")
6771 (match_operand 2 "ext_register_operand" "Q")
6774 (clobber (reg:CC FLAGS_REG))]
6776 "add{b}\t{%h2, %h0|%h0, %h2}"
6777 [(set_attr "type" "alu")
6778 (set_attr "mode" "QI")])
6780 ;; The lea patterns for non-Pmodes needs to be matched by
6781 ;; several insns converted to real lea by splitters.
6783 (define_insn_and_split "*lea_general_1"
6784 [(set (match_operand 0 "register_operand" "=r")
6785 (plus (plus (match_operand 1 "index_register_operand" "l")
6786 (match_operand 2 "register_operand" "r"))
6787 (match_operand 3 "immediate_operand" "i")))]
6788 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6789 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6790 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6791 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6792 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6793 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6794 || GET_MODE (operands[3]) == VOIDmode)"
6796 "&& reload_completed"
6800 operands[0] = gen_lowpart (SImode, operands[0]);
6801 operands[1] = gen_lowpart (Pmode, operands[1]);
6802 operands[2] = gen_lowpart (Pmode, operands[2]);
6803 operands[3] = gen_lowpart (Pmode, operands[3]);
6804 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6806 if (Pmode != SImode)
6807 pat = gen_rtx_SUBREG (SImode, pat, 0);
6808 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6811 [(set_attr "type" "lea")
6812 (set_attr "mode" "SI")])
6814 (define_insn_and_split "*lea_general_1_zext"
6815 [(set (match_operand:DI 0 "register_operand" "=r")
6818 (match_operand:SI 1 "index_register_operand" "l")
6819 (match_operand:SI 2 "register_operand" "r"))
6820 (match_operand:SI 3 "immediate_operand" "i"))))]
6823 "&& reload_completed"
6825 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6827 (match_dup 3)) 0)))]
6829 operands[1] = gen_lowpart (Pmode, operands[1]);
6830 operands[2] = gen_lowpart (Pmode, operands[2]);
6831 operands[3] = gen_lowpart (Pmode, operands[3]);
6833 [(set_attr "type" "lea")
6834 (set_attr "mode" "SI")])
6836 (define_insn_and_split "*lea_general_2"
6837 [(set (match_operand 0 "register_operand" "=r")
6838 (plus (mult (match_operand 1 "index_register_operand" "l")
6839 (match_operand 2 "const248_operand" "i"))
6840 (match_operand 3 "nonmemory_operand" "ri")))]
6841 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6842 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6843 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6844 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6845 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6846 || GET_MODE (operands[3]) == VOIDmode)"
6848 "&& reload_completed"
6852 operands[0] = gen_lowpart (SImode, operands[0]);
6853 operands[1] = gen_lowpart (Pmode, operands[1]);
6854 operands[3] = gen_lowpart (Pmode, operands[3]);
6855 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6857 if (Pmode != SImode)
6858 pat = gen_rtx_SUBREG (SImode, pat, 0);
6859 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6862 [(set_attr "type" "lea")
6863 (set_attr "mode" "SI")])
6865 (define_insn_and_split "*lea_general_2_zext"
6866 [(set (match_operand:DI 0 "register_operand" "=r")
6869 (match_operand:SI 1 "index_register_operand" "l")
6870 (match_operand:SI 2 "const248_operand" "n"))
6871 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6874 "&& reload_completed"
6876 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6878 (match_dup 3)) 0)))]
6880 operands[1] = gen_lowpart (Pmode, operands[1]);
6881 operands[3] = gen_lowpart (Pmode, operands[3]);
6883 [(set_attr "type" "lea")
6884 (set_attr "mode" "SI")])
6886 (define_insn_and_split "*lea_general_3"
6887 [(set (match_operand 0 "register_operand" "=r")
6888 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6889 (match_operand 2 "const248_operand" "i"))
6890 (match_operand 3 "register_operand" "r"))
6891 (match_operand 4 "immediate_operand" "i")))]
6892 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6893 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6894 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6895 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6896 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6898 "&& reload_completed"
6902 operands[0] = gen_lowpart (SImode, operands[0]);
6903 operands[1] = gen_lowpart (Pmode, operands[1]);
6904 operands[3] = gen_lowpart (Pmode, operands[3]);
6905 operands[4] = gen_lowpart (Pmode, operands[4]);
6906 pat = gen_rtx_PLUS (Pmode,
6907 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6911 if (Pmode != SImode)
6912 pat = gen_rtx_SUBREG (SImode, pat, 0);
6913 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6916 [(set_attr "type" "lea")
6917 (set_attr "mode" "SI")])
6919 (define_insn_and_split "*lea_general_3_zext"
6920 [(set (match_operand:DI 0 "register_operand" "=r")
6924 (match_operand:SI 1 "index_register_operand" "l")
6925 (match_operand:SI 2 "const248_operand" "n"))
6926 (match_operand:SI 3 "register_operand" "r"))
6927 (match_operand:SI 4 "immediate_operand" "i"))))]
6930 "&& reload_completed"
6932 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6935 (match_dup 4)) 0)))]
6937 operands[1] = gen_lowpart (Pmode, operands[1]);
6938 operands[3] = gen_lowpart (Pmode, operands[3]);
6939 operands[4] = gen_lowpart (Pmode, operands[4]);
6941 [(set_attr "type" "lea")
6942 (set_attr "mode" "SI")])
6944 ;; Convert lea to the lea pattern to avoid flags dependency.
6946 [(set (match_operand:DI 0 "register_operand" "")
6947 (plus:DI (match_operand:DI 1 "register_operand" "")
6948 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6949 (clobber (reg:CC FLAGS_REG))]
6950 "TARGET_64BIT && reload_completed
6951 && ix86_lea_for_add_ok (PLUS, insn, operands)"
6953 (plus:DI (match_dup 1)
6957 ;; Convert lea to the lea pattern to avoid flags dependency.
6959 [(set (match_operand 0 "register_operand" "")
6960 (plus (match_operand 1 "register_operand" "")
6961 (match_operand 2 "nonmemory_operand" "")))
6962 (clobber (reg:CC FLAGS_REG))]
6963 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
6967 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6968 may confuse gen_lowpart. */
6969 if (GET_MODE (operands[0]) != Pmode)
6971 operands[1] = gen_lowpart (Pmode, operands[1]);
6972 operands[2] = gen_lowpart (Pmode, operands[2]);
6974 operands[0] = gen_lowpart (SImode, operands[0]);
6975 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6976 if (Pmode != SImode)
6977 pat = gen_rtx_SUBREG (SImode, pat, 0);
6978 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6982 ;; Convert lea to the lea pattern to avoid flags dependency.
6984 [(set (match_operand:DI 0 "register_operand" "")
6986 (plus:SI (match_operand:SI 1 "register_operand" "")
6987 (match_operand:SI 2 "nonmemory_operand" ""))))
6988 (clobber (reg:CC FLAGS_REG))]
6989 "TARGET_64BIT && reload_completed
6990 && true_regnum (operands[0]) != true_regnum (operands[1])"
6992 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6994 operands[1] = gen_lowpart (Pmode, operands[1]);
6995 operands[2] = gen_lowpart (Pmode, operands[2]);
6998 ;; Subtract instructions
7000 (define_expand "sub<mode>3"
7001 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7002 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7003 (match_operand:SDWIM 2 "<general_operand>" "")))]
7005 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7007 (define_insn_and_split "*sub<dwi>3_doubleword"
7008 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7010 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7011 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7012 (clobber (reg:CC FLAGS_REG))]
7013 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7016 [(parallel [(set (reg:CC FLAGS_REG)
7017 (compare:CC (match_dup 1) (match_dup 2)))
7019 (minus:DWIH (match_dup 1) (match_dup 2)))])
7020 (parallel [(set (match_dup 3)
7024 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7026 (clobber (reg:CC FLAGS_REG))])]
7027 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7029 (define_insn "*sub<mode>_1"
7030 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7032 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7033 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7034 (clobber (reg:CC FLAGS_REG))]
7035 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7036 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7037 [(set_attr "type" "alu")
7038 (set_attr "mode" "<MODE>")])
7040 (define_insn "*subsi_1_zext"
7041 [(set (match_operand:DI 0 "register_operand" "=r")
7043 (minus:SI (match_operand:SI 1 "register_operand" "0")
7044 (match_operand:SI 2 "general_operand" "g"))))
7045 (clobber (reg:CC FLAGS_REG))]
7046 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7047 "sub{l}\t{%2, %k0|%k0, %2}"
7048 [(set_attr "type" "alu")
7049 (set_attr "mode" "SI")])
7051 (define_insn "*subqi_1_slp"
7052 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7053 (minus:QI (match_dup 0)
7054 (match_operand:QI 1 "general_operand" "qn,qm")))
7055 (clobber (reg:CC FLAGS_REG))]
7056 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7057 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7058 "sub{b}\t{%1, %0|%0, %1}"
7059 [(set_attr "type" "alu1")
7060 (set_attr "mode" "QI")])
7062 (define_insn "*sub<mode>_2"
7063 [(set (reg FLAGS_REG)
7066 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7067 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7069 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7070 (minus:SWI (match_dup 1) (match_dup 2)))]
7071 "ix86_match_ccmode (insn, CCGOCmode)
7072 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7073 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7074 [(set_attr "type" "alu")
7075 (set_attr "mode" "<MODE>")])
7077 (define_insn "*subsi_2_zext"
7078 [(set (reg FLAGS_REG)
7080 (minus:SI (match_operand:SI 1 "register_operand" "0")
7081 (match_operand:SI 2 "general_operand" "g"))
7083 (set (match_operand:DI 0 "register_operand" "=r")
7085 (minus:SI (match_dup 1)
7087 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7088 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7089 "sub{l}\t{%2, %k0|%k0, %2}"
7090 [(set_attr "type" "alu")
7091 (set_attr "mode" "SI")])
7093 (define_insn "*sub<mode>_3"
7094 [(set (reg FLAGS_REG)
7095 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7096 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7097 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7098 (minus:SWI (match_dup 1) (match_dup 2)))]
7099 "ix86_match_ccmode (insn, CCmode)
7100 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7101 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7102 [(set_attr "type" "alu")
7103 (set_attr "mode" "<MODE>")])
7105 (define_insn "*subsi_3_zext"
7106 [(set (reg FLAGS_REG)
7107 (compare (match_operand:SI 1 "register_operand" "0")
7108 (match_operand:SI 2 "general_operand" "g")))
7109 (set (match_operand:DI 0 "register_operand" "=r")
7111 (minus:SI (match_dup 1)
7113 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7114 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7115 "sub{l}\t{%2, %1|%1, %2}"
7116 [(set_attr "type" "alu")
7117 (set_attr "mode" "SI")])
7119 ;; Add with carry and subtract with borrow
7121 (define_expand "<plusminus_insn><mode>3_carry"
7123 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7125 (match_operand:SWI 1 "nonimmediate_operand" "")
7126 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7127 [(match_operand 3 "flags_reg_operand" "")
7129 (match_operand:SWI 2 "<general_operand>" ""))))
7130 (clobber (reg:CC FLAGS_REG))])]
7131 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7134 (define_insn "*<plusminus_insn><mode>3_carry"
7135 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7137 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7139 (match_operator 3 "ix86_carry_flag_operator"
7140 [(reg FLAGS_REG) (const_int 0)])
7141 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7142 (clobber (reg:CC FLAGS_REG))]
7143 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7144 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7145 [(set_attr "type" "alu")
7146 (set_attr "use_carry" "1")
7147 (set_attr "pent_pair" "pu")
7148 (set_attr "mode" "<MODE>")])
7150 (define_insn "*addsi3_carry_zext"
7151 [(set (match_operand:DI 0 "register_operand" "=r")
7153 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7154 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7155 [(reg FLAGS_REG) (const_int 0)])
7156 (match_operand:SI 2 "general_operand" "g")))))
7157 (clobber (reg:CC FLAGS_REG))]
7158 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7159 "adc{l}\t{%2, %k0|%k0, %2}"
7160 [(set_attr "type" "alu")
7161 (set_attr "use_carry" "1")
7162 (set_attr "pent_pair" "pu")
7163 (set_attr "mode" "SI")])
7165 (define_insn "*subsi3_carry_zext"
7166 [(set (match_operand:DI 0 "register_operand" "=r")
7168 (minus:SI (match_operand:SI 1 "register_operand" "0")
7169 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7170 [(reg FLAGS_REG) (const_int 0)])
7171 (match_operand:SI 2 "general_operand" "g")))))
7172 (clobber (reg:CC FLAGS_REG))]
7173 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7174 "sbb{l}\t{%2, %k0|%k0, %2}"
7175 [(set_attr "type" "alu")
7176 (set_attr "pent_pair" "pu")
7177 (set_attr "mode" "SI")])
7179 ;; Overflow setting add and subtract instructions
7181 (define_insn "*add<mode>3_cconly_overflow"
7182 [(set (reg:CCC FLAGS_REG)
7185 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7186 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7188 (clobber (match_scratch:SWI 0 "=<r>"))]
7189 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7190 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7191 [(set_attr "type" "alu")
7192 (set_attr "mode" "<MODE>")])
7194 (define_insn "*sub<mode>3_cconly_overflow"
7195 [(set (reg:CCC FLAGS_REG)
7198 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7199 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7202 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7203 [(set_attr "type" "icmp")
7204 (set_attr "mode" "<MODE>")])
7206 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7207 [(set (reg:CCC FLAGS_REG)
7210 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7211 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7213 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7214 (plusminus:SWI (match_dup 1) (match_dup 2)))]
7215 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7216 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7217 [(set_attr "type" "alu")
7218 (set_attr "mode" "<MODE>")])
7220 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7221 [(set (reg:CCC FLAGS_REG)
7224 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7225 (match_operand:SI 2 "general_operand" "g"))
7227 (set (match_operand:DI 0 "register_operand" "=r")
7228 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7229 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7230 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7231 [(set_attr "type" "alu")
7232 (set_attr "mode" "SI")])
7234 ;; The patterns that match these are at the end of this file.
7236 (define_expand "<plusminus_insn>xf3"
7237 [(set (match_operand:XF 0 "register_operand" "")
7239 (match_operand:XF 1 "register_operand" "")
7240 (match_operand:XF 2 "register_operand" "")))]
7244 (define_expand "<plusminus_insn><mode>3"
7245 [(set (match_operand:MODEF 0 "register_operand" "")
7247 (match_operand:MODEF 1 "register_operand" "")
7248 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7249 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7250 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7253 ;; Multiply instructions
7255 (define_expand "mul<mode>3"
7256 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7258 (match_operand:SWIM248 1 "register_operand" "")
7259 (match_operand:SWIM248 2 "<general_operand>" "")))
7260 (clobber (reg:CC FLAGS_REG))])]
7264 (define_expand "mulqi3"
7265 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7267 (match_operand:QI 1 "register_operand" "")
7268 (match_operand:QI 2 "nonimmediate_operand" "")))
7269 (clobber (reg:CC FLAGS_REG))])]
7270 "TARGET_QIMODE_MATH"
7274 ;; IMUL reg32/64, reg32/64, imm8 Direct
7275 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7276 ;; IMUL reg32/64, reg32/64, imm32 Direct
7277 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7278 ;; IMUL reg32/64, reg32/64 Direct
7279 ;; IMUL reg32/64, mem32/64 Direct
7281 (define_insn "*mul<mode>3_1"
7282 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7284 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7285 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7286 (clobber (reg:CC FLAGS_REG))]
7287 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7289 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7290 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7291 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7292 [(set_attr "type" "imul")
7293 (set_attr "prefix_0f" "0,0,1")
7294 (set (attr "athlon_decode")
7295 (cond [(eq_attr "cpu" "athlon")
7296 (const_string "vector")
7297 (eq_attr "alternative" "1")
7298 (const_string "vector")
7299 (and (eq_attr "alternative" "2")
7300 (match_operand 1 "memory_operand" ""))
7301 (const_string "vector")]
7302 (const_string "direct")))
7303 (set (attr "amdfam10_decode")
7304 (cond [(and (eq_attr "alternative" "0,1")
7305 (match_operand 1 "memory_operand" ""))
7306 (const_string "vector")]
7307 (const_string "direct")))
7308 (set_attr "mode" "<MODE>")])
7310 (define_insn "*mulsi3_1_zext"
7311 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7313 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7314 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7315 (clobber (reg:CC FLAGS_REG))]
7317 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7319 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7320 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7321 imul{l}\t{%2, %k0|%k0, %2}"
7322 [(set_attr "type" "imul")
7323 (set_attr "prefix_0f" "0,0,1")
7324 (set (attr "athlon_decode")
7325 (cond [(eq_attr "cpu" "athlon")
7326 (const_string "vector")
7327 (eq_attr "alternative" "1")
7328 (const_string "vector")
7329 (and (eq_attr "alternative" "2")
7330 (match_operand 1 "memory_operand" ""))
7331 (const_string "vector")]
7332 (const_string "direct")))
7333 (set (attr "amdfam10_decode")
7334 (cond [(and (eq_attr "alternative" "0,1")
7335 (match_operand 1 "memory_operand" ""))
7336 (const_string "vector")]
7337 (const_string "direct")))
7338 (set_attr "mode" "SI")])
7341 ;; IMUL reg16, reg16, imm8 VectorPath
7342 ;; IMUL reg16, mem16, imm8 VectorPath
7343 ;; IMUL reg16, reg16, imm16 VectorPath
7344 ;; IMUL reg16, mem16, imm16 VectorPath
7345 ;; IMUL reg16, reg16 Direct
7346 ;; IMUL reg16, mem16 Direct
7348 (define_insn "*mulhi3_1"
7349 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7350 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7351 (match_operand:HI 2 "general_operand" "K,n,mr")))
7352 (clobber (reg:CC FLAGS_REG))]
7354 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7356 imul{w}\t{%2, %1, %0|%0, %1, %2}
7357 imul{w}\t{%2, %1, %0|%0, %1, %2}
7358 imul{w}\t{%2, %0|%0, %2}"
7359 [(set_attr "type" "imul")
7360 (set_attr "prefix_0f" "0,0,1")
7361 (set (attr "athlon_decode")
7362 (cond [(eq_attr "cpu" "athlon")
7363 (const_string "vector")
7364 (eq_attr "alternative" "1,2")
7365 (const_string "vector")]
7366 (const_string "direct")))
7367 (set (attr "amdfam10_decode")
7368 (cond [(eq_attr "alternative" "0,1")
7369 (const_string "vector")]
7370 (const_string "direct")))
7371 (set_attr "mode" "HI")])
7377 (define_insn "*mulqi3_1"
7378 [(set (match_operand:QI 0 "register_operand" "=a")
7379 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7380 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7381 (clobber (reg:CC FLAGS_REG))]
7383 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7385 [(set_attr "type" "imul")
7386 (set_attr "length_immediate" "0")
7387 (set (attr "athlon_decode")
7388 (if_then_else (eq_attr "cpu" "athlon")
7389 (const_string "vector")
7390 (const_string "direct")))
7391 (set_attr "amdfam10_decode" "direct")
7392 (set_attr "mode" "QI")])
7394 (define_expand "<u>mul<mode><dwi>3"
7395 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7398 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7400 (match_operand:DWIH 2 "register_operand" ""))))
7401 (clobber (reg:CC FLAGS_REG))])]
7405 (define_expand "<u>mulqihi3"
7406 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7409 (match_operand:QI 1 "nonimmediate_operand" ""))
7411 (match_operand:QI 2 "register_operand" ""))))
7412 (clobber (reg:CC FLAGS_REG))])]
7413 "TARGET_QIMODE_MATH"
7416 (define_insn "*<u>mul<mode><dwi>3_1"
7417 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7420 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7422 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7423 (clobber (reg:CC FLAGS_REG))]
7424 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7425 "<sgnprefix>mul{<imodesuffix>}\t%2"
7426 [(set_attr "type" "imul")
7427 (set_attr "length_immediate" "0")
7428 (set (attr "athlon_decode")
7429 (if_then_else (eq_attr "cpu" "athlon")
7430 (const_string "vector")
7431 (const_string "double")))
7432 (set_attr "amdfam10_decode" "double")
7433 (set_attr "mode" "<MODE>")])
7435 (define_insn "*<u>mulqihi3_1"
7436 [(set (match_operand:HI 0 "register_operand" "=a")
7439 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7441 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7442 (clobber (reg:CC FLAGS_REG))]
7444 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7445 "<sgnprefix>mul{b}\t%2"
7446 [(set_attr "type" "imul")
7447 (set_attr "length_immediate" "0")
7448 (set (attr "athlon_decode")
7449 (if_then_else (eq_attr "cpu" "athlon")
7450 (const_string "vector")
7451 (const_string "direct")))
7452 (set_attr "amdfam10_decode" "direct")
7453 (set_attr "mode" "QI")])
7455 (define_expand "<s>mul<mode>3_highpart"
7456 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7461 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7463 (match_operand:SWI48 2 "register_operand" "")))
7465 (clobber (match_scratch:SWI48 3 ""))
7466 (clobber (reg:CC FLAGS_REG))])]
7468 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7470 (define_insn "*<s>muldi3_highpart_1"
7471 [(set (match_operand:DI 0 "register_operand" "=d")
7476 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7478 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7480 (clobber (match_scratch:DI 3 "=1"))
7481 (clobber (reg:CC FLAGS_REG))]
7483 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7484 "<sgnprefix>mul{q}\t%2"
7485 [(set_attr "type" "imul")
7486 (set_attr "length_immediate" "0")
7487 (set (attr "athlon_decode")
7488 (if_then_else (eq_attr "cpu" "athlon")
7489 (const_string "vector")
7490 (const_string "double")))
7491 (set_attr "amdfam10_decode" "double")
7492 (set_attr "mode" "DI")])
7494 (define_insn "*<s>mulsi3_highpart_1"
7495 [(set (match_operand:SI 0 "register_operand" "=d")
7500 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7502 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7504 (clobber (match_scratch:SI 3 "=1"))
7505 (clobber (reg:CC FLAGS_REG))]
7506 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7507 "<sgnprefix>mul{l}\t%2"
7508 [(set_attr "type" "imul")
7509 (set_attr "length_immediate" "0")
7510 (set (attr "athlon_decode")
7511 (if_then_else (eq_attr "cpu" "athlon")
7512 (const_string "vector")
7513 (const_string "double")))
7514 (set_attr "amdfam10_decode" "double")
7515 (set_attr "mode" "SI")])
7517 (define_insn "*<s>mulsi3_highpart_zext"
7518 [(set (match_operand:DI 0 "register_operand" "=d")
7519 (zero_extend:DI (truncate:SI
7521 (mult:DI (any_extend:DI
7522 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7524 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7526 (clobber (match_scratch:SI 3 "=1"))
7527 (clobber (reg:CC FLAGS_REG))]
7529 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7530 "<sgnprefix>mul{l}\t%2"
7531 [(set_attr "type" "imul")
7532 (set_attr "length_immediate" "0")
7533 (set (attr "athlon_decode")
7534 (if_then_else (eq_attr "cpu" "athlon")
7535 (const_string "vector")
7536 (const_string "double")))
7537 (set_attr "amdfam10_decode" "double")
7538 (set_attr "mode" "SI")])
7540 ;; The patterns that match these are at the end of this file.
7542 (define_expand "mulxf3"
7543 [(set (match_operand:XF 0 "register_operand" "")
7544 (mult:XF (match_operand:XF 1 "register_operand" "")
7545 (match_operand:XF 2 "register_operand" "")))]
7549 (define_expand "mul<mode>3"
7550 [(set (match_operand:MODEF 0 "register_operand" "")
7551 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7552 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7553 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7554 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7557 ;; Divide instructions
7559 (define_insn "<u>divqi3"
7560 [(set (match_operand:QI 0 "register_operand" "=a")
7562 (match_operand:HI 1 "register_operand" "0")
7563 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7564 (clobber (reg:CC FLAGS_REG))]
7565 "TARGET_QIMODE_MATH"
7566 "<sgnprefix>div{b}\t%2"
7567 [(set_attr "type" "idiv")
7568 (set_attr "mode" "QI")])
7570 ;; The patterns that match these are at the end of this file.
7572 (define_expand "divxf3"
7573 [(set (match_operand:XF 0 "register_operand" "")
7574 (div:XF (match_operand:XF 1 "register_operand" "")
7575 (match_operand:XF 2 "register_operand" "")))]
7579 (define_expand "divdf3"
7580 [(set (match_operand:DF 0 "register_operand" "")
7581 (div:DF (match_operand:DF 1 "register_operand" "")
7582 (match_operand:DF 2 "nonimmediate_operand" "")))]
7583 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7584 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7587 (define_expand "divsf3"
7588 [(set (match_operand:SF 0 "register_operand" "")
7589 (div:SF (match_operand:SF 1 "register_operand" "")
7590 (match_operand:SF 2 "nonimmediate_operand" "")))]
7591 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7594 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7595 && flag_finite_math_only && !flag_trapping_math
7596 && flag_unsafe_math_optimizations)
7598 ix86_emit_swdivsf (operands[0], operands[1],
7599 operands[2], SFmode);
7604 ;; Divmod instructions.
7606 (define_expand "divmod<mode>4"
7607 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7609 (match_operand:SWIM248 1 "register_operand" "")
7610 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7611 (set (match_operand:SWIM248 3 "register_operand" "")
7612 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7613 (clobber (reg:CC FLAGS_REG))])]
7617 (define_insn_and_split "*divmod<mode>4"
7618 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7619 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7620 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7621 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7622 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7623 (clobber (reg:CC FLAGS_REG))]
7627 [(parallel [(set (match_dup 1)
7628 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7629 (clobber (reg:CC FLAGS_REG))])
7630 (parallel [(set (match_dup 0)
7631 (div:SWIM248 (match_dup 2) (match_dup 3)))
7633 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7635 (clobber (reg:CC FLAGS_REG))])]
7637 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7639 if (<MODE>mode != HImode
7640 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7641 operands[4] = operands[2];
7644 /* Avoid use of cltd in favor of a mov+shift. */
7645 emit_move_insn (operands[1], operands[2]);
7646 operands[4] = operands[1];
7649 [(set_attr "type" "multi")
7650 (set_attr "mode" "<MODE>")])
7652 (define_insn "*divmod<mode>4_noext"
7653 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7654 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7655 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7656 (set (match_operand:SWIM248 1 "register_operand" "=d")
7657 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7658 (use (match_operand:SWIM248 4 "register_operand" "1"))
7659 (clobber (reg:CC FLAGS_REG))]
7661 "idiv{<imodesuffix>}\t%3"
7662 [(set_attr "type" "idiv")
7663 (set_attr "mode" "<MODE>")])
7665 (define_expand "udivmod<mode>4"
7666 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7668 (match_operand:SWIM248 1 "register_operand" "")
7669 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7670 (set (match_operand:SWIM248 3 "register_operand" "")
7671 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7672 (clobber (reg:CC FLAGS_REG))])]
7676 (define_insn_and_split "*udivmod<mode>4"
7677 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7678 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7679 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7680 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7681 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7682 (clobber (reg:CC FLAGS_REG))]
7686 [(set (match_dup 1) (const_int 0))
7687 (parallel [(set (match_dup 0)
7688 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7690 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7692 (clobber (reg:CC FLAGS_REG))])]
7694 [(set_attr "type" "multi")
7695 (set_attr "mode" "<MODE>")])
7697 (define_insn "*udivmod<mode>4_noext"
7698 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7699 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7700 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7701 (set (match_operand:SWIM248 1 "register_operand" "=d")
7702 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7703 (use (match_operand:SWIM248 4 "register_operand" "1"))
7704 (clobber (reg:CC FLAGS_REG))]
7706 "div{<imodesuffix>}\t%3"
7707 [(set_attr "type" "idiv")
7708 (set_attr "mode" "<MODE>")])
7710 ;; We cannot use div/idiv for double division, because it causes
7711 ;; "division by zero" on the overflow and that's not what we expect
7712 ;; from truncate. Because true (non truncating) double division is
7713 ;; never generated, we can't create this insn anyway.
7716 ; [(set (match_operand:SI 0 "register_operand" "=a")
7718 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7720 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7721 ; (set (match_operand:SI 3 "register_operand" "=d")
7723 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7724 ; (clobber (reg:CC FLAGS_REG))]
7726 ; "div{l}\t{%2, %0|%0, %2}"
7727 ; [(set_attr "type" "idiv")])
7729 ;;- Logical AND instructions
7731 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7732 ;; Note that this excludes ah.
7734 (define_expand "testsi_ccno_1"
7735 [(set (reg:CCNO FLAGS_REG)
7737 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7738 (match_operand:SI 1 "nonmemory_operand" ""))
7743 (define_expand "testqi_ccz_1"
7744 [(set (reg:CCZ FLAGS_REG)
7745 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7746 (match_operand:QI 1 "nonmemory_operand" ""))
7751 (define_insn "*testdi_1"
7752 [(set (reg FLAGS_REG)
7755 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7756 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7758 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7759 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7761 test{l}\t{%k1, %k0|%k0, %k1}
7762 test{l}\t{%k1, %k0|%k0, %k1}
7763 test{q}\t{%1, %0|%0, %1}
7764 test{q}\t{%1, %0|%0, %1}
7765 test{q}\t{%1, %0|%0, %1}"
7766 [(set_attr "type" "test")
7767 (set_attr "modrm" "0,1,0,1,1")
7768 (set_attr "mode" "SI,SI,DI,DI,DI")])
7770 (define_insn "*testqi_1_maybe_si"
7771 [(set (reg FLAGS_REG)
7774 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7775 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7777 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7778 && ix86_match_ccmode (insn,
7779 CONST_INT_P (operands[1])
7780 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7782 if (which_alternative == 3)
7784 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7785 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7786 return "test{l}\t{%1, %k0|%k0, %1}";
7788 return "test{b}\t{%1, %0|%0, %1}";
7790 [(set_attr "type" "test")
7791 (set_attr "modrm" "0,1,1,1")
7792 (set_attr "mode" "QI,QI,QI,SI")
7793 (set_attr "pent_pair" "uv,np,uv,np")])
7795 (define_insn "*test<mode>_1"
7796 [(set (reg FLAGS_REG)
7799 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7800 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7802 "ix86_match_ccmode (insn, CCNOmode)
7803 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7804 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7805 [(set_attr "type" "test")
7806 (set_attr "modrm" "0,1,1")
7807 (set_attr "mode" "<MODE>")
7808 (set_attr "pent_pair" "uv,np,uv")])
7810 (define_expand "testqi_ext_ccno_0"
7811 [(set (reg:CCNO FLAGS_REG)
7815 (match_operand 0 "ext_register_operand" "")
7818 (match_operand 1 "const_int_operand" ""))
7823 (define_insn "*testqi_ext_0"
7824 [(set (reg FLAGS_REG)
7828 (match_operand 0 "ext_register_operand" "Q")
7831 (match_operand 1 "const_int_operand" "n"))
7833 "ix86_match_ccmode (insn, CCNOmode)"
7834 "test{b}\t{%1, %h0|%h0, %1}"
7835 [(set_attr "type" "test")
7836 (set_attr "mode" "QI")
7837 (set_attr "length_immediate" "1")
7838 (set_attr "modrm" "1")
7839 (set_attr "pent_pair" "np")])
7841 (define_insn "*testqi_ext_1_rex64"
7842 [(set (reg FLAGS_REG)
7846 (match_operand 0 "ext_register_operand" "Q")
7850 (match_operand:QI 1 "register_operand" "Q")))
7852 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7853 "test{b}\t{%1, %h0|%h0, %1}"
7854 [(set_attr "type" "test")
7855 (set_attr "mode" "QI")])
7857 (define_insn "*testqi_ext_1"
7858 [(set (reg FLAGS_REG)
7862 (match_operand 0 "ext_register_operand" "Q")
7866 (match_operand:QI 1 "general_operand" "Qm")))
7868 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7869 "test{b}\t{%1, %h0|%h0, %1}"
7870 [(set_attr "type" "test")
7871 (set_attr "mode" "QI")])
7873 (define_insn "*testqi_ext_2"
7874 [(set (reg FLAGS_REG)
7878 (match_operand 0 "ext_register_operand" "Q")
7882 (match_operand 1 "ext_register_operand" "Q")
7886 "ix86_match_ccmode (insn, CCNOmode)"
7887 "test{b}\t{%h1, %h0|%h0, %h1}"
7888 [(set_attr "type" "test")
7889 (set_attr "mode" "QI")])
7891 (define_insn "*testqi_ext_3_rex64"
7892 [(set (reg FLAGS_REG)
7893 (compare (zero_extract:DI
7894 (match_operand 0 "nonimmediate_operand" "rm")
7895 (match_operand:DI 1 "const_int_operand" "")
7896 (match_operand:DI 2 "const_int_operand" ""))
7899 && ix86_match_ccmode (insn, CCNOmode)
7900 && INTVAL (operands[1]) > 0
7901 && INTVAL (operands[2]) >= 0
7902 /* Ensure that resulting mask is zero or sign extended operand. */
7903 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7904 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7905 && INTVAL (operands[1]) > 32))
7906 && (GET_MODE (operands[0]) == SImode
7907 || GET_MODE (operands[0]) == DImode
7908 || GET_MODE (operands[0]) == HImode
7909 || GET_MODE (operands[0]) == QImode)"
7912 ;; Combine likes to form bit extractions for some tests. Humor it.
7913 (define_insn "*testqi_ext_3"
7914 [(set (reg FLAGS_REG)
7915 (compare (zero_extract:SI
7916 (match_operand 0 "nonimmediate_operand" "rm")
7917 (match_operand:SI 1 "const_int_operand" "")
7918 (match_operand:SI 2 "const_int_operand" ""))
7920 "ix86_match_ccmode (insn, CCNOmode)
7921 && INTVAL (operands[1]) > 0
7922 && INTVAL (operands[2]) >= 0
7923 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7924 && (GET_MODE (operands[0]) == SImode
7925 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7926 || GET_MODE (operands[0]) == HImode
7927 || GET_MODE (operands[0]) == QImode)"
7931 [(set (match_operand 0 "flags_reg_operand" "")
7932 (match_operator 1 "compare_operator"
7934 (match_operand 2 "nonimmediate_operand" "")
7935 (match_operand 3 "const_int_operand" "")
7936 (match_operand 4 "const_int_operand" ""))
7938 "ix86_match_ccmode (insn, CCNOmode)"
7939 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7941 rtx val = operands[2];
7942 HOST_WIDE_INT len = INTVAL (operands[3]);
7943 HOST_WIDE_INT pos = INTVAL (operands[4]);
7945 enum machine_mode mode, submode;
7947 mode = GET_MODE (val);
7950 /* ??? Combine likes to put non-volatile mem extractions in QImode
7951 no matter the size of the test. So find a mode that works. */
7952 if (! MEM_VOLATILE_P (val))
7954 mode = smallest_mode_for_size (pos + len, MODE_INT);
7955 val = adjust_address (val, mode, 0);
7958 else if (GET_CODE (val) == SUBREG
7959 && (submode = GET_MODE (SUBREG_REG (val)),
7960 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7961 && pos + len <= GET_MODE_BITSIZE (submode)
7962 && GET_MODE_CLASS (submode) == MODE_INT)
7964 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7966 val = SUBREG_REG (val);
7968 else if (mode == HImode && pos + len <= 8)
7970 /* Small HImode tests can be converted to QImode. */
7972 val = gen_lowpart (QImode, val);
7975 if (len == HOST_BITS_PER_WIDE_INT)
7978 mask = ((HOST_WIDE_INT)1 << len) - 1;
7981 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7984 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7985 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7986 ;; this is relatively important trick.
7987 ;; Do the conversion only post-reload to avoid limiting of the register class
7990 [(set (match_operand 0 "flags_reg_operand" "")
7991 (match_operator 1 "compare_operator"
7992 [(and (match_operand 2 "register_operand" "")
7993 (match_operand 3 "const_int_operand" ""))
7996 && QI_REG_P (operands[2])
7997 && GET_MODE (operands[2]) != QImode
7998 && ((ix86_match_ccmode (insn, CCZmode)
7999 && !(INTVAL (operands[3]) & ~(255 << 8)))
8000 || (ix86_match_ccmode (insn, CCNOmode)
8001 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8004 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8007 "operands[2] = gen_lowpart (SImode, operands[2]);
8008 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8011 [(set (match_operand 0 "flags_reg_operand" "")
8012 (match_operator 1 "compare_operator"
8013 [(and (match_operand 2 "nonimmediate_operand" "")
8014 (match_operand 3 "const_int_operand" ""))
8017 && GET_MODE (operands[2]) != QImode
8018 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8019 && ((ix86_match_ccmode (insn, CCZmode)
8020 && !(INTVAL (operands[3]) & ~255))
8021 || (ix86_match_ccmode (insn, CCNOmode)
8022 && !(INTVAL (operands[3]) & ~127)))"
8024 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8026 "operands[2] = gen_lowpart (QImode, operands[2]);
8027 operands[3] = gen_lowpart (QImode, operands[3]);")
8029 ;; %%% This used to optimize known byte-wide and operations to memory,
8030 ;; and sometimes to QImode registers. If this is considered useful,
8031 ;; it should be done with splitters.
8033 (define_expand "and<mode>3"
8034 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8035 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8036 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8038 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8040 (define_insn "*anddi_1"
8041 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8043 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8044 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8045 (clobber (reg:CC FLAGS_REG))]
8046 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8048 switch (get_attr_type (insn))
8052 enum machine_mode mode;
8054 gcc_assert (CONST_INT_P (operands[2]));
8055 if (INTVAL (operands[2]) == 0xff)
8059 gcc_assert (INTVAL (operands[2]) == 0xffff);
8063 operands[1] = gen_lowpart (mode, operands[1]);
8065 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8067 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8071 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8072 if (get_attr_mode (insn) == MODE_SI)
8073 return "and{l}\t{%k2, %k0|%k0, %k2}";
8075 return "and{q}\t{%2, %0|%0, %2}";
8078 [(set_attr "type" "alu,alu,alu,imovx")
8079 (set_attr "length_immediate" "*,*,*,0")
8080 (set (attr "prefix_rex")
8082 (and (eq_attr "type" "imovx")
8083 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8084 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8086 (const_string "*")))
8087 (set_attr "mode" "SI,DI,DI,SI")])
8089 (define_insn "*andsi_1"
8090 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8091 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8092 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8093 (clobber (reg:CC FLAGS_REG))]
8094 "ix86_binary_operator_ok (AND, SImode, operands)"
8096 switch (get_attr_type (insn))
8100 enum machine_mode mode;
8102 gcc_assert (CONST_INT_P (operands[2]));
8103 if (INTVAL (operands[2]) == 0xff)
8107 gcc_assert (INTVAL (operands[2]) == 0xffff);
8111 operands[1] = gen_lowpart (mode, operands[1]);
8113 return "movz{bl|x}\t{%1, %0|%0, %1}";
8115 return "movz{wl|x}\t{%1, %0|%0, %1}";
8119 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8120 return "and{l}\t{%2, %0|%0, %2}";
8123 [(set_attr "type" "alu,alu,imovx")
8124 (set (attr "prefix_rex")
8126 (and (eq_attr "type" "imovx")
8127 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8128 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8130 (const_string "*")))
8131 (set_attr "length_immediate" "*,*,0")
8132 (set_attr "mode" "SI")])
8134 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8135 (define_insn "*andsi_1_zext"
8136 [(set (match_operand:DI 0 "register_operand" "=r")
8138 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8139 (match_operand:SI 2 "general_operand" "g"))))
8140 (clobber (reg:CC FLAGS_REG))]
8141 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8142 "and{l}\t{%2, %k0|%k0, %2}"
8143 [(set_attr "type" "alu")
8144 (set_attr "mode" "SI")])
8146 (define_insn "*andhi_1"
8147 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8148 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8149 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8150 (clobber (reg:CC FLAGS_REG))]
8151 "ix86_binary_operator_ok (AND, HImode, operands)"
8153 switch (get_attr_type (insn))
8156 gcc_assert (CONST_INT_P (operands[2]));
8157 gcc_assert (INTVAL (operands[2]) == 0xff);
8158 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8161 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8163 return "and{w}\t{%2, %0|%0, %2}";
8166 [(set_attr "type" "alu,alu,imovx")
8167 (set_attr "length_immediate" "*,*,0")
8168 (set (attr "prefix_rex")
8170 (and (eq_attr "type" "imovx")
8171 (match_operand 1 "ext_QIreg_nomode_operand" ""))
8173 (const_string "*")))
8174 (set_attr "mode" "HI,HI,SI")])
8176 ;; %%% Potential partial reg stall on alternative 2. What to do?
8177 (define_insn "*andqi_1"
8178 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8179 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8180 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8181 (clobber (reg:CC FLAGS_REG))]
8182 "ix86_binary_operator_ok (AND, QImode, operands)"
8184 and{b}\t{%2, %0|%0, %2}
8185 and{b}\t{%2, %0|%0, %2}
8186 and{l}\t{%k2, %k0|%k0, %k2}"
8187 [(set_attr "type" "alu")
8188 (set_attr "mode" "QI,QI,SI")])
8190 (define_insn "*andqi_1_slp"
8191 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8192 (and:QI (match_dup 0)
8193 (match_operand:QI 1 "general_operand" "qn,qmn")))
8194 (clobber (reg:CC FLAGS_REG))]
8195 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8196 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8197 "and{b}\t{%1, %0|%0, %1}"
8198 [(set_attr "type" "alu1")
8199 (set_attr "mode" "QI")])
8202 [(set (match_operand 0 "register_operand" "")
8204 (const_int -65536)))
8205 (clobber (reg:CC FLAGS_REG))]
8206 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8207 || optimize_function_for_size_p (cfun)"
8208 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8209 "operands[1] = gen_lowpart (HImode, operands[0]);")
8212 [(set (match_operand 0 "ext_register_operand" "")
8215 (clobber (reg:CC FLAGS_REG))]
8216 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8217 && reload_completed"
8218 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8219 "operands[1] = gen_lowpart (QImode, operands[0]);")
8222 [(set (match_operand 0 "ext_register_operand" "")
8224 (const_int -65281)))
8225 (clobber (reg:CC FLAGS_REG))]
8226 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8227 && reload_completed"
8228 [(parallel [(set (zero_extract:SI (match_dup 0)
8232 (zero_extract:SI (match_dup 0)
8235 (zero_extract:SI (match_dup 0)
8238 (clobber (reg:CC FLAGS_REG))])]
8239 "operands[0] = gen_lowpart (SImode, operands[0]);")
8241 (define_insn "*anddi_2"
8242 [(set (reg FLAGS_REG)
8245 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8246 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8248 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8249 (and:DI (match_dup 1) (match_dup 2)))]
8250 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8251 && ix86_binary_operator_ok (AND, DImode, operands)"
8253 and{l}\t{%k2, %k0|%k0, %k2}
8254 and{q}\t{%2, %0|%0, %2}
8255 and{q}\t{%2, %0|%0, %2}"
8256 [(set_attr "type" "alu")
8257 (set_attr "mode" "SI,DI,DI")])
8259 (define_insn "*andqi_2_maybe_si"
8260 [(set (reg FLAGS_REG)
8262 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8263 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8265 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8266 (and:QI (match_dup 1) (match_dup 2)))]
8267 "ix86_binary_operator_ok (AND, QImode, operands)
8268 && ix86_match_ccmode (insn,
8269 CONST_INT_P (operands[2])
8270 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8272 if (which_alternative == 2)
8274 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8275 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8276 return "and{l}\t{%2, %k0|%k0, %2}";
8278 return "and{b}\t{%2, %0|%0, %2}";
8280 [(set_attr "type" "alu")
8281 (set_attr "mode" "QI,QI,SI")])
8283 (define_insn "*and<mode>_2"
8284 [(set (reg FLAGS_REG)
8285 (compare (and:SWI124
8286 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8287 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8289 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8290 (and:SWI124 (match_dup 1) (match_dup 2)))]
8291 "ix86_match_ccmode (insn, CCNOmode)
8292 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8293 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8294 [(set_attr "type" "alu")
8295 (set_attr "mode" "<MODE>")])
8297 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8298 (define_insn "*andsi_2_zext"
8299 [(set (reg FLAGS_REG)
8301 (match_operand:SI 1 "nonimmediate_operand" "%0")
8302 (match_operand:SI 2 "general_operand" "g"))
8304 (set (match_operand:DI 0 "register_operand" "=r")
8305 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8306 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8307 && ix86_binary_operator_ok (AND, SImode, operands)"
8308 "and{l}\t{%2, %k0|%k0, %2}"
8309 [(set_attr "type" "alu")
8310 (set_attr "mode" "SI")])
8312 (define_insn "*andqi_2_slp"
8313 [(set (reg FLAGS_REG)
8315 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8316 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8318 (set (strict_low_part (match_dup 0))
8319 (and:QI (match_dup 0) (match_dup 1)))]
8320 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8321 && ix86_match_ccmode (insn, CCNOmode)
8322 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8323 "and{b}\t{%1, %0|%0, %1}"
8324 [(set_attr "type" "alu1")
8325 (set_attr "mode" "QI")])
8327 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8328 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8329 ;; for a QImode operand, which of course failed.
8330 (define_insn "andqi_ext_0"
8331 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8336 (match_operand 1 "ext_register_operand" "0")
8339 (match_operand 2 "const_int_operand" "n")))
8340 (clobber (reg:CC FLAGS_REG))]
8342 "and{b}\t{%2, %h0|%h0, %2}"
8343 [(set_attr "type" "alu")
8344 (set_attr "length_immediate" "1")
8345 (set_attr "modrm" "1")
8346 (set_attr "mode" "QI")])
8348 ;; Generated by peephole translating test to and. This shows up
8349 ;; often in fp comparisons.
8350 (define_insn "*andqi_ext_0_cc"
8351 [(set (reg FLAGS_REG)
8355 (match_operand 1 "ext_register_operand" "0")
8358 (match_operand 2 "const_int_operand" "n"))
8360 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8369 "ix86_match_ccmode (insn, CCNOmode)"
8370 "and{b}\t{%2, %h0|%h0, %2}"
8371 [(set_attr "type" "alu")
8372 (set_attr "length_immediate" "1")
8373 (set_attr "modrm" "1")
8374 (set_attr "mode" "QI")])
8376 (define_insn "*andqi_ext_1_rex64"
8377 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8382 (match_operand 1 "ext_register_operand" "0")
8386 (match_operand 2 "ext_register_operand" "Q"))))
8387 (clobber (reg:CC FLAGS_REG))]
8389 "and{b}\t{%2, %h0|%h0, %2}"
8390 [(set_attr "type" "alu")
8391 (set_attr "length_immediate" "0")
8392 (set_attr "mode" "QI")])
8394 (define_insn "*andqi_ext_1"
8395 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8400 (match_operand 1 "ext_register_operand" "0")
8404 (match_operand:QI 2 "general_operand" "Qm"))))
8405 (clobber (reg:CC FLAGS_REG))]
8407 "and{b}\t{%2, %h0|%h0, %2}"
8408 [(set_attr "type" "alu")
8409 (set_attr "length_immediate" "0")
8410 (set_attr "mode" "QI")])
8412 (define_insn "*andqi_ext_2"
8413 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8418 (match_operand 1 "ext_register_operand" "%0")
8422 (match_operand 2 "ext_register_operand" "Q")
8425 (clobber (reg:CC FLAGS_REG))]
8427 "and{b}\t{%h2, %h0|%h0, %h2}"
8428 [(set_attr "type" "alu")
8429 (set_attr "length_immediate" "0")
8430 (set_attr "mode" "QI")])
8432 ;; Convert wide AND instructions with immediate operand to shorter QImode
8433 ;; equivalents when possible.
8434 ;; Don't do the splitting with memory operands, since it introduces risk
8435 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8436 ;; for size, but that can (should?) be handled by generic code instead.
8438 [(set (match_operand 0 "register_operand" "")
8439 (and (match_operand 1 "register_operand" "")
8440 (match_operand 2 "const_int_operand" "")))
8441 (clobber (reg:CC FLAGS_REG))]
8443 && QI_REG_P (operands[0])
8444 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8445 && !(~INTVAL (operands[2]) & ~(255 << 8))
8446 && GET_MODE (operands[0]) != QImode"
8447 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8448 (and:SI (zero_extract:SI (match_dup 1)
8449 (const_int 8) (const_int 8))
8451 (clobber (reg:CC FLAGS_REG))])]
8452 "operands[0] = gen_lowpart (SImode, operands[0]);
8453 operands[1] = gen_lowpart (SImode, operands[1]);
8454 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8456 ;; Since AND can be encoded with sign extended immediate, this is only
8457 ;; profitable when 7th bit is not set.
8459 [(set (match_operand 0 "register_operand" "")
8460 (and (match_operand 1 "general_operand" "")
8461 (match_operand 2 "const_int_operand" "")))
8462 (clobber (reg:CC FLAGS_REG))]
8464 && ANY_QI_REG_P (operands[0])
8465 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8466 && !(~INTVAL (operands[2]) & ~255)
8467 && !(INTVAL (operands[2]) & 128)
8468 && GET_MODE (operands[0]) != QImode"
8469 [(parallel [(set (strict_low_part (match_dup 0))
8470 (and:QI (match_dup 1)
8472 (clobber (reg:CC FLAGS_REG))])]
8473 "operands[0] = gen_lowpart (QImode, operands[0]);
8474 operands[1] = gen_lowpart (QImode, operands[1]);
8475 operands[2] = gen_lowpart (QImode, operands[2]);")
8477 ;; Logical inclusive and exclusive OR instructions
8479 ;; %%% This used to optimize known byte-wide and operations to memory.
8480 ;; If this is considered useful, it should be done with splitters.
8482 (define_expand "<code><mode>3"
8483 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8484 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8485 (match_operand:SWIM 2 "<general_operand>" "")))]
8487 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8489 (define_insn "*<code><mode>_1"
8490 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8492 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8493 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8494 (clobber (reg:CC FLAGS_REG))]
8495 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8496 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8497 [(set_attr "type" "alu")
8498 (set_attr "mode" "<MODE>")])
8500 ;; %%% Potential partial reg stall on alternative 2. What to do?
8501 (define_insn "*<code>qi_1"
8502 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8503 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8504 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8505 (clobber (reg:CC FLAGS_REG))]
8506 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8508 <logic>{b}\t{%2, %0|%0, %2}
8509 <logic>{b}\t{%2, %0|%0, %2}
8510 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8511 [(set_attr "type" "alu")
8512 (set_attr "mode" "QI,QI,SI")])
8514 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8515 (define_insn "*<code>si_1_zext"
8516 [(set (match_operand:DI 0 "register_operand" "=r")
8518 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8519 (match_operand:SI 2 "general_operand" "g"))))
8520 (clobber (reg:CC FLAGS_REG))]
8521 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8522 "<logic>{l}\t{%2, %k0|%k0, %2}"
8523 [(set_attr "type" "alu")
8524 (set_attr "mode" "SI")])
8526 (define_insn "*<code>si_1_zext_imm"
8527 [(set (match_operand:DI 0 "register_operand" "=r")
8529 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8530 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8531 (clobber (reg:CC FLAGS_REG))]
8532 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8533 "<logic>{l}\t{%2, %k0|%k0, %2}"
8534 [(set_attr "type" "alu")
8535 (set_attr "mode" "SI")])
8537 (define_insn "*<code>qi_1_slp"
8538 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8539 (any_or:QI (match_dup 0)
8540 (match_operand:QI 1 "general_operand" "qmn,qn")))
8541 (clobber (reg:CC FLAGS_REG))]
8542 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8543 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8544 "<logic>{b}\t{%1, %0|%0, %1}"
8545 [(set_attr "type" "alu1")
8546 (set_attr "mode" "QI")])
8548 (define_insn "*<code><mode>_2"
8549 [(set (reg FLAGS_REG)
8550 (compare (any_or:SWI
8551 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8552 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8554 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8555 (any_or:SWI (match_dup 1) (match_dup 2)))]
8556 "ix86_match_ccmode (insn, CCNOmode)
8557 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8558 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8559 [(set_attr "type" "alu")
8560 (set_attr "mode" "<MODE>")])
8562 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8563 ;; ??? Special case for immediate operand is missing - it is tricky.
8564 (define_insn "*<code>si_2_zext"
8565 [(set (reg FLAGS_REG)
8566 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8567 (match_operand:SI 2 "general_operand" "g"))
8569 (set (match_operand:DI 0 "register_operand" "=r")
8570 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8571 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8572 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8573 "<logic>{l}\t{%2, %k0|%k0, %2}"
8574 [(set_attr "type" "alu")
8575 (set_attr "mode" "SI")])
8577 (define_insn "*<code>si_2_zext_imm"
8578 [(set (reg FLAGS_REG)
8580 (match_operand:SI 1 "nonimmediate_operand" "%0")
8581 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8583 (set (match_operand:DI 0 "register_operand" "=r")
8584 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8585 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8586 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8587 "<logic>{l}\t{%2, %k0|%k0, %2}"
8588 [(set_attr "type" "alu")
8589 (set_attr "mode" "SI")])
8591 (define_insn "*<code>qi_2_slp"
8592 [(set (reg FLAGS_REG)
8593 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8594 (match_operand:QI 1 "general_operand" "qmn,qn"))
8596 (set (strict_low_part (match_dup 0))
8597 (any_or:QI (match_dup 0) (match_dup 1)))]
8598 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8599 && ix86_match_ccmode (insn, CCNOmode)
8600 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8601 "<logic>{b}\t{%1, %0|%0, %1}"
8602 [(set_attr "type" "alu1")
8603 (set_attr "mode" "QI")])
8605 (define_insn "*<code><mode>_3"
8606 [(set (reg FLAGS_REG)
8607 (compare (any_or:SWI
8608 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8609 (match_operand:SWI 2 "<general_operand>" "<g>"))
8611 (clobber (match_scratch:SWI 0 "=<r>"))]
8612 "ix86_match_ccmode (insn, CCNOmode)
8613 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8614 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8615 [(set_attr "type" "alu")
8616 (set_attr "mode" "<MODE>")])
8618 (define_insn "*<code>qi_ext_0"
8619 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8624 (match_operand 1 "ext_register_operand" "0")
8627 (match_operand 2 "const_int_operand" "n")))
8628 (clobber (reg:CC FLAGS_REG))]
8629 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8630 "<logic>{b}\t{%2, %h0|%h0, %2}"
8631 [(set_attr "type" "alu")
8632 (set_attr "length_immediate" "1")
8633 (set_attr "modrm" "1")
8634 (set_attr "mode" "QI")])
8636 (define_insn "*<code>qi_ext_1_rex64"
8637 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8642 (match_operand 1 "ext_register_operand" "0")
8646 (match_operand 2 "ext_register_operand" "Q"))))
8647 (clobber (reg:CC FLAGS_REG))]
8649 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8650 "<logic>{b}\t{%2, %h0|%h0, %2}"
8651 [(set_attr "type" "alu")
8652 (set_attr "length_immediate" "0")
8653 (set_attr "mode" "QI")])
8655 (define_insn "*<code>qi_ext_1"
8656 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8661 (match_operand 1 "ext_register_operand" "0")
8665 (match_operand:QI 2 "general_operand" "Qm"))))
8666 (clobber (reg:CC FLAGS_REG))]
8668 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8669 "<logic>{b}\t{%2, %h0|%h0, %2}"
8670 [(set_attr "type" "alu")
8671 (set_attr "length_immediate" "0")
8672 (set_attr "mode" "QI")])
8674 (define_insn "*<code>qi_ext_2"
8675 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8679 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8682 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8685 (clobber (reg:CC FLAGS_REG))]
8686 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8687 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8688 [(set_attr "type" "alu")
8689 (set_attr "length_immediate" "0")
8690 (set_attr "mode" "QI")])
8693 [(set (match_operand 0 "register_operand" "")
8694 (any_or (match_operand 1 "register_operand" "")
8695 (match_operand 2 "const_int_operand" "")))
8696 (clobber (reg:CC FLAGS_REG))]
8698 && QI_REG_P (operands[0])
8699 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8700 && !(INTVAL (operands[2]) & ~(255 << 8))
8701 && GET_MODE (operands[0]) != QImode"
8702 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8703 (any_or:SI (zero_extract:SI (match_dup 1)
8704 (const_int 8) (const_int 8))
8706 (clobber (reg:CC FLAGS_REG))])]
8707 "operands[0] = gen_lowpart (SImode, operands[0]);
8708 operands[1] = gen_lowpart (SImode, operands[1]);
8709 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8711 ;; Since OR can be encoded with sign extended immediate, this is only
8712 ;; profitable when 7th bit is set.
8714 [(set (match_operand 0 "register_operand" "")
8715 (any_or (match_operand 1 "general_operand" "")
8716 (match_operand 2 "const_int_operand" "")))
8717 (clobber (reg:CC FLAGS_REG))]
8719 && ANY_QI_REG_P (operands[0])
8720 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8721 && !(INTVAL (operands[2]) & ~255)
8722 && (INTVAL (operands[2]) & 128)
8723 && GET_MODE (operands[0]) != QImode"
8724 [(parallel [(set (strict_low_part (match_dup 0))
8725 (any_or:QI (match_dup 1)
8727 (clobber (reg:CC FLAGS_REG))])]
8728 "operands[0] = gen_lowpart (QImode, operands[0]);
8729 operands[1] = gen_lowpart (QImode, operands[1]);
8730 operands[2] = gen_lowpart (QImode, operands[2]);")
8732 (define_expand "xorqi_cc_ext_1"
8734 (set (reg:CCNO FLAGS_REG)
8738 (match_operand 1 "ext_register_operand" "")
8741 (match_operand:QI 2 "general_operand" ""))
8743 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8755 (define_insn "*xorqi_cc_ext_1_rex64"
8756 [(set (reg FLAGS_REG)
8760 (match_operand 1 "ext_register_operand" "0")
8763 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8765 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8774 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8775 "xor{b}\t{%2, %h0|%h0, %2}"
8776 [(set_attr "type" "alu")
8777 (set_attr "modrm" "1")
8778 (set_attr "mode" "QI")])
8780 (define_insn "*xorqi_cc_ext_1"
8781 [(set (reg FLAGS_REG)
8785 (match_operand 1 "ext_register_operand" "0")
8788 (match_operand:QI 2 "general_operand" "qmn"))
8790 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8799 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8800 "xor{b}\t{%2, %h0|%h0, %2}"
8801 [(set_attr "type" "alu")
8802 (set_attr "modrm" "1")
8803 (set_attr "mode" "QI")])
8805 ;; Negation instructions
8807 (define_expand "neg<mode>2"
8808 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8809 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8811 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8813 (define_insn_and_split "*neg<dwi>2_doubleword"
8814 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8815 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8816 (clobber (reg:CC FLAGS_REG))]
8817 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8821 [(set (reg:CCZ FLAGS_REG)
8822 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8823 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8826 (plus:DWIH (match_dup 3)
8827 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8829 (clobber (reg:CC FLAGS_REG))])
8832 (neg:DWIH (match_dup 2)))
8833 (clobber (reg:CC FLAGS_REG))])]
8834 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
8836 (define_insn "*neg<mode>2_1"
8837 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8838 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8839 (clobber (reg:CC FLAGS_REG))]
8840 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8841 "neg{<imodesuffix>}\t%0"
8842 [(set_attr "type" "negnot")
8843 (set_attr "mode" "<MODE>")])
8845 ;; Combine is quite creative about this pattern.
8846 (define_insn "*negsi2_1_zext"
8847 [(set (match_operand:DI 0 "register_operand" "=r")
8849 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8852 (clobber (reg:CC FLAGS_REG))]
8853 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8855 [(set_attr "type" "negnot")
8856 (set_attr "mode" "SI")])
8858 ;; The problem with neg is that it does not perform (compare x 0),
8859 ;; it really performs (compare 0 x), which leaves us with the zero
8860 ;; flag being the only useful item.
8862 (define_insn "*neg<mode>2_cmpz"
8863 [(set (reg:CCZ FLAGS_REG)
8865 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8867 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8868 (neg:SWI (match_dup 1)))]
8869 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8870 "neg{<imodesuffix>}\t%0"
8871 [(set_attr "type" "negnot")
8872 (set_attr "mode" "<MODE>")])
8874 (define_insn "*negsi2_cmpz_zext"
8875 [(set (reg:CCZ FLAGS_REG)
8879 (match_operand:DI 1 "register_operand" "0")
8883 (set (match_operand:DI 0 "register_operand" "=r")
8884 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8887 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8889 [(set_attr "type" "negnot")
8890 (set_attr "mode" "SI")])
8892 ;; Changing of sign for FP values is doable using integer unit too.
8894 (define_expand "<code><mode>2"
8895 [(set (match_operand:X87MODEF 0 "register_operand" "")
8896 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8897 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8898 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8900 (define_insn "*absneg<mode>2_mixed"
8901 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8902 (match_operator:MODEF 3 "absneg_operator"
8903 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8904 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8905 (clobber (reg:CC FLAGS_REG))]
8906 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8909 (define_insn "*absneg<mode>2_sse"
8910 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8911 (match_operator:MODEF 3 "absneg_operator"
8912 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8913 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8914 (clobber (reg:CC FLAGS_REG))]
8915 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8918 (define_insn "*absneg<mode>2_i387"
8919 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8920 (match_operator:X87MODEF 3 "absneg_operator"
8921 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8922 (use (match_operand 2 "" ""))
8923 (clobber (reg:CC FLAGS_REG))]
8924 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8927 (define_expand "<code>tf2"
8928 [(set (match_operand:TF 0 "register_operand" "")
8929 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8931 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8933 (define_insn "*absnegtf2_sse"
8934 [(set (match_operand:TF 0 "register_operand" "=x,x")
8935 (match_operator:TF 3 "absneg_operator"
8936 [(match_operand:TF 1 "register_operand" "0,x")]))
8937 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8938 (clobber (reg:CC FLAGS_REG))]
8942 ;; Splitters for fp abs and neg.
8945 [(set (match_operand 0 "fp_register_operand" "")
8946 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8947 (use (match_operand 2 "" ""))
8948 (clobber (reg:CC FLAGS_REG))]
8950 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8953 [(set (match_operand 0 "register_operand" "")
8954 (match_operator 3 "absneg_operator"
8955 [(match_operand 1 "register_operand" "")]))
8956 (use (match_operand 2 "nonimmediate_operand" ""))
8957 (clobber (reg:CC FLAGS_REG))]
8958 "reload_completed && SSE_REG_P (operands[0])"
8959 [(set (match_dup 0) (match_dup 3))]
8961 enum machine_mode mode = GET_MODE (operands[0]);
8962 enum machine_mode vmode = GET_MODE (operands[2]);
8965 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8966 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8967 if (operands_match_p (operands[0], operands[2]))
8970 operands[1] = operands[2];
8973 if (GET_CODE (operands[3]) == ABS)
8974 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8976 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8981 [(set (match_operand:SF 0 "register_operand" "")
8982 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8983 (use (match_operand:V4SF 2 "" ""))
8984 (clobber (reg:CC FLAGS_REG))]
8986 [(parallel [(set (match_dup 0) (match_dup 1))
8987 (clobber (reg:CC FLAGS_REG))])]
8990 operands[0] = gen_lowpart (SImode, operands[0]);
8991 if (GET_CODE (operands[1]) == ABS)
8993 tmp = gen_int_mode (0x7fffffff, SImode);
8994 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8998 tmp = gen_int_mode (0x80000000, SImode);
8999 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9005 [(set (match_operand:DF 0 "register_operand" "")
9006 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9007 (use (match_operand 2 "" ""))
9008 (clobber (reg:CC FLAGS_REG))]
9010 [(parallel [(set (match_dup 0) (match_dup 1))
9011 (clobber (reg:CC FLAGS_REG))])]
9016 tmp = gen_lowpart (DImode, operands[0]);
9017 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9020 if (GET_CODE (operands[1]) == ABS)
9023 tmp = gen_rtx_NOT (DImode, tmp);
9027 operands[0] = gen_highpart (SImode, operands[0]);
9028 if (GET_CODE (operands[1]) == ABS)
9030 tmp = gen_int_mode (0x7fffffff, SImode);
9031 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9035 tmp = gen_int_mode (0x80000000, SImode);
9036 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9043 [(set (match_operand:XF 0 "register_operand" "")
9044 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9045 (use (match_operand 2 "" ""))
9046 (clobber (reg:CC FLAGS_REG))]
9048 [(parallel [(set (match_dup 0) (match_dup 1))
9049 (clobber (reg:CC FLAGS_REG))])]
9052 operands[0] = gen_rtx_REG (SImode,
9053 true_regnum (operands[0])
9054 + (TARGET_64BIT ? 1 : 2));
9055 if (GET_CODE (operands[1]) == ABS)
9057 tmp = GEN_INT (0x7fff);
9058 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9062 tmp = GEN_INT (0x8000);
9063 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9068 ;; Conditionalize these after reload. If they match before reload, we
9069 ;; lose the clobber and ability to use integer instructions.
9071 (define_insn "*<code><mode>2_1"
9072 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9073 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9075 && (reload_completed
9076 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9077 "f<absneg_mnemonic>"
9078 [(set_attr "type" "fsgn")
9079 (set_attr "mode" "<MODE>")])
9081 (define_insn "*<code>extendsfdf2"
9082 [(set (match_operand:DF 0 "register_operand" "=f")
9083 (absneg:DF (float_extend:DF
9084 (match_operand:SF 1 "register_operand" "0"))))]
9085 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9086 "f<absneg_mnemonic>"
9087 [(set_attr "type" "fsgn")
9088 (set_attr "mode" "DF")])
9090 (define_insn "*<code>extendsfxf2"
9091 [(set (match_operand:XF 0 "register_operand" "=f")
9092 (absneg:XF (float_extend:XF
9093 (match_operand:SF 1 "register_operand" "0"))))]
9095 "f<absneg_mnemonic>"
9096 [(set_attr "type" "fsgn")
9097 (set_attr "mode" "XF")])
9099 (define_insn "*<code>extenddfxf2"
9100 [(set (match_operand:XF 0 "register_operand" "=f")
9101 (absneg:XF (float_extend:XF
9102 (match_operand:DF 1 "register_operand" "0"))))]
9104 "f<absneg_mnemonic>"
9105 [(set_attr "type" "fsgn")
9106 (set_attr "mode" "XF")])
9108 ;; Copysign instructions
9110 (define_mode_iterator CSGNMODE [SF DF TF])
9111 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9113 (define_expand "copysign<mode>3"
9114 [(match_operand:CSGNMODE 0 "register_operand" "")
9115 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9116 (match_operand:CSGNMODE 2 "register_operand" "")]
9117 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9118 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9120 ix86_expand_copysign (operands);
9124 (define_insn_and_split "copysign<mode>3_const"
9125 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9127 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9128 (match_operand:CSGNMODE 2 "register_operand" "0")
9129 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9131 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9132 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9134 "&& reload_completed"
9137 ix86_split_copysign_const (operands);
9141 (define_insn "copysign<mode>3_var"
9142 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9144 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9145 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9146 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9147 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9149 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9150 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9151 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9155 [(set (match_operand:CSGNMODE 0 "register_operand" "")
9157 [(match_operand:CSGNMODE 2 "register_operand" "")
9158 (match_operand:CSGNMODE 3 "register_operand" "")
9159 (match_operand:<CSGNVMODE> 4 "" "")
9160 (match_operand:<CSGNVMODE> 5 "" "")]
9162 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9163 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9164 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9165 && reload_completed"
9168 ix86_split_copysign_var (operands);
9172 ;; One complement instructions
9174 (define_expand "one_cmpl<mode>2"
9175 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9176 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9178 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9180 (define_insn "*one_cmpl<mode>2_1"
9181 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9182 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9183 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9184 "not{<imodesuffix>}\t%0"
9185 [(set_attr "type" "negnot")
9186 (set_attr "mode" "<MODE>")])
9188 ;; %%% Potential partial reg stall on alternative 1. What to do?
9189 (define_insn "*one_cmplqi2_1"
9190 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9191 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9192 "ix86_unary_operator_ok (NOT, QImode, operands)"
9196 [(set_attr "type" "negnot")
9197 (set_attr "mode" "QI,SI")])
9199 ;; ??? Currently never generated - xor is used instead.
9200 (define_insn "*one_cmplsi2_1_zext"
9201 [(set (match_operand:DI 0 "register_operand" "=r")
9203 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9204 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9206 [(set_attr "type" "negnot")
9207 (set_attr "mode" "SI")])
9209 (define_insn "*one_cmpl<mode>2_2"
9210 [(set (reg FLAGS_REG)
9211 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9213 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9214 (not:SWI (match_dup 1)))]
9215 "ix86_match_ccmode (insn, CCNOmode)
9216 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9218 [(set_attr "type" "alu1")
9219 (set_attr "mode" "<MODE>")])
9222 [(set (match_operand 0 "flags_reg_operand" "")
9223 (match_operator 2 "compare_operator"
9224 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9226 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9227 (not:SWI (match_dup 3)))]
9228 "ix86_match_ccmode (insn, CCNOmode)"
9229 [(parallel [(set (match_dup 0)
9230 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9233 (xor:SWI (match_dup 3) (const_int -1)))])]
9236 ;; ??? Currently never generated - xor is used instead.
9237 (define_insn "*one_cmplsi2_2_zext"
9238 [(set (reg FLAGS_REG)
9239 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9241 (set (match_operand:DI 0 "register_operand" "=r")
9242 (zero_extend:DI (not:SI (match_dup 1))))]
9243 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9244 && ix86_unary_operator_ok (NOT, SImode, operands)"
9246 [(set_attr "type" "alu1")
9247 (set_attr "mode" "SI")])
9250 [(set (match_operand 0 "flags_reg_operand" "")
9251 (match_operator 2 "compare_operator"
9252 [(not:SI (match_operand:SI 3 "register_operand" ""))
9254 (set (match_operand:DI 1 "register_operand" "")
9255 (zero_extend:DI (not:SI (match_dup 3))))]
9256 "ix86_match_ccmode (insn, CCNOmode)"
9257 [(parallel [(set (match_dup 0)
9258 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9261 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9264 ;; Shift instructions
9266 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9267 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9268 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9269 ;; from the assembler input.
9271 ;; This instruction shifts the target reg/mem as usual, but instead of
9272 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9273 ;; is a left shift double, bits are taken from the high order bits of
9274 ;; reg, else if the insn is a shift right double, bits are taken from the
9275 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9276 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9278 ;; Since sh[lr]d does not change the `reg' operand, that is done
9279 ;; separately, making all shifts emit pairs of shift double and normal
9280 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9281 ;; support a 63 bit shift, each shift where the count is in a reg expands
9282 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9284 ;; If the shift count is a constant, we need never emit more than one
9285 ;; shift pair, instead using moves and sign extension for counts greater
9288 (define_expand "ashl<mode>3"
9289 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9290 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9291 (match_operand:QI 2 "nonmemory_operand" "")))]
9293 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9295 (define_insn "*ashl<mode>3_doubleword"
9296 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9297 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9298 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9299 (clobber (reg:CC FLAGS_REG))]
9302 [(set_attr "type" "multi")])
9305 [(set (match_operand:DWI 0 "register_operand" "")
9306 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9307 (match_operand:QI 2 "nonmemory_operand" "")))
9308 (clobber (reg:CC FLAGS_REG))]
9309 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9311 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9313 ;; By default we don't ask for a scratch register, because when DWImode
9314 ;; values are manipulated, registers are already at a premium. But if
9315 ;; we have one handy, we won't turn it away.
9318 [(match_scratch:DWIH 3 "r")
9319 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9321 (match_operand:<DWI> 1 "nonmemory_operand" "")
9322 (match_operand:QI 2 "nonmemory_operand" "")))
9323 (clobber (reg:CC FLAGS_REG))])
9327 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9329 (define_insn "x86_64_shld"
9330 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9331 (ior:DI (ashift:DI (match_dup 0)
9332 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9333 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9334 (minus:QI (const_int 64) (match_dup 2)))))
9335 (clobber (reg:CC FLAGS_REG))]
9337 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9338 [(set_attr "type" "ishift")
9339 (set_attr "prefix_0f" "1")
9340 (set_attr "mode" "DI")
9341 (set_attr "athlon_decode" "vector")
9342 (set_attr "amdfam10_decode" "vector")])
9344 (define_insn "x86_shld"
9345 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9346 (ior:SI (ashift:SI (match_dup 0)
9347 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9348 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9349 (minus:QI (const_int 32) (match_dup 2)))))
9350 (clobber (reg:CC FLAGS_REG))]
9352 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9353 [(set_attr "type" "ishift")
9354 (set_attr "prefix_0f" "1")
9355 (set_attr "mode" "SI")
9356 (set_attr "pent_pair" "np")
9357 (set_attr "athlon_decode" "vector")
9358 (set_attr "amdfam10_decode" "vector")])
9360 (define_expand "x86_shift<mode>_adj_1"
9361 [(set (reg:CCZ FLAGS_REG)
9362 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9365 (set (match_operand:SWI48 0 "register_operand" "")
9366 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9367 (match_operand:SWI48 1 "register_operand" "")
9370 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9371 (match_operand:SWI48 3 "register_operand" "r")
9374 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9376 (define_expand "x86_shift<mode>_adj_2"
9377 [(use (match_operand:SWI48 0 "register_operand" ""))
9378 (use (match_operand:SWI48 1 "register_operand" ""))
9379 (use (match_operand:QI 2 "register_operand" ""))]
9382 rtx label = gen_label_rtx ();
9385 emit_insn (gen_testqi_ccz_1 (operands[2],
9386 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9388 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9389 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9390 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9391 gen_rtx_LABEL_REF (VOIDmode, label),
9393 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9394 JUMP_LABEL (tmp) = label;
9396 emit_move_insn (operands[0], operands[1]);
9397 ix86_expand_clear (operands[1]);
9400 LABEL_NUSES (label) = 1;
9405 (define_insn "*ashl<mode>3_1"
9406 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9407 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9408 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9409 (clobber (reg:CC FLAGS_REG))]
9410 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9412 switch (get_attr_type (insn))
9418 gcc_assert (operands[2] == const1_rtx);
9419 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9420 return "add{<imodesuffix>}\t%0, %0";
9423 if (operands[2] == const1_rtx
9424 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9425 return "sal{<imodesuffix>}\t%0";
9427 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9431 (cond [(eq_attr "alternative" "1")
9432 (const_string "lea")
9433 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9435 (match_operand 0 "register_operand" ""))
9436 (match_operand 2 "const1_operand" ""))
9437 (const_string "alu")
9439 (const_string "ishift")))
9440 (set (attr "length_immediate")
9442 (ior (eq_attr "type" "alu")
9443 (and (eq_attr "type" "ishift")
9444 (and (match_operand 2 "const1_operand" "")
9445 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9448 (const_string "*")))
9449 (set_attr "mode" "<MODE>")])
9451 (define_insn "*ashlsi3_1_zext"
9452 [(set (match_operand:DI 0 "register_operand" "=r,r")
9454 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9455 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9456 (clobber (reg:CC FLAGS_REG))]
9457 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9459 switch (get_attr_type (insn))
9465 gcc_assert (operands[2] == const1_rtx);
9466 return "add{l}\t%k0, %k0";
9469 if (operands[2] == const1_rtx
9470 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9471 return "sal{l}\t%k0";
9473 return "sal{l}\t{%2, %k0|%k0, %2}";
9477 (cond [(eq_attr "alternative" "1")
9478 (const_string "lea")
9479 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9481 (match_operand 2 "const1_operand" ""))
9482 (const_string "alu")
9484 (const_string "ishift")))
9485 (set (attr "length_immediate")
9487 (ior (eq_attr "type" "alu")
9488 (and (eq_attr "type" "ishift")
9489 (and (match_operand 2 "const1_operand" "")
9490 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9493 (const_string "*")))
9494 (set_attr "mode" "SI")])
9496 (define_insn "*ashlhi3_1"
9497 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9498 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9499 (match_operand:QI 2 "nonmemory_operand" "cI")))
9500 (clobber (reg:CC FLAGS_REG))]
9501 "TARGET_PARTIAL_REG_STALL
9502 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9504 switch (get_attr_type (insn))
9507 gcc_assert (operands[2] == const1_rtx);
9508 return "add{w}\t%0, %0";
9511 if (operands[2] == const1_rtx
9512 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9513 return "sal{w}\t%0";
9515 return "sal{w}\t{%2, %0|%0, %2}";
9519 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9521 (match_operand 0 "register_operand" ""))
9522 (match_operand 2 "const1_operand" ""))
9523 (const_string "alu")
9525 (const_string "ishift")))
9526 (set (attr "length_immediate")
9528 (ior (eq_attr "type" "alu")
9529 (and (eq_attr "type" "ishift")
9530 (and (match_operand 2 "const1_operand" "")
9531 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9534 (const_string "*")))
9535 (set_attr "mode" "HI")])
9537 (define_insn "*ashlhi3_1_lea"
9538 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9539 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9540 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9541 (clobber (reg:CC FLAGS_REG))]
9542 "!TARGET_PARTIAL_REG_STALL
9543 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9545 switch (get_attr_type (insn))
9551 gcc_assert (operands[2] == const1_rtx);
9552 return "add{w}\t%0, %0";
9555 if (operands[2] == const1_rtx
9556 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9557 return "sal{w}\t%0";
9559 return "sal{w}\t{%2, %0|%0, %2}";
9563 (cond [(eq_attr "alternative" "1")
9564 (const_string "lea")
9565 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9567 (match_operand 0 "register_operand" ""))
9568 (match_operand 2 "const1_operand" ""))
9569 (const_string "alu")
9571 (const_string "ishift")))
9572 (set (attr "length_immediate")
9574 (ior (eq_attr "type" "alu")
9575 (and (eq_attr "type" "ishift")
9576 (and (match_operand 2 "const1_operand" "")
9577 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9580 (const_string "*")))
9581 (set_attr "mode" "HI,SI")])
9583 (define_insn "*ashlqi3_1"
9584 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9585 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9586 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9587 (clobber (reg:CC FLAGS_REG))]
9588 "TARGET_PARTIAL_REG_STALL
9589 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9591 switch (get_attr_type (insn))
9594 gcc_assert (operands[2] == const1_rtx);
9595 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9596 return "add{l}\t%k0, %k0";
9598 return "add{b}\t%0, %0";
9601 if (operands[2] == const1_rtx
9602 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9604 if (get_attr_mode (insn) == MODE_SI)
9605 return "sal{l}\t%k0";
9607 return "sal{b}\t%0";
9611 if (get_attr_mode (insn) == MODE_SI)
9612 return "sal{l}\t{%2, %k0|%k0, %2}";
9614 return "sal{b}\t{%2, %0|%0, %2}";
9619 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9621 (match_operand 0 "register_operand" ""))
9622 (match_operand 2 "const1_operand" ""))
9623 (const_string "alu")
9625 (const_string "ishift")))
9626 (set (attr "length_immediate")
9628 (ior (eq_attr "type" "alu")
9629 (and (eq_attr "type" "ishift")
9630 (and (match_operand 2 "const1_operand" "")
9631 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9634 (const_string "*")))
9635 (set_attr "mode" "QI,SI")])
9637 ;; %%% Potential partial reg stall on alternative 2. What to do?
9638 (define_insn "*ashlqi3_1_lea"
9639 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9640 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9641 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9642 (clobber (reg:CC FLAGS_REG))]
9643 "!TARGET_PARTIAL_REG_STALL
9644 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9646 switch (get_attr_type (insn))
9652 gcc_assert (operands[2] == const1_rtx);
9653 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9654 return "add{l}\t%k0, %k0";
9656 return "add{b}\t%0, %0";
9659 if (operands[2] == const1_rtx
9660 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9662 if (get_attr_mode (insn) == MODE_SI)
9663 return "sal{l}\t%k0";
9665 return "sal{b}\t%0";
9669 if (get_attr_mode (insn) == MODE_SI)
9670 return "sal{l}\t{%2, %k0|%k0, %2}";
9672 return "sal{b}\t{%2, %0|%0, %2}";
9677 (cond [(eq_attr "alternative" "2")
9678 (const_string "lea")
9679 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9681 (match_operand 0 "register_operand" ""))
9682 (match_operand 2 "const1_operand" ""))
9683 (const_string "alu")
9685 (const_string "ishift")))
9686 (set (attr "length_immediate")
9688 (ior (eq_attr "type" "alu")
9689 (and (eq_attr "type" "ishift")
9690 (and (match_operand 2 "const1_operand" "")
9691 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9694 (const_string "*")))
9695 (set_attr "mode" "QI,SI,SI")])
9697 (define_insn "*ashlqi3_1_slp"
9698 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9699 (ashift:QI (match_dup 0)
9700 (match_operand:QI 1 "nonmemory_operand" "cI")))
9701 (clobber (reg:CC FLAGS_REG))]
9702 "(optimize_function_for_size_p (cfun)
9703 || !TARGET_PARTIAL_FLAG_REG_STALL
9704 || (operands[1] == const1_rtx
9706 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9708 switch (get_attr_type (insn))
9711 gcc_assert (operands[1] == const1_rtx);
9712 return "add{b}\t%0, %0";
9715 if (operands[1] == const1_rtx
9716 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9717 return "sal{b}\t%0";
9719 return "sal{b}\t{%1, %0|%0, %1}";
9723 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9725 (match_operand 0 "register_operand" ""))
9726 (match_operand 1 "const1_operand" ""))
9727 (const_string "alu")
9729 (const_string "ishift1")))
9730 (set (attr "length_immediate")
9732 (ior (eq_attr "type" "alu")
9733 (and (eq_attr "type" "ishift1")
9734 (and (match_operand 1 "const1_operand" "")
9735 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9738 (const_string "*")))
9739 (set_attr "mode" "QI")])
9741 ;; Convert lea to the lea pattern to avoid flags dependency.
9743 [(set (match_operand:DI 0 "register_operand" "")
9744 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9745 (match_operand:QI 2 "const_int_operand" "")))
9746 (clobber (reg:CC FLAGS_REG))]
9747 "TARGET_64BIT && reload_completed
9748 && true_regnum (operands[0]) != true_regnum (operands[1])"
9750 (mult:DI (match_dup 1)
9752 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9754 ;; Convert lea to the lea pattern to avoid flags dependency.
9756 [(set (match_operand 0 "register_operand" "")
9757 (ashift (match_operand 1 "index_register_operand" "")
9758 (match_operand:QI 2 "const_int_operand" "")))
9759 (clobber (reg:CC FLAGS_REG))]
9761 && true_regnum (operands[0]) != true_regnum (operands[1])
9762 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
9766 enum machine_mode mode = GET_MODE (operands[0]);
9768 if (GET_MODE_SIZE (mode) < 4)
9769 operands[0] = gen_lowpart (SImode, operands[0]);
9771 operands[1] = gen_lowpart (Pmode, operands[1]);
9772 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9774 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9775 if (Pmode != SImode)
9776 pat = gen_rtx_SUBREG (SImode, pat, 0);
9777 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9781 ;; Rare case of shifting RSP is handled by generating move and shift
9783 [(set (match_operand 0 "register_operand" "")
9784 (ashift (match_operand 1 "register_operand" "")
9785 (match_operand:QI 2 "const_int_operand" "")))
9786 (clobber (reg:CC FLAGS_REG))]
9788 && true_regnum (operands[0]) != true_regnum (operands[1])"
9792 emit_move_insn (operands[0], operands[1]);
9793 pat = gen_rtx_SET (VOIDmode, operands[0],
9794 gen_rtx_ASHIFT (GET_MODE (operands[0]),
9795 operands[0], operands[2]));
9796 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
9797 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
9801 ;; Convert lea to the lea pattern to avoid flags dependency.
9803 [(set (match_operand:DI 0 "register_operand" "")
9805 (ashift:SI (match_operand:SI 1 "register_operand" "")
9806 (match_operand:QI 2 "const_int_operand" ""))))
9807 (clobber (reg:CC FLAGS_REG))]
9808 "TARGET_64BIT && reload_completed
9809 && true_regnum (operands[0]) != true_regnum (operands[1])"
9811 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9813 operands[1] = gen_lowpart (Pmode, operands[1]);
9814 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9817 ;; This pattern can't accept a variable shift count, since shifts by
9818 ;; zero don't affect the flags. We assume that shifts by constant
9819 ;; zero are optimized away.
9820 (define_insn "*ashl<mode>3_cmp"
9821 [(set (reg FLAGS_REG)
9823 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9824 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9826 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9827 (ashift:SWI (match_dup 1) (match_dup 2)))]
9828 "(optimize_function_for_size_p (cfun)
9829 || !TARGET_PARTIAL_FLAG_REG_STALL
9830 || (operands[2] == const1_rtx
9832 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9833 && ix86_match_ccmode (insn, CCGOCmode)
9834 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9836 switch (get_attr_type (insn))
9839 gcc_assert (operands[2] == const1_rtx);
9840 return "add{<imodesuffix>}\t%0, %0";
9843 if (operands[2] == const1_rtx
9844 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9845 return "sal{<imodesuffix>}\t%0";
9847 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9851 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9853 (match_operand 0 "register_operand" ""))
9854 (match_operand 2 "const1_operand" ""))
9855 (const_string "alu")
9857 (const_string "ishift")))
9858 (set (attr "length_immediate")
9860 (ior (eq_attr "type" "alu")
9861 (and (eq_attr "type" "ishift")
9862 (and (match_operand 2 "const1_operand" "")
9863 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9866 (const_string "*")))
9867 (set_attr "mode" "<MODE>")])
9869 (define_insn "*ashlsi3_cmp_zext"
9870 [(set (reg FLAGS_REG)
9872 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9873 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9875 (set (match_operand:DI 0 "register_operand" "=r")
9876 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9878 && (optimize_function_for_size_p (cfun)
9879 || !TARGET_PARTIAL_FLAG_REG_STALL
9880 || (operands[2] == const1_rtx
9882 || TARGET_DOUBLE_WITH_ADD)))
9883 && ix86_match_ccmode (insn, CCGOCmode)
9884 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9886 switch (get_attr_type (insn))
9889 gcc_assert (operands[2] == const1_rtx);
9890 return "add{l}\t%k0, %k0";
9893 if (operands[2] == const1_rtx
9894 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9895 return "sal{l}\t%k0";
9897 return "sal{l}\t{%2, %k0|%k0, %2}";
9901 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9903 (match_operand 2 "const1_operand" ""))
9904 (const_string "alu")
9906 (const_string "ishift")))
9907 (set (attr "length_immediate")
9909 (ior (eq_attr "type" "alu")
9910 (and (eq_attr "type" "ishift")
9911 (and (match_operand 2 "const1_operand" "")
9912 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9915 (const_string "*")))
9916 (set_attr "mode" "SI")])
9918 (define_insn "*ashl<mode>3_cconly"
9919 [(set (reg FLAGS_REG)
9921 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9922 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9924 (clobber (match_scratch:SWI 0 "=<r>"))]
9925 "(optimize_function_for_size_p (cfun)
9926 || !TARGET_PARTIAL_FLAG_REG_STALL
9927 || (operands[2] == const1_rtx
9929 || TARGET_DOUBLE_WITH_ADD)))
9930 && ix86_match_ccmode (insn, CCGOCmode)
9931 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9933 switch (get_attr_type (insn))
9936 gcc_assert (operands[2] == const1_rtx);
9937 return "add{<imodesuffix>}\t%0, %0";
9940 if (operands[2] == const1_rtx
9941 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9942 return "sal{<imodesuffix>}\t%0";
9944 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9948 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9950 (match_operand 0 "register_operand" ""))
9951 (match_operand 2 "const1_operand" ""))
9952 (const_string "alu")
9954 (const_string "ishift")))
9955 (set (attr "length_immediate")
9957 (ior (eq_attr "type" "alu")
9958 (and (eq_attr "type" "ishift")
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 ;; See comment above `ashl<mode>3' about how this works.
9968 (define_expand "<shiftrt_insn><mode>3"
9969 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9970 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9971 (match_operand:QI 2 "nonmemory_operand" "")))]
9973 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9975 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9976 [(set (match_operand:DWI 0 "register_operand" "=r")
9977 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9978 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9979 (clobber (reg:CC FLAGS_REG))]
9982 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9984 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9985 [(set_attr "type" "multi")])
9987 ;; By default we don't ask for a scratch register, because when DWImode
9988 ;; values are manipulated, registers are already at a premium. But if
9989 ;; we have one handy, we won't turn it away.
9992 [(match_scratch:DWIH 3 "r")
9993 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9995 (match_operand:<DWI> 1 "register_operand" "")
9996 (match_operand:QI 2 "nonmemory_operand" "")))
9997 (clobber (reg:CC FLAGS_REG))])
10001 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
10003 (define_insn "x86_64_shrd"
10004 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10005 (ior:DI (ashiftrt:DI (match_dup 0)
10006 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10007 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10008 (minus:QI (const_int 64) (match_dup 2)))))
10009 (clobber (reg:CC FLAGS_REG))]
10011 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10012 [(set_attr "type" "ishift")
10013 (set_attr "prefix_0f" "1")
10014 (set_attr "mode" "DI")
10015 (set_attr "athlon_decode" "vector")
10016 (set_attr "amdfam10_decode" "vector")])
10018 (define_insn "x86_shrd"
10019 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10020 (ior:SI (ashiftrt:SI (match_dup 0)
10021 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10022 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10023 (minus:QI (const_int 32) (match_dup 2)))))
10024 (clobber (reg:CC FLAGS_REG))]
10026 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10027 [(set_attr "type" "ishift")
10028 (set_attr "prefix_0f" "1")
10029 (set_attr "mode" "SI")
10030 (set_attr "pent_pair" "np")
10031 (set_attr "athlon_decode" "vector")
10032 (set_attr "amdfam10_decode" "vector")])
10034 (define_insn "ashrdi3_cvt"
10035 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10036 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10037 (match_operand:QI 2 "const_int_operand" "")))
10038 (clobber (reg:CC FLAGS_REG))]
10039 "TARGET_64BIT && INTVAL (operands[2]) == 63
10040 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10041 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10044 sar{q}\t{%2, %0|%0, %2}"
10045 [(set_attr "type" "imovx,ishift")
10046 (set_attr "prefix_0f" "0,*")
10047 (set_attr "length_immediate" "0,*")
10048 (set_attr "modrm" "0,1")
10049 (set_attr "mode" "DI")])
10051 (define_insn "ashrsi3_cvt"
10052 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10053 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10054 (match_operand:QI 2 "const_int_operand" "")))
10055 (clobber (reg:CC FLAGS_REG))]
10056 "INTVAL (operands[2]) == 31
10057 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10058 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10061 sar{l}\t{%2, %0|%0, %2}"
10062 [(set_attr "type" "imovx,ishift")
10063 (set_attr "prefix_0f" "0,*")
10064 (set_attr "length_immediate" "0,*")
10065 (set_attr "modrm" "0,1")
10066 (set_attr "mode" "SI")])
10068 (define_insn "*ashrsi3_cvt_zext"
10069 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10071 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10072 (match_operand:QI 2 "const_int_operand" ""))))
10073 (clobber (reg:CC FLAGS_REG))]
10074 "TARGET_64BIT && INTVAL (operands[2]) == 31
10075 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10076 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10079 sar{l}\t{%2, %k0|%k0, %2}"
10080 [(set_attr "type" "imovx,ishift")
10081 (set_attr "prefix_0f" "0,*")
10082 (set_attr "length_immediate" "0,*")
10083 (set_attr "modrm" "0,1")
10084 (set_attr "mode" "SI")])
10086 (define_expand "x86_shift<mode>_adj_3"
10087 [(use (match_operand:SWI48 0 "register_operand" ""))
10088 (use (match_operand:SWI48 1 "register_operand" ""))
10089 (use (match_operand:QI 2 "register_operand" ""))]
10092 rtx label = gen_label_rtx ();
10095 emit_insn (gen_testqi_ccz_1 (operands[2],
10096 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10098 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10099 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10100 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10101 gen_rtx_LABEL_REF (VOIDmode, label),
10103 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10104 JUMP_LABEL (tmp) = label;
10106 emit_move_insn (operands[0], operands[1]);
10107 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10108 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10109 emit_label (label);
10110 LABEL_NUSES (label) = 1;
10115 (define_insn "*<shiftrt_insn><mode>3_1"
10116 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10117 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10118 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10119 (clobber (reg:CC FLAGS_REG))]
10120 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10122 if (operands[2] == const1_rtx
10123 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10124 return "<shiftrt>{<imodesuffix>}\t%0";
10126 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10128 [(set_attr "type" "ishift")
10129 (set (attr "length_immediate")
10131 (and (match_operand 2 "const1_operand" "")
10132 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10135 (const_string "*")))
10136 (set_attr "mode" "<MODE>")])
10138 (define_insn "*<shiftrt_insn>si3_1_zext"
10139 [(set (match_operand:DI 0 "register_operand" "=r")
10141 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10142 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10143 (clobber (reg:CC FLAGS_REG))]
10144 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10146 if (operands[2] == const1_rtx
10147 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10148 return "<shiftrt>{l}\t%k0";
10150 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10152 [(set_attr "type" "ishift")
10153 (set (attr "length_immediate")
10155 (and (match_operand 2 "const1_operand" "")
10156 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10159 (const_string "*")))
10160 (set_attr "mode" "SI")])
10162 (define_insn "*<shiftrt_insn>qi3_1_slp"
10163 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10164 (any_shiftrt:QI (match_dup 0)
10165 (match_operand:QI 1 "nonmemory_operand" "cI")))
10166 (clobber (reg:CC FLAGS_REG))]
10167 "(optimize_function_for_size_p (cfun)
10168 || !TARGET_PARTIAL_REG_STALL
10169 || (operands[1] == const1_rtx
10170 && TARGET_SHIFT1))"
10172 if (operands[1] == const1_rtx
10173 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10174 return "<shiftrt>{b}\t%0";
10176 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10178 [(set_attr "type" "ishift1")
10179 (set (attr "length_immediate")
10181 (and (match_operand 1 "const1_operand" "")
10182 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10185 (const_string "*")))
10186 (set_attr "mode" "QI")])
10188 ;; This pattern can't accept a variable shift count, since shifts by
10189 ;; zero don't affect the flags. We assume that shifts by constant
10190 ;; zero are optimized away.
10191 (define_insn "*<shiftrt_insn><mode>3_cmp"
10192 [(set (reg FLAGS_REG)
10195 (match_operand:SWI 1 "nonimmediate_operand" "0")
10196 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10198 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10199 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10200 "(optimize_function_for_size_p (cfun)
10201 || !TARGET_PARTIAL_FLAG_REG_STALL
10202 || (operands[2] == const1_rtx
10204 && ix86_match_ccmode (insn, CCGOCmode)
10205 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10207 if (operands[2] == const1_rtx
10208 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10209 return "<shiftrt>{<imodesuffix>}\t%0";
10211 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10213 [(set_attr "type" "ishift")
10214 (set (attr "length_immediate")
10216 (and (match_operand 2 "const1_operand" "")
10217 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10220 (const_string "*")))
10221 (set_attr "mode" "<MODE>")])
10223 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10224 [(set (reg FLAGS_REG)
10226 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10227 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10229 (set (match_operand:DI 0 "register_operand" "=r")
10230 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10232 && (optimize_function_for_size_p (cfun)
10233 || !TARGET_PARTIAL_FLAG_REG_STALL
10234 || (operands[2] == const1_rtx
10236 && ix86_match_ccmode (insn, CCGOCmode)
10237 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10239 if (operands[2] == const1_rtx
10240 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10241 return "<shiftrt>{l}\t%k0";
10243 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10245 [(set_attr "type" "ishift")
10246 (set (attr "length_immediate")
10248 (and (match_operand 2 "const1_operand" "")
10249 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10252 (const_string "*")))
10253 (set_attr "mode" "SI")])
10255 (define_insn "*<shiftrt_insn><mode>3_cconly"
10256 [(set (reg FLAGS_REG)
10259 (match_operand:SWI 1 "nonimmediate_operand" "0")
10260 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10262 (clobber (match_scratch:SWI 0 "=<r>"))]
10263 "(optimize_function_for_size_p (cfun)
10264 || !TARGET_PARTIAL_FLAG_REG_STALL
10265 || (operands[2] == const1_rtx
10267 && ix86_match_ccmode (insn, CCGOCmode)
10268 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10270 if (operands[2] == const1_rtx
10271 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10272 return "<shiftrt>{<imodesuffix>}\t%0";
10274 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10276 [(set_attr "type" "ishift")
10277 (set (attr "length_immediate")
10279 (and (match_operand 2 "const1_operand" "")
10280 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10283 (const_string "*")))
10284 (set_attr "mode" "<MODE>")])
10286 ;; Rotate instructions
10288 (define_expand "<rotate_insn>ti3"
10289 [(set (match_operand:TI 0 "register_operand" "")
10290 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10291 (match_operand:QI 2 "nonmemory_operand" "")))]
10294 if (const_1_to_63_operand (operands[2], VOIDmode))
10295 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10296 (operands[0], operands[1], operands[2]));
10303 (define_expand "<rotate_insn>di3"
10304 [(set (match_operand:DI 0 "shiftdi_operand" "")
10305 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10306 (match_operand:QI 2 "nonmemory_operand" "")))]
10310 ix86_expand_binary_operator (<CODE>, DImode, operands);
10311 else if (const_1_to_31_operand (operands[2], VOIDmode))
10312 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10313 (operands[0], operands[1], operands[2]));
10320 (define_expand "<rotate_insn><mode>3"
10321 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10322 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10323 (match_operand:QI 2 "nonmemory_operand" "")))]
10325 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10327 ;; Implement rotation using two double-precision
10328 ;; shift instructions and a scratch register.
10330 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10331 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10332 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10333 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10334 (clobber (reg:CC FLAGS_REG))
10335 (clobber (match_scratch:DWIH 3 "=&r"))]
10339 [(set (match_dup 3) (match_dup 4))
10341 [(set (match_dup 4)
10342 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10343 (lshiftrt:DWIH (match_dup 5)
10344 (minus:QI (match_dup 6) (match_dup 2)))))
10345 (clobber (reg:CC FLAGS_REG))])
10347 [(set (match_dup 5)
10348 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10349 (lshiftrt:DWIH (match_dup 3)
10350 (minus:QI (match_dup 6) (match_dup 2)))))
10351 (clobber (reg:CC FLAGS_REG))])]
10353 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10355 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10358 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10359 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10360 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10361 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10362 (clobber (reg:CC FLAGS_REG))
10363 (clobber (match_scratch:DWIH 3 "=&r"))]
10367 [(set (match_dup 3) (match_dup 4))
10369 [(set (match_dup 4)
10370 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10371 (ashift:DWIH (match_dup 5)
10372 (minus:QI (match_dup 6) (match_dup 2)))))
10373 (clobber (reg:CC FLAGS_REG))])
10375 [(set (match_dup 5)
10376 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10377 (ashift:DWIH (match_dup 3)
10378 (minus:QI (match_dup 6) (match_dup 2)))))
10379 (clobber (reg:CC FLAGS_REG))])]
10381 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10383 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10386 (define_insn "*<rotate_insn><mode>3_1"
10387 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10388 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10389 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10390 (clobber (reg:CC FLAGS_REG))]
10391 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10393 if (operands[2] == const1_rtx
10394 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10395 return "<rotate>{<imodesuffix>}\t%0";
10397 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10399 [(set_attr "type" "rotate")
10400 (set (attr "length_immediate")
10402 (and (match_operand 2 "const1_operand" "")
10403 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10406 (const_string "*")))
10407 (set_attr "mode" "<MODE>")])
10409 (define_insn "*<rotate_insn>si3_1_zext"
10410 [(set (match_operand:DI 0 "register_operand" "=r")
10412 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10413 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10414 (clobber (reg:CC FLAGS_REG))]
10415 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10417 if (operands[2] == const1_rtx
10418 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10419 return "<rotate>{l}\t%k0";
10421 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10423 [(set_attr "type" "rotate")
10424 (set (attr "length_immediate")
10426 (and (match_operand 2 "const1_operand" "")
10427 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10430 (const_string "*")))
10431 (set_attr "mode" "SI")])
10433 (define_insn "*<rotate_insn>qi3_1_slp"
10434 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10435 (any_rotate:QI (match_dup 0)
10436 (match_operand:QI 1 "nonmemory_operand" "cI")))
10437 (clobber (reg:CC FLAGS_REG))]
10438 "(optimize_function_for_size_p (cfun)
10439 || !TARGET_PARTIAL_REG_STALL
10440 || (operands[1] == const1_rtx
10441 && TARGET_SHIFT1))"
10443 if (operands[1] == const1_rtx
10444 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10445 return "<rotate>{b}\t%0";
10447 return "<rotate>{b}\t{%1, %0|%0, %1}";
10449 [(set_attr "type" "rotate1")
10450 (set (attr "length_immediate")
10452 (and (match_operand 1 "const1_operand" "")
10453 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10456 (const_string "*")))
10457 (set_attr "mode" "QI")])
10460 [(set (match_operand:HI 0 "register_operand" "")
10461 (any_rotate:HI (match_dup 0) (const_int 8)))
10462 (clobber (reg:CC FLAGS_REG))]
10464 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10465 [(parallel [(set (strict_low_part (match_dup 0))
10466 (bswap:HI (match_dup 0)))
10467 (clobber (reg:CC FLAGS_REG))])]
10470 ;; Bit set / bit test instructions
10472 (define_expand "extv"
10473 [(set (match_operand:SI 0 "register_operand" "")
10474 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10475 (match_operand:SI 2 "const8_operand" "")
10476 (match_operand:SI 3 "const8_operand" "")))]
10479 /* Handle extractions from %ah et al. */
10480 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10483 /* From mips.md: extract_bit_field doesn't verify that our source
10484 matches the predicate, so check it again here. */
10485 if (! ext_register_operand (operands[1], VOIDmode))
10489 (define_expand "extzv"
10490 [(set (match_operand:SI 0 "register_operand" "")
10491 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10492 (match_operand:SI 2 "const8_operand" "")
10493 (match_operand:SI 3 "const8_operand" "")))]
10496 /* Handle extractions from %ah et al. */
10497 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10500 /* From mips.md: extract_bit_field doesn't verify that our source
10501 matches the predicate, so check it again here. */
10502 if (! ext_register_operand (operands[1], VOIDmode))
10506 (define_expand "insv"
10507 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10508 (match_operand 1 "const8_operand" "")
10509 (match_operand 2 "const8_operand" ""))
10510 (match_operand 3 "register_operand" ""))]
10513 /* Handle insertions to %ah et al. */
10514 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10517 /* From mips.md: insert_bit_field doesn't verify that our source
10518 matches the predicate, so check it again here. */
10519 if (! ext_register_operand (operands[0], VOIDmode))
10523 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
10525 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
10530 ;; %%% bts, btr, btc, bt.
10531 ;; In general these instructions are *slow* when applied to memory,
10532 ;; since they enforce atomic operation. When applied to registers,
10533 ;; it depends on the cpu implementation. They're never faster than
10534 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10535 ;; no point. But in 64-bit, we can't hold the relevant immediates
10536 ;; within the instruction itself, so operating on bits in the high
10537 ;; 32-bits of a register becomes easier.
10539 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10540 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10541 ;; negdf respectively, so they can never be disabled entirely.
10543 (define_insn "*btsq"
10544 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10546 (match_operand:DI 1 "const_0_to_63_operand" ""))
10548 (clobber (reg:CC FLAGS_REG))]
10549 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10550 "bts{q}\t{%1, %0|%0, %1}"
10551 [(set_attr "type" "alu1")
10552 (set_attr "prefix_0f" "1")
10553 (set_attr "mode" "DI")])
10555 (define_insn "*btrq"
10556 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10558 (match_operand:DI 1 "const_0_to_63_operand" ""))
10560 (clobber (reg:CC FLAGS_REG))]
10561 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10562 "btr{q}\t{%1, %0|%0, %1}"
10563 [(set_attr "type" "alu1")
10564 (set_attr "prefix_0f" "1")
10565 (set_attr "mode" "DI")])
10567 (define_insn "*btcq"
10568 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10570 (match_operand:DI 1 "const_0_to_63_operand" ""))
10571 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10572 (clobber (reg:CC FLAGS_REG))]
10573 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10574 "btc{q}\t{%1, %0|%0, %1}"
10575 [(set_attr "type" "alu1")
10576 (set_attr "prefix_0f" "1")
10577 (set_attr "mode" "DI")])
10579 ;; Allow Nocona to avoid these instructions if a register is available.
10582 [(match_scratch:DI 2 "r")
10583 (parallel [(set (zero_extract:DI
10584 (match_operand:DI 0 "register_operand" "")
10586 (match_operand:DI 1 "const_0_to_63_operand" ""))
10588 (clobber (reg:CC FLAGS_REG))])]
10589 "TARGET_64BIT && !TARGET_USE_BT"
10592 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10595 if (HOST_BITS_PER_WIDE_INT >= 64)
10596 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10597 else if (i < HOST_BITS_PER_WIDE_INT)
10598 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10600 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10602 op1 = immed_double_const (lo, hi, DImode);
10605 emit_move_insn (operands[2], op1);
10609 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10614 [(match_scratch:DI 2 "r")
10615 (parallel [(set (zero_extract:DI
10616 (match_operand:DI 0 "register_operand" "")
10618 (match_operand:DI 1 "const_0_to_63_operand" ""))
10620 (clobber (reg:CC FLAGS_REG))])]
10621 "TARGET_64BIT && !TARGET_USE_BT"
10624 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10627 if (HOST_BITS_PER_WIDE_INT >= 64)
10628 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10629 else if (i < HOST_BITS_PER_WIDE_INT)
10630 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10632 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10634 op1 = immed_double_const (~lo, ~hi, DImode);
10637 emit_move_insn (operands[2], op1);
10641 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10646 [(match_scratch:DI 2 "r")
10647 (parallel [(set (zero_extract:DI
10648 (match_operand:DI 0 "register_operand" "")
10650 (match_operand:DI 1 "const_0_to_63_operand" ""))
10651 (not:DI (zero_extract:DI
10652 (match_dup 0) (const_int 1) (match_dup 1))))
10653 (clobber (reg:CC FLAGS_REG))])]
10654 "TARGET_64BIT && !TARGET_USE_BT"
10657 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10660 if (HOST_BITS_PER_WIDE_INT >= 64)
10661 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10662 else if (i < HOST_BITS_PER_WIDE_INT)
10663 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10665 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10667 op1 = immed_double_const (lo, hi, DImode);
10670 emit_move_insn (operands[2], op1);
10674 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10678 (define_insn "*bt<mode>"
10679 [(set (reg:CCC FLAGS_REG)
10681 (zero_extract:SWI48
10682 (match_operand:SWI48 0 "register_operand" "r")
10684 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10686 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10687 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10688 [(set_attr "type" "alu1")
10689 (set_attr "prefix_0f" "1")
10690 (set_attr "mode" "<MODE>")])
10692 ;; Store-flag instructions.
10694 ;; For all sCOND expanders, also expand the compare or test insn that
10695 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10697 (define_insn_and_split "*setcc_di_1"
10698 [(set (match_operand:DI 0 "register_operand" "=q")
10699 (match_operator:DI 1 "ix86_comparison_operator"
10700 [(reg FLAGS_REG) (const_int 0)]))]
10701 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10703 "&& reload_completed"
10704 [(set (match_dup 2) (match_dup 1))
10705 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10707 PUT_MODE (operands[1], QImode);
10708 operands[2] = gen_lowpart (QImode, operands[0]);
10711 (define_insn_and_split "*setcc_si_1_and"
10712 [(set (match_operand:SI 0 "register_operand" "=q")
10713 (match_operator:SI 1 "ix86_comparison_operator"
10714 [(reg FLAGS_REG) (const_int 0)]))
10715 (clobber (reg:CC FLAGS_REG))]
10716 "!TARGET_PARTIAL_REG_STALL
10717 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10719 "&& reload_completed"
10720 [(set (match_dup 2) (match_dup 1))
10721 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10722 (clobber (reg:CC FLAGS_REG))])]
10724 PUT_MODE (operands[1], QImode);
10725 operands[2] = gen_lowpart (QImode, operands[0]);
10728 (define_insn_and_split "*setcc_si_1_movzbl"
10729 [(set (match_operand:SI 0 "register_operand" "=q")
10730 (match_operator:SI 1 "ix86_comparison_operator"
10731 [(reg FLAGS_REG) (const_int 0)]))]
10732 "!TARGET_PARTIAL_REG_STALL
10733 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10735 "&& reload_completed"
10736 [(set (match_dup 2) (match_dup 1))
10737 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10739 PUT_MODE (operands[1], QImode);
10740 operands[2] = gen_lowpart (QImode, operands[0]);
10743 (define_insn "*setcc_qi"
10744 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10745 (match_operator:QI 1 "ix86_comparison_operator"
10746 [(reg FLAGS_REG) (const_int 0)]))]
10749 [(set_attr "type" "setcc")
10750 (set_attr "mode" "QI")])
10752 (define_insn "*setcc_qi_slp"
10753 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10754 (match_operator:QI 1 "ix86_comparison_operator"
10755 [(reg FLAGS_REG) (const_int 0)]))]
10758 [(set_attr "type" "setcc")
10759 (set_attr "mode" "QI")])
10761 ;; In general it is not safe to assume too much about CCmode registers,
10762 ;; so simplify-rtx stops when it sees a second one. Under certain
10763 ;; conditions this is safe on x86, so help combine not create
10770 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10771 (ne:QI (match_operator 1 "ix86_comparison_operator"
10772 [(reg FLAGS_REG) (const_int 0)])
10775 [(set (match_dup 0) (match_dup 1))]
10777 PUT_MODE (operands[1], QImode);
10781 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10782 (ne:QI (match_operator 1 "ix86_comparison_operator"
10783 [(reg FLAGS_REG) (const_int 0)])
10786 [(set (match_dup 0) (match_dup 1))]
10788 PUT_MODE (operands[1], QImode);
10792 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10793 (eq:QI (match_operator 1 "ix86_comparison_operator"
10794 [(reg FLAGS_REG) (const_int 0)])
10797 [(set (match_dup 0) (match_dup 1))]
10799 rtx new_op1 = copy_rtx (operands[1]);
10800 operands[1] = new_op1;
10801 PUT_MODE (new_op1, QImode);
10802 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10803 GET_MODE (XEXP (new_op1, 0))));
10805 /* Make sure that (a) the CCmode we have for the flags is strong
10806 enough for the reversed compare or (b) we have a valid FP compare. */
10807 if (! ix86_comparison_operator (new_op1, VOIDmode))
10812 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10813 (eq:QI (match_operator 1 "ix86_comparison_operator"
10814 [(reg FLAGS_REG) (const_int 0)])
10817 [(set (match_dup 0) (match_dup 1))]
10819 rtx new_op1 = copy_rtx (operands[1]);
10820 operands[1] = new_op1;
10821 PUT_MODE (new_op1, QImode);
10822 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10823 GET_MODE (XEXP (new_op1, 0))));
10825 /* Make sure that (a) the CCmode we have for the flags is strong
10826 enough for the reversed compare or (b) we have a valid FP compare. */
10827 if (! ix86_comparison_operator (new_op1, VOIDmode))
10831 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10832 ;; subsequent logical operations are used to imitate conditional moves.
10833 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10836 (define_insn "*avx_setcc<mode>"
10837 [(set (match_operand:MODEF 0 "register_operand" "=x")
10838 (match_operator:MODEF 1 "avx_comparison_float_operator"
10839 [(match_operand:MODEF 2 "register_operand" "x")
10840 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10842 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10843 [(set_attr "type" "ssecmp")
10844 (set_attr "prefix" "vex")
10845 (set_attr "length_immediate" "1")
10846 (set_attr "mode" "<MODE>")])
10848 (define_insn "*sse_setcc<mode>"
10849 [(set (match_operand:MODEF 0 "register_operand" "=x")
10850 (match_operator:MODEF 1 "sse_comparison_operator"
10851 [(match_operand:MODEF 2 "register_operand" "0")
10852 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10853 "SSE_FLOAT_MODE_P (<MODE>mode)"
10854 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10855 [(set_attr "type" "ssecmp")
10856 (set_attr "length_immediate" "1")
10857 (set_attr "mode" "<MODE>")])
10859 ;; Basic conditional jump instructions.
10860 ;; We ignore the overflow flag for signed branch instructions.
10862 (define_insn "*jcc_1"
10864 (if_then_else (match_operator 1 "ix86_comparison_operator"
10865 [(reg FLAGS_REG) (const_int 0)])
10866 (label_ref (match_operand 0 "" ""))
10870 [(set_attr "type" "ibr")
10871 (set_attr "modrm" "0")
10872 (set (attr "length")
10873 (if_then_else (and (ge (minus (match_dup 0) (pc))
10875 (lt (minus (match_dup 0) (pc))
10880 (define_insn "*jcc_2"
10882 (if_then_else (match_operator 1 "ix86_comparison_operator"
10883 [(reg FLAGS_REG) (const_int 0)])
10885 (label_ref (match_operand 0 "" ""))))]
10888 [(set_attr "type" "ibr")
10889 (set_attr "modrm" "0")
10890 (set (attr "length")
10891 (if_then_else (and (ge (minus (match_dup 0) (pc))
10893 (lt (minus (match_dup 0) (pc))
10898 ;; In general it is not safe to assume too much about CCmode registers,
10899 ;; so simplify-rtx stops when it sees a second one. Under certain
10900 ;; conditions this is safe on x86, so help combine not create
10908 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10909 [(reg FLAGS_REG) (const_int 0)])
10911 (label_ref (match_operand 1 "" ""))
10915 (if_then_else (match_dup 0)
10916 (label_ref (match_dup 1))
10919 PUT_MODE (operands[0], VOIDmode);
10924 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10925 [(reg FLAGS_REG) (const_int 0)])
10927 (label_ref (match_operand 1 "" ""))
10931 (if_then_else (match_dup 0)
10932 (label_ref (match_dup 1))
10935 rtx new_op0 = copy_rtx (operands[0]);
10936 operands[0] = new_op0;
10937 PUT_MODE (new_op0, VOIDmode);
10938 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10939 GET_MODE (XEXP (new_op0, 0))));
10941 /* Make sure that (a) the CCmode we have for the flags is strong
10942 enough for the reversed compare or (b) we have a valid FP compare. */
10943 if (! ix86_comparison_operator (new_op0, VOIDmode))
10947 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10948 ;; pass generates from shift insn with QImode operand. Actually, the mode
10949 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10950 ;; appropriate modulo of the bit offset value.
10952 (define_insn_and_split "*jcc_bt<mode>"
10954 (if_then_else (match_operator 0 "bt_comparison_operator"
10955 [(zero_extract:SWI48
10956 (match_operand:SWI48 1 "register_operand" "r")
10959 (match_operand:QI 2 "register_operand" "r")))
10961 (label_ref (match_operand 3 "" ""))
10963 (clobber (reg:CC FLAGS_REG))]
10964 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10967 [(set (reg:CCC FLAGS_REG)
10969 (zero_extract:SWI48
10975 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10976 (label_ref (match_dup 3))
10979 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10981 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10984 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10985 ;; also for DImode, this is what combine produces.
10986 (define_insn_and_split "*jcc_bt<mode>_mask"
10988 (if_then_else (match_operator 0 "bt_comparison_operator"
10989 [(zero_extract:SWI48
10990 (match_operand:SWI48 1 "register_operand" "r")
10993 (match_operand:SI 2 "register_operand" "r")
10994 (match_operand:SI 3 "const_int_operand" "n")))])
10995 (label_ref (match_operand 4 "" ""))
10997 (clobber (reg:CC FLAGS_REG))]
10998 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10999 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11000 == GET_MODE_BITSIZE (<MODE>mode)-1"
11003 [(set (reg:CCC FLAGS_REG)
11005 (zero_extract:SWI48
11011 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11012 (label_ref (match_dup 4))
11015 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11017 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11020 (define_insn_and_split "*jcc_btsi_1"
11022 (if_then_else (match_operator 0 "bt_comparison_operator"
11025 (match_operand:SI 1 "register_operand" "r")
11026 (match_operand:QI 2 "register_operand" "r"))
11029 (label_ref (match_operand 3 "" ""))
11031 (clobber (reg:CC FLAGS_REG))]
11032 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11035 [(set (reg:CCC FLAGS_REG)
11043 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11044 (label_ref (match_dup 3))
11047 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11049 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11052 ;; avoid useless masking of bit offset operand
11053 (define_insn_and_split "*jcc_btsi_mask_1"
11056 (match_operator 0 "bt_comparison_operator"
11059 (match_operand:SI 1 "register_operand" "r")
11062 (match_operand:SI 2 "register_operand" "r")
11063 (match_operand:SI 3 "const_int_operand" "n")) 0))
11066 (label_ref (match_operand 4 "" ""))
11068 (clobber (reg:CC FLAGS_REG))]
11069 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11070 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11073 [(set (reg:CCC FLAGS_REG)
11081 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11082 (label_ref (match_dup 4))
11084 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11086 ;; Define combination compare-and-branch fp compare instructions to help
11089 (define_insn "*fp_jcc_3_387"
11091 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11092 [(match_operand 1 "register_operand" "f")
11093 (match_operand 2 "nonimmediate_operand" "fm")])
11094 (label_ref (match_operand 3 "" ""))
11096 (clobber (reg:CCFP FPSR_REG))
11097 (clobber (reg:CCFP FLAGS_REG))
11098 (clobber (match_scratch:HI 4 "=a"))]
11100 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11101 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11102 && SELECT_CC_MODE (GET_CODE (operands[0]),
11103 operands[1], operands[2]) == CCFPmode
11107 (define_insn "*fp_jcc_4_387"
11109 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11110 [(match_operand 1 "register_operand" "f")
11111 (match_operand 2 "nonimmediate_operand" "fm")])
11113 (label_ref (match_operand 3 "" ""))))
11114 (clobber (reg:CCFP FPSR_REG))
11115 (clobber (reg:CCFP FLAGS_REG))
11116 (clobber (match_scratch:HI 4 "=a"))]
11118 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11119 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11120 && SELECT_CC_MODE (GET_CODE (operands[0]),
11121 operands[1], operands[2]) == CCFPmode
11125 (define_insn "*fp_jcc_5_387"
11127 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11128 [(match_operand 1 "register_operand" "f")
11129 (match_operand 2 "register_operand" "f")])
11130 (label_ref (match_operand 3 "" ""))
11132 (clobber (reg:CCFP FPSR_REG))
11133 (clobber (reg:CCFP FLAGS_REG))
11134 (clobber (match_scratch:HI 4 "=a"))]
11135 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11136 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11140 (define_insn "*fp_jcc_6_387"
11142 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11143 [(match_operand 1 "register_operand" "f")
11144 (match_operand 2 "register_operand" "f")])
11146 (label_ref (match_operand 3 "" ""))))
11147 (clobber (reg:CCFP FPSR_REG))
11148 (clobber (reg:CCFP FLAGS_REG))
11149 (clobber (match_scratch:HI 4 "=a"))]
11150 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11151 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11155 (define_insn "*fp_jcc_7_387"
11157 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11158 [(match_operand 1 "register_operand" "f")
11159 (match_operand 2 "const0_operand" "")])
11160 (label_ref (match_operand 3 "" ""))
11162 (clobber (reg:CCFP FPSR_REG))
11163 (clobber (reg:CCFP FLAGS_REG))
11164 (clobber (match_scratch:HI 4 "=a"))]
11165 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11166 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11167 && SELECT_CC_MODE (GET_CODE (operands[0]),
11168 operands[1], operands[2]) == CCFPmode
11172 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
11173 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11174 ;; with a precedence over other operators and is always put in the first
11175 ;; place. Swap condition and operands to match ficom instruction.
11177 (define_insn "*fp_jcc_8<mode>_387"
11179 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11180 [(match_operator 1 "float_operator"
11181 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11182 (match_operand 3 "register_operand" "f,f")])
11183 (label_ref (match_operand 4 "" ""))
11185 (clobber (reg:CCFP FPSR_REG))
11186 (clobber (reg:CCFP FLAGS_REG))
11187 (clobber (match_scratch:HI 5 "=a,a"))]
11188 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11189 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11190 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11191 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11197 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11198 [(match_operand 1 "register_operand" "")
11199 (match_operand 2 "nonimmediate_operand" "")])
11200 (match_operand 3 "" "")
11201 (match_operand 4 "" "")))
11202 (clobber (reg:CCFP FPSR_REG))
11203 (clobber (reg:CCFP FLAGS_REG))]
11207 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11208 operands[3], operands[4], NULL_RTX, NULL_RTX);
11214 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11215 [(match_operand 1 "register_operand" "")
11216 (match_operand 2 "general_operand" "")])
11217 (match_operand 3 "" "")
11218 (match_operand 4 "" "")))
11219 (clobber (reg:CCFP FPSR_REG))
11220 (clobber (reg:CCFP FLAGS_REG))
11221 (clobber (match_scratch:HI 5 "=a"))]
11225 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11226 operands[3], operands[4], operands[5], NULL_RTX);
11232 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11233 [(match_operator 1 "float_operator"
11234 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11235 (match_operand 3 "register_operand" "")])
11236 (match_operand 4 "" "")
11237 (match_operand 5 "" "")))
11238 (clobber (reg:CCFP FPSR_REG))
11239 (clobber (reg:CCFP FLAGS_REG))
11240 (clobber (match_scratch:HI 6 "=a"))]
11244 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11246 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11247 operands[3], operands[7],
11248 operands[4], operands[5], operands[6], NULL_RTX);
11252 ;; %%% Kill this when reload knows how to do it.
11255 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11256 [(match_operator 1 "float_operator"
11257 [(match_operand:X87MODEI12 2 "register_operand" "")])
11258 (match_operand 3 "register_operand" "")])
11259 (match_operand 4 "" "")
11260 (match_operand 5 "" "")))
11261 (clobber (reg:CCFP FPSR_REG))
11262 (clobber (reg:CCFP FLAGS_REG))
11263 (clobber (match_scratch:HI 6 "=a"))]
11267 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11268 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11270 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11271 operands[3], operands[7],
11272 operands[4], operands[5], operands[6], operands[2]);
11276 ;; Unconditional and other jump instructions
11278 (define_insn "jump"
11280 (label_ref (match_operand 0 "" "")))]
11283 [(set_attr "type" "ibr")
11284 (set (attr "length")
11285 (if_then_else (and (ge (minus (match_dup 0) (pc))
11287 (lt (minus (match_dup 0) (pc))
11291 (set_attr "modrm" "0")])
11293 (define_expand "indirect_jump"
11294 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11298 (define_insn "*indirect_jump"
11299 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11302 [(set_attr "type" "ibr")
11303 (set_attr "length_immediate" "0")])
11305 (define_expand "tablejump"
11306 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11307 (use (label_ref (match_operand 1 "" "")))])]
11310 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11311 relative. Convert the relative address to an absolute address. */
11315 enum rtx_code code;
11317 /* We can't use @GOTOFF for text labels on VxWorks;
11318 see gotoff_operand. */
11319 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11323 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11325 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11329 op1 = pic_offset_table_rtx;
11334 op0 = pic_offset_table_rtx;
11338 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11343 (define_insn "*tablejump_1"
11344 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11345 (use (label_ref (match_operand 1 "" "")))]
11348 [(set_attr "type" "ibr")
11349 (set_attr "length_immediate" "0")])
11351 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11354 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11355 (set (match_operand:QI 1 "register_operand" "")
11356 (match_operator:QI 2 "ix86_comparison_operator"
11357 [(reg FLAGS_REG) (const_int 0)]))
11358 (set (match_operand 3 "q_regs_operand" "")
11359 (zero_extend (match_dup 1)))]
11360 "(peep2_reg_dead_p (3, operands[1])
11361 || operands_match_p (operands[1], operands[3]))
11362 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11363 [(set (match_dup 4) (match_dup 0))
11364 (set (strict_low_part (match_dup 5))
11367 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11368 operands[5] = gen_lowpart (QImode, operands[3]);
11369 ix86_expand_clear (operands[3]);
11372 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11375 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11376 (set (match_operand:QI 1 "register_operand" "")
11377 (match_operator:QI 2 "ix86_comparison_operator"
11378 [(reg FLAGS_REG) (const_int 0)]))
11379 (parallel [(set (match_operand 3 "q_regs_operand" "")
11380 (zero_extend (match_dup 1)))
11381 (clobber (reg:CC FLAGS_REG))])]
11382 "(peep2_reg_dead_p (3, operands[1])
11383 || operands_match_p (operands[1], operands[3]))
11384 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11385 [(set (match_dup 4) (match_dup 0))
11386 (set (strict_low_part (match_dup 5))
11389 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11390 operands[5] = gen_lowpart (QImode, operands[3]);
11391 ix86_expand_clear (operands[3]);
11394 ;; Call instructions.
11396 ;; The predicates normally associated with named expanders are not properly
11397 ;; checked for calls. This is a bug in the generic code, but it isn't that
11398 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11400 ;; P6 processors will jump to the address after the decrement when %esp
11401 ;; is used as a call operand, so they will execute return address as a code.
11402 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11404 ;; Call subroutine returning no value.
11406 (define_expand "call_pop"
11407 [(parallel [(call (match_operand:QI 0 "" "")
11408 (match_operand:SI 1 "" ""))
11409 (set (reg:SI SP_REG)
11410 (plus:SI (reg:SI SP_REG)
11411 (match_operand:SI 3 "" "")))])]
11414 ix86_expand_call (NULL, operands[0], operands[1],
11415 operands[2], operands[3], 0);
11419 (define_insn "*call_pop_0"
11420 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11421 (match_operand:SI 1 "" ""))
11422 (set (reg:SI SP_REG)
11423 (plus:SI (reg:SI SP_REG)
11424 (match_operand:SI 2 "immediate_operand" "")))]
11427 if (SIBLING_CALL_P (insn))
11430 return "call\t%P0";
11432 [(set_attr "type" "call")])
11434 (define_insn "*call_pop_1"
11435 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11436 (match_operand:SI 1 "" ""))
11437 (set (reg:SI SP_REG)
11438 (plus:SI (reg:SI SP_REG)
11439 (match_operand:SI 2 "immediate_operand" "i")))]
11440 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11442 if (constant_call_address_operand (operands[0], Pmode))
11443 return "call\t%P0";
11444 return "call\t%A0";
11446 [(set_attr "type" "call")])
11448 (define_insn "*sibcall_pop_1"
11449 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11450 (match_operand:SI 1 "" ""))
11451 (set (reg:SI SP_REG)
11452 (plus:SI (reg:SI SP_REG)
11453 (match_operand:SI 2 "immediate_operand" "i,i")))]
11454 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11458 [(set_attr "type" "call")])
11460 (define_expand "call"
11461 [(call (match_operand:QI 0 "" "")
11462 (match_operand 1 "" ""))
11463 (use (match_operand 2 "" ""))]
11466 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11470 (define_expand "sibcall"
11471 [(call (match_operand:QI 0 "" "")
11472 (match_operand 1 "" ""))
11473 (use (match_operand 2 "" ""))]
11476 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11480 (define_insn "*call_0"
11481 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11482 (match_operand 1 "" ""))]
11485 if (SIBLING_CALL_P (insn))
11488 return "call\t%P0";
11490 [(set_attr "type" "call")])
11492 (define_insn "*call_1"
11493 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11494 (match_operand 1 "" ""))]
11495 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11497 if (constant_call_address_operand (operands[0], Pmode))
11498 return "call\t%P0";
11499 return "call\t%A0";
11501 [(set_attr "type" "call")])
11503 (define_insn "*sibcall_1"
11504 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11505 (match_operand 1 "" ""))]
11506 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11510 [(set_attr "type" "call")])
11512 (define_insn "*call_1_rex64"
11513 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11514 (match_operand 1 "" ""))]
11515 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11516 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11518 if (constant_call_address_operand (operands[0], Pmode))
11519 return "call\t%P0";
11520 return "call\t%A0";
11522 [(set_attr "type" "call")])
11524 (define_insn "*call_1_rex64_ms_sysv"
11525 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11526 (match_operand 1 "" ""))
11527 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11528 (clobber (reg:TI XMM6_REG))
11529 (clobber (reg:TI XMM7_REG))
11530 (clobber (reg:TI XMM8_REG))
11531 (clobber (reg:TI XMM9_REG))
11532 (clobber (reg:TI XMM10_REG))
11533 (clobber (reg:TI XMM11_REG))
11534 (clobber (reg:TI XMM12_REG))
11535 (clobber (reg:TI XMM13_REG))
11536 (clobber (reg:TI XMM14_REG))
11537 (clobber (reg:TI XMM15_REG))
11538 (clobber (reg:DI SI_REG))
11539 (clobber (reg:DI DI_REG))]
11540 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11542 if (constant_call_address_operand (operands[0], Pmode))
11543 return "call\t%P0";
11544 return "call\t%A0";
11546 [(set_attr "type" "call")])
11548 (define_insn "*call_1_rex64_large"
11549 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11550 (match_operand 1 "" ""))]
11551 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11553 [(set_attr "type" "call")])
11555 (define_insn "*sibcall_1_rex64"
11556 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11557 (match_operand 1 "" ""))]
11558 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11562 [(set_attr "type" "call")])
11564 ;; Call subroutine, returning value in operand 0
11565 (define_expand "call_value_pop"
11566 [(parallel [(set (match_operand 0 "" "")
11567 (call (match_operand:QI 1 "" "")
11568 (match_operand:SI 2 "" "")))
11569 (set (reg:SI SP_REG)
11570 (plus:SI (reg:SI SP_REG)
11571 (match_operand:SI 4 "" "")))])]
11574 ix86_expand_call (operands[0], operands[1], operands[2],
11575 operands[3], operands[4], 0);
11579 (define_expand "call_value"
11580 [(set (match_operand 0 "" "")
11581 (call (match_operand:QI 1 "" "")
11582 (match_operand:SI 2 "" "")))
11583 (use (match_operand:SI 3 "" ""))]
11584 ;; Operand 3 is not used on the i386.
11587 ix86_expand_call (operands[0], operands[1], operands[2],
11588 operands[3], NULL, 0);
11592 (define_expand "sibcall_value"
11593 [(set (match_operand 0 "" "")
11594 (call (match_operand:QI 1 "" "")
11595 (match_operand:SI 2 "" "")))
11596 (use (match_operand:SI 3 "" ""))]
11597 ;; Operand 3 is not used on the i386.
11600 ix86_expand_call (operands[0], operands[1], operands[2],
11601 operands[3], NULL, 1);
11605 ;; Call subroutine returning any type.
11607 (define_expand "untyped_call"
11608 [(parallel [(call (match_operand 0 "" "")
11610 (match_operand 1 "" "")
11611 (match_operand 2 "" "")])]
11616 /* In order to give reg-stack an easier job in validating two
11617 coprocessor registers as containing a possible return value,
11618 simply pretend the untyped call returns a complex long double
11621 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11622 and should have the default ABI. */
11624 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11625 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11626 operands[0], const0_rtx,
11627 GEN_INT ((TARGET_64BIT
11628 ? (ix86_abi == SYSV_ABI
11629 ? X86_64_SSE_REGPARM_MAX
11630 : X86_64_MS_SSE_REGPARM_MAX)
11631 : X86_32_SSE_REGPARM_MAX)
11635 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11637 rtx set = XVECEXP (operands[2], 0, i);
11638 emit_move_insn (SET_DEST (set), SET_SRC (set));
11641 /* The optimizer does not know that the call sets the function value
11642 registers we stored in the result block. We avoid problems by
11643 claiming that all hard registers are used and clobbered at this
11645 emit_insn (gen_blockage ());
11650 ;; Prologue and epilogue instructions
11652 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11653 ;; all of memory. This blocks insns from being moved across this point.
11655 (define_insn "blockage"
11656 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11659 [(set_attr "length" "0")])
11661 ;; Do not schedule instructions accessing memory across this point.
11663 (define_expand "memory_blockage"
11664 [(set (match_dup 0)
11665 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11668 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11669 MEM_VOLATILE_P (operands[0]) = 1;
11672 (define_insn "*memory_blockage"
11673 [(set (match_operand:BLK 0 "" "")
11674 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11677 [(set_attr "length" "0")])
11679 ;; As USE insns aren't meaningful after reload, this is used instead
11680 ;; to prevent deleting instructions setting registers for PIC code
11681 (define_insn "prologue_use"
11682 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11685 [(set_attr "length" "0")])
11687 ;; Insn emitted into the body of a function to return from a function.
11688 ;; This is only done if the function's epilogue is known to be simple.
11689 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11691 (define_expand "return"
11693 "ix86_can_use_return_insn_p ()"
11695 if (crtl->args.pops_args)
11697 rtx popc = GEN_INT (crtl->args.pops_args);
11698 emit_jump_insn (gen_return_pop_internal (popc));
11703 (define_insn "return_internal"
11707 [(set_attr "length" "1")
11708 (set_attr "atom_unit" "jeu")
11709 (set_attr "length_immediate" "0")
11710 (set_attr "modrm" "0")])
11712 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11713 ;; instruction Athlon and K8 have.
11715 (define_insn "return_internal_long"
11717 (unspec [(const_int 0)] UNSPEC_REP)]
11720 [(set_attr "length" "2")
11721 (set_attr "atom_unit" "jeu")
11722 (set_attr "length_immediate" "0")
11723 (set_attr "prefix_rep" "1")
11724 (set_attr "modrm" "0")])
11726 (define_insn "return_pop_internal"
11728 (use (match_operand:SI 0 "const_int_operand" ""))]
11731 [(set_attr "length" "3")
11732 (set_attr "atom_unit" "jeu")
11733 (set_attr "length_immediate" "2")
11734 (set_attr "modrm" "0")])
11736 (define_insn "return_indirect_internal"
11738 (use (match_operand:SI 0 "register_operand" "r"))]
11741 [(set_attr "type" "ibr")
11742 (set_attr "length_immediate" "0")])
11748 [(set_attr "length" "1")
11749 (set_attr "length_immediate" "0")
11750 (set_attr "modrm" "0")])
11752 (define_insn "vswapmov"
11753 [(set (match_operand:SI 0 "register_operand" "=r")
11754 (match_operand:SI 1 "register_operand" "r"))
11755 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
11757 "movl.s\t{%1, %0|%0, %1}"
11758 [(set_attr "length" "2")
11759 (set_attr "length_immediate" "0")
11760 (set_attr "modrm" "0")])
11762 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11763 ;; branch prediction penalty for the third jump in a 16-byte
11767 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11770 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11771 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11773 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11774 The align insn is used to avoid 3 jump instructions in the row to improve
11775 branch prediction and the benefits hardly outweigh the cost of extra 8
11776 nops on the average inserted by full alignment pseudo operation. */
11780 [(set_attr "length" "16")])
11782 (define_expand "prologue"
11785 "ix86_expand_prologue (); DONE;")
11787 (define_insn "set_got"
11788 [(set (match_operand:SI 0 "register_operand" "=r")
11789 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11790 (clobber (reg:CC FLAGS_REG))]
11792 { return output_set_got (operands[0], NULL_RTX); }
11793 [(set_attr "type" "multi")
11794 (set_attr "length" "12")])
11796 (define_insn "set_got_labelled"
11797 [(set (match_operand:SI 0 "register_operand" "=r")
11798 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11800 (clobber (reg:CC FLAGS_REG))]
11802 { return output_set_got (operands[0], operands[1]); }
11803 [(set_attr "type" "multi")
11804 (set_attr "length" "12")])
11806 (define_insn "set_got_rex64"
11807 [(set (match_operand:DI 0 "register_operand" "=r")
11808 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11810 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11811 [(set_attr "type" "lea")
11812 (set_attr "length_address" "4")
11813 (set_attr "mode" "DI")])
11815 (define_insn "set_rip_rex64"
11816 [(set (match_operand:DI 0 "register_operand" "=r")
11817 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11819 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11820 [(set_attr "type" "lea")
11821 (set_attr "length_address" "4")
11822 (set_attr "mode" "DI")])
11824 (define_insn "set_got_offset_rex64"
11825 [(set (match_operand:DI 0 "register_operand" "=r")
11827 [(label_ref (match_operand 1 "" ""))]
11828 UNSPEC_SET_GOT_OFFSET))]
11830 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11831 [(set_attr "type" "imov")
11832 (set_attr "length_immediate" "0")
11833 (set_attr "length_address" "8")
11834 (set_attr "mode" "DI")])
11836 (define_expand "epilogue"
11839 "ix86_expand_epilogue (1); DONE;")
11841 (define_expand "sibcall_epilogue"
11844 "ix86_expand_epilogue (0); DONE;")
11846 (define_expand "eh_return"
11847 [(use (match_operand 0 "register_operand" ""))]
11850 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11852 /* Tricky bit: we write the address of the handler to which we will
11853 be returning into someone else's stack frame, one word below the
11854 stack address we wish to restore. */
11855 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11856 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11857 tmp = gen_rtx_MEM (Pmode, tmp);
11858 emit_move_insn (tmp, ra);
11860 emit_jump_insn (gen_eh_return_internal ());
11865 (define_insn_and_split "eh_return_internal"
11869 "epilogue_completed"
11871 "ix86_expand_epilogue (2); DONE;")
11873 (define_insn "leave"
11874 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11875 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11876 (clobber (mem:BLK (scratch)))]
11879 [(set_attr "type" "leave")])
11881 (define_insn "leave_rex64"
11882 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11883 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11884 (clobber (mem:BLK (scratch)))]
11887 [(set_attr "type" "leave")])
11889 ;; Bit manipulation instructions.
11891 (define_expand "ffs<mode>2"
11892 [(set (match_dup 2) (const_int -1))
11893 (parallel [(set (reg:CCZ FLAGS_REG)
11895 (match_operand:SWI48 1 "nonimmediate_operand" "")
11897 (set (match_operand:SWI48 0 "register_operand" "")
11898 (ctz:SWI48 (match_dup 1)))])
11899 (set (match_dup 0) (if_then_else:SWI48
11900 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11903 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11904 (clobber (reg:CC FLAGS_REG))])]
11907 if (<MODE>mode == SImode && !TARGET_CMOVE)
11909 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11912 operands[2] = gen_reg_rtx (<MODE>mode);
11915 (define_insn_and_split "ffssi2_no_cmove"
11916 [(set (match_operand:SI 0 "register_operand" "=r")
11917 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11918 (clobber (match_scratch:SI 2 "=&q"))
11919 (clobber (reg:CC FLAGS_REG))]
11922 "&& reload_completed"
11923 [(parallel [(set (reg:CCZ FLAGS_REG)
11924 (compare:CCZ (match_dup 1) (const_int 0)))
11925 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11926 (set (strict_low_part (match_dup 3))
11927 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11928 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11929 (clobber (reg:CC FLAGS_REG))])
11930 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11931 (clobber (reg:CC FLAGS_REG))])
11932 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11933 (clobber (reg:CC FLAGS_REG))])]
11935 operands[3] = gen_lowpart (QImode, operands[2]);
11936 ix86_expand_clear (operands[2]);
11939 (define_insn "*ffs<mode>_1"
11940 [(set (reg:CCZ FLAGS_REG)
11941 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11943 (set (match_operand:SWI48 0 "register_operand" "=r")
11944 (ctz:SWI48 (match_dup 1)))]
11946 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11947 [(set_attr "type" "alu1")
11948 (set_attr "prefix_0f" "1")
11949 (set_attr "mode" "<MODE>")])
11951 (define_insn "ctz<mode>2"
11952 [(set (match_operand:SWI48 0 "register_operand" "=r")
11953 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11954 (clobber (reg:CC FLAGS_REG))]
11956 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11957 [(set_attr "type" "alu1")
11958 (set_attr "prefix_0f" "1")
11959 (set_attr "mode" "<MODE>")])
11961 (define_expand "clz<mode>2"
11963 [(set (match_operand:SWI248 0 "register_operand" "")
11966 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11967 (clobber (reg:CC FLAGS_REG))])
11969 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11970 (clobber (reg:CC FLAGS_REG))])]
11975 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11978 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11981 (define_insn "clz<mode>2_abm"
11982 [(set (match_operand:SWI248 0 "register_operand" "=r")
11983 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11984 (clobber (reg:CC FLAGS_REG))]
11986 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11987 [(set_attr "prefix_rep" "1")
11988 (set_attr "type" "bitmanip")
11989 (set_attr "mode" "<MODE>")])
11991 (define_insn "bsr_rex64"
11992 [(set (match_operand:DI 0 "register_operand" "=r")
11993 (minus:DI (const_int 63)
11994 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11995 (clobber (reg:CC FLAGS_REG))]
11997 "bsr{q}\t{%1, %0|%0, %1}"
11998 [(set_attr "type" "alu1")
11999 (set_attr "prefix_0f" "1")
12000 (set_attr "mode" "DI")])
12003 [(set (match_operand:SI 0 "register_operand" "=r")
12004 (minus:SI (const_int 31)
12005 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12006 (clobber (reg:CC FLAGS_REG))]
12008 "bsr{l}\t{%1, %0|%0, %1}"
12009 [(set_attr "type" "alu1")
12010 (set_attr "prefix_0f" "1")
12011 (set_attr "mode" "SI")])
12013 (define_insn "*bsrhi"
12014 [(set (match_operand:HI 0 "register_operand" "=r")
12015 (minus:HI (const_int 15)
12016 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12017 (clobber (reg:CC FLAGS_REG))]
12019 "bsr{w}\t{%1, %0|%0, %1}"
12020 [(set_attr "type" "alu1")
12021 (set_attr "prefix_0f" "1")
12022 (set_attr "mode" "HI")])
12024 (define_insn "popcount<mode>2"
12025 [(set (match_operand:SWI248 0 "register_operand" "=r")
12027 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12028 (clobber (reg:CC FLAGS_REG))]
12032 return "popcnt\t{%1, %0|%0, %1}";
12034 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12037 [(set_attr "prefix_rep" "1")
12038 (set_attr "type" "bitmanip")
12039 (set_attr "mode" "<MODE>")])
12041 (define_insn "*popcount<mode>2_cmp"
12042 [(set (reg FLAGS_REG)
12045 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12047 (set (match_operand:SWI248 0 "register_operand" "=r")
12048 (popcount:SWI248 (match_dup 1)))]
12049 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12052 return "popcnt\t{%1, %0|%0, %1}";
12054 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12057 [(set_attr "prefix_rep" "1")
12058 (set_attr "type" "bitmanip")
12059 (set_attr "mode" "<MODE>")])
12061 (define_insn "*popcountsi2_cmp_zext"
12062 [(set (reg FLAGS_REG)
12064 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12066 (set (match_operand:DI 0 "register_operand" "=r")
12067 (zero_extend:DI(popcount:SI (match_dup 1))))]
12068 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12071 return "popcnt\t{%1, %0|%0, %1}";
12073 return "popcnt{l}\t{%1, %0|%0, %1}";
12076 [(set_attr "prefix_rep" "1")
12077 (set_attr "type" "bitmanip")
12078 (set_attr "mode" "SI")])
12080 (define_expand "bswap<mode>2"
12081 [(set (match_operand:SWI48 0 "register_operand" "")
12082 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12085 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12087 rtx x = operands[0];
12089 emit_move_insn (x, operands[1]);
12090 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12091 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12092 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12097 (define_insn "*bswap<mode>2_movbe"
12098 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12099 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12101 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12104 movbe\t{%1, %0|%0, %1}
12105 movbe\t{%1, %0|%0, %1}"
12106 [(set_attr "type" "bitmanip,imov,imov")
12107 (set_attr "modrm" "0,1,1")
12108 (set_attr "prefix_0f" "*,1,1")
12109 (set_attr "prefix_extra" "*,1,1")
12110 (set_attr "mode" "<MODE>")])
12112 (define_insn "*bswap<mode>2_1"
12113 [(set (match_operand:SWI48 0 "register_operand" "=r")
12114 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12117 [(set_attr "type" "bitmanip")
12118 (set_attr "modrm" "0")
12119 (set_attr "mode" "<MODE>")])
12121 (define_insn "*bswaphi_lowpart_1"
12122 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12123 (bswap:HI (match_dup 0)))
12124 (clobber (reg:CC FLAGS_REG))]
12125 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12127 xchg{b}\t{%h0, %b0|%b0, %h0}
12128 rol{w}\t{$8, %0|%0, 8}"
12129 [(set_attr "length" "2,4")
12130 (set_attr "mode" "QI,HI")])
12132 (define_insn "bswaphi_lowpart"
12133 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12134 (bswap:HI (match_dup 0)))
12135 (clobber (reg:CC FLAGS_REG))]
12137 "rol{w}\t{$8, %0|%0, 8}"
12138 [(set_attr "length" "4")
12139 (set_attr "mode" "HI")])
12141 (define_expand "paritydi2"
12142 [(set (match_operand:DI 0 "register_operand" "")
12143 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12146 rtx scratch = gen_reg_rtx (QImode);
12149 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12150 NULL_RTX, operands[1]));
12152 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12153 gen_rtx_REG (CCmode, FLAGS_REG),
12155 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12158 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12161 rtx tmp = gen_reg_rtx (SImode);
12163 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12164 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12169 (define_expand "paritysi2"
12170 [(set (match_operand:SI 0 "register_operand" "")
12171 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12174 rtx scratch = gen_reg_rtx (QImode);
12177 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12179 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12180 gen_rtx_REG (CCmode, FLAGS_REG),
12182 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12184 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12188 (define_insn_and_split "paritydi2_cmp"
12189 [(set (reg:CC FLAGS_REG)
12190 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12192 (clobber (match_scratch:DI 0 "=r"))
12193 (clobber (match_scratch:SI 1 "=&r"))
12194 (clobber (match_scratch:HI 2 "=Q"))]
12197 "&& reload_completed"
12199 [(set (match_dup 1)
12200 (xor:SI (match_dup 1) (match_dup 4)))
12201 (clobber (reg:CC FLAGS_REG))])
12203 [(set (reg:CC FLAGS_REG)
12204 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12205 (clobber (match_dup 1))
12206 (clobber (match_dup 2))])]
12208 operands[4] = gen_lowpart (SImode, operands[3]);
12212 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12213 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12216 operands[1] = gen_highpart (SImode, operands[3]);
12219 (define_insn_and_split "paritysi2_cmp"
12220 [(set (reg:CC FLAGS_REG)
12221 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12223 (clobber (match_scratch:SI 0 "=r"))
12224 (clobber (match_scratch:HI 1 "=&Q"))]
12227 "&& reload_completed"
12229 [(set (match_dup 1)
12230 (xor:HI (match_dup 1) (match_dup 3)))
12231 (clobber (reg:CC FLAGS_REG))])
12233 [(set (reg:CC FLAGS_REG)
12234 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12235 (clobber (match_dup 1))])]
12237 operands[3] = gen_lowpart (HImode, operands[2]);
12239 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12240 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12243 (define_insn "*parityhi2_cmp"
12244 [(set (reg:CC FLAGS_REG)
12245 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12247 (clobber (match_scratch:HI 0 "=Q"))]
12249 "xor{b}\t{%h0, %b0|%b0, %h0}"
12250 [(set_attr "length" "2")
12251 (set_attr "mode" "HI")])
12253 ;; Thread-local storage patterns for ELF.
12255 ;; Note that these code sequences must appear exactly as shown
12256 ;; in order to allow linker relaxation.
12258 (define_insn "*tls_global_dynamic_32_gnu"
12259 [(set (match_operand:SI 0 "register_operand" "=a")
12260 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12261 (match_operand:SI 2 "tls_symbolic_operand" "")
12262 (match_operand:SI 3 "call_insn_operand" "")]
12264 (clobber (match_scratch:SI 4 "=d"))
12265 (clobber (match_scratch:SI 5 "=c"))
12266 (clobber (reg:CC FLAGS_REG))]
12267 "!TARGET_64BIT && TARGET_GNU_TLS"
12268 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12269 [(set_attr "type" "multi")
12270 (set_attr "length" "12")])
12272 (define_expand "tls_global_dynamic_32"
12273 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12276 (match_operand:SI 1 "tls_symbolic_operand" "")
12279 (clobber (match_scratch:SI 4 ""))
12280 (clobber (match_scratch:SI 5 ""))
12281 (clobber (reg:CC FLAGS_REG))])]
12285 operands[2] = pic_offset_table_rtx;
12288 operands[2] = gen_reg_rtx (Pmode);
12289 emit_insn (gen_set_got (operands[2]));
12291 if (TARGET_GNU2_TLS)
12293 emit_insn (gen_tls_dynamic_gnu2_32
12294 (operands[0], operands[1], operands[2]));
12297 operands[3] = ix86_tls_get_addr ();
12300 (define_insn "*tls_global_dynamic_64"
12301 [(set (match_operand:DI 0 "register_operand" "=a")
12302 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12303 (match_operand:DI 3 "" "")))
12304 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12307 { 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"; }
12308 [(set_attr "type" "multi")
12309 (set_attr "length" "16")])
12311 (define_expand "tls_global_dynamic_64"
12312 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12313 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12314 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12318 if (TARGET_GNU2_TLS)
12320 emit_insn (gen_tls_dynamic_gnu2_64
12321 (operands[0], operands[1]));
12324 operands[2] = ix86_tls_get_addr ();
12327 (define_insn "*tls_local_dynamic_base_32_gnu"
12328 [(set (match_operand:SI 0 "register_operand" "=a")
12329 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12330 (match_operand:SI 2 "call_insn_operand" "")]
12331 UNSPEC_TLS_LD_BASE))
12332 (clobber (match_scratch:SI 3 "=d"))
12333 (clobber (match_scratch:SI 4 "=c"))
12334 (clobber (reg:CC FLAGS_REG))]
12335 "!TARGET_64BIT && TARGET_GNU_TLS"
12336 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12337 [(set_attr "type" "multi")
12338 (set_attr "length" "11")])
12340 (define_expand "tls_local_dynamic_base_32"
12341 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12342 (unspec:SI [(match_dup 1) (match_dup 2)]
12343 UNSPEC_TLS_LD_BASE))
12344 (clobber (match_scratch:SI 3 ""))
12345 (clobber (match_scratch:SI 4 ""))
12346 (clobber (reg:CC FLAGS_REG))])]
12350 operands[1] = pic_offset_table_rtx;
12353 operands[1] = gen_reg_rtx (Pmode);
12354 emit_insn (gen_set_got (operands[1]));
12356 if (TARGET_GNU2_TLS)
12358 emit_insn (gen_tls_dynamic_gnu2_32
12359 (operands[0], ix86_tls_module_base (), operands[1]));
12362 operands[2] = ix86_tls_get_addr ();
12365 (define_insn "*tls_local_dynamic_base_64"
12366 [(set (match_operand:DI 0 "register_operand" "=a")
12367 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12368 (match_operand:DI 2 "" "")))
12369 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12371 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12372 [(set_attr "type" "multi")
12373 (set_attr "length" "12")])
12375 (define_expand "tls_local_dynamic_base_64"
12376 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12377 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12378 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12381 if (TARGET_GNU2_TLS)
12383 emit_insn (gen_tls_dynamic_gnu2_64
12384 (operands[0], ix86_tls_module_base ()));
12387 operands[1] = ix86_tls_get_addr ();
12390 ;; Local dynamic of a single variable is a lose. Show combine how
12391 ;; to convert that back to global dynamic.
12393 (define_insn_and_split "*tls_local_dynamic_32_once"
12394 [(set (match_operand:SI 0 "register_operand" "=a")
12395 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12396 (match_operand:SI 2 "call_insn_operand" "")]
12397 UNSPEC_TLS_LD_BASE)
12398 (const:SI (unspec:SI
12399 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12401 (clobber (match_scratch:SI 4 "=d"))
12402 (clobber (match_scratch:SI 5 "=c"))
12403 (clobber (reg:CC FLAGS_REG))]
12407 [(parallel [(set (match_dup 0)
12408 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12410 (clobber (match_dup 4))
12411 (clobber (match_dup 5))
12412 (clobber (reg:CC FLAGS_REG))])]
12415 ;; Load and add the thread base pointer from %gs:0.
12417 (define_insn "*load_tp_si"
12418 [(set (match_operand:SI 0 "register_operand" "=r")
12419 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12421 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12422 [(set_attr "type" "imov")
12423 (set_attr "modrm" "0")
12424 (set_attr "length" "7")
12425 (set_attr "memory" "load")
12426 (set_attr "imm_disp" "false")])
12428 (define_insn "*add_tp_si"
12429 [(set (match_operand:SI 0 "register_operand" "=r")
12430 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12431 (match_operand:SI 1 "register_operand" "0")))
12432 (clobber (reg:CC FLAGS_REG))]
12434 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12435 [(set_attr "type" "alu")
12436 (set_attr "modrm" "0")
12437 (set_attr "length" "7")
12438 (set_attr "memory" "load")
12439 (set_attr "imm_disp" "false")])
12441 (define_insn "*load_tp_di"
12442 [(set (match_operand:DI 0 "register_operand" "=r")
12443 (unspec:DI [(const_int 0)] UNSPEC_TP))]
12445 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12446 [(set_attr "type" "imov")
12447 (set_attr "modrm" "0")
12448 (set_attr "length" "7")
12449 (set_attr "memory" "load")
12450 (set_attr "imm_disp" "false")])
12452 (define_insn "*add_tp_di"
12453 [(set (match_operand:DI 0 "register_operand" "=r")
12454 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12455 (match_operand:DI 1 "register_operand" "0")))
12456 (clobber (reg:CC FLAGS_REG))]
12458 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12459 [(set_attr "type" "alu")
12460 (set_attr "modrm" "0")
12461 (set_attr "length" "7")
12462 (set_attr "memory" "load")
12463 (set_attr "imm_disp" "false")])
12465 ;; GNU2 TLS patterns can be split.
12467 (define_expand "tls_dynamic_gnu2_32"
12468 [(set (match_dup 3)
12469 (plus:SI (match_operand:SI 2 "register_operand" "")
12471 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12474 [(set (match_operand:SI 0 "register_operand" "")
12475 (unspec:SI [(match_dup 1) (match_dup 3)
12476 (match_dup 2) (reg:SI SP_REG)]
12478 (clobber (reg:CC FLAGS_REG))])]
12479 "!TARGET_64BIT && TARGET_GNU2_TLS"
12481 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12482 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12485 (define_insn "*tls_dynamic_lea_32"
12486 [(set (match_operand:SI 0 "register_operand" "=r")
12487 (plus:SI (match_operand:SI 1 "register_operand" "b")
12489 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12490 UNSPEC_TLSDESC))))]
12491 "!TARGET_64BIT && TARGET_GNU2_TLS"
12492 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12493 [(set_attr "type" "lea")
12494 (set_attr "mode" "SI")
12495 (set_attr "length" "6")
12496 (set_attr "length_address" "4")])
12498 (define_insn "*tls_dynamic_call_32"
12499 [(set (match_operand:SI 0 "register_operand" "=a")
12500 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12501 (match_operand:SI 2 "register_operand" "0")
12502 ;; we have to make sure %ebx still points to the GOT
12503 (match_operand:SI 3 "register_operand" "b")
12506 (clobber (reg:CC FLAGS_REG))]
12507 "!TARGET_64BIT && TARGET_GNU2_TLS"
12508 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12509 [(set_attr "type" "call")
12510 (set_attr "length" "2")
12511 (set_attr "length_address" "0")])
12513 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12514 [(set (match_operand:SI 0 "register_operand" "=&a")
12516 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12517 (match_operand:SI 4 "" "")
12518 (match_operand:SI 2 "register_operand" "b")
12521 (const:SI (unspec:SI
12522 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12524 (clobber (reg:CC FLAGS_REG))]
12525 "!TARGET_64BIT && TARGET_GNU2_TLS"
12528 [(set (match_dup 0) (match_dup 5))]
12530 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12531 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12534 (define_expand "tls_dynamic_gnu2_64"
12535 [(set (match_dup 2)
12536 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12539 [(set (match_operand:DI 0 "register_operand" "")
12540 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12542 (clobber (reg:CC FLAGS_REG))])]
12543 "TARGET_64BIT && TARGET_GNU2_TLS"
12545 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12546 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12549 (define_insn "*tls_dynamic_lea_64"
12550 [(set (match_operand:DI 0 "register_operand" "=r")
12551 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12553 "TARGET_64BIT && TARGET_GNU2_TLS"
12554 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12555 [(set_attr "type" "lea")
12556 (set_attr "mode" "DI")
12557 (set_attr "length" "7")
12558 (set_attr "length_address" "4")])
12560 (define_insn "*tls_dynamic_call_64"
12561 [(set (match_operand:DI 0 "register_operand" "=a")
12562 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12563 (match_operand:DI 2 "register_operand" "0")
12566 (clobber (reg:CC FLAGS_REG))]
12567 "TARGET_64BIT && TARGET_GNU2_TLS"
12568 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12569 [(set_attr "type" "call")
12570 (set_attr "length" "2")
12571 (set_attr "length_address" "0")])
12573 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12574 [(set (match_operand:DI 0 "register_operand" "=&a")
12576 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12577 (match_operand:DI 3 "" "")
12580 (const:DI (unspec:DI
12581 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12583 (clobber (reg:CC FLAGS_REG))]
12584 "TARGET_64BIT && TARGET_GNU2_TLS"
12587 [(set (match_dup 0) (match_dup 4))]
12589 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12590 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12595 ;; These patterns match the binary 387 instructions for addM3, subM3,
12596 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12597 ;; SFmode. The first is the normal insn, the second the same insn but
12598 ;; with one operand a conversion, and the third the same insn but with
12599 ;; the other operand a conversion. The conversion may be SFmode or
12600 ;; SImode if the target mode DFmode, but only SImode if the target mode
12603 ;; Gcc is slightly more smart about handling normal two address instructions
12604 ;; so use special patterns for add and mull.
12606 (define_insn "*fop_<mode>_comm_mixed_avx"
12607 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12608 (match_operator:MODEF 3 "binary_fp_operator"
12609 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12610 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12611 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12612 && COMMUTATIVE_ARITH_P (operands[3])
12613 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12614 "* return output_387_binary_op (insn, operands);"
12615 [(set (attr "type")
12616 (if_then_else (eq_attr "alternative" "1")
12617 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12618 (const_string "ssemul")
12619 (const_string "sseadd"))
12620 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12621 (const_string "fmul")
12622 (const_string "fop"))))
12623 (set_attr "prefix" "orig,maybe_vex")
12624 (set_attr "mode" "<MODE>")])
12626 (define_insn "*fop_<mode>_comm_mixed"
12627 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12628 (match_operator:MODEF 3 "binary_fp_operator"
12629 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12630 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12631 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12632 && COMMUTATIVE_ARITH_P (operands[3])
12633 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12634 "* return output_387_binary_op (insn, operands);"
12635 [(set (attr "type")
12636 (if_then_else (eq_attr "alternative" "1")
12637 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12638 (const_string "ssemul")
12639 (const_string "sseadd"))
12640 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12641 (const_string "fmul")
12642 (const_string "fop"))))
12643 (set_attr "mode" "<MODE>")])
12645 (define_insn "*fop_<mode>_comm_avx"
12646 [(set (match_operand:MODEF 0 "register_operand" "=x")
12647 (match_operator:MODEF 3 "binary_fp_operator"
12648 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12649 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12650 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12651 && COMMUTATIVE_ARITH_P (operands[3])
12652 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12653 "* return output_387_binary_op (insn, operands);"
12654 [(set (attr "type")
12655 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12656 (const_string "ssemul")
12657 (const_string "sseadd")))
12658 (set_attr "prefix" "vex")
12659 (set_attr "mode" "<MODE>")])
12661 (define_insn "*fop_<mode>_comm_sse"
12662 [(set (match_operand:MODEF 0 "register_operand" "=x")
12663 (match_operator:MODEF 3 "binary_fp_operator"
12664 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12665 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12666 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12667 && COMMUTATIVE_ARITH_P (operands[3])
12668 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12669 "* return output_387_binary_op (insn, operands);"
12670 [(set (attr "type")
12671 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12672 (const_string "ssemul")
12673 (const_string "sseadd")))
12674 (set_attr "mode" "<MODE>")])
12676 (define_insn "*fop_<mode>_comm_i387"
12677 [(set (match_operand:MODEF 0 "register_operand" "=f")
12678 (match_operator:MODEF 3 "binary_fp_operator"
12679 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12680 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12681 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12682 && COMMUTATIVE_ARITH_P (operands[3])
12683 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12684 "* return output_387_binary_op (insn, operands);"
12685 [(set (attr "type")
12686 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12687 (const_string "fmul")
12688 (const_string "fop")))
12689 (set_attr "mode" "<MODE>")])
12691 (define_insn "*fop_<mode>_1_mixed_avx"
12692 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12693 (match_operator:MODEF 3 "binary_fp_operator"
12694 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12695 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12696 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12697 && !COMMUTATIVE_ARITH_P (operands[3])
12698 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12699 "* return output_387_binary_op (insn, operands);"
12700 [(set (attr "type")
12701 (cond [(and (eq_attr "alternative" "2")
12702 (match_operand:MODEF 3 "mult_operator" ""))
12703 (const_string "ssemul")
12704 (and (eq_attr "alternative" "2")
12705 (match_operand:MODEF 3 "div_operator" ""))
12706 (const_string "ssediv")
12707 (eq_attr "alternative" "2")
12708 (const_string "sseadd")
12709 (match_operand:MODEF 3 "mult_operator" "")
12710 (const_string "fmul")
12711 (match_operand:MODEF 3 "div_operator" "")
12712 (const_string "fdiv")
12714 (const_string "fop")))
12715 (set_attr "prefix" "orig,orig,maybe_vex")
12716 (set_attr "mode" "<MODE>")])
12718 (define_insn "*fop_<mode>_1_mixed"
12719 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12720 (match_operator:MODEF 3 "binary_fp_operator"
12721 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12722 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12723 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12724 && !COMMUTATIVE_ARITH_P (operands[3])
12725 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12726 "* return output_387_binary_op (insn, operands);"
12727 [(set (attr "type")
12728 (cond [(and (eq_attr "alternative" "2")
12729 (match_operand:MODEF 3 "mult_operator" ""))
12730 (const_string "ssemul")
12731 (and (eq_attr "alternative" "2")
12732 (match_operand:MODEF 3 "div_operator" ""))
12733 (const_string "ssediv")
12734 (eq_attr "alternative" "2")
12735 (const_string "sseadd")
12736 (match_operand:MODEF 3 "mult_operator" "")
12737 (const_string "fmul")
12738 (match_operand:MODEF 3 "div_operator" "")
12739 (const_string "fdiv")
12741 (const_string "fop")))
12742 (set_attr "mode" "<MODE>")])
12744 (define_insn "*rcpsf2_sse"
12745 [(set (match_operand:SF 0 "register_operand" "=x")
12746 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12749 "%vrcpss\t{%1, %d0|%d0, %1}"
12750 [(set_attr "type" "sse")
12751 (set_attr "atom_sse_attr" "rcp")
12752 (set_attr "prefix" "maybe_vex")
12753 (set_attr "mode" "SF")])
12755 (define_insn "*fop_<mode>_1_avx"
12756 [(set (match_operand:MODEF 0 "register_operand" "=x")
12757 (match_operator:MODEF 3 "binary_fp_operator"
12758 [(match_operand:MODEF 1 "register_operand" "x")
12759 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12760 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12761 && !COMMUTATIVE_ARITH_P (operands[3])"
12762 "* return output_387_binary_op (insn, operands);"
12763 [(set (attr "type")
12764 (cond [(match_operand:MODEF 3 "mult_operator" "")
12765 (const_string "ssemul")
12766 (match_operand:MODEF 3 "div_operator" "")
12767 (const_string "ssediv")
12769 (const_string "sseadd")))
12770 (set_attr "prefix" "vex")
12771 (set_attr "mode" "<MODE>")])
12773 (define_insn "*fop_<mode>_1_sse"
12774 [(set (match_operand:MODEF 0 "register_operand" "=x")
12775 (match_operator:MODEF 3 "binary_fp_operator"
12776 [(match_operand:MODEF 1 "register_operand" "0")
12777 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12778 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12779 && !COMMUTATIVE_ARITH_P (operands[3])"
12780 "* return output_387_binary_op (insn, operands);"
12781 [(set (attr "type")
12782 (cond [(match_operand:MODEF 3 "mult_operator" "")
12783 (const_string "ssemul")
12784 (match_operand:MODEF 3 "div_operator" "")
12785 (const_string "ssediv")
12787 (const_string "sseadd")))
12788 (set_attr "mode" "<MODE>")])
12790 ;; This pattern is not fully shadowed by the pattern above.
12791 (define_insn "*fop_<mode>_1_i387"
12792 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12793 (match_operator:MODEF 3 "binary_fp_operator"
12794 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12795 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12796 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12797 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12798 && !COMMUTATIVE_ARITH_P (operands[3])
12799 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12800 "* return output_387_binary_op (insn, operands);"
12801 [(set (attr "type")
12802 (cond [(match_operand:MODEF 3 "mult_operator" "")
12803 (const_string "fmul")
12804 (match_operand:MODEF 3 "div_operator" "")
12805 (const_string "fdiv")
12807 (const_string "fop")))
12808 (set_attr "mode" "<MODE>")])
12810 ;; ??? Add SSE splitters for these!
12811 (define_insn "*fop_<MODEF:mode>_2_i387"
12812 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12813 (match_operator:MODEF 3 "binary_fp_operator"
12815 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12816 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12817 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12818 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12819 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12820 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12821 [(set (attr "type")
12822 (cond [(match_operand:MODEF 3 "mult_operator" "")
12823 (const_string "fmul")
12824 (match_operand:MODEF 3 "div_operator" "")
12825 (const_string "fdiv")
12827 (const_string "fop")))
12828 (set_attr "fp_int_src" "true")
12829 (set_attr "mode" "<X87MODEI12:MODE>")])
12831 (define_insn "*fop_<MODEF:mode>_3_i387"
12832 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12833 (match_operator:MODEF 3 "binary_fp_operator"
12834 [(match_operand:MODEF 1 "register_operand" "0,0")
12836 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12837 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12838 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12839 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12840 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12841 [(set (attr "type")
12842 (cond [(match_operand:MODEF 3 "mult_operator" "")
12843 (const_string "fmul")
12844 (match_operand:MODEF 3 "div_operator" "")
12845 (const_string "fdiv")
12847 (const_string "fop")))
12848 (set_attr "fp_int_src" "true")
12849 (set_attr "mode" "<MODE>")])
12851 (define_insn "*fop_df_4_i387"
12852 [(set (match_operand:DF 0 "register_operand" "=f,f")
12853 (match_operator:DF 3 "binary_fp_operator"
12855 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12856 (match_operand:DF 2 "register_operand" "0,f")]))]
12857 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12858 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12859 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12860 "* return output_387_binary_op (insn, operands);"
12861 [(set (attr "type")
12862 (cond [(match_operand:DF 3 "mult_operator" "")
12863 (const_string "fmul")
12864 (match_operand:DF 3 "div_operator" "")
12865 (const_string "fdiv")
12867 (const_string "fop")))
12868 (set_attr "mode" "SF")])
12870 (define_insn "*fop_df_5_i387"
12871 [(set (match_operand:DF 0 "register_operand" "=f,f")
12872 (match_operator:DF 3 "binary_fp_operator"
12873 [(match_operand:DF 1 "register_operand" "0,f")
12875 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12876 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12877 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12878 "* return output_387_binary_op (insn, operands);"
12879 [(set (attr "type")
12880 (cond [(match_operand:DF 3 "mult_operator" "")
12881 (const_string "fmul")
12882 (match_operand:DF 3 "div_operator" "")
12883 (const_string "fdiv")
12885 (const_string "fop")))
12886 (set_attr "mode" "SF")])
12888 (define_insn "*fop_df_6_i387"
12889 [(set (match_operand:DF 0 "register_operand" "=f,f")
12890 (match_operator:DF 3 "binary_fp_operator"
12892 (match_operand:SF 1 "register_operand" "0,f"))
12894 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12895 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12896 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12897 "* return output_387_binary_op (insn, operands);"
12898 [(set (attr "type")
12899 (cond [(match_operand:DF 3 "mult_operator" "")
12900 (const_string "fmul")
12901 (match_operand:DF 3 "div_operator" "")
12902 (const_string "fdiv")
12904 (const_string "fop")))
12905 (set_attr "mode" "SF")])
12907 (define_insn "*fop_xf_comm_i387"
12908 [(set (match_operand:XF 0 "register_operand" "=f")
12909 (match_operator:XF 3 "binary_fp_operator"
12910 [(match_operand:XF 1 "register_operand" "%0")
12911 (match_operand:XF 2 "register_operand" "f")]))]
12913 && COMMUTATIVE_ARITH_P (operands[3])"
12914 "* return output_387_binary_op (insn, operands);"
12915 [(set (attr "type")
12916 (if_then_else (match_operand:XF 3 "mult_operator" "")
12917 (const_string "fmul")
12918 (const_string "fop")))
12919 (set_attr "mode" "XF")])
12921 (define_insn "*fop_xf_1_i387"
12922 [(set (match_operand:XF 0 "register_operand" "=f,f")
12923 (match_operator:XF 3 "binary_fp_operator"
12924 [(match_operand:XF 1 "register_operand" "0,f")
12925 (match_operand:XF 2 "register_operand" "f,0")]))]
12927 && !COMMUTATIVE_ARITH_P (operands[3])"
12928 "* return output_387_binary_op (insn, operands);"
12929 [(set (attr "type")
12930 (cond [(match_operand:XF 3 "mult_operator" "")
12931 (const_string "fmul")
12932 (match_operand:XF 3 "div_operator" "")
12933 (const_string "fdiv")
12935 (const_string "fop")))
12936 (set_attr "mode" "XF")])
12938 (define_insn "*fop_xf_2_i387"
12939 [(set (match_operand:XF 0 "register_operand" "=f,f")
12940 (match_operator:XF 3 "binary_fp_operator"
12942 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12943 (match_operand:XF 2 "register_operand" "0,0")]))]
12944 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12945 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12946 [(set (attr "type")
12947 (cond [(match_operand:XF 3 "mult_operator" "")
12948 (const_string "fmul")
12949 (match_operand:XF 3 "div_operator" "")
12950 (const_string "fdiv")
12952 (const_string "fop")))
12953 (set_attr "fp_int_src" "true")
12954 (set_attr "mode" "<MODE>")])
12956 (define_insn "*fop_xf_3_i387"
12957 [(set (match_operand:XF 0 "register_operand" "=f,f")
12958 (match_operator:XF 3 "binary_fp_operator"
12959 [(match_operand:XF 1 "register_operand" "0,0")
12961 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12962 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12963 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12964 [(set (attr "type")
12965 (cond [(match_operand:XF 3 "mult_operator" "")
12966 (const_string "fmul")
12967 (match_operand:XF 3 "div_operator" "")
12968 (const_string "fdiv")
12970 (const_string "fop")))
12971 (set_attr "fp_int_src" "true")
12972 (set_attr "mode" "<MODE>")])
12974 (define_insn "*fop_xf_4_i387"
12975 [(set (match_operand:XF 0 "register_operand" "=f,f")
12976 (match_operator:XF 3 "binary_fp_operator"
12978 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12979 (match_operand:XF 2 "register_operand" "0,f")]))]
12981 "* return output_387_binary_op (insn, operands);"
12982 [(set (attr "type")
12983 (cond [(match_operand:XF 3 "mult_operator" "")
12984 (const_string "fmul")
12985 (match_operand:XF 3 "div_operator" "")
12986 (const_string "fdiv")
12988 (const_string "fop")))
12989 (set_attr "mode" "<MODE>")])
12991 (define_insn "*fop_xf_5_i387"
12992 [(set (match_operand:XF 0 "register_operand" "=f,f")
12993 (match_operator:XF 3 "binary_fp_operator"
12994 [(match_operand:XF 1 "register_operand" "0,f")
12996 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12998 "* return output_387_binary_op (insn, operands);"
12999 [(set (attr "type")
13000 (cond [(match_operand:XF 3 "mult_operator" "")
13001 (const_string "fmul")
13002 (match_operand:XF 3 "div_operator" "")
13003 (const_string "fdiv")
13005 (const_string "fop")))
13006 (set_attr "mode" "<MODE>")])
13008 (define_insn "*fop_xf_6_i387"
13009 [(set (match_operand:XF 0 "register_operand" "=f,f")
13010 (match_operator:XF 3 "binary_fp_operator"
13012 (match_operand:MODEF 1 "register_operand" "0,f"))
13014 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13016 "* return output_387_binary_op (insn, operands);"
13017 [(set (attr "type")
13018 (cond [(match_operand:XF 3 "mult_operator" "")
13019 (const_string "fmul")
13020 (match_operand:XF 3 "div_operator" "")
13021 (const_string "fdiv")
13023 (const_string "fop")))
13024 (set_attr "mode" "<MODE>")])
13027 [(set (match_operand 0 "register_operand" "")
13028 (match_operator 3 "binary_fp_operator"
13029 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13030 (match_operand 2 "register_operand" "")]))]
13032 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13033 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13036 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13037 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13038 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13039 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13040 GET_MODE (operands[3]),
13043 ix86_free_from_memory (GET_MODE (operands[1]));
13048 [(set (match_operand 0 "register_operand" "")
13049 (match_operator 3 "binary_fp_operator"
13050 [(match_operand 1 "register_operand" "")
13051 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13053 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13054 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13057 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13058 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13059 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13060 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13061 GET_MODE (operands[3]),
13064 ix86_free_from_memory (GET_MODE (operands[2]));
13068 ;; FPU special functions.
13070 ;; This pattern implements a no-op XFmode truncation for
13071 ;; all fancy i386 XFmode math functions.
13073 (define_insn "truncxf<mode>2_i387_noop_unspec"
13074 [(set (match_operand:MODEF 0 "register_operand" "=f")
13075 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13076 UNSPEC_TRUNC_NOOP))]
13077 "TARGET_USE_FANCY_MATH_387"
13078 "* return output_387_reg_move (insn, operands);"
13079 [(set_attr "type" "fmov")
13080 (set_attr "mode" "<MODE>")])
13082 (define_insn "sqrtxf2"
13083 [(set (match_operand:XF 0 "register_operand" "=f")
13084 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13085 "TARGET_USE_FANCY_MATH_387"
13087 [(set_attr "type" "fpspc")
13088 (set_attr "mode" "XF")
13089 (set_attr "athlon_decode" "direct")
13090 (set_attr "amdfam10_decode" "direct")])
13092 (define_insn "sqrt_extend<mode>xf2_i387"
13093 [(set (match_operand:XF 0 "register_operand" "=f")
13096 (match_operand:MODEF 1 "register_operand" "0"))))]
13097 "TARGET_USE_FANCY_MATH_387"
13099 [(set_attr "type" "fpspc")
13100 (set_attr "mode" "XF")
13101 (set_attr "athlon_decode" "direct")
13102 (set_attr "amdfam10_decode" "direct")])
13104 (define_insn "*rsqrtsf2_sse"
13105 [(set (match_operand:SF 0 "register_operand" "=x")
13106 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13109 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13110 [(set_attr "type" "sse")
13111 (set_attr "atom_sse_attr" "rcp")
13112 (set_attr "prefix" "maybe_vex")
13113 (set_attr "mode" "SF")])
13115 (define_expand "rsqrtsf2"
13116 [(set (match_operand:SF 0 "register_operand" "")
13117 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13121 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13125 (define_insn "*sqrt<mode>2_sse"
13126 [(set (match_operand:MODEF 0 "register_operand" "=x")
13128 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13129 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13130 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13131 [(set_attr "type" "sse")
13132 (set_attr "atom_sse_attr" "sqrt")
13133 (set_attr "prefix" "maybe_vex")
13134 (set_attr "mode" "<MODE>")
13135 (set_attr "athlon_decode" "*")
13136 (set_attr "amdfam10_decode" "*")])
13138 (define_expand "sqrt<mode>2"
13139 [(set (match_operand:MODEF 0 "register_operand" "")
13141 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13142 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13143 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13145 if (<MODE>mode == SFmode
13146 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13147 && flag_finite_math_only && !flag_trapping_math
13148 && flag_unsafe_math_optimizations)
13150 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13154 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13156 rtx op0 = gen_reg_rtx (XFmode);
13157 rtx op1 = force_reg (<MODE>mode, operands[1]);
13159 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13160 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13165 (define_insn "fpremxf4_i387"
13166 [(set (match_operand:XF 0 "register_operand" "=f")
13167 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13168 (match_operand:XF 3 "register_operand" "1")]
13170 (set (match_operand:XF 1 "register_operand" "=u")
13171 (unspec:XF [(match_dup 2) (match_dup 3)]
13173 (set (reg:CCFP FPSR_REG)
13174 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13176 "TARGET_USE_FANCY_MATH_387"
13178 [(set_attr "type" "fpspc")
13179 (set_attr "mode" "XF")])
13181 (define_expand "fmodxf3"
13182 [(use (match_operand:XF 0 "register_operand" ""))
13183 (use (match_operand:XF 1 "general_operand" ""))
13184 (use (match_operand:XF 2 "general_operand" ""))]
13185 "TARGET_USE_FANCY_MATH_387"
13187 rtx label = gen_label_rtx ();
13189 rtx op1 = gen_reg_rtx (XFmode);
13190 rtx op2 = gen_reg_rtx (XFmode);
13192 emit_move_insn (op2, operands[2]);
13193 emit_move_insn (op1, operands[1]);
13195 emit_label (label);
13196 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13197 ix86_emit_fp_unordered_jump (label);
13198 LABEL_NUSES (label) = 1;
13200 emit_move_insn (operands[0], op1);
13204 (define_expand "fmod<mode>3"
13205 [(use (match_operand:MODEF 0 "register_operand" ""))
13206 (use (match_operand:MODEF 1 "general_operand" ""))
13207 (use (match_operand:MODEF 2 "general_operand" ""))]
13208 "TARGET_USE_FANCY_MATH_387"
13210 rtx label = gen_label_rtx ();
13212 rtx op1 = gen_reg_rtx (XFmode);
13213 rtx op2 = gen_reg_rtx (XFmode);
13215 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13216 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13218 emit_label (label);
13219 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13220 ix86_emit_fp_unordered_jump (label);
13221 LABEL_NUSES (label) = 1;
13223 /* Truncate the result properly for strict SSE math. */
13224 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13225 && !TARGET_MIX_SSE_I387)
13226 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13228 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13233 (define_insn "fprem1xf4_i387"
13234 [(set (match_operand:XF 0 "register_operand" "=f")
13235 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13236 (match_operand:XF 3 "register_operand" "1")]
13238 (set (match_operand:XF 1 "register_operand" "=u")
13239 (unspec:XF [(match_dup 2) (match_dup 3)]
13241 (set (reg:CCFP FPSR_REG)
13242 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13244 "TARGET_USE_FANCY_MATH_387"
13246 [(set_attr "type" "fpspc")
13247 (set_attr "mode" "XF")])
13249 (define_expand "remainderxf3"
13250 [(use (match_operand:XF 0 "register_operand" ""))
13251 (use (match_operand:XF 1 "general_operand" ""))
13252 (use (match_operand:XF 2 "general_operand" ""))]
13253 "TARGET_USE_FANCY_MATH_387"
13255 rtx label = gen_label_rtx ();
13257 rtx op1 = gen_reg_rtx (XFmode);
13258 rtx op2 = gen_reg_rtx (XFmode);
13260 emit_move_insn (op2, operands[2]);
13261 emit_move_insn (op1, operands[1]);
13263 emit_label (label);
13264 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13265 ix86_emit_fp_unordered_jump (label);
13266 LABEL_NUSES (label) = 1;
13268 emit_move_insn (operands[0], op1);
13272 (define_expand "remainder<mode>3"
13273 [(use (match_operand:MODEF 0 "register_operand" ""))
13274 (use (match_operand:MODEF 1 "general_operand" ""))
13275 (use (match_operand:MODEF 2 "general_operand" ""))]
13276 "TARGET_USE_FANCY_MATH_387"
13278 rtx label = gen_label_rtx ();
13280 rtx op1 = gen_reg_rtx (XFmode);
13281 rtx op2 = gen_reg_rtx (XFmode);
13283 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13284 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13286 emit_label (label);
13288 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13289 ix86_emit_fp_unordered_jump (label);
13290 LABEL_NUSES (label) = 1;
13292 /* Truncate the result properly for strict SSE math. */
13293 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13294 && !TARGET_MIX_SSE_I387)
13295 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13297 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13302 (define_insn "*sinxf2_i387"
13303 [(set (match_operand:XF 0 "register_operand" "=f")
13304 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13305 "TARGET_USE_FANCY_MATH_387
13306 && flag_unsafe_math_optimizations"
13308 [(set_attr "type" "fpspc")
13309 (set_attr "mode" "XF")])
13311 (define_insn "*sin_extend<mode>xf2_i387"
13312 [(set (match_operand:XF 0 "register_operand" "=f")
13313 (unspec:XF [(float_extend:XF
13314 (match_operand:MODEF 1 "register_operand" "0"))]
13316 "TARGET_USE_FANCY_MATH_387
13317 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13318 || TARGET_MIX_SSE_I387)
13319 && flag_unsafe_math_optimizations"
13321 [(set_attr "type" "fpspc")
13322 (set_attr "mode" "XF")])
13324 (define_insn "*cosxf2_i387"
13325 [(set (match_operand:XF 0 "register_operand" "=f")
13326 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13327 "TARGET_USE_FANCY_MATH_387
13328 && flag_unsafe_math_optimizations"
13330 [(set_attr "type" "fpspc")
13331 (set_attr "mode" "XF")])
13333 (define_insn "*cos_extend<mode>xf2_i387"
13334 [(set (match_operand:XF 0 "register_operand" "=f")
13335 (unspec:XF [(float_extend:XF
13336 (match_operand:MODEF 1 "register_operand" "0"))]
13338 "TARGET_USE_FANCY_MATH_387
13339 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13340 || TARGET_MIX_SSE_I387)
13341 && flag_unsafe_math_optimizations"
13343 [(set_attr "type" "fpspc")
13344 (set_attr "mode" "XF")])
13346 ;; When sincos pattern is defined, sin and cos builtin functions will be
13347 ;; expanded to sincos pattern with one of its outputs left unused.
13348 ;; CSE pass will figure out if two sincos patterns can be combined,
13349 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13350 ;; depending on the unused output.
13352 (define_insn "sincosxf3"
13353 [(set (match_operand:XF 0 "register_operand" "=f")
13354 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13355 UNSPEC_SINCOS_COS))
13356 (set (match_operand:XF 1 "register_operand" "=u")
13357 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13358 "TARGET_USE_FANCY_MATH_387
13359 && flag_unsafe_math_optimizations"
13361 [(set_attr "type" "fpspc")
13362 (set_attr "mode" "XF")])
13365 [(set (match_operand:XF 0 "register_operand" "")
13366 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13367 UNSPEC_SINCOS_COS))
13368 (set (match_operand:XF 1 "register_operand" "")
13369 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13370 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13371 && !(reload_completed || reload_in_progress)"
13372 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13376 [(set (match_operand:XF 0 "register_operand" "")
13377 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13378 UNSPEC_SINCOS_COS))
13379 (set (match_operand:XF 1 "register_operand" "")
13380 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13381 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13382 && !(reload_completed || reload_in_progress)"
13383 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13386 (define_insn "sincos_extend<mode>xf3_i387"
13387 [(set (match_operand:XF 0 "register_operand" "=f")
13388 (unspec:XF [(float_extend:XF
13389 (match_operand:MODEF 2 "register_operand" "0"))]
13390 UNSPEC_SINCOS_COS))
13391 (set (match_operand:XF 1 "register_operand" "=u")
13392 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13393 "TARGET_USE_FANCY_MATH_387
13394 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13395 || TARGET_MIX_SSE_I387)
13396 && flag_unsafe_math_optimizations"
13398 [(set_attr "type" "fpspc")
13399 (set_attr "mode" "XF")])
13402 [(set (match_operand:XF 0 "register_operand" "")
13403 (unspec:XF [(float_extend:XF
13404 (match_operand:MODEF 2 "register_operand" ""))]
13405 UNSPEC_SINCOS_COS))
13406 (set (match_operand:XF 1 "register_operand" "")
13407 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13408 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13409 && !(reload_completed || reload_in_progress)"
13410 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13414 [(set (match_operand:XF 0 "register_operand" "")
13415 (unspec:XF [(float_extend:XF
13416 (match_operand:MODEF 2 "register_operand" ""))]
13417 UNSPEC_SINCOS_COS))
13418 (set (match_operand:XF 1 "register_operand" "")
13419 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13420 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13421 && !(reload_completed || reload_in_progress)"
13422 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13425 (define_expand "sincos<mode>3"
13426 [(use (match_operand:MODEF 0 "register_operand" ""))
13427 (use (match_operand:MODEF 1 "register_operand" ""))
13428 (use (match_operand:MODEF 2 "register_operand" ""))]
13429 "TARGET_USE_FANCY_MATH_387
13430 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13431 || TARGET_MIX_SSE_I387)
13432 && flag_unsafe_math_optimizations"
13434 rtx op0 = gen_reg_rtx (XFmode);
13435 rtx op1 = gen_reg_rtx (XFmode);
13437 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13438 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13439 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13443 (define_insn "fptanxf4_i387"
13444 [(set (match_operand:XF 0 "register_operand" "=f")
13445 (match_operand:XF 3 "const_double_operand" "F"))
13446 (set (match_operand:XF 1 "register_operand" "=u")
13447 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13449 "TARGET_USE_FANCY_MATH_387
13450 && flag_unsafe_math_optimizations
13451 && standard_80387_constant_p (operands[3]) == 2"
13453 [(set_attr "type" "fpspc")
13454 (set_attr "mode" "XF")])
13456 (define_insn "fptan_extend<mode>xf4_i387"
13457 [(set (match_operand:MODEF 0 "register_operand" "=f")
13458 (match_operand:MODEF 3 "const_double_operand" "F"))
13459 (set (match_operand:XF 1 "register_operand" "=u")
13460 (unspec:XF [(float_extend:XF
13461 (match_operand:MODEF 2 "register_operand" "0"))]
13463 "TARGET_USE_FANCY_MATH_387
13464 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13465 || TARGET_MIX_SSE_I387)
13466 && flag_unsafe_math_optimizations
13467 && standard_80387_constant_p (operands[3]) == 2"
13469 [(set_attr "type" "fpspc")
13470 (set_attr "mode" "XF")])
13472 (define_expand "tanxf2"
13473 [(use (match_operand:XF 0 "register_operand" ""))
13474 (use (match_operand:XF 1 "register_operand" ""))]
13475 "TARGET_USE_FANCY_MATH_387
13476 && flag_unsafe_math_optimizations"
13478 rtx one = gen_reg_rtx (XFmode);
13479 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13481 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13485 (define_expand "tan<mode>2"
13486 [(use (match_operand:MODEF 0 "register_operand" ""))
13487 (use (match_operand:MODEF 1 "register_operand" ""))]
13488 "TARGET_USE_FANCY_MATH_387
13489 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13490 || TARGET_MIX_SSE_I387)
13491 && flag_unsafe_math_optimizations"
13493 rtx op0 = gen_reg_rtx (XFmode);
13495 rtx one = gen_reg_rtx (<MODE>mode);
13496 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13498 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13499 operands[1], op2));
13500 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13504 (define_insn "*fpatanxf3_i387"
13505 [(set (match_operand:XF 0 "register_operand" "=f")
13506 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13507 (match_operand:XF 2 "register_operand" "u")]
13509 (clobber (match_scratch:XF 3 "=2"))]
13510 "TARGET_USE_FANCY_MATH_387
13511 && flag_unsafe_math_optimizations"
13513 [(set_attr "type" "fpspc")
13514 (set_attr "mode" "XF")])
13516 (define_insn "fpatan_extend<mode>xf3_i387"
13517 [(set (match_operand:XF 0 "register_operand" "=f")
13518 (unspec:XF [(float_extend:XF
13519 (match_operand:MODEF 1 "register_operand" "0"))
13521 (match_operand:MODEF 2 "register_operand" "u"))]
13523 (clobber (match_scratch:XF 3 "=2"))]
13524 "TARGET_USE_FANCY_MATH_387
13525 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13526 || TARGET_MIX_SSE_I387)
13527 && flag_unsafe_math_optimizations"
13529 [(set_attr "type" "fpspc")
13530 (set_attr "mode" "XF")])
13532 (define_expand "atan2xf3"
13533 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13534 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13535 (match_operand:XF 1 "register_operand" "")]
13537 (clobber (match_scratch:XF 3 ""))])]
13538 "TARGET_USE_FANCY_MATH_387
13539 && flag_unsafe_math_optimizations"
13542 (define_expand "atan2<mode>3"
13543 [(use (match_operand:MODEF 0 "register_operand" ""))
13544 (use (match_operand:MODEF 1 "register_operand" ""))
13545 (use (match_operand:MODEF 2 "register_operand" ""))]
13546 "TARGET_USE_FANCY_MATH_387
13547 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13548 || TARGET_MIX_SSE_I387)
13549 && flag_unsafe_math_optimizations"
13551 rtx op0 = gen_reg_rtx (XFmode);
13553 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13554 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13558 (define_expand "atanxf2"
13559 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13560 (unspec:XF [(match_dup 2)
13561 (match_operand:XF 1 "register_operand" "")]
13563 (clobber (match_scratch:XF 3 ""))])]
13564 "TARGET_USE_FANCY_MATH_387
13565 && flag_unsafe_math_optimizations"
13567 operands[2] = gen_reg_rtx (XFmode);
13568 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13571 (define_expand "atan<mode>2"
13572 [(use (match_operand:MODEF 0 "register_operand" ""))
13573 (use (match_operand:MODEF 1 "register_operand" ""))]
13574 "TARGET_USE_FANCY_MATH_387
13575 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13576 || TARGET_MIX_SSE_I387)
13577 && flag_unsafe_math_optimizations"
13579 rtx op0 = gen_reg_rtx (XFmode);
13581 rtx op2 = gen_reg_rtx (<MODE>mode);
13582 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13584 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13585 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13589 (define_expand "asinxf2"
13590 [(set (match_dup 2)
13591 (mult:XF (match_operand:XF 1 "register_operand" "")
13593 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13594 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13595 (parallel [(set (match_operand:XF 0 "register_operand" "")
13596 (unspec:XF [(match_dup 5) (match_dup 1)]
13598 (clobber (match_scratch:XF 6 ""))])]
13599 "TARGET_USE_FANCY_MATH_387
13600 && flag_unsafe_math_optimizations"
13604 if (optimize_insn_for_size_p ())
13607 for (i = 2; i < 6; i++)
13608 operands[i] = gen_reg_rtx (XFmode);
13610 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13613 (define_expand "asin<mode>2"
13614 [(use (match_operand:MODEF 0 "register_operand" ""))
13615 (use (match_operand:MODEF 1 "general_operand" ""))]
13616 "TARGET_USE_FANCY_MATH_387
13617 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13618 || TARGET_MIX_SSE_I387)
13619 && flag_unsafe_math_optimizations"
13621 rtx op0 = gen_reg_rtx (XFmode);
13622 rtx op1 = gen_reg_rtx (XFmode);
13624 if (optimize_insn_for_size_p ())
13627 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13628 emit_insn (gen_asinxf2 (op0, op1));
13629 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13633 (define_expand "acosxf2"
13634 [(set (match_dup 2)
13635 (mult:XF (match_operand:XF 1 "register_operand" "")
13637 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13638 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13639 (parallel [(set (match_operand:XF 0 "register_operand" "")
13640 (unspec:XF [(match_dup 1) (match_dup 5)]
13642 (clobber (match_scratch:XF 6 ""))])]
13643 "TARGET_USE_FANCY_MATH_387
13644 && flag_unsafe_math_optimizations"
13648 if (optimize_insn_for_size_p ())
13651 for (i = 2; i < 6; i++)
13652 operands[i] = gen_reg_rtx (XFmode);
13654 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13657 (define_expand "acos<mode>2"
13658 [(use (match_operand:MODEF 0 "register_operand" ""))
13659 (use (match_operand:MODEF 1 "general_operand" ""))]
13660 "TARGET_USE_FANCY_MATH_387
13661 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13662 || TARGET_MIX_SSE_I387)
13663 && flag_unsafe_math_optimizations"
13665 rtx op0 = gen_reg_rtx (XFmode);
13666 rtx op1 = gen_reg_rtx (XFmode);
13668 if (optimize_insn_for_size_p ())
13671 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13672 emit_insn (gen_acosxf2 (op0, op1));
13673 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13677 (define_insn "fyl2xxf3_i387"
13678 [(set (match_operand:XF 0 "register_operand" "=f")
13679 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13680 (match_operand:XF 2 "register_operand" "u")]
13682 (clobber (match_scratch:XF 3 "=2"))]
13683 "TARGET_USE_FANCY_MATH_387
13684 && flag_unsafe_math_optimizations"
13686 [(set_attr "type" "fpspc")
13687 (set_attr "mode" "XF")])
13689 (define_insn "fyl2x_extend<mode>xf3_i387"
13690 [(set (match_operand:XF 0 "register_operand" "=f")
13691 (unspec:XF [(float_extend:XF
13692 (match_operand:MODEF 1 "register_operand" "0"))
13693 (match_operand:XF 2 "register_operand" "u")]
13695 (clobber (match_scratch:XF 3 "=2"))]
13696 "TARGET_USE_FANCY_MATH_387
13697 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13698 || TARGET_MIX_SSE_I387)
13699 && flag_unsafe_math_optimizations"
13701 [(set_attr "type" "fpspc")
13702 (set_attr "mode" "XF")])
13704 (define_expand "logxf2"
13705 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13706 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13707 (match_dup 2)] UNSPEC_FYL2X))
13708 (clobber (match_scratch:XF 3 ""))])]
13709 "TARGET_USE_FANCY_MATH_387
13710 && flag_unsafe_math_optimizations"
13712 operands[2] = gen_reg_rtx (XFmode);
13713 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13716 (define_expand "log<mode>2"
13717 [(use (match_operand:MODEF 0 "register_operand" ""))
13718 (use (match_operand:MODEF 1 "register_operand" ""))]
13719 "TARGET_USE_FANCY_MATH_387
13720 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13721 || TARGET_MIX_SSE_I387)
13722 && flag_unsafe_math_optimizations"
13724 rtx op0 = gen_reg_rtx (XFmode);
13726 rtx op2 = gen_reg_rtx (XFmode);
13727 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13729 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13730 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13734 (define_expand "log10xf2"
13735 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13736 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13737 (match_dup 2)] UNSPEC_FYL2X))
13738 (clobber (match_scratch:XF 3 ""))])]
13739 "TARGET_USE_FANCY_MATH_387
13740 && flag_unsafe_math_optimizations"
13742 operands[2] = gen_reg_rtx (XFmode);
13743 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13746 (define_expand "log10<mode>2"
13747 [(use (match_operand:MODEF 0 "register_operand" ""))
13748 (use (match_operand:MODEF 1 "register_operand" ""))]
13749 "TARGET_USE_FANCY_MATH_387
13750 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13751 || TARGET_MIX_SSE_I387)
13752 && flag_unsafe_math_optimizations"
13754 rtx op0 = gen_reg_rtx (XFmode);
13756 rtx op2 = gen_reg_rtx (XFmode);
13757 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13759 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13760 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13764 (define_expand "log2xf2"
13765 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13766 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13767 (match_dup 2)] UNSPEC_FYL2X))
13768 (clobber (match_scratch:XF 3 ""))])]
13769 "TARGET_USE_FANCY_MATH_387
13770 && flag_unsafe_math_optimizations"
13772 operands[2] = gen_reg_rtx (XFmode);
13773 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13776 (define_expand "log2<mode>2"
13777 [(use (match_operand:MODEF 0 "register_operand" ""))
13778 (use (match_operand:MODEF 1 "register_operand" ""))]
13779 "TARGET_USE_FANCY_MATH_387
13780 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13781 || TARGET_MIX_SSE_I387)
13782 && flag_unsafe_math_optimizations"
13784 rtx op0 = gen_reg_rtx (XFmode);
13786 rtx op2 = gen_reg_rtx (XFmode);
13787 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13789 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13790 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13794 (define_insn "fyl2xp1xf3_i387"
13795 [(set (match_operand:XF 0 "register_operand" "=f")
13796 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13797 (match_operand:XF 2 "register_operand" "u")]
13799 (clobber (match_scratch:XF 3 "=2"))]
13800 "TARGET_USE_FANCY_MATH_387
13801 && flag_unsafe_math_optimizations"
13803 [(set_attr "type" "fpspc")
13804 (set_attr "mode" "XF")])
13806 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13807 [(set (match_operand:XF 0 "register_operand" "=f")
13808 (unspec:XF [(float_extend:XF
13809 (match_operand:MODEF 1 "register_operand" "0"))
13810 (match_operand:XF 2 "register_operand" "u")]
13812 (clobber (match_scratch:XF 3 "=2"))]
13813 "TARGET_USE_FANCY_MATH_387
13814 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13815 || TARGET_MIX_SSE_I387)
13816 && flag_unsafe_math_optimizations"
13818 [(set_attr "type" "fpspc")
13819 (set_attr "mode" "XF")])
13821 (define_expand "log1pxf2"
13822 [(use (match_operand:XF 0 "register_operand" ""))
13823 (use (match_operand:XF 1 "register_operand" ""))]
13824 "TARGET_USE_FANCY_MATH_387
13825 && flag_unsafe_math_optimizations"
13827 if (optimize_insn_for_size_p ())
13830 ix86_emit_i387_log1p (operands[0], operands[1]);
13834 (define_expand "log1p<mode>2"
13835 [(use (match_operand:MODEF 0 "register_operand" ""))
13836 (use (match_operand:MODEF 1 "register_operand" ""))]
13837 "TARGET_USE_FANCY_MATH_387
13838 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13839 || TARGET_MIX_SSE_I387)
13840 && flag_unsafe_math_optimizations"
13844 if (optimize_insn_for_size_p ())
13847 op0 = gen_reg_rtx (XFmode);
13849 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13851 ix86_emit_i387_log1p (op0, operands[1]);
13852 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13856 (define_insn "fxtractxf3_i387"
13857 [(set (match_operand:XF 0 "register_operand" "=f")
13858 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13859 UNSPEC_XTRACT_FRACT))
13860 (set (match_operand:XF 1 "register_operand" "=u")
13861 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13862 "TARGET_USE_FANCY_MATH_387
13863 && flag_unsafe_math_optimizations"
13865 [(set_attr "type" "fpspc")
13866 (set_attr "mode" "XF")])
13868 (define_insn "fxtract_extend<mode>xf3_i387"
13869 [(set (match_operand:XF 0 "register_operand" "=f")
13870 (unspec:XF [(float_extend:XF
13871 (match_operand:MODEF 2 "register_operand" "0"))]
13872 UNSPEC_XTRACT_FRACT))
13873 (set (match_operand:XF 1 "register_operand" "=u")
13874 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13875 "TARGET_USE_FANCY_MATH_387
13876 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13877 || TARGET_MIX_SSE_I387)
13878 && flag_unsafe_math_optimizations"
13880 [(set_attr "type" "fpspc")
13881 (set_attr "mode" "XF")])
13883 (define_expand "logbxf2"
13884 [(parallel [(set (match_dup 2)
13885 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13886 UNSPEC_XTRACT_FRACT))
13887 (set (match_operand:XF 0 "register_operand" "")
13888 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13889 "TARGET_USE_FANCY_MATH_387
13890 && flag_unsafe_math_optimizations"
13892 operands[2] = gen_reg_rtx (XFmode);
13895 (define_expand "logb<mode>2"
13896 [(use (match_operand:MODEF 0 "register_operand" ""))
13897 (use (match_operand:MODEF 1 "register_operand" ""))]
13898 "TARGET_USE_FANCY_MATH_387
13899 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13900 || TARGET_MIX_SSE_I387)
13901 && flag_unsafe_math_optimizations"
13903 rtx op0 = gen_reg_rtx (XFmode);
13904 rtx op1 = gen_reg_rtx (XFmode);
13906 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13907 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13911 (define_expand "ilogbxf2"
13912 [(use (match_operand:SI 0 "register_operand" ""))
13913 (use (match_operand:XF 1 "register_operand" ""))]
13914 "TARGET_USE_FANCY_MATH_387
13915 && flag_unsafe_math_optimizations"
13919 if (optimize_insn_for_size_p ())
13922 op0 = gen_reg_rtx (XFmode);
13923 op1 = gen_reg_rtx (XFmode);
13925 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13926 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13930 (define_expand "ilogb<mode>2"
13931 [(use (match_operand:SI 0 "register_operand" ""))
13932 (use (match_operand:MODEF 1 "register_operand" ""))]
13933 "TARGET_USE_FANCY_MATH_387
13934 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13935 || TARGET_MIX_SSE_I387)
13936 && flag_unsafe_math_optimizations"
13940 if (optimize_insn_for_size_p ())
13943 op0 = gen_reg_rtx (XFmode);
13944 op1 = gen_reg_rtx (XFmode);
13946 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13947 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13951 (define_insn "*f2xm1xf2_i387"
13952 [(set (match_operand:XF 0 "register_operand" "=f")
13953 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13955 "TARGET_USE_FANCY_MATH_387
13956 && flag_unsafe_math_optimizations"
13958 [(set_attr "type" "fpspc")
13959 (set_attr "mode" "XF")])
13961 (define_insn "*fscalexf4_i387"
13962 [(set (match_operand:XF 0 "register_operand" "=f")
13963 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13964 (match_operand:XF 3 "register_operand" "1")]
13965 UNSPEC_FSCALE_FRACT))
13966 (set (match_operand:XF 1 "register_operand" "=u")
13967 (unspec:XF [(match_dup 2) (match_dup 3)]
13968 UNSPEC_FSCALE_EXP))]
13969 "TARGET_USE_FANCY_MATH_387
13970 && flag_unsafe_math_optimizations"
13972 [(set_attr "type" "fpspc")
13973 (set_attr "mode" "XF")])
13975 (define_expand "expNcorexf3"
13976 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13977 (match_operand:XF 2 "register_operand" "")))
13978 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13979 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13980 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13981 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13982 (parallel [(set (match_operand:XF 0 "register_operand" "")
13983 (unspec:XF [(match_dup 8) (match_dup 4)]
13984 UNSPEC_FSCALE_FRACT))
13986 (unspec:XF [(match_dup 8) (match_dup 4)]
13987 UNSPEC_FSCALE_EXP))])]
13988 "TARGET_USE_FANCY_MATH_387
13989 && flag_unsafe_math_optimizations"
13993 if (optimize_insn_for_size_p ())
13996 for (i = 3; i < 10; i++)
13997 operands[i] = gen_reg_rtx (XFmode);
13999 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14002 (define_expand "expxf2"
14003 [(use (match_operand:XF 0 "register_operand" ""))
14004 (use (match_operand:XF 1 "register_operand" ""))]
14005 "TARGET_USE_FANCY_MATH_387
14006 && flag_unsafe_math_optimizations"
14010 if (optimize_insn_for_size_p ())
14013 op2 = gen_reg_rtx (XFmode);
14014 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14016 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14020 (define_expand "exp<mode>2"
14021 [(use (match_operand:MODEF 0 "register_operand" ""))
14022 (use (match_operand:MODEF 1 "general_operand" ""))]
14023 "TARGET_USE_FANCY_MATH_387
14024 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14025 || TARGET_MIX_SSE_I387)
14026 && flag_unsafe_math_optimizations"
14030 if (optimize_insn_for_size_p ())
14033 op0 = gen_reg_rtx (XFmode);
14034 op1 = gen_reg_rtx (XFmode);
14036 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14037 emit_insn (gen_expxf2 (op0, op1));
14038 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14042 (define_expand "exp10xf2"
14043 [(use (match_operand:XF 0 "register_operand" ""))
14044 (use (match_operand:XF 1 "register_operand" ""))]
14045 "TARGET_USE_FANCY_MATH_387
14046 && flag_unsafe_math_optimizations"
14050 if (optimize_insn_for_size_p ())
14053 op2 = gen_reg_rtx (XFmode);
14054 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14056 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14060 (define_expand "exp10<mode>2"
14061 [(use (match_operand:MODEF 0 "register_operand" ""))
14062 (use (match_operand:MODEF 1 "general_operand" ""))]
14063 "TARGET_USE_FANCY_MATH_387
14064 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14065 || TARGET_MIX_SSE_I387)
14066 && flag_unsafe_math_optimizations"
14070 if (optimize_insn_for_size_p ())
14073 op0 = gen_reg_rtx (XFmode);
14074 op1 = gen_reg_rtx (XFmode);
14076 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14077 emit_insn (gen_exp10xf2 (op0, op1));
14078 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14082 (define_expand "exp2xf2"
14083 [(use (match_operand:XF 0 "register_operand" ""))
14084 (use (match_operand:XF 1 "register_operand" ""))]
14085 "TARGET_USE_FANCY_MATH_387
14086 && flag_unsafe_math_optimizations"
14090 if (optimize_insn_for_size_p ())
14093 op2 = gen_reg_rtx (XFmode);
14094 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14096 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14100 (define_expand "exp2<mode>2"
14101 [(use (match_operand:MODEF 0 "register_operand" ""))
14102 (use (match_operand:MODEF 1 "general_operand" ""))]
14103 "TARGET_USE_FANCY_MATH_387
14104 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14105 || TARGET_MIX_SSE_I387)
14106 && flag_unsafe_math_optimizations"
14110 if (optimize_insn_for_size_p ())
14113 op0 = gen_reg_rtx (XFmode);
14114 op1 = gen_reg_rtx (XFmode);
14116 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14117 emit_insn (gen_exp2xf2 (op0, op1));
14118 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14122 (define_expand "expm1xf2"
14123 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14125 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14126 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14127 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14128 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14129 (parallel [(set (match_dup 7)
14130 (unspec:XF [(match_dup 6) (match_dup 4)]
14131 UNSPEC_FSCALE_FRACT))
14133 (unspec:XF [(match_dup 6) (match_dup 4)]
14134 UNSPEC_FSCALE_EXP))])
14135 (parallel [(set (match_dup 10)
14136 (unspec:XF [(match_dup 9) (match_dup 8)]
14137 UNSPEC_FSCALE_FRACT))
14138 (set (match_dup 11)
14139 (unspec:XF [(match_dup 9) (match_dup 8)]
14140 UNSPEC_FSCALE_EXP))])
14141 (set (match_dup 12) (minus:XF (match_dup 10)
14142 (float_extend:XF (match_dup 13))))
14143 (set (match_operand:XF 0 "register_operand" "")
14144 (plus:XF (match_dup 12) (match_dup 7)))]
14145 "TARGET_USE_FANCY_MATH_387
14146 && flag_unsafe_math_optimizations"
14150 if (optimize_insn_for_size_p ())
14153 for (i = 2; i < 13; i++)
14154 operands[i] = gen_reg_rtx (XFmode);
14157 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14159 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14162 (define_expand "expm1<mode>2"
14163 [(use (match_operand:MODEF 0 "register_operand" ""))
14164 (use (match_operand:MODEF 1 "general_operand" ""))]
14165 "TARGET_USE_FANCY_MATH_387
14166 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14167 || TARGET_MIX_SSE_I387)
14168 && flag_unsafe_math_optimizations"
14172 if (optimize_insn_for_size_p ())
14175 op0 = gen_reg_rtx (XFmode);
14176 op1 = gen_reg_rtx (XFmode);
14178 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14179 emit_insn (gen_expm1xf2 (op0, op1));
14180 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14184 (define_expand "ldexpxf3"
14185 [(set (match_dup 3)
14186 (float:XF (match_operand:SI 2 "register_operand" "")))
14187 (parallel [(set (match_operand:XF 0 " register_operand" "")
14188 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14190 UNSPEC_FSCALE_FRACT))
14192 (unspec:XF [(match_dup 1) (match_dup 3)]
14193 UNSPEC_FSCALE_EXP))])]
14194 "TARGET_USE_FANCY_MATH_387
14195 && flag_unsafe_math_optimizations"
14197 if (optimize_insn_for_size_p ())
14200 operands[3] = gen_reg_rtx (XFmode);
14201 operands[4] = gen_reg_rtx (XFmode);
14204 (define_expand "ldexp<mode>3"
14205 [(use (match_operand:MODEF 0 "register_operand" ""))
14206 (use (match_operand:MODEF 1 "general_operand" ""))
14207 (use (match_operand:SI 2 "register_operand" ""))]
14208 "TARGET_USE_FANCY_MATH_387
14209 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14210 || TARGET_MIX_SSE_I387)
14211 && flag_unsafe_math_optimizations"
14215 if (optimize_insn_for_size_p ())
14218 op0 = gen_reg_rtx (XFmode);
14219 op1 = gen_reg_rtx (XFmode);
14221 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14222 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14223 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14227 (define_expand "scalbxf3"
14228 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14229 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14230 (match_operand:XF 2 "register_operand" "")]
14231 UNSPEC_FSCALE_FRACT))
14233 (unspec:XF [(match_dup 1) (match_dup 2)]
14234 UNSPEC_FSCALE_EXP))])]
14235 "TARGET_USE_FANCY_MATH_387
14236 && flag_unsafe_math_optimizations"
14238 if (optimize_insn_for_size_p ())
14241 operands[3] = gen_reg_rtx (XFmode);
14244 (define_expand "scalb<mode>3"
14245 [(use (match_operand:MODEF 0 "register_operand" ""))
14246 (use (match_operand:MODEF 1 "general_operand" ""))
14247 (use (match_operand:MODEF 2 "general_operand" ""))]
14248 "TARGET_USE_FANCY_MATH_387
14249 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14250 || TARGET_MIX_SSE_I387)
14251 && flag_unsafe_math_optimizations"
14255 if (optimize_insn_for_size_p ())
14258 op0 = gen_reg_rtx (XFmode);
14259 op1 = gen_reg_rtx (XFmode);
14260 op2 = gen_reg_rtx (XFmode);
14262 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14263 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14264 emit_insn (gen_scalbxf3 (op0, op1, op2));
14265 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14269 (define_expand "significandxf2"
14270 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14271 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14272 UNSPEC_XTRACT_FRACT))
14274 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14275 "TARGET_USE_FANCY_MATH_387
14276 && flag_unsafe_math_optimizations"
14278 operands[2] = gen_reg_rtx (XFmode);
14281 (define_expand "significand<mode>2"
14282 [(use (match_operand:MODEF 0 "register_operand" ""))
14283 (use (match_operand:MODEF 1 "register_operand" ""))]
14284 "TARGET_USE_FANCY_MATH_387
14285 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14286 || TARGET_MIX_SSE_I387)
14287 && flag_unsafe_math_optimizations"
14289 rtx op0 = gen_reg_rtx (XFmode);
14290 rtx op1 = gen_reg_rtx (XFmode);
14292 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14293 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14298 (define_insn "sse4_1_round<mode>2"
14299 [(set (match_operand:MODEF 0 "register_operand" "=x")
14300 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14301 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14304 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14305 [(set_attr "type" "ssecvt")
14306 (set_attr "prefix_extra" "1")
14307 (set_attr "prefix" "maybe_vex")
14308 (set_attr "mode" "<MODE>")])
14310 (define_insn "rintxf2"
14311 [(set (match_operand:XF 0 "register_operand" "=f")
14312 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14314 "TARGET_USE_FANCY_MATH_387
14315 && flag_unsafe_math_optimizations"
14317 [(set_attr "type" "fpspc")
14318 (set_attr "mode" "XF")])
14320 (define_expand "rint<mode>2"
14321 [(use (match_operand:MODEF 0 "register_operand" ""))
14322 (use (match_operand:MODEF 1 "register_operand" ""))]
14323 "(TARGET_USE_FANCY_MATH_387
14324 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14325 || TARGET_MIX_SSE_I387)
14326 && flag_unsafe_math_optimizations)
14327 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14328 && !flag_trapping_math)"
14330 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14331 && !flag_trapping_math)
14333 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14336 emit_insn (gen_sse4_1_round<mode>2
14337 (operands[0], operands[1], GEN_INT (0x04)));
14339 ix86_expand_rint (operand0, operand1);
14343 rtx op0 = gen_reg_rtx (XFmode);
14344 rtx op1 = gen_reg_rtx (XFmode);
14346 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14347 emit_insn (gen_rintxf2 (op0, op1));
14349 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14354 (define_expand "round<mode>2"
14355 [(match_operand:MODEF 0 "register_operand" "")
14356 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14357 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14358 && !flag_trapping_math && !flag_rounding_math"
14360 if (optimize_insn_for_size_p ())
14362 if (TARGET_64BIT || (<MODE>mode != DFmode))
14363 ix86_expand_round (operand0, operand1);
14365 ix86_expand_rounddf_32 (operand0, operand1);
14369 (define_insn_and_split "*fistdi2_1"
14370 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14371 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14373 "TARGET_USE_FANCY_MATH_387
14374 && can_create_pseudo_p ()"
14379 if (memory_operand (operands[0], VOIDmode))
14380 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14383 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14384 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14389 [(set_attr "type" "fpspc")
14390 (set_attr "mode" "DI")])
14392 (define_insn "fistdi2"
14393 [(set (match_operand:DI 0 "memory_operand" "=m")
14394 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14396 (clobber (match_scratch:XF 2 "=&1f"))]
14397 "TARGET_USE_FANCY_MATH_387"
14398 "* return output_fix_trunc (insn, operands, 0);"
14399 [(set_attr "type" "fpspc")
14400 (set_attr "mode" "DI")])
14402 (define_insn "fistdi2_with_temp"
14403 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14404 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14406 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14407 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14408 "TARGET_USE_FANCY_MATH_387"
14410 [(set_attr "type" "fpspc")
14411 (set_attr "mode" "DI")])
14414 [(set (match_operand:DI 0 "register_operand" "")
14415 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14417 (clobber (match_operand:DI 2 "memory_operand" ""))
14418 (clobber (match_scratch 3 ""))]
14420 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14421 (clobber (match_dup 3))])
14422 (set (match_dup 0) (match_dup 2))]
14426 [(set (match_operand:DI 0 "memory_operand" "")
14427 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14429 (clobber (match_operand:DI 2 "memory_operand" ""))
14430 (clobber (match_scratch 3 ""))]
14432 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14433 (clobber (match_dup 3))])]
14436 (define_insn_and_split "*fist<mode>2_1"
14437 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14438 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14440 "TARGET_USE_FANCY_MATH_387
14441 && can_create_pseudo_p ()"
14446 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14447 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14451 [(set_attr "type" "fpspc")
14452 (set_attr "mode" "<MODE>")])
14454 (define_insn "fist<mode>2"
14455 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14456 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14458 "TARGET_USE_FANCY_MATH_387"
14459 "* return output_fix_trunc (insn, operands, 0);"
14460 [(set_attr "type" "fpspc")
14461 (set_attr "mode" "<MODE>")])
14463 (define_insn "fist<mode>2_with_temp"
14464 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14465 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14467 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14468 "TARGET_USE_FANCY_MATH_387"
14470 [(set_attr "type" "fpspc")
14471 (set_attr "mode" "<MODE>")])
14474 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14475 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14477 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14479 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14480 (set (match_dup 0) (match_dup 2))]
14484 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14485 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14487 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14489 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14492 (define_expand "lrintxf<mode>2"
14493 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14494 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14496 "TARGET_USE_FANCY_MATH_387"
14499 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14500 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14501 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14502 UNSPEC_FIX_NOTRUNC))]
14503 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14504 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14507 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14508 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14509 (match_operand:MODEF 1 "register_operand" "")]
14510 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14511 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14512 && !flag_trapping_math && !flag_rounding_math"
14514 if (optimize_insn_for_size_p ())
14516 ix86_expand_lround (operand0, operand1);
14520 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14521 (define_insn_and_split "frndintxf2_floor"
14522 [(set (match_operand:XF 0 "register_operand" "")
14523 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14524 UNSPEC_FRNDINT_FLOOR))
14525 (clobber (reg:CC FLAGS_REG))]
14526 "TARGET_USE_FANCY_MATH_387
14527 && flag_unsafe_math_optimizations
14528 && can_create_pseudo_p ()"
14533 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14535 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14536 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14538 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14539 operands[2], operands[3]));
14542 [(set_attr "type" "frndint")
14543 (set_attr "i387_cw" "floor")
14544 (set_attr "mode" "XF")])
14546 (define_insn "frndintxf2_floor_i387"
14547 [(set (match_operand:XF 0 "register_operand" "=f")
14548 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14549 UNSPEC_FRNDINT_FLOOR))
14550 (use (match_operand:HI 2 "memory_operand" "m"))
14551 (use (match_operand:HI 3 "memory_operand" "m"))]
14552 "TARGET_USE_FANCY_MATH_387
14553 && flag_unsafe_math_optimizations"
14554 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14555 [(set_attr "type" "frndint")
14556 (set_attr "i387_cw" "floor")
14557 (set_attr "mode" "XF")])
14559 (define_expand "floorxf2"
14560 [(use (match_operand:XF 0 "register_operand" ""))
14561 (use (match_operand:XF 1 "register_operand" ""))]
14562 "TARGET_USE_FANCY_MATH_387
14563 && flag_unsafe_math_optimizations"
14565 if (optimize_insn_for_size_p ())
14567 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14571 (define_expand "floor<mode>2"
14572 [(use (match_operand:MODEF 0 "register_operand" ""))
14573 (use (match_operand:MODEF 1 "register_operand" ""))]
14574 "(TARGET_USE_FANCY_MATH_387
14575 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14576 || TARGET_MIX_SSE_I387)
14577 && flag_unsafe_math_optimizations)
14578 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14579 && !flag_trapping_math)"
14581 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14582 && !flag_trapping_math
14583 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14585 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14588 emit_insn (gen_sse4_1_round<mode>2
14589 (operands[0], operands[1], GEN_INT (0x01)));
14590 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14591 ix86_expand_floorceil (operand0, operand1, true);
14593 ix86_expand_floorceildf_32 (operand0, operand1, true);
14599 if (optimize_insn_for_size_p ())
14602 op0 = gen_reg_rtx (XFmode);
14603 op1 = gen_reg_rtx (XFmode);
14604 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14605 emit_insn (gen_frndintxf2_floor (op0, op1));
14607 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14612 (define_insn_and_split "*fist<mode>2_floor_1"
14613 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14614 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14615 UNSPEC_FIST_FLOOR))
14616 (clobber (reg:CC FLAGS_REG))]
14617 "TARGET_USE_FANCY_MATH_387
14618 && flag_unsafe_math_optimizations
14619 && can_create_pseudo_p ()"
14624 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14626 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14627 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14628 if (memory_operand (operands[0], VOIDmode))
14629 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14630 operands[2], operands[3]));
14633 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14634 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14635 operands[2], operands[3],
14640 [(set_attr "type" "fistp")
14641 (set_attr "i387_cw" "floor")
14642 (set_attr "mode" "<MODE>")])
14644 (define_insn "fistdi2_floor"
14645 [(set (match_operand:DI 0 "memory_operand" "=m")
14646 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14647 UNSPEC_FIST_FLOOR))
14648 (use (match_operand:HI 2 "memory_operand" "m"))
14649 (use (match_operand:HI 3 "memory_operand" "m"))
14650 (clobber (match_scratch:XF 4 "=&1f"))]
14651 "TARGET_USE_FANCY_MATH_387
14652 && flag_unsafe_math_optimizations"
14653 "* return output_fix_trunc (insn, operands, 0);"
14654 [(set_attr "type" "fistp")
14655 (set_attr "i387_cw" "floor")
14656 (set_attr "mode" "DI")])
14658 (define_insn "fistdi2_floor_with_temp"
14659 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14660 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14661 UNSPEC_FIST_FLOOR))
14662 (use (match_operand:HI 2 "memory_operand" "m,m"))
14663 (use (match_operand:HI 3 "memory_operand" "m,m"))
14664 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14665 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14666 "TARGET_USE_FANCY_MATH_387
14667 && flag_unsafe_math_optimizations"
14669 [(set_attr "type" "fistp")
14670 (set_attr "i387_cw" "floor")
14671 (set_attr "mode" "DI")])
14674 [(set (match_operand:DI 0 "register_operand" "")
14675 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14676 UNSPEC_FIST_FLOOR))
14677 (use (match_operand:HI 2 "memory_operand" ""))
14678 (use (match_operand:HI 3 "memory_operand" ""))
14679 (clobber (match_operand:DI 4 "memory_operand" ""))
14680 (clobber (match_scratch 5 ""))]
14682 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14683 (use (match_dup 2))
14684 (use (match_dup 3))
14685 (clobber (match_dup 5))])
14686 (set (match_dup 0) (match_dup 4))]
14690 [(set (match_operand:DI 0 "memory_operand" "")
14691 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14692 UNSPEC_FIST_FLOOR))
14693 (use (match_operand:HI 2 "memory_operand" ""))
14694 (use (match_operand:HI 3 "memory_operand" ""))
14695 (clobber (match_operand:DI 4 "memory_operand" ""))
14696 (clobber (match_scratch 5 ""))]
14698 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14699 (use (match_dup 2))
14700 (use (match_dup 3))
14701 (clobber (match_dup 5))])]
14704 (define_insn "fist<mode>2_floor"
14705 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14706 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14707 UNSPEC_FIST_FLOOR))
14708 (use (match_operand:HI 2 "memory_operand" "m"))
14709 (use (match_operand:HI 3 "memory_operand" "m"))]
14710 "TARGET_USE_FANCY_MATH_387
14711 && flag_unsafe_math_optimizations"
14712 "* return output_fix_trunc (insn, operands, 0);"
14713 [(set_attr "type" "fistp")
14714 (set_attr "i387_cw" "floor")
14715 (set_attr "mode" "<MODE>")])
14717 (define_insn "fist<mode>2_floor_with_temp"
14718 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14719 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14720 UNSPEC_FIST_FLOOR))
14721 (use (match_operand:HI 2 "memory_operand" "m,m"))
14722 (use (match_operand:HI 3 "memory_operand" "m,m"))
14723 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14724 "TARGET_USE_FANCY_MATH_387
14725 && flag_unsafe_math_optimizations"
14727 [(set_attr "type" "fistp")
14728 (set_attr "i387_cw" "floor")
14729 (set_attr "mode" "<MODE>")])
14732 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14733 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14734 UNSPEC_FIST_FLOOR))
14735 (use (match_operand:HI 2 "memory_operand" ""))
14736 (use (match_operand:HI 3 "memory_operand" ""))
14737 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14739 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14740 UNSPEC_FIST_FLOOR))
14741 (use (match_dup 2))
14742 (use (match_dup 3))])
14743 (set (match_dup 0) (match_dup 4))]
14747 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14748 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14749 UNSPEC_FIST_FLOOR))
14750 (use (match_operand:HI 2 "memory_operand" ""))
14751 (use (match_operand:HI 3 "memory_operand" ""))
14752 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14754 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14755 UNSPEC_FIST_FLOOR))
14756 (use (match_dup 2))
14757 (use (match_dup 3))])]
14760 (define_expand "lfloorxf<mode>2"
14761 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14762 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14763 UNSPEC_FIST_FLOOR))
14764 (clobber (reg:CC FLAGS_REG))])]
14765 "TARGET_USE_FANCY_MATH_387
14766 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14767 && flag_unsafe_math_optimizations"
14770 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14771 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14772 (match_operand:MODEF 1 "register_operand" "")]
14773 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14774 && !flag_trapping_math"
14776 if (TARGET_64BIT && optimize_insn_for_size_p ())
14778 ix86_expand_lfloorceil (operand0, operand1, true);
14782 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14783 (define_insn_and_split "frndintxf2_ceil"
14784 [(set (match_operand:XF 0 "register_operand" "")
14785 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14786 UNSPEC_FRNDINT_CEIL))
14787 (clobber (reg:CC FLAGS_REG))]
14788 "TARGET_USE_FANCY_MATH_387
14789 && flag_unsafe_math_optimizations
14790 && can_create_pseudo_p ()"
14795 ix86_optimize_mode_switching[I387_CEIL] = 1;
14797 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14798 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14800 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14801 operands[2], operands[3]));
14804 [(set_attr "type" "frndint")
14805 (set_attr "i387_cw" "ceil")
14806 (set_attr "mode" "XF")])
14808 (define_insn "frndintxf2_ceil_i387"
14809 [(set (match_operand:XF 0 "register_operand" "=f")
14810 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14811 UNSPEC_FRNDINT_CEIL))
14812 (use (match_operand:HI 2 "memory_operand" "m"))
14813 (use (match_operand:HI 3 "memory_operand" "m"))]
14814 "TARGET_USE_FANCY_MATH_387
14815 && flag_unsafe_math_optimizations"
14816 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14817 [(set_attr "type" "frndint")
14818 (set_attr "i387_cw" "ceil")
14819 (set_attr "mode" "XF")])
14821 (define_expand "ceilxf2"
14822 [(use (match_operand:XF 0 "register_operand" ""))
14823 (use (match_operand:XF 1 "register_operand" ""))]
14824 "TARGET_USE_FANCY_MATH_387
14825 && flag_unsafe_math_optimizations"
14827 if (optimize_insn_for_size_p ())
14829 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14833 (define_expand "ceil<mode>2"
14834 [(use (match_operand:MODEF 0 "register_operand" ""))
14835 (use (match_operand:MODEF 1 "register_operand" ""))]
14836 "(TARGET_USE_FANCY_MATH_387
14837 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14838 || TARGET_MIX_SSE_I387)
14839 && flag_unsafe_math_optimizations)
14840 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14841 && !flag_trapping_math)"
14843 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14844 && !flag_trapping_math
14845 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14848 emit_insn (gen_sse4_1_round<mode>2
14849 (operands[0], operands[1], GEN_INT (0x02)));
14850 else if (optimize_insn_for_size_p ())
14852 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14853 ix86_expand_floorceil (operand0, operand1, false);
14855 ix86_expand_floorceildf_32 (operand0, operand1, false);
14861 if (optimize_insn_for_size_p ())
14864 op0 = gen_reg_rtx (XFmode);
14865 op1 = gen_reg_rtx (XFmode);
14866 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14867 emit_insn (gen_frndintxf2_ceil (op0, op1));
14869 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14874 (define_insn_and_split "*fist<mode>2_ceil_1"
14875 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14876 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14878 (clobber (reg:CC FLAGS_REG))]
14879 "TARGET_USE_FANCY_MATH_387
14880 && flag_unsafe_math_optimizations
14881 && can_create_pseudo_p ()"
14886 ix86_optimize_mode_switching[I387_CEIL] = 1;
14888 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14889 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14890 if (memory_operand (operands[0], VOIDmode))
14891 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14892 operands[2], operands[3]));
14895 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14896 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14897 operands[2], operands[3],
14902 [(set_attr "type" "fistp")
14903 (set_attr "i387_cw" "ceil")
14904 (set_attr "mode" "<MODE>")])
14906 (define_insn "fistdi2_ceil"
14907 [(set (match_operand:DI 0 "memory_operand" "=m")
14908 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14910 (use (match_operand:HI 2 "memory_operand" "m"))
14911 (use (match_operand:HI 3 "memory_operand" "m"))
14912 (clobber (match_scratch:XF 4 "=&1f"))]
14913 "TARGET_USE_FANCY_MATH_387
14914 && flag_unsafe_math_optimizations"
14915 "* return output_fix_trunc (insn, operands, 0);"
14916 [(set_attr "type" "fistp")
14917 (set_attr "i387_cw" "ceil")
14918 (set_attr "mode" "DI")])
14920 (define_insn "fistdi2_ceil_with_temp"
14921 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14922 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14924 (use (match_operand:HI 2 "memory_operand" "m,m"))
14925 (use (match_operand:HI 3 "memory_operand" "m,m"))
14926 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14927 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14928 "TARGET_USE_FANCY_MATH_387
14929 && flag_unsafe_math_optimizations"
14931 [(set_attr "type" "fistp")
14932 (set_attr "i387_cw" "ceil")
14933 (set_attr "mode" "DI")])
14936 [(set (match_operand:DI 0 "register_operand" "")
14937 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14939 (use (match_operand:HI 2 "memory_operand" ""))
14940 (use (match_operand:HI 3 "memory_operand" ""))
14941 (clobber (match_operand:DI 4 "memory_operand" ""))
14942 (clobber (match_scratch 5 ""))]
14944 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14945 (use (match_dup 2))
14946 (use (match_dup 3))
14947 (clobber (match_dup 5))])
14948 (set (match_dup 0) (match_dup 4))]
14952 [(set (match_operand:DI 0 "memory_operand" "")
14953 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14955 (use (match_operand:HI 2 "memory_operand" ""))
14956 (use (match_operand:HI 3 "memory_operand" ""))
14957 (clobber (match_operand:DI 4 "memory_operand" ""))
14958 (clobber (match_scratch 5 ""))]
14960 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14961 (use (match_dup 2))
14962 (use (match_dup 3))
14963 (clobber (match_dup 5))])]
14966 (define_insn "fist<mode>2_ceil"
14967 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14968 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14970 (use (match_operand:HI 2 "memory_operand" "m"))
14971 (use (match_operand:HI 3 "memory_operand" "m"))]
14972 "TARGET_USE_FANCY_MATH_387
14973 && flag_unsafe_math_optimizations"
14974 "* return output_fix_trunc (insn, operands, 0);"
14975 [(set_attr "type" "fistp")
14976 (set_attr "i387_cw" "ceil")
14977 (set_attr "mode" "<MODE>")])
14979 (define_insn "fist<mode>2_ceil_with_temp"
14980 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14981 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14983 (use (match_operand:HI 2 "memory_operand" "m,m"))
14984 (use (match_operand:HI 3 "memory_operand" "m,m"))
14985 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14986 "TARGET_USE_FANCY_MATH_387
14987 && flag_unsafe_math_optimizations"
14989 [(set_attr "type" "fistp")
14990 (set_attr "i387_cw" "ceil")
14991 (set_attr "mode" "<MODE>")])
14994 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14995 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14997 (use (match_operand:HI 2 "memory_operand" ""))
14998 (use (match_operand:HI 3 "memory_operand" ""))
14999 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15001 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15003 (use (match_dup 2))
15004 (use (match_dup 3))])
15005 (set (match_dup 0) (match_dup 4))]
15009 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15010 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15012 (use (match_operand:HI 2 "memory_operand" ""))
15013 (use (match_operand:HI 3 "memory_operand" ""))
15014 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15016 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15018 (use (match_dup 2))
15019 (use (match_dup 3))])]
15022 (define_expand "lceilxf<mode>2"
15023 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15024 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15026 (clobber (reg:CC FLAGS_REG))])]
15027 "TARGET_USE_FANCY_MATH_387
15028 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15029 && flag_unsafe_math_optimizations"
15032 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15033 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15034 (match_operand:MODEF 1 "register_operand" "")]
15035 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15036 && !flag_trapping_math"
15038 ix86_expand_lfloorceil (operand0, operand1, false);
15042 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15043 (define_insn_and_split "frndintxf2_trunc"
15044 [(set (match_operand:XF 0 "register_operand" "")
15045 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15046 UNSPEC_FRNDINT_TRUNC))
15047 (clobber (reg:CC FLAGS_REG))]
15048 "TARGET_USE_FANCY_MATH_387
15049 && flag_unsafe_math_optimizations
15050 && can_create_pseudo_p ()"
15055 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15057 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15058 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15060 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15061 operands[2], operands[3]));
15064 [(set_attr "type" "frndint")
15065 (set_attr "i387_cw" "trunc")
15066 (set_attr "mode" "XF")])
15068 (define_insn "frndintxf2_trunc_i387"
15069 [(set (match_operand:XF 0 "register_operand" "=f")
15070 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15071 UNSPEC_FRNDINT_TRUNC))
15072 (use (match_operand:HI 2 "memory_operand" "m"))
15073 (use (match_operand:HI 3 "memory_operand" "m"))]
15074 "TARGET_USE_FANCY_MATH_387
15075 && flag_unsafe_math_optimizations"
15076 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15077 [(set_attr "type" "frndint")
15078 (set_attr "i387_cw" "trunc")
15079 (set_attr "mode" "XF")])
15081 (define_expand "btruncxf2"
15082 [(use (match_operand:XF 0 "register_operand" ""))
15083 (use (match_operand:XF 1 "register_operand" ""))]
15084 "TARGET_USE_FANCY_MATH_387
15085 && flag_unsafe_math_optimizations"
15087 if (optimize_insn_for_size_p ())
15089 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15093 (define_expand "btrunc<mode>2"
15094 [(use (match_operand:MODEF 0 "register_operand" ""))
15095 (use (match_operand:MODEF 1 "register_operand" ""))]
15096 "(TARGET_USE_FANCY_MATH_387
15097 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15098 || TARGET_MIX_SSE_I387)
15099 && flag_unsafe_math_optimizations)
15100 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15101 && !flag_trapping_math)"
15103 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15104 && !flag_trapping_math
15105 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15108 emit_insn (gen_sse4_1_round<mode>2
15109 (operands[0], operands[1], GEN_INT (0x03)));
15110 else if (optimize_insn_for_size_p ())
15112 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15113 ix86_expand_trunc (operand0, operand1);
15115 ix86_expand_truncdf_32 (operand0, operand1);
15121 if (optimize_insn_for_size_p ())
15124 op0 = gen_reg_rtx (XFmode);
15125 op1 = gen_reg_rtx (XFmode);
15126 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15127 emit_insn (gen_frndintxf2_trunc (op0, op1));
15129 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15134 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15135 (define_insn_and_split "frndintxf2_mask_pm"
15136 [(set (match_operand:XF 0 "register_operand" "")
15137 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15138 UNSPEC_FRNDINT_MASK_PM))
15139 (clobber (reg:CC FLAGS_REG))]
15140 "TARGET_USE_FANCY_MATH_387
15141 && flag_unsafe_math_optimizations
15142 && can_create_pseudo_p ()"
15147 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15149 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15150 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15152 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15153 operands[2], operands[3]));
15156 [(set_attr "type" "frndint")
15157 (set_attr "i387_cw" "mask_pm")
15158 (set_attr "mode" "XF")])
15160 (define_insn "frndintxf2_mask_pm_i387"
15161 [(set (match_operand:XF 0 "register_operand" "=f")
15162 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15163 UNSPEC_FRNDINT_MASK_PM))
15164 (use (match_operand:HI 2 "memory_operand" "m"))
15165 (use (match_operand:HI 3 "memory_operand" "m"))]
15166 "TARGET_USE_FANCY_MATH_387
15167 && flag_unsafe_math_optimizations"
15168 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15169 [(set_attr "type" "frndint")
15170 (set_attr "i387_cw" "mask_pm")
15171 (set_attr "mode" "XF")])
15173 (define_expand "nearbyintxf2"
15174 [(use (match_operand:XF 0 "register_operand" ""))
15175 (use (match_operand:XF 1 "register_operand" ""))]
15176 "TARGET_USE_FANCY_MATH_387
15177 && flag_unsafe_math_optimizations"
15179 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15184 (define_expand "nearbyint<mode>2"
15185 [(use (match_operand:MODEF 0 "register_operand" ""))
15186 (use (match_operand:MODEF 1 "register_operand" ""))]
15187 "TARGET_USE_FANCY_MATH_387
15188 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15189 || TARGET_MIX_SSE_I387)
15190 && flag_unsafe_math_optimizations"
15192 rtx op0 = gen_reg_rtx (XFmode);
15193 rtx op1 = gen_reg_rtx (XFmode);
15195 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15196 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15198 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15202 (define_insn "fxam<mode>2_i387"
15203 [(set (match_operand:HI 0 "register_operand" "=a")
15205 [(match_operand:X87MODEF 1 "register_operand" "f")]
15207 "TARGET_USE_FANCY_MATH_387"
15208 "fxam\n\tfnstsw\t%0"
15209 [(set_attr "type" "multi")
15210 (set_attr "length" "4")
15211 (set_attr "unit" "i387")
15212 (set_attr "mode" "<MODE>")])
15214 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15215 [(set (match_operand:HI 0 "register_operand" "")
15217 [(match_operand:MODEF 1 "memory_operand" "")]
15219 "TARGET_USE_FANCY_MATH_387
15220 && can_create_pseudo_p ()"
15223 [(set (match_dup 2)(match_dup 1))
15225 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15227 operands[2] = gen_reg_rtx (<MODE>mode);
15229 MEM_VOLATILE_P (operands[1]) = 1;
15231 [(set_attr "type" "multi")
15232 (set_attr "unit" "i387")
15233 (set_attr "mode" "<MODE>")])
15235 (define_expand "isinfxf2"
15236 [(use (match_operand:SI 0 "register_operand" ""))
15237 (use (match_operand:XF 1 "register_operand" ""))]
15238 "TARGET_USE_FANCY_MATH_387
15239 && TARGET_C99_FUNCTIONS"
15241 rtx mask = GEN_INT (0x45);
15242 rtx val = GEN_INT (0x05);
15246 rtx scratch = gen_reg_rtx (HImode);
15247 rtx res = gen_reg_rtx (QImode);
15249 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15251 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15252 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15253 cond = gen_rtx_fmt_ee (EQ, QImode,
15254 gen_rtx_REG (CCmode, FLAGS_REG),
15256 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15257 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15261 (define_expand "isinf<mode>2"
15262 [(use (match_operand:SI 0 "register_operand" ""))
15263 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15264 "TARGET_USE_FANCY_MATH_387
15265 && TARGET_C99_FUNCTIONS
15266 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15268 rtx mask = GEN_INT (0x45);
15269 rtx val = GEN_INT (0x05);
15273 rtx scratch = gen_reg_rtx (HImode);
15274 rtx res = gen_reg_rtx (QImode);
15276 /* Remove excess precision by forcing value through memory. */
15277 if (memory_operand (operands[1], VOIDmode))
15278 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15281 enum ix86_stack_slot slot = (virtuals_instantiated
15284 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15286 emit_move_insn (temp, operands[1]);
15287 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15290 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15291 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15292 cond = gen_rtx_fmt_ee (EQ, QImode,
15293 gen_rtx_REG (CCmode, FLAGS_REG),
15295 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15296 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15300 (define_expand "signbit<mode>2"
15301 [(use (match_operand:SI 0 "register_operand" ""))
15302 (use (match_operand:X87MODEF 1 "register_operand" ""))]
15303 "TARGET_USE_FANCY_MATH_387
15304 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15306 rtx mask = GEN_INT (0x0200);
15308 rtx scratch = gen_reg_rtx (HImode);
15310 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15311 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15315 ;; Block operation instructions
15318 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15321 [(set_attr "length" "1")
15322 (set_attr "length_immediate" "0")
15323 (set_attr "modrm" "0")])
15325 (define_expand "movmemsi"
15326 [(use (match_operand:BLK 0 "memory_operand" ""))
15327 (use (match_operand:BLK 1 "memory_operand" ""))
15328 (use (match_operand:SI 2 "nonmemory_operand" ""))
15329 (use (match_operand:SI 3 "const_int_operand" ""))
15330 (use (match_operand:SI 4 "const_int_operand" ""))
15331 (use (match_operand:SI 5 "const_int_operand" ""))]
15334 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15335 operands[4], operands[5]))
15341 (define_expand "movmemdi"
15342 [(use (match_operand:BLK 0 "memory_operand" ""))
15343 (use (match_operand:BLK 1 "memory_operand" ""))
15344 (use (match_operand:DI 2 "nonmemory_operand" ""))
15345 (use (match_operand:DI 3 "const_int_operand" ""))
15346 (use (match_operand:SI 4 "const_int_operand" ""))
15347 (use (match_operand:SI 5 "const_int_operand" ""))]
15350 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15351 operands[4], operands[5]))
15357 ;; Most CPUs don't like single string operations
15358 ;; Handle this case here to simplify previous expander.
15360 (define_expand "strmov"
15361 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15362 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15363 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15364 (clobber (reg:CC FLAGS_REG))])
15365 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15366 (clobber (reg:CC FLAGS_REG))])]
15369 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15371 /* If .md ever supports :P for Pmode, these can be directly
15372 in the pattern above. */
15373 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15374 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15376 /* Can't use this if the user has appropriated esi or edi. */
15377 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15378 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15380 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15381 operands[2], operands[3],
15382 operands[5], operands[6]));
15386 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15389 (define_expand "strmov_singleop"
15390 [(parallel [(set (match_operand 1 "memory_operand" "")
15391 (match_operand 3 "memory_operand" ""))
15392 (set (match_operand 0 "register_operand" "")
15393 (match_operand 4 "" ""))
15394 (set (match_operand 2 "register_operand" "")
15395 (match_operand 5 "" ""))])]
15397 "ix86_current_function_needs_cld = 1;")
15399 (define_insn "*strmovdi_rex_1"
15400 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15401 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15402 (set (match_operand:DI 0 "register_operand" "=D")
15403 (plus:DI (match_dup 2)
15405 (set (match_operand:DI 1 "register_operand" "=S")
15406 (plus:DI (match_dup 3)
15410 [(set_attr "type" "str")
15411 (set_attr "mode" "DI")
15412 (set_attr "memory" "both")])
15414 (define_insn "*strmovsi_1"
15415 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15416 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15417 (set (match_operand:SI 0 "register_operand" "=D")
15418 (plus:SI (match_dup 2)
15420 (set (match_operand:SI 1 "register_operand" "=S")
15421 (plus:SI (match_dup 3)
15425 [(set_attr "type" "str")
15426 (set_attr "mode" "SI")
15427 (set_attr "memory" "both")])
15429 (define_insn "*strmovsi_rex_1"
15430 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15431 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15432 (set (match_operand:DI 0 "register_operand" "=D")
15433 (plus:DI (match_dup 2)
15435 (set (match_operand:DI 1 "register_operand" "=S")
15436 (plus:DI (match_dup 3)
15440 [(set_attr "type" "str")
15441 (set_attr "mode" "SI")
15442 (set_attr "memory" "both")])
15444 (define_insn "*strmovhi_1"
15445 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15446 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15447 (set (match_operand:SI 0 "register_operand" "=D")
15448 (plus:SI (match_dup 2)
15450 (set (match_operand:SI 1 "register_operand" "=S")
15451 (plus:SI (match_dup 3)
15455 [(set_attr "type" "str")
15456 (set_attr "memory" "both")
15457 (set_attr "mode" "HI")])
15459 (define_insn "*strmovhi_rex_1"
15460 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15461 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15462 (set (match_operand:DI 0 "register_operand" "=D")
15463 (plus:DI (match_dup 2)
15465 (set (match_operand:DI 1 "register_operand" "=S")
15466 (plus:DI (match_dup 3)
15470 [(set_attr "type" "str")
15471 (set_attr "memory" "both")
15472 (set_attr "mode" "HI")])
15474 (define_insn "*strmovqi_1"
15475 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15476 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15477 (set (match_operand:SI 0 "register_operand" "=D")
15478 (plus:SI (match_dup 2)
15480 (set (match_operand:SI 1 "register_operand" "=S")
15481 (plus:SI (match_dup 3)
15485 [(set_attr "type" "str")
15486 (set_attr "memory" "both")
15487 (set_attr "mode" "QI")])
15489 (define_insn "*strmovqi_rex_1"
15490 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15491 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15492 (set (match_operand:DI 0 "register_operand" "=D")
15493 (plus:DI (match_dup 2)
15495 (set (match_operand:DI 1 "register_operand" "=S")
15496 (plus:DI (match_dup 3)
15500 [(set_attr "type" "str")
15501 (set_attr "memory" "both")
15502 (set_attr "prefix_rex" "0")
15503 (set_attr "mode" "QI")])
15505 (define_expand "rep_mov"
15506 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15507 (set (match_operand 0 "register_operand" "")
15508 (match_operand 5 "" ""))
15509 (set (match_operand 2 "register_operand" "")
15510 (match_operand 6 "" ""))
15511 (set (match_operand 1 "memory_operand" "")
15512 (match_operand 3 "memory_operand" ""))
15513 (use (match_dup 4))])]
15515 "ix86_current_function_needs_cld = 1;")
15517 (define_insn "*rep_movdi_rex64"
15518 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15519 (set (match_operand:DI 0 "register_operand" "=D")
15520 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15522 (match_operand:DI 3 "register_operand" "0")))
15523 (set (match_operand:DI 1 "register_operand" "=S")
15524 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15525 (match_operand:DI 4 "register_operand" "1")))
15526 (set (mem:BLK (match_dup 3))
15527 (mem:BLK (match_dup 4)))
15528 (use (match_dup 5))]
15531 [(set_attr "type" "str")
15532 (set_attr "prefix_rep" "1")
15533 (set_attr "memory" "both")
15534 (set_attr "mode" "DI")])
15536 (define_insn "*rep_movsi"
15537 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15538 (set (match_operand:SI 0 "register_operand" "=D")
15539 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15541 (match_operand:SI 3 "register_operand" "0")))
15542 (set (match_operand:SI 1 "register_operand" "=S")
15543 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15544 (match_operand:SI 4 "register_operand" "1")))
15545 (set (mem:BLK (match_dup 3))
15546 (mem:BLK (match_dup 4)))
15547 (use (match_dup 5))]
15549 "rep{%;} movs{l|d}"
15550 [(set_attr "type" "str")
15551 (set_attr "prefix_rep" "1")
15552 (set_attr "memory" "both")
15553 (set_attr "mode" "SI")])
15555 (define_insn "*rep_movsi_rex64"
15556 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15557 (set (match_operand:DI 0 "register_operand" "=D")
15558 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15560 (match_operand:DI 3 "register_operand" "0")))
15561 (set (match_operand:DI 1 "register_operand" "=S")
15562 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15563 (match_operand:DI 4 "register_operand" "1")))
15564 (set (mem:BLK (match_dup 3))
15565 (mem:BLK (match_dup 4)))
15566 (use (match_dup 5))]
15568 "rep{%;} movs{l|d}"
15569 [(set_attr "type" "str")
15570 (set_attr "prefix_rep" "1")
15571 (set_attr "memory" "both")
15572 (set_attr "mode" "SI")])
15574 (define_insn "*rep_movqi"
15575 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15576 (set (match_operand:SI 0 "register_operand" "=D")
15577 (plus:SI (match_operand:SI 3 "register_operand" "0")
15578 (match_operand:SI 5 "register_operand" "2")))
15579 (set (match_operand:SI 1 "register_operand" "=S")
15580 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15581 (set (mem:BLK (match_dup 3))
15582 (mem:BLK (match_dup 4)))
15583 (use (match_dup 5))]
15586 [(set_attr "type" "str")
15587 (set_attr "prefix_rep" "1")
15588 (set_attr "memory" "both")
15589 (set_attr "mode" "SI")])
15591 (define_insn "*rep_movqi_rex64"
15592 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15593 (set (match_operand:DI 0 "register_operand" "=D")
15594 (plus:DI (match_operand:DI 3 "register_operand" "0")
15595 (match_operand:DI 5 "register_operand" "2")))
15596 (set (match_operand:DI 1 "register_operand" "=S")
15597 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15598 (set (mem:BLK (match_dup 3))
15599 (mem:BLK (match_dup 4)))
15600 (use (match_dup 5))]
15603 [(set_attr "type" "str")
15604 (set_attr "prefix_rep" "1")
15605 (set_attr "memory" "both")
15606 (set_attr "mode" "SI")])
15608 (define_expand "setmemsi"
15609 [(use (match_operand:BLK 0 "memory_operand" ""))
15610 (use (match_operand:SI 1 "nonmemory_operand" ""))
15611 (use (match_operand 2 "const_int_operand" ""))
15612 (use (match_operand 3 "const_int_operand" ""))
15613 (use (match_operand:SI 4 "const_int_operand" ""))
15614 (use (match_operand:SI 5 "const_int_operand" ""))]
15617 if (ix86_expand_setmem (operands[0], operands[1],
15618 operands[2], operands[3],
15619 operands[4], operands[5]))
15625 (define_expand "setmemdi"
15626 [(use (match_operand:BLK 0 "memory_operand" ""))
15627 (use (match_operand:DI 1 "nonmemory_operand" ""))
15628 (use (match_operand 2 "const_int_operand" ""))
15629 (use (match_operand 3 "const_int_operand" ""))
15630 (use (match_operand 4 "const_int_operand" ""))
15631 (use (match_operand 5 "const_int_operand" ""))]
15634 if (ix86_expand_setmem (operands[0], operands[1],
15635 operands[2], operands[3],
15636 operands[4], operands[5]))
15642 ;; Most CPUs don't like single string operations
15643 ;; Handle this case here to simplify previous expander.
15645 (define_expand "strset"
15646 [(set (match_operand 1 "memory_operand" "")
15647 (match_operand 2 "register_operand" ""))
15648 (parallel [(set (match_operand 0 "register_operand" "")
15650 (clobber (reg:CC FLAGS_REG))])]
15653 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15654 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15656 /* If .md ever supports :P for Pmode, this can be directly
15657 in the pattern above. */
15658 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15659 GEN_INT (GET_MODE_SIZE (GET_MODE
15661 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15663 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15669 (define_expand "strset_singleop"
15670 [(parallel [(set (match_operand 1 "memory_operand" "")
15671 (match_operand 2 "register_operand" ""))
15672 (set (match_operand 0 "register_operand" "")
15673 (match_operand 3 "" ""))])]
15675 "ix86_current_function_needs_cld = 1;")
15677 (define_insn "*strsetdi_rex_1"
15678 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15679 (match_operand:DI 2 "register_operand" "a"))
15680 (set (match_operand:DI 0 "register_operand" "=D")
15681 (plus:DI (match_dup 1)
15685 [(set_attr "type" "str")
15686 (set_attr "memory" "store")
15687 (set_attr "mode" "DI")])
15689 (define_insn "*strsetsi_1"
15690 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15691 (match_operand:SI 2 "register_operand" "a"))
15692 (set (match_operand:SI 0 "register_operand" "=D")
15693 (plus:SI (match_dup 1)
15697 [(set_attr "type" "str")
15698 (set_attr "memory" "store")
15699 (set_attr "mode" "SI")])
15701 (define_insn "*strsetsi_rex_1"
15702 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15703 (match_operand:SI 2 "register_operand" "a"))
15704 (set (match_operand:DI 0 "register_operand" "=D")
15705 (plus:DI (match_dup 1)
15709 [(set_attr "type" "str")
15710 (set_attr "memory" "store")
15711 (set_attr "mode" "SI")])
15713 (define_insn "*strsethi_1"
15714 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15715 (match_operand:HI 2 "register_operand" "a"))
15716 (set (match_operand:SI 0 "register_operand" "=D")
15717 (plus:SI (match_dup 1)
15721 [(set_attr "type" "str")
15722 (set_attr "memory" "store")
15723 (set_attr "mode" "HI")])
15725 (define_insn "*strsethi_rex_1"
15726 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15727 (match_operand:HI 2 "register_operand" "a"))
15728 (set (match_operand:DI 0 "register_operand" "=D")
15729 (plus:DI (match_dup 1)
15733 [(set_attr "type" "str")
15734 (set_attr "memory" "store")
15735 (set_attr "mode" "HI")])
15737 (define_insn "*strsetqi_1"
15738 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15739 (match_operand:QI 2 "register_operand" "a"))
15740 (set (match_operand:SI 0 "register_operand" "=D")
15741 (plus:SI (match_dup 1)
15745 [(set_attr "type" "str")
15746 (set_attr "memory" "store")
15747 (set_attr "mode" "QI")])
15749 (define_insn "*strsetqi_rex_1"
15750 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15751 (match_operand:QI 2 "register_operand" "a"))
15752 (set (match_operand:DI 0 "register_operand" "=D")
15753 (plus:DI (match_dup 1)
15757 [(set_attr "type" "str")
15758 (set_attr "memory" "store")
15759 (set_attr "prefix_rex" "0")
15760 (set_attr "mode" "QI")])
15762 (define_expand "rep_stos"
15763 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15764 (set (match_operand 0 "register_operand" "")
15765 (match_operand 4 "" ""))
15766 (set (match_operand 2 "memory_operand" "") (const_int 0))
15767 (use (match_operand 3 "register_operand" ""))
15768 (use (match_dup 1))])]
15770 "ix86_current_function_needs_cld = 1;")
15772 (define_insn "*rep_stosdi_rex64"
15773 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15774 (set (match_operand:DI 0 "register_operand" "=D")
15775 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15777 (match_operand:DI 3 "register_operand" "0")))
15778 (set (mem:BLK (match_dup 3))
15780 (use (match_operand:DI 2 "register_operand" "a"))
15781 (use (match_dup 4))]
15784 [(set_attr "type" "str")
15785 (set_attr "prefix_rep" "1")
15786 (set_attr "memory" "store")
15787 (set_attr "mode" "DI")])
15789 (define_insn "*rep_stossi"
15790 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15791 (set (match_operand:SI 0 "register_operand" "=D")
15792 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15794 (match_operand:SI 3 "register_operand" "0")))
15795 (set (mem:BLK (match_dup 3))
15797 (use (match_operand:SI 2 "register_operand" "a"))
15798 (use (match_dup 4))]
15800 "rep{%;} stos{l|d}"
15801 [(set_attr "type" "str")
15802 (set_attr "prefix_rep" "1")
15803 (set_attr "memory" "store")
15804 (set_attr "mode" "SI")])
15806 (define_insn "*rep_stossi_rex64"
15807 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15808 (set (match_operand:DI 0 "register_operand" "=D")
15809 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15811 (match_operand:DI 3 "register_operand" "0")))
15812 (set (mem:BLK (match_dup 3))
15814 (use (match_operand:SI 2 "register_operand" "a"))
15815 (use (match_dup 4))]
15817 "rep{%;} stos{l|d}"
15818 [(set_attr "type" "str")
15819 (set_attr "prefix_rep" "1")
15820 (set_attr "memory" "store")
15821 (set_attr "mode" "SI")])
15823 (define_insn "*rep_stosqi"
15824 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15825 (set (match_operand:SI 0 "register_operand" "=D")
15826 (plus:SI (match_operand:SI 3 "register_operand" "0")
15827 (match_operand:SI 4 "register_operand" "1")))
15828 (set (mem:BLK (match_dup 3))
15830 (use (match_operand:QI 2 "register_operand" "a"))
15831 (use (match_dup 4))]
15834 [(set_attr "type" "str")
15835 (set_attr "prefix_rep" "1")
15836 (set_attr "memory" "store")
15837 (set_attr "mode" "QI")])
15839 (define_insn "*rep_stosqi_rex64"
15840 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15841 (set (match_operand:DI 0 "register_operand" "=D")
15842 (plus:DI (match_operand:DI 3 "register_operand" "0")
15843 (match_operand:DI 4 "register_operand" "1")))
15844 (set (mem:BLK (match_dup 3))
15846 (use (match_operand:QI 2 "register_operand" "a"))
15847 (use (match_dup 4))]
15850 [(set_attr "type" "str")
15851 (set_attr "prefix_rep" "1")
15852 (set_attr "memory" "store")
15853 (set_attr "prefix_rex" "0")
15854 (set_attr "mode" "QI")])
15856 (define_expand "cmpstrnsi"
15857 [(set (match_operand:SI 0 "register_operand" "")
15858 (compare:SI (match_operand:BLK 1 "general_operand" "")
15859 (match_operand:BLK 2 "general_operand" "")))
15860 (use (match_operand 3 "general_operand" ""))
15861 (use (match_operand 4 "immediate_operand" ""))]
15864 rtx addr1, addr2, out, outlow, count, countreg, align;
15866 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15869 /* Can't use this if the user has appropriated esi or edi. */
15870 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15875 out = gen_reg_rtx (SImode);
15877 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15878 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15879 if (addr1 != XEXP (operands[1], 0))
15880 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15881 if (addr2 != XEXP (operands[2], 0))
15882 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15884 count = operands[3];
15885 countreg = ix86_zero_extend_to_Pmode (count);
15887 /* %%% Iff we are testing strict equality, we can use known alignment
15888 to good advantage. This may be possible with combine, particularly
15889 once cc0 is dead. */
15890 align = operands[4];
15892 if (CONST_INT_P (count))
15894 if (INTVAL (count) == 0)
15896 emit_move_insn (operands[0], const0_rtx);
15899 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15900 operands[1], operands[2]));
15904 rtx (*cmp_insn)(rtx, rtx);
15907 cmp_insn = gen_cmpdi_1;
15909 cmp_insn = gen_cmpsi_1;
15910 emit_insn (cmp_insn (countreg, countreg));
15911 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15912 operands[1], operands[2]));
15915 outlow = gen_lowpart (QImode, out);
15916 emit_insn (gen_cmpintqi (outlow));
15917 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15919 if (operands[0] != out)
15920 emit_move_insn (operands[0], out);
15925 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15927 (define_expand "cmpintqi"
15928 [(set (match_dup 1)
15929 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15931 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15932 (parallel [(set (match_operand:QI 0 "register_operand" "")
15933 (minus:QI (match_dup 1)
15935 (clobber (reg:CC FLAGS_REG))])]
15937 "operands[1] = gen_reg_rtx (QImode);
15938 operands[2] = gen_reg_rtx (QImode);")
15940 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15941 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15943 (define_expand "cmpstrnqi_nz_1"
15944 [(parallel [(set (reg:CC FLAGS_REG)
15945 (compare:CC (match_operand 4 "memory_operand" "")
15946 (match_operand 5 "memory_operand" "")))
15947 (use (match_operand 2 "register_operand" ""))
15948 (use (match_operand:SI 3 "immediate_operand" ""))
15949 (clobber (match_operand 0 "register_operand" ""))
15950 (clobber (match_operand 1 "register_operand" ""))
15951 (clobber (match_dup 2))])]
15953 "ix86_current_function_needs_cld = 1;")
15955 (define_insn "*cmpstrnqi_nz_1"
15956 [(set (reg:CC FLAGS_REG)
15957 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15958 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15959 (use (match_operand:SI 6 "register_operand" "2"))
15960 (use (match_operand:SI 3 "immediate_operand" "i"))
15961 (clobber (match_operand:SI 0 "register_operand" "=S"))
15962 (clobber (match_operand:SI 1 "register_operand" "=D"))
15963 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15966 [(set_attr "type" "str")
15967 (set_attr "mode" "QI")
15968 (set_attr "prefix_rep" "1")])
15970 (define_insn "*cmpstrnqi_nz_rex_1"
15971 [(set (reg:CC FLAGS_REG)
15972 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15973 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15974 (use (match_operand:DI 6 "register_operand" "2"))
15975 (use (match_operand:SI 3 "immediate_operand" "i"))
15976 (clobber (match_operand:DI 0 "register_operand" "=S"))
15977 (clobber (match_operand:DI 1 "register_operand" "=D"))
15978 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15981 [(set_attr "type" "str")
15982 (set_attr "mode" "QI")
15983 (set_attr "prefix_rex" "0")
15984 (set_attr "prefix_rep" "1")])
15986 ;; The same, but the count is not known to not be zero.
15988 (define_expand "cmpstrnqi_1"
15989 [(parallel [(set (reg:CC FLAGS_REG)
15990 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15992 (compare:CC (match_operand 4 "memory_operand" "")
15993 (match_operand 5 "memory_operand" ""))
15995 (use (match_operand:SI 3 "immediate_operand" ""))
15996 (use (reg:CC FLAGS_REG))
15997 (clobber (match_operand 0 "register_operand" ""))
15998 (clobber (match_operand 1 "register_operand" ""))
15999 (clobber (match_dup 2))])]
16001 "ix86_current_function_needs_cld = 1;")
16003 (define_insn "*cmpstrnqi_1"
16004 [(set (reg:CC FLAGS_REG)
16005 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16007 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16008 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16010 (use (match_operand:SI 3 "immediate_operand" "i"))
16011 (use (reg:CC FLAGS_REG))
16012 (clobber (match_operand:SI 0 "register_operand" "=S"))
16013 (clobber (match_operand:SI 1 "register_operand" "=D"))
16014 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16017 [(set_attr "type" "str")
16018 (set_attr "mode" "QI")
16019 (set_attr "prefix_rep" "1")])
16021 (define_insn "*cmpstrnqi_rex_1"
16022 [(set (reg:CC FLAGS_REG)
16023 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16025 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16026 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16028 (use (match_operand:SI 3 "immediate_operand" "i"))
16029 (use (reg:CC FLAGS_REG))
16030 (clobber (match_operand:DI 0 "register_operand" "=S"))
16031 (clobber (match_operand:DI 1 "register_operand" "=D"))
16032 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16035 [(set_attr "type" "str")
16036 (set_attr "mode" "QI")
16037 (set_attr "prefix_rex" "0")
16038 (set_attr "prefix_rep" "1")])
16040 (define_expand "strlensi"
16041 [(set (match_operand:SI 0 "register_operand" "")
16042 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16043 (match_operand:QI 2 "immediate_operand" "")
16044 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16047 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16053 (define_expand "strlendi"
16054 [(set (match_operand:DI 0 "register_operand" "")
16055 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16056 (match_operand:QI 2 "immediate_operand" "")
16057 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16060 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16066 (define_expand "strlenqi_1"
16067 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16068 (clobber (match_operand 1 "register_operand" ""))
16069 (clobber (reg:CC FLAGS_REG))])]
16071 "ix86_current_function_needs_cld = 1;")
16073 (define_insn "*strlenqi_1"
16074 [(set (match_operand:SI 0 "register_operand" "=&c")
16075 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16076 (match_operand:QI 2 "register_operand" "a")
16077 (match_operand:SI 3 "immediate_operand" "i")
16078 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16079 (clobber (match_operand:SI 1 "register_operand" "=D"))
16080 (clobber (reg:CC FLAGS_REG))]
16083 [(set_attr "type" "str")
16084 (set_attr "mode" "QI")
16085 (set_attr "prefix_rep" "1")])
16087 (define_insn "*strlenqi_rex_1"
16088 [(set (match_operand:DI 0 "register_operand" "=&c")
16089 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16090 (match_operand:QI 2 "register_operand" "a")
16091 (match_operand:DI 3 "immediate_operand" "i")
16092 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16093 (clobber (match_operand:DI 1 "register_operand" "=D"))
16094 (clobber (reg:CC FLAGS_REG))]
16097 [(set_attr "type" "str")
16098 (set_attr "mode" "QI")
16099 (set_attr "prefix_rex" "0")
16100 (set_attr "prefix_rep" "1")])
16102 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16103 ;; handled in combine, but it is not currently up to the task.
16104 ;; When used for their truth value, the cmpstrn* expanders generate
16113 ;; The intermediate three instructions are unnecessary.
16115 ;; This one handles cmpstrn*_nz_1...
16118 (set (reg:CC FLAGS_REG)
16119 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16120 (mem:BLK (match_operand 5 "register_operand" ""))))
16121 (use (match_operand 6 "register_operand" ""))
16122 (use (match_operand:SI 3 "immediate_operand" ""))
16123 (clobber (match_operand 0 "register_operand" ""))
16124 (clobber (match_operand 1 "register_operand" ""))
16125 (clobber (match_operand 2 "register_operand" ""))])
16126 (set (match_operand:QI 7 "register_operand" "")
16127 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16128 (set (match_operand:QI 8 "register_operand" "")
16129 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16130 (set (reg FLAGS_REG)
16131 (compare (match_dup 7) (match_dup 8)))
16133 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16135 (set (reg:CC FLAGS_REG)
16136 (compare:CC (mem:BLK (match_dup 4))
16137 (mem:BLK (match_dup 5))))
16138 (use (match_dup 6))
16139 (use (match_dup 3))
16140 (clobber (match_dup 0))
16141 (clobber (match_dup 1))
16142 (clobber (match_dup 2))])]
16145 ;; ...and this one handles cmpstrn*_1.
16148 (set (reg:CC FLAGS_REG)
16149 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16151 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16152 (mem:BLK (match_operand 5 "register_operand" "")))
16154 (use (match_operand:SI 3 "immediate_operand" ""))
16155 (use (reg:CC FLAGS_REG))
16156 (clobber (match_operand 0 "register_operand" ""))
16157 (clobber (match_operand 1 "register_operand" ""))
16158 (clobber (match_operand 2 "register_operand" ""))])
16159 (set (match_operand:QI 7 "register_operand" "")
16160 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16161 (set (match_operand:QI 8 "register_operand" "")
16162 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16163 (set (reg FLAGS_REG)
16164 (compare (match_dup 7) (match_dup 8)))
16166 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16168 (set (reg:CC FLAGS_REG)
16169 (if_then_else:CC (ne (match_dup 6)
16171 (compare:CC (mem:BLK (match_dup 4))
16172 (mem:BLK (match_dup 5)))
16174 (use (match_dup 3))
16175 (use (reg:CC FLAGS_REG))
16176 (clobber (match_dup 0))
16177 (clobber (match_dup 1))
16178 (clobber (match_dup 2))])]
16183 ;; Conditional move instructions.
16185 (define_expand "mov<mode>cc"
16186 [(set (match_operand:SWIM 0 "register_operand" "")
16187 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
16188 (match_operand:SWIM 2 "general_operand" "")
16189 (match_operand:SWIM 3 "general_operand" "")))]
16191 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16193 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16194 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16195 ;; So just document what we're doing explicitly.
16197 (define_expand "x86_mov<mode>cc_0_m1"
16199 [(set (match_operand:SWI48 0 "register_operand" "")
16200 (if_then_else:SWI48
16201 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16202 [(match_operand 1 "flags_reg_operand" "")
16206 (clobber (reg:CC FLAGS_REG))])]
16210 (define_insn "*x86_mov<mode>cc_0_m1"
16211 [(set (match_operand:SWI48 0 "register_operand" "=r")
16212 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16213 [(reg FLAGS_REG) (const_int 0)])
16216 (clobber (reg:CC FLAGS_REG))]
16218 "sbb{<imodesuffix>}\t%0, %0"
16219 ; Since we don't have the proper number of operands for an alu insn,
16220 ; fill in all the blanks.
16221 [(set_attr "type" "alu")
16222 (set_attr "use_carry" "1")
16223 (set_attr "pent_pair" "pu")
16224 (set_attr "memory" "none")
16225 (set_attr "imm_disp" "false")
16226 (set_attr "mode" "<MODE>")
16227 (set_attr "length_immediate" "0")])
16229 (define_insn "*x86_mov<mode>cc_0_m1_se"
16230 [(set (match_operand:SWI48 0 "register_operand" "=r")
16231 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16232 [(reg FLAGS_REG) (const_int 0)])
16235 (clobber (reg:CC FLAGS_REG))]
16237 "sbb{<imodesuffix>}\t%0, %0"
16238 [(set_attr "type" "alu")
16239 (set_attr "use_carry" "1")
16240 (set_attr "pent_pair" "pu")
16241 (set_attr "memory" "none")
16242 (set_attr "imm_disp" "false")
16243 (set_attr "mode" "<MODE>")
16244 (set_attr "length_immediate" "0")])
16246 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16247 [(set (match_operand:SWI48 0 "register_operand" "=r")
16248 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16249 [(reg FLAGS_REG) (const_int 0)])))]
16251 "sbb{<imodesuffix>}\t%0, %0"
16252 [(set_attr "type" "alu")
16253 (set_attr "use_carry" "1")
16254 (set_attr "pent_pair" "pu")
16255 (set_attr "memory" "none")
16256 (set_attr "imm_disp" "false")
16257 (set_attr "mode" "<MODE>")
16258 (set_attr "length_immediate" "0")])
16260 (define_insn "*mov<mode>cc_noc"
16261 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16262 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16263 [(reg FLAGS_REG) (const_int 0)])
16264 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16265 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16266 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16268 cmov%O2%C1\t{%2, %0|%0, %2}
16269 cmov%O2%c1\t{%3, %0|%0, %3}"
16270 [(set_attr "type" "icmov")
16271 (set_attr "mode" "<MODE>")])
16273 (define_insn_and_split "*movqicc_noc"
16274 [(set (match_operand:QI 0 "register_operand" "=r,r")
16275 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16276 [(match_operand 4 "flags_reg_operand" "")
16278 (match_operand:QI 2 "register_operand" "r,0")
16279 (match_operand:QI 3 "register_operand" "0,r")))]
16280 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16282 "&& reload_completed"
16283 [(set (match_dup 0)
16284 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16287 "operands[0] = gen_lowpart (SImode, operands[0]);
16288 operands[2] = gen_lowpart (SImode, operands[2]);
16289 operands[3] = gen_lowpart (SImode, operands[3]);"
16290 [(set_attr "type" "icmov")
16291 (set_attr "mode" "SI")])
16293 (define_expand "mov<mode>cc"
16294 [(set (match_operand:X87MODEF 0 "register_operand" "")
16295 (if_then_else:X87MODEF
16296 (match_operand 1 "ix86_fp_comparison_operator" "")
16297 (match_operand:X87MODEF 2 "register_operand" "")
16298 (match_operand:X87MODEF 3 "register_operand" "")))]
16299 "(TARGET_80387 && TARGET_CMOVE)
16300 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16301 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16303 (define_insn "*movsfcc_1_387"
16304 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16305 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16306 [(reg FLAGS_REG) (const_int 0)])
16307 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16308 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16309 "TARGET_80387 && TARGET_CMOVE
16310 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16312 fcmov%F1\t{%2, %0|%0, %2}
16313 fcmov%f1\t{%3, %0|%0, %3}
16314 cmov%O2%C1\t{%2, %0|%0, %2}
16315 cmov%O2%c1\t{%3, %0|%0, %3}"
16316 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16317 (set_attr "mode" "SF,SF,SI,SI")])
16319 (define_insn "*movdfcc_1"
16320 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16321 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16322 [(reg FLAGS_REG) (const_int 0)])
16323 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16324 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16325 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16326 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16328 fcmov%F1\t{%2, %0|%0, %2}
16329 fcmov%f1\t{%3, %0|%0, %3}
16332 [(set_attr "type" "fcmov,fcmov,multi,multi")
16333 (set_attr "mode" "DF")])
16335 (define_insn "*movdfcc_1_rex64"
16336 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16337 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16338 [(reg FLAGS_REG) (const_int 0)])
16339 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16340 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16341 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16342 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16344 fcmov%F1\t{%2, %0|%0, %2}
16345 fcmov%f1\t{%3, %0|%0, %3}
16346 cmov%O2%C1\t{%2, %0|%0, %2}
16347 cmov%O2%c1\t{%3, %0|%0, %3}"
16348 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16349 (set_attr "mode" "DF")])
16352 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16353 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16354 [(match_operand 4 "flags_reg_operand" "")
16356 (match_operand:DF 2 "nonimmediate_operand" "")
16357 (match_operand:DF 3 "nonimmediate_operand" "")))]
16358 "!TARGET_64BIT && reload_completed"
16359 [(set (match_dup 2)
16360 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16364 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16368 split_di (&operands[2], 2, &operands[5], &operands[7]);
16369 split_di (&operands[0], 1, &operands[2], &operands[3]);
16372 (define_insn "*movxfcc_1"
16373 [(set (match_operand:XF 0 "register_operand" "=f,f")
16374 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16375 [(reg FLAGS_REG) (const_int 0)])
16376 (match_operand:XF 2 "register_operand" "f,0")
16377 (match_operand:XF 3 "register_operand" "0,f")))]
16378 "TARGET_80387 && TARGET_CMOVE"
16380 fcmov%F1\t{%2, %0|%0, %2}
16381 fcmov%f1\t{%3, %0|%0, %3}"
16382 [(set_attr "type" "fcmov")
16383 (set_attr "mode" "XF")])
16385 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16386 ;; the scalar versions to have only XMM registers as operands.
16388 ;; XOP conditional move
16389 (define_insn "*xop_pcmov_<mode>"
16390 [(set (match_operand:MODEF 0 "register_operand" "=x")
16391 (if_then_else:MODEF
16392 (match_operand:MODEF 1 "register_operand" "x")
16393 (match_operand:MODEF 2 "register_operand" "x")
16394 (match_operand:MODEF 3 "register_operand" "x")))]
16396 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16397 [(set_attr "type" "sse4arg")])
16399 ;; These versions of the min/max patterns are intentionally ignorant of
16400 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16401 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16402 ;; are undefined in this condition, we're certain this is correct.
16404 (define_insn "*avx_<code><mode>3"
16405 [(set (match_operand:MODEF 0 "register_operand" "=x")
16407 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16408 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16409 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16410 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16411 [(set_attr "type" "sseadd")
16412 (set_attr "prefix" "vex")
16413 (set_attr "mode" "<MODE>")])
16415 (define_insn "<code><mode>3"
16416 [(set (match_operand:MODEF 0 "register_operand" "=x")
16418 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16419 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16420 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16421 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16422 [(set_attr "type" "sseadd")
16423 (set_attr "mode" "<MODE>")])
16425 ;; These versions of the min/max patterns implement exactly the operations
16426 ;; min = (op1 < op2 ? op1 : op2)
16427 ;; max = (!(op1 < op2) ? op1 : op2)
16428 ;; Their operands are not commutative, and thus they may be used in the
16429 ;; presence of -0.0 and NaN.
16431 (define_insn "*avx_ieee_smin<mode>3"
16432 [(set (match_operand:MODEF 0 "register_operand" "=x")
16434 [(match_operand:MODEF 1 "register_operand" "x")
16435 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16437 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16438 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16439 [(set_attr "type" "sseadd")
16440 (set_attr "prefix" "vex")
16441 (set_attr "mode" "<MODE>")])
16443 (define_insn "*ieee_smin<mode>3"
16444 [(set (match_operand:MODEF 0 "register_operand" "=x")
16446 [(match_operand:MODEF 1 "register_operand" "0")
16447 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16449 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16450 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16451 [(set_attr "type" "sseadd")
16452 (set_attr "mode" "<MODE>")])
16454 (define_insn "*avx_ieee_smax<mode>3"
16455 [(set (match_operand:MODEF 0 "register_operand" "=x")
16457 [(match_operand:MODEF 1 "register_operand" "0")
16458 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16460 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16461 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16462 [(set_attr "type" "sseadd")
16463 (set_attr "prefix" "vex")
16464 (set_attr "mode" "<MODE>")])
16466 (define_insn "*ieee_smax<mode>3"
16467 [(set (match_operand:MODEF 0 "register_operand" "=x")
16469 [(match_operand:MODEF 1 "register_operand" "0")
16470 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16472 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16473 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16474 [(set_attr "type" "sseadd")
16475 (set_attr "mode" "<MODE>")])
16477 ;; Make two stack loads independent:
16479 ;; fld %st(0) -> fld bb
16480 ;; fmul bb fmul %st(1), %st
16482 ;; Actually we only match the last two instructions for simplicity.
16484 [(set (match_operand 0 "fp_register_operand" "")
16485 (match_operand 1 "fp_register_operand" ""))
16487 (match_operator 2 "binary_fp_operator"
16489 (match_operand 3 "memory_operand" "")]))]
16490 "REGNO (operands[0]) != REGNO (operands[1])"
16491 [(set (match_dup 0) (match_dup 3))
16492 (set (match_dup 0) (match_dup 4))]
16494 ;; The % modifier is not operational anymore in peephole2's, so we have to
16495 ;; swap the operands manually in the case of addition and multiplication.
16496 "if (COMMUTATIVE_ARITH_P (operands[2]))
16497 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16498 operands[0], operands[1]);
16500 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16501 operands[1], operands[0]);")
16503 ;; Conditional addition patterns
16504 (define_expand "add<mode>cc"
16505 [(match_operand:SWI 0 "register_operand" "")
16506 (match_operand 1 "comparison_operator" "")
16507 (match_operand:SWI 2 "register_operand" "")
16508 (match_operand:SWI 3 "const_int_operand" "")]
16510 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16513 ;; Misc patterns (?)
16515 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16516 ;; Otherwise there will be nothing to keep
16518 ;; [(set (reg ebp) (reg esp))]
16519 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16520 ;; (clobber (eflags)]
16521 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16523 ;; in proper program order.
16524 (define_insn "pro_epilogue_adjust_stack_1"
16525 [(set (match_operand:SI 0 "register_operand" "=r,r")
16526 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16527 (match_operand:SI 2 "immediate_operand" "i,i")))
16528 (clobber (reg:CC FLAGS_REG))
16529 (clobber (mem:BLK (scratch)))]
16532 switch (get_attr_type (insn))
16535 return "mov{l}\t{%1, %0|%0, %1}";
16538 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16539 if (x86_maybe_negate_const_int (&operands[2], SImode))
16540 return "sub{l}\t{%2, %0|%0, %2}";
16542 return "add{l}\t{%2, %0|%0, %2}";
16545 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16546 return "lea{l}\t{%a2, %0|%0, %a2}";
16549 [(set (attr "type")
16550 (cond [(and (eq_attr "alternative" "0")
16551 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16552 (const_string "alu")
16553 (match_operand:SI 2 "const0_operand" "")
16554 (const_string "imov")
16556 (const_string "lea")))
16557 (set (attr "length_immediate")
16558 (cond [(eq_attr "type" "imov")
16560 (and (eq_attr "type" "alu")
16561 (match_operand 2 "const128_operand" ""))
16564 (const_string "*")))
16565 (set_attr "mode" "SI")])
16567 (define_insn "pro_epilogue_adjust_stack_rex64"
16568 [(set (match_operand:DI 0 "register_operand" "=r,r")
16569 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16570 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16571 (clobber (reg:CC FLAGS_REG))
16572 (clobber (mem:BLK (scratch)))]
16575 switch (get_attr_type (insn))
16578 return "mov{q}\t{%1, %0|%0, %1}";
16581 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16582 if (x86_maybe_negate_const_int (&operands[2], DImode))
16583 return "sub{q}\t{%2, %0|%0, %2}";
16585 return "add{q}\t{%2, %0|%0, %2}";
16588 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16589 return "lea{q}\t{%a2, %0|%0, %a2}";
16592 [(set (attr "type")
16593 (cond [(and (eq_attr "alternative" "0")
16594 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16595 (const_string "alu")
16596 (match_operand:DI 2 "const0_operand" "")
16597 (const_string "imov")
16599 (const_string "lea")))
16600 (set (attr "length_immediate")
16601 (cond [(eq_attr "type" "imov")
16603 (and (eq_attr "type" "alu")
16604 (match_operand 2 "const128_operand" ""))
16607 (const_string "*")))
16608 (set_attr "mode" "DI")])
16610 (define_insn "pro_epilogue_adjust_stack_rex64_2"
16611 [(set (match_operand:DI 0 "register_operand" "=r,r")
16612 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16613 (match_operand:DI 3 "immediate_operand" "i,i")))
16614 (use (match_operand:DI 2 "register_operand" "r,r"))
16615 (clobber (reg:CC FLAGS_REG))
16616 (clobber (mem:BLK (scratch)))]
16619 switch (get_attr_type (insn))
16622 return "add{q}\t{%2, %0|%0, %2}";
16625 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16626 return "lea{q}\t{%a2, %0|%0, %a2}";
16629 gcc_unreachable ();
16632 [(set_attr "type" "alu,lea")
16633 (set_attr "mode" "DI")])
16635 (define_insn "allocate_stack_worker_32"
16636 [(set (match_operand:SI 0 "register_operand" "=a")
16637 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16638 UNSPECV_STACK_PROBE))
16639 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16640 (clobber (reg:CC FLAGS_REG))]
16641 "!TARGET_64BIT && TARGET_STACK_PROBE"
16643 [(set_attr "type" "multi")
16644 (set_attr "length" "5")])
16646 (define_insn "allocate_stack_worker_64"
16647 [(set (match_operand:DI 0 "register_operand" "=a")
16648 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
16649 UNSPECV_STACK_PROBE))
16650 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
16651 (clobber (reg:DI R10_REG))
16652 (clobber (reg:DI R11_REG))
16653 (clobber (reg:CC FLAGS_REG))]
16654 "TARGET_64BIT && TARGET_STACK_PROBE"
16656 [(set_attr "type" "multi")
16657 (set_attr "length" "5")])
16659 (define_expand "allocate_stack"
16660 [(match_operand 0 "register_operand" "")
16661 (match_operand 1 "general_operand" "")]
16662 "TARGET_STACK_PROBE"
16666 #ifndef CHECK_STACK_LIMIT
16667 #define CHECK_STACK_LIMIT 0
16670 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16671 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16673 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16674 stack_pointer_rtx, 0, OPTAB_DIRECT);
16675 if (x != stack_pointer_rtx)
16676 emit_move_insn (stack_pointer_rtx, x);
16680 x = copy_to_mode_reg (Pmode, operands[1]);
16682 x = gen_allocate_stack_worker_64 (x, x);
16684 x = gen_allocate_stack_worker_32 (x, x);
16688 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16692 ;; Use IOR for stack probes, this is shorter.
16693 (define_expand "probe_stack"
16694 [(match_operand 0 "memory_operand" "")]
16697 if (GET_MODE (operands[0]) == DImode)
16698 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
16700 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
16704 (define_expand "builtin_setjmp_receiver"
16705 [(label_ref (match_operand 0 "" ""))]
16706 "!TARGET_64BIT && flag_pic"
16712 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16713 rtx label_rtx = gen_label_rtx ();
16714 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16715 xops[0] = xops[1] = picreg;
16716 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16717 ix86_expand_binary_operator (MINUS, SImode, xops);
16721 emit_insn (gen_set_got (pic_offset_table_rtx));
16725 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16728 [(set (match_operand 0 "register_operand" "")
16729 (match_operator 3 "promotable_binary_operator"
16730 [(match_operand 1 "register_operand" "")
16731 (match_operand 2 "aligned_operand" "")]))
16732 (clobber (reg:CC FLAGS_REG))]
16733 "! TARGET_PARTIAL_REG_STALL && reload_completed
16734 && ((GET_MODE (operands[0]) == HImode
16735 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16736 /* ??? next two lines just !satisfies_constraint_K (...) */
16737 || !CONST_INT_P (operands[2])
16738 || satisfies_constraint_K (operands[2])))
16739 || (GET_MODE (operands[0]) == QImode
16740 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16741 [(parallel [(set (match_dup 0)
16742 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16743 (clobber (reg:CC FLAGS_REG))])]
16744 "operands[0] = gen_lowpart (SImode, operands[0]);
16745 operands[1] = gen_lowpart (SImode, operands[1]);
16746 if (GET_CODE (operands[3]) != ASHIFT)
16747 operands[2] = gen_lowpart (SImode, operands[2]);
16748 PUT_MODE (operands[3], SImode);")
16750 ; Promote the QImode tests, as i386 has encoding of the AND
16751 ; instruction with 32-bit sign-extended immediate and thus the
16752 ; instruction size is unchanged, except in the %eax case for
16753 ; which it is increased by one byte, hence the ! optimize_size.
16755 [(set (match_operand 0 "flags_reg_operand" "")
16756 (match_operator 2 "compare_operator"
16757 [(and (match_operand 3 "aligned_operand" "")
16758 (match_operand 4 "const_int_operand" ""))
16760 (set (match_operand 1 "register_operand" "")
16761 (and (match_dup 3) (match_dup 4)))]
16762 "! TARGET_PARTIAL_REG_STALL && reload_completed
16763 && optimize_insn_for_speed_p ()
16764 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16765 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16766 /* Ensure that the operand will remain sign-extended immediate. */
16767 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16768 [(parallel [(set (match_dup 0)
16769 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16772 (and:SI (match_dup 3) (match_dup 4)))])]
16775 = gen_int_mode (INTVAL (operands[4])
16776 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16777 operands[1] = gen_lowpart (SImode, operands[1]);
16778 operands[3] = gen_lowpart (SImode, operands[3]);
16781 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16782 ; the TEST instruction with 32-bit sign-extended immediate and thus
16783 ; the instruction size would at least double, which is not what we
16784 ; want even with ! optimize_size.
16786 [(set (match_operand 0 "flags_reg_operand" "")
16787 (match_operator 1 "compare_operator"
16788 [(and (match_operand:HI 2 "aligned_operand" "")
16789 (match_operand:HI 3 "const_int_operand" ""))
16791 "! TARGET_PARTIAL_REG_STALL && reload_completed
16792 && ! TARGET_FAST_PREFIX
16793 && optimize_insn_for_speed_p ()
16794 /* Ensure that the operand will remain sign-extended immediate. */
16795 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16796 [(set (match_dup 0)
16797 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16801 = gen_int_mode (INTVAL (operands[3])
16802 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16803 operands[2] = gen_lowpart (SImode, operands[2]);
16807 [(set (match_operand 0 "register_operand" "")
16808 (neg (match_operand 1 "register_operand" "")))
16809 (clobber (reg:CC FLAGS_REG))]
16810 "! TARGET_PARTIAL_REG_STALL && reload_completed
16811 && (GET_MODE (operands[0]) == HImode
16812 || (GET_MODE (operands[0]) == QImode
16813 && (TARGET_PROMOTE_QImode
16814 || optimize_insn_for_size_p ())))"
16815 [(parallel [(set (match_dup 0)
16816 (neg:SI (match_dup 1)))
16817 (clobber (reg:CC FLAGS_REG))])]
16818 "operands[0] = gen_lowpart (SImode, operands[0]);
16819 operands[1] = gen_lowpart (SImode, operands[1]);")
16822 [(set (match_operand 0 "register_operand" "")
16823 (not (match_operand 1 "register_operand" "")))]
16824 "! TARGET_PARTIAL_REG_STALL && reload_completed
16825 && (GET_MODE (operands[0]) == HImode
16826 || (GET_MODE (operands[0]) == QImode
16827 && (TARGET_PROMOTE_QImode
16828 || optimize_insn_for_size_p ())))"
16829 [(set (match_dup 0)
16830 (not:SI (match_dup 1)))]
16831 "operands[0] = gen_lowpart (SImode, operands[0]);
16832 operands[1] = gen_lowpart (SImode, operands[1]);")
16835 [(set (match_operand 0 "register_operand" "")
16836 (if_then_else (match_operator 1 "comparison_operator"
16837 [(reg FLAGS_REG) (const_int 0)])
16838 (match_operand 2 "register_operand" "")
16839 (match_operand 3 "register_operand" "")))]
16840 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16841 && (GET_MODE (operands[0]) == HImode
16842 || (GET_MODE (operands[0]) == QImode
16843 && (TARGET_PROMOTE_QImode
16844 || optimize_insn_for_size_p ())))"
16845 [(set (match_dup 0)
16846 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16847 "operands[0] = gen_lowpart (SImode, operands[0]);
16848 operands[2] = gen_lowpart (SImode, operands[2]);
16849 operands[3] = gen_lowpart (SImode, operands[3]);")
16852 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16853 ;; transform a complex memory operation into two memory to register operations.
16855 ;; Don't push memory operands
16857 [(set (match_operand:SI 0 "push_operand" "")
16858 (match_operand:SI 1 "memory_operand" ""))
16859 (match_scratch:SI 2 "r")]
16860 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16861 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16862 [(set (match_dup 2) (match_dup 1))
16863 (set (match_dup 0) (match_dup 2))]
16867 [(set (match_operand:DI 0 "push_operand" "")
16868 (match_operand:DI 1 "memory_operand" ""))
16869 (match_scratch:DI 2 "r")]
16870 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16871 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16872 [(set (match_dup 2) (match_dup 1))
16873 (set (match_dup 0) (match_dup 2))]
16876 ;; We need to handle SFmode only, because DFmode and XFmode is split to
16879 [(set (match_operand:SF 0 "push_operand" "")
16880 (match_operand:SF 1 "memory_operand" ""))
16881 (match_scratch:SF 2 "r")]
16882 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16883 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16884 [(set (match_dup 2) (match_dup 1))
16885 (set (match_dup 0) (match_dup 2))]
16889 [(set (match_operand:HI 0 "push_operand" "")
16890 (match_operand:HI 1 "memory_operand" ""))
16891 (match_scratch:HI 2 "r")]
16892 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16893 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16894 [(set (match_dup 2) (match_dup 1))
16895 (set (match_dup 0) (match_dup 2))]
16899 [(set (match_operand:QI 0 "push_operand" "")
16900 (match_operand:QI 1 "memory_operand" ""))
16901 (match_scratch:QI 2 "q")]
16902 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16903 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16904 [(set (match_dup 2) (match_dup 1))
16905 (set (match_dup 0) (match_dup 2))]
16908 ;; Don't move an immediate directly to memory when the instruction
16911 [(match_scratch:SI 1 "r")
16912 (set (match_operand:SI 0 "memory_operand" "")
16914 "optimize_insn_for_speed_p ()
16915 && ! TARGET_USE_MOV0
16916 && TARGET_SPLIT_LONG_MOVES
16917 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16918 && peep2_regno_dead_p (0, FLAGS_REG)"
16919 [(parallel [(set (match_dup 1) (const_int 0))
16920 (clobber (reg:CC FLAGS_REG))])
16921 (set (match_dup 0) (match_dup 1))]
16925 [(match_scratch:HI 1 "r")
16926 (set (match_operand:HI 0 "memory_operand" "")
16928 "optimize_insn_for_speed_p ()
16929 && ! TARGET_USE_MOV0
16930 && TARGET_SPLIT_LONG_MOVES
16931 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16932 && peep2_regno_dead_p (0, FLAGS_REG)"
16933 [(parallel [(set (match_dup 2) (const_int 0))
16934 (clobber (reg:CC FLAGS_REG))])
16935 (set (match_dup 0) (match_dup 1))]
16936 "operands[2] = gen_lowpart (SImode, operands[1]);")
16939 [(match_scratch:QI 1 "q")
16940 (set (match_operand:QI 0 "memory_operand" "")
16942 "optimize_insn_for_speed_p ()
16943 && ! TARGET_USE_MOV0
16944 && TARGET_SPLIT_LONG_MOVES
16945 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16946 && peep2_regno_dead_p (0, FLAGS_REG)"
16947 [(parallel [(set (match_dup 2) (const_int 0))
16948 (clobber (reg:CC FLAGS_REG))])
16949 (set (match_dup 0) (match_dup 1))]
16950 "operands[2] = gen_lowpart (SImode, operands[1]);")
16953 [(match_scratch:SI 2 "r")
16954 (set (match_operand:SI 0 "memory_operand" "")
16955 (match_operand:SI 1 "immediate_operand" ""))]
16956 "optimize_insn_for_speed_p ()
16957 && TARGET_SPLIT_LONG_MOVES
16958 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16959 [(set (match_dup 2) (match_dup 1))
16960 (set (match_dup 0) (match_dup 2))]
16964 [(match_scratch:HI 2 "r")
16965 (set (match_operand:HI 0 "memory_operand" "")
16966 (match_operand:HI 1 "immediate_operand" ""))]
16967 "optimize_insn_for_speed_p ()
16968 && TARGET_SPLIT_LONG_MOVES
16969 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16970 [(set (match_dup 2) (match_dup 1))
16971 (set (match_dup 0) (match_dup 2))]
16975 [(match_scratch:QI 2 "q")
16976 (set (match_operand:QI 0 "memory_operand" "")
16977 (match_operand:QI 1 "immediate_operand" ""))]
16978 "optimize_insn_for_speed_p ()
16979 && TARGET_SPLIT_LONG_MOVES
16980 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16981 [(set (match_dup 2) (match_dup 1))
16982 (set (match_dup 0) (match_dup 2))]
16985 ;; Don't compare memory with zero, load and use a test instead.
16987 [(set (match_operand 0 "flags_reg_operand" "")
16988 (match_operator 1 "compare_operator"
16989 [(match_operand:SI 2 "memory_operand" "")
16991 (match_scratch:SI 3 "r")]
16992 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16993 [(set (match_dup 3) (match_dup 2))
16994 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
16997 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16998 ;; Don't split NOTs with a displacement operand, because resulting XOR
16999 ;; will not be pairable anyway.
17001 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17002 ;; represented using a modRM byte. The XOR replacement is long decoded,
17003 ;; so this split helps here as well.
17005 ;; Note: Can't do this as a regular split because we can't get proper
17006 ;; lifetime information then.
17009 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17010 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17011 "optimize_insn_for_speed_p ()
17012 && ((TARGET_NOT_UNPAIRABLE
17013 && (!MEM_P (operands[0])
17014 || !memory_displacement_operand (operands[0], SImode)))
17015 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
17016 && peep2_regno_dead_p (0, FLAGS_REG)"
17017 [(parallel [(set (match_dup 0)
17018 (xor:SI (match_dup 1) (const_int -1)))
17019 (clobber (reg:CC FLAGS_REG))])]
17023 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17024 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17025 "optimize_insn_for_speed_p ()
17026 && ((TARGET_NOT_UNPAIRABLE
17027 && (!MEM_P (operands[0])
17028 || !memory_displacement_operand (operands[0], HImode)))
17029 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
17030 && peep2_regno_dead_p (0, FLAGS_REG)"
17031 [(parallel [(set (match_dup 0)
17032 (xor:HI (match_dup 1) (const_int -1)))
17033 (clobber (reg:CC FLAGS_REG))])]
17037 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17038 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17039 "optimize_insn_for_speed_p ()
17040 && ((TARGET_NOT_UNPAIRABLE
17041 && (!MEM_P (operands[0])
17042 || !memory_displacement_operand (operands[0], QImode)))
17043 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
17044 && peep2_regno_dead_p (0, FLAGS_REG)"
17045 [(parallel [(set (match_dup 0)
17046 (xor:QI (match_dup 1) (const_int -1)))
17047 (clobber (reg:CC FLAGS_REG))])]
17050 ;; Non pairable "test imm, reg" instructions can be translated to
17051 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17052 ;; byte opcode instead of two, have a short form for byte operands),
17053 ;; so do it for other CPUs as well. Given that the value was dead,
17054 ;; this should not create any new dependencies. Pass on the sub-word
17055 ;; versions if we're concerned about partial register stalls.
17058 [(set (match_operand 0 "flags_reg_operand" "")
17059 (match_operator 1 "compare_operator"
17060 [(and:SI (match_operand:SI 2 "register_operand" "")
17061 (match_operand:SI 3 "immediate_operand" ""))
17063 "ix86_match_ccmode (insn, CCNOmode)
17064 && (true_regnum (operands[2]) != AX_REG
17065 || satisfies_constraint_K (operands[3]))
17066 && peep2_reg_dead_p (1, operands[2])"
17068 [(set (match_dup 0)
17069 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17072 (and:SI (match_dup 2) (match_dup 3)))])]
17075 ;; We don't need to handle HImode case, because it will be promoted to SImode
17076 ;; on ! TARGET_PARTIAL_REG_STALL
17079 [(set (match_operand 0 "flags_reg_operand" "")
17080 (match_operator 1 "compare_operator"
17081 [(and:QI (match_operand:QI 2 "register_operand" "")
17082 (match_operand:QI 3 "immediate_operand" ""))
17084 "! TARGET_PARTIAL_REG_STALL
17085 && ix86_match_ccmode (insn, CCNOmode)
17086 && true_regnum (operands[2]) != AX_REG
17087 && peep2_reg_dead_p (1, operands[2])"
17089 [(set (match_dup 0)
17090 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17093 (and:QI (match_dup 2) (match_dup 3)))])]
17097 [(set (match_operand 0 "flags_reg_operand" "")
17098 (match_operator 1 "compare_operator"
17101 (match_operand 2 "ext_register_operand" "")
17104 (match_operand 3 "const_int_operand" ""))
17106 "! TARGET_PARTIAL_REG_STALL
17107 && ix86_match_ccmode (insn, CCNOmode)
17108 && true_regnum (operands[2]) != AX_REG
17109 && peep2_reg_dead_p (1, operands[2])"
17110 [(parallel [(set (match_dup 0)
17119 (set (zero_extract:SI (match_dup 2)
17130 ;; Don't do logical operations with memory inputs.
17132 [(match_scratch:SI 2 "r")
17133 (parallel [(set (match_operand:SI 0 "register_operand" "")
17134 (match_operator:SI 3 "arith_or_logical_operator"
17136 (match_operand:SI 1 "memory_operand" "")]))
17137 (clobber (reg:CC FLAGS_REG))])]
17138 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17139 [(set (match_dup 2) (match_dup 1))
17140 (parallel [(set (match_dup 0)
17141 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17142 (clobber (reg:CC FLAGS_REG))])]
17146 [(match_scratch:SI 2 "r")
17147 (parallel [(set (match_operand:SI 0 "register_operand" "")
17148 (match_operator:SI 3 "arith_or_logical_operator"
17149 [(match_operand:SI 1 "memory_operand" "")
17151 (clobber (reg:CC FLAGS_REG))])]
17152 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17153 [(set (match_dup 2) (match_dup 1))
17154 (parallel [(set (match_dup 0)
17155 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17156 (clobber (reg:CC FLAGS_REG))])]
17159 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17160 ;; refers to the destination of the load!
17163 [(set (match_operand:SI 0 "register_operand" "")
17164 (match_operand:SI 1 "register_operand" ""))
17165 (parallel [(set (match_dup 0)
17166 (match_operator:SI 3 "commutative_operator"
17168 (match_operand:SI 2 "memory_operand" "")]))
17169 (clobber (reg:CC FLAGS_REG))])]
17170 "REGNO (operands[0]) != REGNO (operands[1])
17171 && GENERAL_REGNO_P (REGNO (operands[0]))
17172 && GENERAL_REGNO_P (REGNO (operands[1]))"
17173 [(set (match_dup 0) (match_dup 4))
17174 (parallel [(set (match_dup 0)
17175 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17176 (clobber (reg:CC FLAGS_REG))])]
17177 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17180 [(set (match_operand 0 "register_operand" "")
17181 (match_operand 1 "register_operand" ""))
17183 (match_operator 3 "commutative_operator"
17185 (match_operand 2 "memory_operand" "")]))]
17186 "REGNO (operands[0]) != REGNO (operands[1])
17187 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17188 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17189 [(set (match_dup 0) (match_dup 2))
17191 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
17194 ; Don't do logical operations with memory outputs
17196 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17197 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17198 ; the same decoder scheduling characteristics as the original.
17201 [(match_scratch:SI 2 "r")
17202 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17203 (match_operator:SI 3 "arith_or_logical_operator"
17205 (match_operand:SI 1 "nonmemory_operand" "")]))
17206 (clobber (reg:CC FLAGS_REG))])]
17207 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17208 /* Do not split stack checking probes. */
17209 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17210 [(set (match_dup 2) (match_dup 0))
17211 (parallel [(set (match_dup 2)
17212 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17213 (clobber (reg:CC FLAGS_REG))])
17214 (set (match_dup 0) (match_dup 2))]
17218 [(match_scratch:SI 2 "r")
17219 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17220 (match_operator:SI 3 "arith_or_logical_operator"
17221 [(match_operand:SI 1 "nonmemory_operand" "")
17223 (clobber (reg:CC FLAGS_REG))])]
17224 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17225 /* Do not split stack checking probes. */
17226 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17227 [(set (match_dup 2) (match_dup 0))
17228 (parallel [(set (match_dup 2)
17229 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17230 (clobber (reg:CC FLAGS_REG))])
17231 (set (match_dup 0) (match_dup 2))]
17234 ;; Attempt to always use XOR for zeroing registers.
17236 [(set (match_operand 0 "register_operand" "")
17237 (match_operand 1 "const0_operand" ""))]
17238 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17239 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17240 && GENERAL_REG_P (operands[0])
17241 && peep2_regno_dead_p (0, FLAGS_REG)"
17242 [(parallel [(set (match_dup 0) (const_int 0))
17243 (clobber (reg:CC FLAGS_REG))])]
17245 operands[0] = gen_lowpart (word_mode, operands[0]);
17249 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17251 "(GET_MODE (operands[0]) == QImode
17252 || GET_MODE (operands[0]) == HImode)
17253 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17254 && peep2_regno_dead_p (0, FLAGS_REG)"
17255 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17256 (clobber (reg:CC FLAGS_REG))])])
17258 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17260 [(set (match_operand 0 "register_operand" "")
17262 "(GET_MODE (operands[0]) == HImode
17263 || GET_MODE (operands[0]) == SImode
17264 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17265 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17266 && peep2_regno_dead_p (0, FLAGS_REG)"
17267 [(parallel [(set (match_dup 0) (const_int -1))
17268 (clobber (reg:CC FLAGS_REG))])]
17269 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17272 ;; Attempt to convert simple leas to adds. These can be created by
17275 [(set (match_operand:SI 0 "register_operand" "")
17276 (plus:SI (match_dup 0)
17277 (match_operand:SI 1 "nonmemory_operand" "")))]
17278 "peep2_regno_dead_p (0, FLAGS_REG)"
17279 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17280 (clobber (reg:CC FLAGS_REG))])]
17284 [(set (match_operand:SI 0 "register_operand" "")
17285 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17286 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17287 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17288 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17289 (clobber (reg:CC FLAGS_REG))])]
17290 "operands[2] = gen_lowpart (SImode, operands[2]);")
17293 [(set (match_operand:DI 0 "register_operand" "")
17294 (plus:DI (match_dup 0)
17295 (match_operand:DI 1 "x86_64_general_operand" "")))]
17296 "peep2_regno_dead_p (0, FLAGS_REG)"
17297 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17298 (clobber (reg:CC FLAGS_REG))])]
17302 [(set (match_operand:SI 0 "register_operand" "")
17303 (mult:SI (match_dup 0)
17304 (match_operand:SI 1 "const_int_operand" "")))]
17305 "exact_log2 (INTVAL (operands[1])) >= 0
17306 && peep2_regno_dead_p (0, FLAGS_REG)"
17307 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17308 (clobber (reg:CC FLAGS_REG))])]
17309 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17312 [(set (match_operand:DI 0 "register_operand" "")
17313 (mult:DI (match_dup 0)
17314 (match_operand:DI 1 "const_int_operand" "")))]
17315 "exact_log2 (INTVAL (operands[1])) >= 0
17316 && peep2_regno_dead_p (0, FLAGS_REG)"
17317 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17318 (clobber (reg:CC FLAGS_REG))])]
17319 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17322 [(set (match_operand:SI 0 "register_operand" "")
17323 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17324 (match_operand:DI 2 "const_int_operand" "")) 0))]
17325 "exact_log2 (INTVAL (operands[2])) >= 0
17326 && REGNO (operands[0]) == REGNO (operands[1])
17327 && peep2_regno_dead_p (0, FLAGS_REG)"
17328 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17329 (clobber (reg:CC FLAGS_REG))])]
17330 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17332 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17333 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17334 ;; many CPUs it is also faster, since special hardware to avoid esp
17335 ;; dependencies is present.
17337 ;; While some of these conversions may be done using splitters, we use peepholes
17338 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17340 ;; Convert prologue esp subtractions to push.
17341 ;; We need register to push. In order to keep verify_flow_info happy we have
17343 ;; - use scratch and clobber it in order to avoid dependencies
17344 ;; - use already live register
17345 ;; We can't use the second way right now, since there is no reliable way how to
17346 ;; verify that given register is live. First choice will also most likely in
17347 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17348 ;; call clobbered registers are dead. We may want to use base pointer as an
17349 ;; alternative when no register is available later.
17352 [(match_scratch:SI 0 "r")
17353 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17354 (clobber (reg:CC FLAGS_REG))
17355 (clobber (mem:BLK (scratch)))])]
17356 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17357 [(clobber (match_dup 0))
17358 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17359 (clobber (mem:BLK (scratch)))])])
17362 [(match_scratch:SI 0 "r")
17363 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17364 (clobber (reg:CC FLAGS_REG))
17365 (clobber (mem:BLK (scratch)))])]
17366 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17367 [(clobber (match_dup 0))
17368 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17369 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17370 (clobber (mem:BLK (scratch)))])])
17372 ;; Convert esp subtractions to push.
17374 [(match_scratch:SI 0 "r")
17375 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17376 (clobber (reg:CC FLAGS_REG))])]
17377 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17378 [(clobber (match_dup 0))
17379 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17382 [(match_scratch:SI 0 "r")
17383 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17384 (clobber (reg:CC FLAGS_REG))])]
17385 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17386 [(clobber (match_dup 0))
17387 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17388 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17390 ;; Convert epilogue deallocator to pop.
17392 [(match_scratch:SI 0 "r")
17393 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17394 (clobber (reg:CC FLAGS_REG))
17395 (clobber (mem:BLK (scratch)))])]
17396 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17397 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17398 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17399 (clobber (mem:BLK (scratch)))])]
17402 ;; Two pops case is tricky, since pop causes dependency on destination register.
17403 ;; We use two registers if available.
17405 [(match_scratch:SI 0 "r")
17406 (match_scratch:SI 1 "r")
17407 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17408 (clobber (reg:CC FLAGS_REG))
17409 (clobber (mem:BLK (scratch)))])]
17410 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17411 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17412 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17413 (clobber (mem:BLK (scratch)))])
17414 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17415 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17419 [(match_scratch:SI 0 "r")
17420 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17421 (clobber (reg:CC FLAGS_REG))
17422 (clobber (mem:BLK (scratch)))])]
17423 "optimize_insn_for_size_p ()"
17424 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17425 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17426 (clobber (mem:BLK (scratch)))])
17427 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17428 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17431 ;; Convert esp additions to pop.
17433 [(match_scratch:SI 0 "r")
17434 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17435 (clobber (reg:CC FLAGS_REG))])]
17437 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17438 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17441 ;; Two pops case is tricky, since pop causes dependency on destination register.
17442 ;; We use two registers if available.
17444 [(match_scratch:SI 0 "r")
17445 (match_scratch:SI 1 "r")
17446 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17447 (clobber (reg:CC FLAGS_REG))])]
17449 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17450 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17451 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17452 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17456 [(match_scratch:SI 0 "r")
17457 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17458 (clobber (reg:CC FLAGS_REG))])]
17459 "optimize_insn_for_size_p ()"
17460 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17461 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17462 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17463 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17466 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17467 ;; required and register dies. Similarly for 128 to -128.
17469 [(set (match_operand 0 "flags_reg_operand" "")
17470 (match_operator 1 "compare_operator"
17471 [(match_operand 2 "register_operand" "")
17472 (match_operand 3 "const_int_operand" "")]))]
17473 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17474 && incdec_operand (operands[3], GET_MODE (operands[3])))
17475 || (!TARGET_FUSE_CMP_AND_BRANCH
17476 && INTVAL (operands[3]) == 128))
17477 && ix86_match_ccmode (insn, CCGCmode)
17478 && peep2_reg_dead_p (1, operands[2])"
17479 [(parallel [(set (match_dup 0)
17480 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17481 (clobber (match_dup 2))])]
17485 [(match_scratch:DI 0 "r")
17486 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17487 (clobber (reg:CC FLAGS_REG))
17488 (clobber (mem:BLK (scratch)))])]
17489 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17490 [(clobber (match_dup 0))
17491 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17492 (clobber (mem:BLK (scratch)))])])
17495 [(match_scratch:DI 0 "r")
17496 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17497 (clobber (reg:CC FLAGS_REG))
17498 (clobber (mem:BLK (scratch)))])]
17499 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17500 [(clobber (match_dup 0))
17501 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17502 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17503 (clobber (mem:BLK (scratch)))])])
17505 ;; Convert esp subtractions to push.
17507 [(match_scratch:DI 0 "r")
17508 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17509 (clobber (reg:CC FLAGS_REG))])]
17510 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17511 [(clobber (match_dup 0))
17512 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17515 [(match_scratch:DI 0 "r")
17516 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17517 (clobber (reg:CC FLAGS_REG))])]
17518 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17519 [(clobber (match_dup 0))
17520 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17521 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17523 ;; Convert epilogue deallocator to pop.
17525 [(match_scratch:DI 0 "r")
17526 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17527 (clobber (reg:CC FLAGS_REG))
17528 (clobber (mem:BLK (scratch)))])]
17529 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17530 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17531 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17532 (clobber (mem:BLK (scratch)))])]
17535 ;; Two pops case is tricky, since pop causes dependency on destination register.
17536 ;; We use two registers if available.
17538 [(match_scratch:DI 0 "r")
17539 (match_scratch:DI 1 "r")
17540 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17541 (clobber (reg:CC FLAGS_REG))
17542 (clobber (mem:BLK (scratch)))])]
17543 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17544 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17545 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17546 (clobber (mem:BLK (scratch)))])
17547 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17548 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17552 [(match_scratch:DI 0 "r")
17553 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17554 (clobber (reg:CC FLAGS_REG))
17555 (clobber (mem:BLK (scratch)))])]
17556 "optimize_insn_for_size_p ()"
17557 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17558 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17559 (clobber (mem:BLK (scratch)))])
17560 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17561 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17564 ;; Convert esp additions to pop.
17566 [(match_scratch:DI 0 "r")
17567 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17568 (clobber (reg:CC FLAGS_REG))])]
17570 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17571 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17574 ;; Two pops case is tricky, since pop causes dependency on destination register.
17575 ;; We use two registers if available.
17577 [(match_scratch:DI 0 "r")
17578 (match_scratch:DI 1 "r")
17579 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17580 (clobber (reg:CC FLAGS_REG))])]
17582 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17583 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17584 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17585 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17589 [(match_scratch:DI 0 "r")
17590 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17591 (clobber (reg:CC FLAGS_REG))])]
17592 "optimize_insn_for_size_p ()"
17593 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17594 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17595 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17596 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17599 ;; Convert imul by three, five and nine into lea
17602 [(set (match_operand:SI 0 "register_operand" "")
17603 (mult:SI (match_operand:SI 1 "register_operand" "")
17604 (match_operand:SI 2 "const_int_operand" "")))
17605 (clobber (reg:CC FLAGS_REG))])]
17606 "INTVAL (operands[2]) == 3
17607 || INTVAL (operands[2]) == 5
17608 || INTVAL (operands[2]) == 9"
17609 [(set (match_dup 0)
17610 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
17612 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17616 [(set (match_operand:SI 0 "register_operand" "")
17617 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17618 (match_operand:SI 2 "const_int_operand" "")))
17619 (clobber (reg:CC FLAGS_REG))])]
17620 "optimize_insn_for_speed_p ()
17621 && (INTVAL (operands[2]) == 3
17622 || INTVAL (operands[2]) == 5
17623 || INTVAL (operands[2]) == 9)"
17624 [(set (match_dup 0) (match_dup 1))
17626 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
17628 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17632 [(set (match_operand:DI 0 "register_operand" "")
17633 (mult:DI (match_operand:DI 1 "register_operand" "")
17634 (match_operand:DI 2 "const_int_operand" "")))
17635 (clobber (reg:CC FLAGS_REG))])]
17637 && (INTVAL (operands[2]) == 3
17638 || INTVAL (operands[2]) == 5
17639 || INTVAL (operands[2]) == 9)"
17640 [(set (match_dup 0)
17641 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
17643 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17647 [(set (match_operand:DI 0 "register_operand" "")
17648 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17649 (match_operand:DI 2 "const_int_operand" "")))
17650 (clobber (reg:CC FLAGS_REG))])]
17652 && optimize_insn_for_speed_p ()
17653 && (INTVAL (operands[2]) == 3
17654 || INTVAL (operands[2]) == 5
17655 || INTVAL (operands[2]) == 9)"
17656 [(set (match_dup 0) (match_dup 1))
17658 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
17660 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17662 ;; Imul $32bit_imm, mem, reg is vector decoded, while
17663 ;; imul $32bit_imm, reg, reg is direct decoded.
17665 [(match_scratch:DI 3 "r")
17666 (parallel [(set (match_operand:DI 0 "register_operand" "")
17667 (mult:DI (match_operand:DI 1 "memory_operand" "")
17668 (match_operand:DI 2 "immediate_operand" "")))
17669 (clobber (reg:CC FLAGS_REG))])]
17670 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17671 && !satisfies_constraint_K (operands[2])"
17672 [(set (match_dup 3) (match_dup 1))
17673 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
17674 (clobber (reg:CC FLAGS_REG))])]
17678 [(match_scratch:SI 3 "r")
17679 (parallel [(set (match_operand:SI 0 "register_operand" "")
17680 (mult:SI (match_operand:SI 1 "memory_operand" "")
17681 (match_operand:SI 2 "immediate_operand" "")))
17682 (clobber (reg:CC FLAGS_REG))])]
17683 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17684 && !satisfies_constraint_K (operands[2])"
17685 [(set (match_dup 3) (match_dup 1))
17686 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
17687 (clobber (reg:CC FLAGS_REG))])]
17691 [(match_scratch:SI 3 "r")
17692 (parallel [(set (match_operand:DI 0 "register_operand" "")
17694 (mult:SI (match_operand:SI 1 "memory_operand" "")
17695 (match_operand:SI 2 "immediate_operand" ""))))
17696 (clobber (reg:CC FLAGS_REG))])]
17697 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17698 && !satisfies_constraint_K (operands[2])"
17699 [(set (match_dup 3) (match_dup 1))
17700 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17701 (clobber (reg:CC FLAGS_REG))])]
17704 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17705 ;; Convert it into imul reg, reg
17706 ;; It would be better to force assembler to encode instruction using long
17707 ;; immediate, but there is apparently no way to do so.
17709 [(parallel [(set (match_operand:DI 0 "register_operand" "")
17710 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17711 (match_operand:DI 2 "const_int_operand" "")))
17712 (clobber (reg:CC FLAGS_REG))])
17713 (match_scratch:DI 3 "r")]
17714 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17715 && satisfies_constraint_K (operands[2])"
17716 [(set (match_dup 3) (match_dup 2))
17717 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
17718 (clobber (reg:CC FLAGS_REG))])]
17720 if (!rtx_equal_p (operands[0], operands[1]))
17721 emit_move_insn (operands[0], operands[1]);
17725 [(parallel [(set (match_operand:SI 0 "register_operand" "")
17726 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17727 (match_operand:SI 2 "const_int_operand" "")))
17728 (clobber (reg:CC FLAGS_REG))])
17729 (match_scratch:SI 3 "r")]
17730 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17731 && satisfies_constraint_K (operands[2])"
17732 [(set (match_dup 3) (match_dup 2))
17733 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
17734 (clobber (reg:CC FLAGS_REG))])]
17736 if (!rtx_equal_p (operands[0], operands[1]))
17737 emit_move_insn (operands[0], operands[1]);
17741 [(parallel [(set (match_operand:HI 0 "register_operand" "")
17742 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
17743 (match_operand:HI 2 "immediate_operand" "")))
17744 (clobber (reg:CC FLAGS_REG))])
17745 (match_scratch:HI 3 "r")]
17746 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
17747 [(set (match_dup 3) (match_dup 2))
17748 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
17749 (clobber (reg:CC FLAGS_REG))])]
17751 if (!rtx_equal_p (operands[0], operands[1]))
17752 emit_move_insn (operands[0], operands[1]);
17755 ;; After splitting up read-modify operations, array accesses with memory
17756 ;; operands might end up in form:
17758 ;; movl 4(%esp), %edx
17760 ;; instead of pre-splitting:
17762 ;; addl 4(%esp), %eax
17764 ;; movl 4(%esp), %edx
17765 ;; leal (%edx,%eax,4), %eax
17768 [(parallel [(set (match_operand 0 "register_operand" "")
17769 (ashift (match_operand 1 "register_operand" "")
17770 (match_operand 2 "const_int_operand" "")))
17771 (clobber (reg:CC FLAGS_REG))])
17772 (set (match_operand 3 "register_operand")
17773 (match_operand 4 "x86_64_general_operand" ""))
17774 (parallel [(set (match_operand 5 "register_operand" "")
17775 (plus (match_operand 6 "register_operand" "")
17776 (match_operand 7 "register_operand" "")))
17777 (clobber (reg:CC FLAGS_REG))])]
17778 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17779 /* Validate MODE for lea. */
17780 && ((!TARGET_PARTIAL_REG_STALL
17781 && (GET_MODE (operands[0]) == QImode
17782 || GET_MODE (operands[0]) == HImode))
17783 || GET_MODE (operands[0]) == SImode
17784 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17785 /* We reorder load and the shift. */
17786 && !rtx_equal_p (operands[1], operands[3])
17787 && !reg_overlap_mentioned_p (operands[0], operands[4])
17788 /* Last PLUS must consist of operand 0 and 3. */
17789 && !rtx_equal_p (operands[0], operands[3])
17790 && (rtx_equal_p (operands[3], operands[6])
17791 || rtx_equal_p (operands[3], operands[7]))
17792 && (rtx_equal_p (operands[0], operands[6])
17793 || rtx_equal_p (operands[0], operands[7]))
17794 /* The intermediate operand 0 must die or be same as output. */
17795 && (rtx_equal_p (operands[0], operands[5])
17796 || peep2_reg_dead_p (3, operands[0]))"
17797 [(set (match_dup 3) (match_dup 4))
17798 (set (match_dup 0) (match_dup 1))]
17800 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
17801 int scale = 1 << INTVAL (operands[2]);
17802 rtx index = gen_lowpart (Pmode, operands[1]);
17803 rtx base = gen_lowpart (Pmode, operands[3]);
17804 rtx dest = gen_lowpart (mode, operands[5]);
17806 operands[1] = gen_rtx_PLUS (Pmode, base,
17807 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17809 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17810 operands[0] = dest;
17813 ;; Call-value patterns last so that the wildcard operand does not
17814 ;; disrupt insn-recog's switch tables.
17816 (define_insn "*call_value_pop_0"
17817 [(set (match_operand 0 "" "")
17818 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17819 (match_operand:SI 2 "" "")))
17820 (set (reg:SI SP_REG)
17821 (plus:SI (reg:SI SP_REG)
17822 (match_operand:SI 3 "immediate_operand" "")))]
17825 if (SIBLING_CALL_P (insn))
17828 return "call\t%P1";
17830 [(set_attr "type" "callv")])
17832 (define_insn "*call_value_pop_1"
17833 [(set (match_operand 0 "" "")
17834 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17835 (match_operand:SI 2 "" "")))
17836 (set (reg:SI SP_REG)
17837 (plus:SI (reg:SI SP_REG)
17838 (match_operand:SI 3 "immediate_operand" "i")))]
17839 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17841 if (constant_call_address_operand (operands[1], Pmode))
17842 return "call\t%P1";
17843 return "call\t%A1";
17845 [(set_attr "type" "callv")])
17847 (define_insn "*sibcall_value_pop_1"
17848 [(set (match_operand 0 "" "")
17849 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17850 (match_operand:SI 2 "" "")))
17851 (set (reg:SI SP_REG)
17852 (plus:SI (reg:SI SP_REG)
17853 (match_operand:SI 3 "immediate_operand" "i,i")))]
17854 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17858 [(set_attr "type" "callv")])
17860 (define_insn "*call_value_0"
17861 [(set (match_operand 0 "" "")
17862 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17863 (match_operand:SI 2 "" "")))]
17866 if (SIBLING_CALL_P (insn))
17869 return "call\t%P1";
17871 [(set_attr "type" "callv")])
17873 (define_insn "*call_value_0_rex64"
17874 [(set (match_operand 0 "" "")
17875 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17876 (match_operand:DI 2 "const_int_operand" "")))]
17879 if (SIBLING_CALL_P (insn))
17882 return "call\t%P1";
17884 [(set_attr "type" "callv")])
17886 (define_insn "*call_value_0_rex64_ms_sysv"
17887 [(set (match_operand 0 "" "")
17888 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17889 (match_operand:DI 2 "const_int_operand" "")))
17890 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17891 (clobber (reg:TI XMM6_REG))
17892 (clobber (reg:TI XMM7_REG))
17893 (clobber (reg:TI XMM8_REG))
17894 (clobber (reg:TI XMM9_REG))
17895 (clobber (reg:TI XMM10_REG))
17896 (clobber (reg:TI XMM11_REG))
17897 (clobber (reg:TI XMM12_REG))
17898 (clobber (reg:TI XMM13_REG))
17899 (clobber (reg:TI XMM14_REG))
17900 (clobber (reg:TI XMM15_REG))
17901 (clobber (reg:DI SI_REG))
17902 (clobber (reg:DI DI_REG))]
17903 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17905 if (SIBLING_CALL_P (insn))
17908 return "call\t%P1";
17910 [(set_attr "type" "callv")])
17912 (define_insn "*call_value_1"
17913 [(set (match_operand 0 "" "")
17914 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17915 (match_operand:SI 2 "" "")))]
17916 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17918 if (constant_call_address_operand (operands[1], Pmode))
17919 return "call\t%P1";
17920 return "call\t%A1";
17922 [(set_attr "type" "callv")])
17924 (define_insn "*sibcall_value_1"
17925 [(set (match_operand 0 "" "")
17926 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17927 (match_operand:SI 2 "" "")))]
17928 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17932 [(set_attr "type" "callv")])
17934 (define_insn "*call_value_1_rex64"
17935 [(set (match_operand 0 "" "")
17936 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17937 (match_operand:DI 2 "" "")))]
17938 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17939 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17941 if (constant_call_address_operand (operands[1], Pmode))
17942 return "call\t%P1";
17943 return "call\t%A1";
17945 [(set_attr "type" "callv")])
17947 (define_insn "*call_value_1_rex64_ms_sysv"
17948 [(set (match_operand 0 "" "")
17949 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17950 (match_operand:DI 2 "" "")))
17951 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17952 (clobber (reg:TI XMM6_REG))
17953 (clobber (reg:TI XMM7_REG))
17954 (clobber (reg:TI XMM8_REG))
17955 (clobber (reg:TI XMM9_REG))
17956 (clobber (reg:TI XMM10_REG))
17957 (clobber (reg:TI XMM11_REG))
17958 (clobber (reg:TI XMM12_REG))
17959 (clobber (reg:TI XMM13_REG))
17960 (clobber (reg:TI XMM14_REG))
17961 (clobber (reg:TI XMM15_REG))
17962 (clobber (reg:DI SI_REG))
17963 (clobber (reg:DI DI_REG))]
17964 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17966 if (constant_call_address_operand (operands[1], Pmode))
17967 return "call\t%P1";
17968 return "call\t%A1";
17970 [(set_attr "type" "callv")])
17972 (define_insn "*call_value_1_rex64_large"
17973 [(set (match_operand 0 "" "")
17974 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17975 (match_operand:DI 2 "" "")))]
17976 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17978 [(set_attr "type" "callv")])
17980 (define_insn "*sibcall_value_1_rex64"
17981 [(set (match_operand 0 "" "")
17982 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17983 (match_operand:DI 2 "" "")))]
17984 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17988 [(set_attr "type" "callv")])
17990 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17991 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17992 ;; caught for use by garbage collectors and the like. Using an insn that
17993 ;; maps to SIGILL makes it more likely the program will rightfully die.
17994 ;; Keeping with tradition, "6" is in honor of #UD.
17995 (define_insn "trap"
17996 [(trap_if (const_int 1) (const_int 6))]
17998 { return ASM_SHORT "0x0b0f"; }
17999 [(set_attr "length" "2")])
18001 (define_expand "sse_prologue_save"
18002 [(parallel [(set (match_operand:BLK 0 "" "")
18003 (unspec:BLK [(reg:DI XMM0_REG)
18010 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18011 (clobber (reg:CC FLAGS_REG))
18012 (clobber (match_operand:DI 1 "register_operand" ""))
18013 (use (match_operand:DI 2 "immediate_operand" ""))
18014 (use (label_ref:DI (match_operand 3 "" "")))
18015 (clobber (match_operand:DI 4 "register_operand" ""))
18016 (use (match_dup 1))])]
18020 ;; Pre-reload version of prologue save. Until after prologue generation we don't know
18021 ;; what the size of save instruction will be.
18022 ;; Operand 0+operand 6 is the memory save area
18023 ;; Operand 1 is number of registers to save (will get overwritten to operand 5)
18024 ;; Operand 2 is number of non-vaargs SSE arguments
18025 ;; Operand 3 is label starting the save block
18026 ;; Operand 4 is used for temporary computation of jump address
18027 (define_insn "*sse_prologue_save_insn1"
18028 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18029 (match_operand:DI 6 "const_int_operand" "n")))
18030 (unspec:BLK [(reg:DI XMM0_REG)
18037 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18038 (clobber (reg:CC FLAGS_REG))
18039 (clobber (match_operand:DI 1 "register_operand" "=r"))
18040 (use (match_operand:DI 2 "const_int_operand" "i"))
18041 (use (label_ref:DI (match_operand 3 "" "X")))
18042 (clobber (match_operand:DI 4 "register_operand" "=&r"))
18043 (use (match_operand:DI 5 "register_operand" "1"))]
18045 && INTVAL (operands[6]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18046 && INTVAL (operands[6]) + INTVAL (operands[2]) * 16 >= -128"
18048 [(set_attr "type" "other")
18049 (set_attr "memory" "store")
18050 (set_attr "mode" "DI")])
18052 ;; We know size of save instruction; expand the computation of jump address
18053 ;; in the jumptable.
18055 [(parallel [(set (match_operand:BLK 0 "" "")
18056 (unspec:BLK [(reg:DI XMM0_REG)
18063 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18064 (clobber (reg:CC FLAGS_REG))
18065 (clobber (match_operand:DI 1 "register_operand" ""))
18066 (use (match_operand:DI 2 "const_int_operand" ""))
18067 (use (match_operand 3 "" ""))
18068 (clobber (match_operand:DI 4 "register_operand" ""))
18069 (use (match_operand:DI 5 "register_operand" ""))])]
18071 [(parallel [(set (match_dup 0)
18072 (unspec:BLK [(reg:DI XMM0_REG)
18079 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
18080 (use (match_dup 1))
18081 (use (match_dup 2))
18082 (use (match_dup 3))
18083 (use (match_dup 5))])]
18085 /* Movaps is 4 bytes, AVX and movsd is 5 bytes. */
18086 int size = 4 + (TARGET_AVX || crtl->stack_alignment_needed < 128);
18088 /* Compute address to jump to:
18089 label - eax*size + nnamed_sse_arguments*size. */
18091 emit_insn (gen_rtx_SET (VOIDmode, operands[4],
18094 gen_rtx_MULT (Pmode, operands[1],
18097 else if (size == 4)
18098 emit_insn (gen_rtx_SET (VOIDmode, operands[4],
18099 gen_rtx_MULT (Pmode, operands[1],
18102 gcc_unreachable ();
18103 if (INTVAL (operands[2]))
18106 gen_rtx_CONST (DImode,
18107 gen_rtx_PLUS (DImode,
18109 GEN_INT (INTVAL (operands[2])
18112 emit_move_insn (operands[1], operands[3]);
18113 emit_insn (gen_subdi3 (operands[1], operands[1], operands[4]));
18114 operands[5] = GEN_INT (size);
18117 (define_insn "sse_prologue_save_insn"
18118 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18119 (match_operand:DI 4 "const_int_operand" "n")))
18120 (unspec:BLK [(reg:DI XMM0_REG)
18127 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
18128 (use (match_operand:DI 1 "register_operand" "r"))
18129 (use (match_operand:DI 2 "const_int_operand" "i"))
18130 (use (label_ref:DI (match_operand 3 "" "X")))
18131 (use (match_operand:DI 5 "const_int_operand" "i"))]
18133 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18134 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
18137 operands[0] = gen_rtx_MEM (Pmode,
18138 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
18139 /* VEX instruction with a REX prefix will #UD. */
18140 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
18141 gcc_unreachable ();
18143 output_asm_insn ("jmp\t%A1", operands);
18144 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
18146 operands[4] = adjust_address (operands[0], DImode, i*16);
18147 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
18148 PUT_MODE (operands[4], TImode);
18149 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
18150 output_asm_insn ("rex", operands);
18151 if (crtl->stack_alignment_needed < 128)
18152 output_asm_insn ("%vmovsd\t{%5, %4|%4, %5}", operands);
18154 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
18156 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18157 CODE_LABEL_NUMBER (operands[3]));
18160 [(set_attr "type" "other")
18161 (set_attr "length_immediate" "0")
18162 (set_attr "length_address" "0")
18163 ;; 2 bytes for jump and opernds[4] bytes for each save.
18164 (set (attr "length")
18165 (plus (const_int 2)
18166 (mult (symbol_ref ("INTVAL (operands[5])"))
18167 (symbol_ref ("X86_64_SSE_REGPARM_MAX - INTVAL (operands[2])")))))
18168 (set_attr "memory" "store")
18169 (set_attr "modrm" "0")
18170 (set_attr "prefix" "maybe_vex")
18171 (set_attr "mode" "DI")])
18173 (define_expand "prefetch"
18174 [(prefetch (match_operand 0 "address_operand" "")
18175 (match_operand:SI 1 "const_int_operand" "")
18176 (match_operand:SI 2 "const_int_operand" ""))]
18177 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
18179 int rw = INTVAL (operands[1]);
18180 int locality = INTVAL (operands[2]);
18182 gcc_assert (rw == 0 || rw == 1);
18183 gcc_assert (locality >= 0 && locality <= 3);
18184 gcc_assert (GET_MODE (operands[0]) == Pmode
18185 || GET_MODE (operands[0]) == VOIDmode);
18187 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18188 supported by SSE counterpart or the SSE prefetch is not available
18189 (K6 machines). Otherwise use SSE prefetch as it allows specifying
18191 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
18192 operands[2] = GEN_INT (3);
18194 operands[1] = const0_rtx;
18197 (define_insn "*prefetch_sse_<mode>"
18198 [(prefetch (match_operand:P 0 "address_operand" "p")
18200 (match_operand:SI 1 "const_int_operand" ""))]
18201 "TARGET_PREFETCH_SSE"
18203 static const char * const patterns[4] = {
18204 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18207 int locality = INTVAL (operands[1]);
18208 gcc_assert (locality >= 0 && locality <= 3);
18210 return patterns[locality];
18212 [(set_attr "type" "sse")
18213 (set_attr "atom_sse_attr" "prefetch")
18214 (set (attr "length_address")
18215 (symbol_ref "memory_address_length (operands[0])"))
18216 (set_attr "memory" "none")])
18218 (define_insn "*prefetch_3dnow_<mode>"
18219 [(prefetch (match_operand:P 0 "address_operand" "p")
18220 (match_operand:SI 1 "const_int_operand" "n")
18224 if (INTVAL (operands[1]) == 0)
18225 return "prefetch\t%a0";
18227 return "prefetchw\t%a0";
18229 [(set_attr "type" "mmx")
18230 (set (attr "length_address")
18231 (symbol_ref "memory_address_length (operands[0])"))
18232 (set_attr "memory" "none")])
18234 (define_expand "stack_protect_set"
18235 [(match_operand 0 "memory_operand" "")
18236 (match_operand 1 "memory_operand" "")]
18239 #ifdef TARGET_THREAD_SSP_OFFSET
18241 emit_insn (gen_stack_tls_protect_set_di (operands[0],
18242 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18244 emit_insn (gen_stack_tls_protect_set_si (operands[0],
18245 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18248 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
18250 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
18255 (define_insn "stack_protect_set_si"
18256 [(set (match_operand:SI 0 "memory_operand" "=m")
18257 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18258 (set (match_scratch:SI 2 "=&r") (const_int 0))
18259 (clobber (reg:CC FLAGS_REG))]
18261 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18262 [(set_attr "type" "multi")])
18264 (define_insn "stack_protect_set_di"
18265 [(set (match_operand:DI 0 "memory_operand" "=m")
18266 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18267 (set (match_scratch:DI 2 "=&r") (const_int 0))
18268 (clobber (reg:CC FLAGS_REG))]
18270 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18271 [(set_attr "type" "multi")])
18273 (define_insn "stack_tls_protect_set_si"
18274 [(set (match_operand:SI 0 "memory_operand" "=m")
18275 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")]
18276 UNSPEC_SP_TLS_SET))
18277 (set (match_scratch:SI 2 "=&r") (const_int 0))
18278 (clobber (reg:CC FLAGS_REG))]
18280 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18281 [(set_attr "type" "multi")])
18283 (define_insn "stack_tls_protect_set_di"
18284 [(set (match_operand:DI 0 "memory_operand" "=m")
18285 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")]
18286 UNSPEC_SP_TLS_SET))
18287 (set (match_scratch:DI 2 "=&r") (const_int 0))
18288 (clobber (reg:CC FLAGS_REG))]
18291 /* The kernel uses a different segment register for performance reasons; a
18292 system call would not have to trash the userspace segment register,
18293 which would be expensive */
18294 if (ix86_cmodel != CM_KERNEL)
18295 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18297 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18299 [(set_attr "type" "multi")])
18301 (define_expand "stack_protect_test"
18302 [(match_operand 0 "memory_operand" "")
18303 (match_operand 1 "memory_operand" "")
18304 (match_operand 2 "" "")]
18307 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18309 #ifdef TARGET_THREAD_SSP_OFFSET
18311 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18312 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18314 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18315 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18318 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18320 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18323 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18324 flags, const0_rtx, operands[2]));
18328 (define_insn "stack_protect_test_si"
18329 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18330 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18331 (match_operand:SI 2 "memory_operand" "m")]
18333 (clobber (match_scratch:SI 3 "=&r"))]
18335 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
18336 [(set_attr "type" "multi")])
18338 (define_insn "stack_protect_test_di"
18339 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18340 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18341 (match_operand:DI 2 "memory_operand" "m")]
18343 (clobber (match_scratch:DI 3 "=&r"))]
18345 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18346 [(set_attr "type" "multi")])
18348 (define_insn "stack_tls_protect_test_si"
18349 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18350 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18351 (match_operand:SI 2 "const_int_operand" "i")]
18352 UNSPEC_SP_TLS_TEST))
18353 (clobber (match_scratch:SI 3 "=r"))]
18355 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18356 [(set_attr "type" "multi")])
18358 (define_insn "stack_tls_protect_test_di"
18359 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18360 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18361 (match_operand:DI 2 "const_int_operand" "i")]
18362 UNSPEC_SP_TLS_TEST))
18363 (clobber (match_scratch:DI 3 "=r"))]
18366 /* The kernel uses a different segment register for performance reasons; a
18367 system call would not have to trash the userspace segment register,
18368 which would be expensive */
18369 if (ix86_cmodel != CM_KERNEL)
18370 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18372 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18374 [(set_attr "type" "multi")])
18376 (define_insn "sse4_2_crc32<mode>"
18377 [(set (match_operand:SI 0 "register_operand" "=r")
18379 [(match_operand:SI 1 "register_operand" "0")
18380 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18382 "TARGET_SSE4_2 || TARGET_CRC32"
18383 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18384 [(set_attr "type" "sselog1")
18385 (set_attr "prefix_rep" "1")
18386 (set_attr "prefix_extra" "1")
18387 (set (attr "prefix_data16")
18388 (if_then_else (match_operand:HI 2 "" "")
18390 (const_string "*")))
18391 (set (attr "prefix_rex")
18392 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18394 (const_string "*")))
18395 (set_attr "mode" "SI")])
18397 (define_insn "sse4_2_crc32di"
18398 [(set (match_operand:DI 0 "register_operand" "=r")
18400 [(match_operand:DI 1 "register_operand" "0")
18401 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18403 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18404 "crc32{q}\t{%2, %0|%0, %2}"
18405 [(set_attr "type" "sselog1")
18406 (set_attr "prefix_rep" "1")
18407 (set_attr "prefix_extra" "1")
18408 (set_attr "mode" "DI")])
18410 (define_expand "rdpmc"
18411 [(match_operand:DI 0 "register_operand" "")
18412 (match_operand:SI 1 "register_operand" "")]
18415 rtx reg = gen_reg_rtx (DImode);
18418 /* Force operand 1 into ECX. */
18419 rtx ecx = gen_rtx_REG (SImode, CX_REG);
18420 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18421 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18426 rtvec vec = rtvec_alloc (2);
18427 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18428 rtx upper = gen_reg_rtx (DImode);
18429 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18430 gen_rtvec (1, const0_rtx),
18432 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18433 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18435 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18436 NULL, 1, OPTAB_DIRECT);
18437 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18441 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18442 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18446 (define_insn "*rdpmc"
18447 [(set (match_operand:DI 0 "register_operand" "=A")
18448 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18452 [(set_attr "type" "other")
18453 (set_attr "length" "2")])
18455 (define_insn "*rdpmc_rex64"
18456 [(set (match_operand:DI 0 "register_operand" "=a")
18457 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18459 (set (match_operand:DI 1 "register_operand" "=d")
18460 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18463 [(set_attr "type" "other")
18464 (set_attr "length" "2")])
18466 (define_expand "rdtsc"
18467 [(set (match_operand:DI 0 "register_operand" "")
18468 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18473 rtvec vec = rtvec_alloc (2);
18474 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18475 rtx upper = gen_reg_rtx (DImode);
18476 rtx lower = gen_reg_rtx (DImode);
18477 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18478 gen_rtvec (1, const0_rtx),
18480 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18481 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18483 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18484 NULL, 1, OPTAB_DIRECT);
18485 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18487 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18492 (define_insn "*rdtsc"
18493 [(set (match_operand:DI 0 "register_operand" "=A")
18494 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18497 [(set_attr "type" "other")
18498 (set_attr "length" "2")])
18500 (define_insn "*rdtsc_rex64"
18501 [(set (match_operand:DI 0 "register_operand" "=a")
18502 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18503 (set (match_operand:DI 1 "register_operand" "=d")
18504 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18507 [(set_attr "type" "other")
18508 (set_attr "length" "2")])
18510 (define_expand "rdtscp"
18511 [(match_operand:DI 0 "register_operand" "")
18512 (match_operand:SI 1 "memory_operand" "")]
18515 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18516 gen_rtvec (1, const0_rtx),
18518 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18519 gen_rtvec (1, const0_rtx),
18521 rtx reg = gen_reg_rtx (DImode);
18522 rtx tmp = gen_reg_rtx (SImode);
18526 rtvec vec = rtvec_alloc (3);
18527 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18528 rtx upper = gen_reg_rtx (DImode);
18529 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18530 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18531 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18533 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18534 NULL, 1, OPTAB_DIRECT);
18535 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18540 rtvec vec = rtvec_alloc (2);
18541 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18542 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18543 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18546 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18547 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18551 (define_insn "*rdtscp"
18552 [(set (match_operand:DI 0 "register_operand" "=A")
18553 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18554 (set (match_operand:SI 1 "register_operand" "=c")
18555 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18558 [(set_attr "type" "other")
18559 (set_attr "length" "3")])
18561 (define_insn "*rdtscp_rex64"
18562 [(set (match_operand:DI 0 "register_operand" "=a")
18563 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18564 (set (match_operand:DI 1 "register_operand" "=d")
18565 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18566 (set (match_operand:SI 2 "register_operand" "=c")
18567 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18570 [(set_attr "type" "other")
18571 (set_attr "length" "3")])
18573 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18575 ;; LWP instructions
18577 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18579 (define_expand "lwp_llwpcb"
18580 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18581 UNSPECV_LLWP_INTRINSIC)]
18585 (define_insn "*lwp_llwpcb<mode>1"
18586 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18587 UNSPECV_LLWP_INTRINSIC)]
18590 [(set_attr "type" "lwp")
18591 (set_attr "mode" "<MODE>")
18592 (set_attr "length" "5")])
18594 (define_expand "lwp_slwpcb"
18595 [(set (match_operand 0 "register_operand" "=r")
18596 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18600 emit_insn (gen_lwp_slwpcbdi (operands[0]));
18602 emit_insn (gen_lwp_slwpcbsi (operands[0]));
18606 (define_insn "lwp_slwpcb<mode>"
18607 [(set (match_operand:P 0 "register_operand" "=r")
18608 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18611 [(set_attr "type" "lwp")
18612 (set_attr "mode" "<MODE>")
18613 (set_attr "length" "5")])
18615 (define_expand "lwp_lwpval<mode>3"
18616 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18617 (match_operand:SI 2 "nonimmediate_operand" "rm")
18618 (match_operand:SI 3 "const_int_operand" "i")]
18619 UNSPECV_LWPVAL_INTRINSIC)]
18621 "/* Avoid unused variable warning. */
18624 (define_insn "*lwp_lwpval<mode>3_1"
18625 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18626 (match_operand:SI 1 "nonimmediate_operand" "rm")
18627 (match_operand:SI 2 "const_int_operand" "i")]
18628 UNSPECV_LWPVAL_INTRINSIC)]
18630 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18631 [(set_attr "type" "lwp")
18632 (set_attr "mode" "<MODE>")
18633 (set (attr "length")
18634 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18636 (define_expand "lwp_lwpins<mode>3"
18637 [(set (reg:CCC FLAGS_REG)
18638 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18639 (match_operand:SI 2 "nonimmediate_operand" "rm")
18640 (match_operand:SI 3 "const_int_operand" "i")]
18641 UNSPECV_LWPINS_INTRINSIC))
18642 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18643 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18647 (define_insn "*lwp_lwpins<mode>3_1"
18648 [(set (reg:CCC FLAGS_REG)
18649 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18650 (match_operand:SI 1 "nonimmediate_operand" "rm")
18651 (match_operand:SI 2 "const_int_operand" "i")]
18652 UNSPECV_LWPINS_INTRINSIC))]
18654 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18655 [(set_attr "type" "lwp")
18656 (set_attr "mode" "<MODE>")
18657 (set (attr "length")
18658 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18662 (include "sync.md")