1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62 ;; @ -- print a segment register of thread base pointer load
66 (define_c_enum "unspec" [
67 ;; Relocation specifiers
78 UNSPEC_MACHOPIC_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
96 ;; Other random patterns
105 UNSPEC_LD_MPIC ; load_macho_picbase
107 UNSPEC_DIV_ALREADY_SPLIT
109 ;; For SSE/MMX support:
127 UNSPEC_MS_TO_SYSV_CALL
129 ;; Generic math support
131 UNSPEC_IEEE_MIN ; not commutative
132 UNSPEC_IEEE_MAX ; not commutative
134 ;; x87 Floating point
150 UNSPEC_FRNDINT_MASK_PM
154 ;; x87 Double output FP
186 ;; For SSE4.1 support
196 ;; For SSE4.2 support
203 UNSPEC_XOP_UNSIGNED_CMP
214 UNSPEC_AESKEYGENASSIST
216 ;; For PCLMUL support
232 (define_c_enum "unspecv" [
235 UNSPECV_PROBE_STACK_RANGE
255 UNSPECV_LLWP_INTRINSIC
256 UNSPECV_SLWP_INTRINSIC
257 UNSPECV_LWPVAL_INTRINSIC
258 UNSPECV_LWPINS_INTRINSIC
264 UNSPECV_SPLIT_STACK_RETURN
267 ;; Constants to represent pcomtrue/pcomfalse variants
277 ;; Constants used in the XOP pperm instruction
279 [(PPERM_SRC 0x00) /* copy source */
280 (PPERM_INVERT 0x20) /* invert source */
281 (PPERM_REVERSE 0x40) /* bit reverse source */
282 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
283 (PPERM_ZERO 0x80) /* all 0's */
284 (PPERM_ONES 0xa0) /* all 1's */
285 (PPERM_SIGN 0xc0) /* propagate sign bit */
286 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
287 (PPERM_SRC1 0x00) /* use first source byte */
288 (PPERM_SRC2 0x10) /* use second source byte */
291 ;; Registers by name.
344 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
347 ;; In C guard expressions, put expressions which may be compile-time
348 ;; constants first. This allows for better optimization. For
349 ;; example, write "TARGET_64BIT && reload_completed", not
350 ;; "reload_completed && TARGET_64BIT".
354 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
355 generic64,amdfam10,bdver1"
356 (const (symbol_ref "ix86_schedule")))
358 ;; A basic instruction type. Refinements due to arguments to be
359 ;; provided in other attributes.
362 alu,alu1,negnot,imov,imovx,lea,
363 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
364 icmp,test,ibr,setcc,icmov,
365 push,pop,call,callv,leave,
367 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
368 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
369 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
370 ssemuladd,sse4arg,lwp,
371 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
372 (const_string "other"))
374 ;; Main data type used by the insn
376 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
377 (const_string "unknown"))
379 ;; The CPU unit operations uses.
380 (define_attr "unit" "integer,i387,sse,mmx,unknown"
381 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
382 (const_string "i387")
383 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
384 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
385 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
387 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
389 (eq_attr "type" "other")
390 (const_string "unknown")]
391 (const_string "integer")))
393 ;; The (bounding maximum) length of an instruction immediate.
394 (define_attr "length_immediate" ""
395 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
398 (eq_attr "unit" "i387,sse,mmx")
400 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
402 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
403 (eq_attr "type" "imov,test")
404 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
405 (eq_attr "type" "call")
406 (if_then_else (match_operand 0 "constant_call_address_operand" "")
409 (eq_attr "type" "callv")
410 (if_then_else (match_operand 1 "constant_call_address_operand" "")
413 ;; We don't know the size before shorten_branches. Expect
414 ;; the instruction to fit for better scheduling.
415 (eq_attr "type" "ibr")
418 (symbol_ref "/* Update immediate_length and other attributes! */
419 gcc_unreachable (),1")))
421 ;; The (bounding maximum) length of an instruction address.
422 (define_attr "length_address" ""
423 (cond [(eq_attr "type" "str,other,multi,fxch")
425 (and (eq_attr "type" "call")
426 (match_operand 0 "constant_call_address_operand" ""))
428 (and (eq_attr "type" "callv")
429 (match_operand 1 "constant_call_address_operand" ""))
432 (symbol_ref "ix86_attr_length_address_default (insn)")))
434 ;; Set when length prefix is used.
435 (define_attr "prefix_data16" ""
436 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
438 (eq_attr "mode" "HI")
440 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
445 ;; Set when string REP prefix is used.
446 (define_attr "prefix_rep" ""
447 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
449 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
454 ;; Set when 0f opcode prefix is used.
455 (define_attr "prefix_0f" ""
457 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
458 (eq_attr "unit" "sse,mmx"))
462 ;; Set when REX opcode prefix is used.
463 (define_attr "prefix_rex" ""
464 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
466 (and (eq_attr "mode" "DI")
467 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
468 (eq_attr "unit" "!mmx")))
470 (and (eq_attr "mode" "QI")
471 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
474 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
477 (and (eq_attr "type" "imovx")
478 (match_operand:QI 1 "ext_QIreg_operand" ""))
483 ;; There are also additional prefixes in 3DNOW, SSSE3.
484 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
485 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
486 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
487 (define_attr "prefix_extra" ""
488 (cond [(eq_attr "type" "ssemuladd,sse4arg")
490 (eq_attr "type" "sseiadd1,ssecvt1")
495 ;; Prefix used: original, VEX or maybe VEX.
496 (define_attr "prefix" "orig,vex,maybe_vex"
497 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
499 (const_string "orig")))
501 ;; VEX W bit is used.
502 (define_attr "prefix_vex_w" "" (const_int 0))
504 ;; The length of VEX prefix
505 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
506 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
507 ;; still prefix_0f 1, with prefix_extra 1.
508 (define_attr "length_vex" ""
509 (if_then_else (and (eq_attr "prefix_0f" "1")
510 (eq_attr "prefix_extra" "0"))
511 (if_then_else (eq_attr "prefix_vex_w" "1")
512 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
513 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
514 (if_then_else (eq_attr "prefix_vex_w" "1")
515 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
516 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
518 ;; Set when modrm byte is used.
519 (define_attr "modrm" ""
520 (cond [(eq_attr "type" "str,leave")
522 (eq_attr "unit" "i387")
524 (and (eq_attr "type" "incdec")
525 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
526 (ior (match_operand:SI 1 "register_operand" "")
527 (match_operand:HI 1 "register_operand" ""))))
529 (and (eq_attr "type" "push")
530 (not (match_operand 1 "memory_operand" "")))
532 (and (eq_attr "type" "pop")
533 (not (match_operand 0 "memory_operand" "")))
535 (and (eq_attr "type" "imov")
536 (and (not (eq_attr "mode" "DI"))
537 (ior (and (match_operand 0 "register_operand" "")
538 (match_operand 1 "immediate_operand" ""))
539 (ior (and (match_operand 0 "ax_reg_operand" "")
540 (match_operand 1 "memory_displacement_only_operand" ""))
541 (and (match_operand 0 "memory_displacement_only_operand" "")
542 (match_operand 1 "ax_reg_operand" ""))))))
544 (and (eq_attr "type" "call")
545 (match_operand 0 "constant_call_address_operand" ""))
547 (and (eq_attr "type" "callv")
548 (match_operand 1 "constant_call_address_operand" ""))
550 (and (eq_attr "type" "alu,alu1,icmp,test")
551 (match_operand 0 "ax_reg_operand" ""))
552 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
556 ;; The (bounding maximum) length of an instruction in bytes.
557 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
558 ;; Later we may want to split them and compute proper length as for
560 (define_attr "length" ""
561 (cond [(eq_attr "type" "other,multi,fistp,frndint")
563 (eq_attr "type" "fcmp")
565 (eq_attr "unit" "i387")
567 (plus (attr "prefix_data16")
568 (attr "length_address")))
569 (ior (eq_attr "prefix" "vex")
570 (and (eq_attr "prefix" "maybe_vex")
571 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
572 (plus (attr "length_vex")
573 (plus (attr "length_immediate")
575 (attr "length_address"))))]
576 (plus (plus (attr "modrm")
577 (plus (attr "prefix_0f")
578 (plus (attr "prefix_rex")
579 (plus (attr "prefix_extra")
581 (plus (attr "prefix_rep")
582 (plus (attr "prefix_data16")
583 (plus (attr "length_immediate")
584 (attr "length_address")))))))
586 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
587 ;; `store' if there is a simple memory reference therein, or `unknown'
588 ;; if the instruction is complex.
590 (define_attr "memory" "none,load,store,both,unknown"
591 (cond [(eq_attr "type" "other,multi,str,lwp")
592 (const_string "unknown")
593 (eq_attr "type" "lea,fcmov,fpspc")
594 (const_string "none")
595 (eq_attr "type" "fistp,leave")
596 (const_string "both")
597 (eq_attr "type" "frndint")
598 (const_string "load")
599 (eq_attr "type" "push")
600 (if_then_else (match_operand 1 "memory_operand" "")
601 (const_string "both")
602 (const_string "store"))
603 (eq_attr "type" "pop")
604 (if_then_else (match_operand 0 "memory_operand" "")
605 (const_string "both")
606 (const_string "load"))
607 (eq_attr "type" "setcc")
608 (if_then_else (match_operand 0 "memory_operand" "")
609 (const_string "store")
610 (const_string "none"))
611 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
612 (if_then_else (ior (match_operand 0 "memory_operand" "")
613 (match_operand 1 "memory_operand" ""))
614 (const_string "load")
615 (const_string "none"))
616 (eq_attr "type" "ibr")
617 (if_then_else (match_operand 0 "memory_operand" "")
618 (const_string "load")
619 (const_string "none"))
620 (eq_attr "type" "call")
621 (if_then_else (match_operand 0 "constant_call_address_operand" "")
622 (const_string "none")
623 (const_string "load"))
624 (eq_attr "type" "callv")
625 (if_then_else (match_operand 1 "constant_call_address_operand" "")
626 (const_string "none")
627 (const_string "load"))
628 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
629 (match_operand 1 "memory_operand" ""))
630 (const_string "both")
631 (and (match_operand 0 "memory_operand" "")
632 (match_operand 1 "memory_operand" ""))
633 (const_string "both")
634 (match_operand 0 "memory_operand" "")
635 (const_string "store")
636 (match_operand 1 "memory_operand" "")
637 (const_string "load")
639 "!alu1,negnot,ishift1,
640 imov,imovx,icmp,test,bitmanip,
642 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
643 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
644 (match_operand 2 "memory_operand" ""))
645 (const_string "load")
646 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
647 (match_operand 3 "memory_operand" ""))
648 (const_string "load")
650 (const_string "none")))
652 ;; Indicates if an instruction has both an immediate and a displacement.
654 (define_attr "imm_disp" "false,true,unknown"
655 (cond [(eq_attr "type" "other,multi")
656 (const_string "unknown")
657 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
658 (and (match_operand 0 "memory_displacement_operand" "")
659 (match_operand 1 "immediate_operand" "")))
660 (const_string "true")
661 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
662 (and (match_operand 0 "memory_displacement_operand" "")
663 (match_operand 2 "immediate_operand" "")))
664 (const_string "true")
666 (const_string "false")))
668 ;; Indicates if an FP operation has an integer source.
670 (define_attr "fp_int_src" "false,true"
671 (const_string "false"))
673 ;; Defines rounding mode of an FP operation.
675 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
676 (const_string "any"))
678 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
679 (define_attr "use_carry" "0,1" (const_string "0"))
681 ;; Define attribute to indicate unaligned ssemov insns
682 (define_attr "movu" "0,1" (const_string "0"))
684 ;; Describe a user's asm statement.
685 (define_asm_attributes
686 [(set_attr "length" "128")
687 (set_attr "type" "multi")])
689 (define_code_iterator plusminus [plus minus])
691 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
693 ;; Base name for define_insn
694 (define_code_attr plusminus_insn
695 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
696 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
698 ;; Base name for insn mnemonic.
699 (define_code_attr plusminus_mnemonic
700 [(plus "add") (ss_plus "adds") (us_plus "addus")
701 (minus "sub") (ss_minus "subs") (us_minus "subus")])
702 (define_code_attr plusminus_carry_mnemonic
703 [(plus "adc") (minus "sbb")])
705 ;; Mark commutative operators as such in constraints.
706 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
707 (minus "") (ss_minus "") (us_minus "")])
709 ;; Mapping of signed max and min
710 (define_code_iterator smaxmin [smax smin])
712 ;; Mapping of unsigned max and min
713 (define_code_iterator umaxmin [umax umin])
715 ;; Base name for integer and FP insn mnemonic
716 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
717 (umax "maxu") (umin "minu")])
718 (define_code_attr maxmin_float [(smax "max") (smin "min")])
720 ;; Mapping of logic operators
721 (define_code_iterator any_logic [and ior xor])
722 (define_code_iterator any_or [ior xor])
724 ;; Base name for insn mnemonic.
725 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
727 ;; Mapping of shift-right operators
728 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
730 ;; Base name for define_insn
731 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
733 ;; Base name for insn mnemonic.
734 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
736 ;; Mapping of rotate operators
737 (define_code_iterator any_rotate [rotate rotatert])
739 ;; Base name for define_insn
740 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
742 ;; Base name for insn mnemonic.
743 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
745 ;; Mapping of abs neg operators
746 (define_code_iterator absneg [abs neg])
748 ;; Base name for x87 insn mnemonic.
749 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
751 ;; Used in signed and unsigned widening multiplications.
752 (define_code_iterator any_extend [sign_extend zero_extend])
754 ;; Various insn prefixes for signed and unsigned operations.
755 (define_code_attr u [(sign_extend "") (zero_extend "u")
756 (div "") (udiv "u")])
757 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
759 ;; Used in signed and unsigned divisions.
760 (define_code_iterator any_div [div udiv])
762 ;; Instruction prefix for signed and unsigned operations.
763 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
764 (div "i") (udiv "")])
766 ;; 64bit single word integer modes.
767 (define_mode_iterator SWI1248x [QI HI SI DI])
769 ;; 64bit single word integer modes without QImode and HImode.
770 (define_mode_iterator SWI48x [SI DI])
772 ;; Single word integer modes.
773 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
775 ;; Single word integer modes without SImode and DImode.
776 (define_mode_iterator SWI12 [QI HI])
778 ;; Single word integer modes without DImode.
779 (define_mode_iterator SWI124 [QI HI SI])
781 ;; Single word integer modes without QImode and DImode.
782 (define_mode_iterator SWI24 [HI SI])
784 ;; Single word integer modes without QImode.
785 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
787 ;; Single word integer modes without QImode and HImode.
788 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
790 ;; All math-dependant single and double word integer modes.
791 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
792 (HI "TARGET_HIMODE_MATH")
793 SI DI (TI "TARGET_64BIT")])
795 ;; Math-dependant single word integer modes.
796 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
797 (HI "TARGET_HIMODE_MATH")
798 SI (DI "TARGET_64BIT")])
800 ;; Math-dependant single word integer modes without DImode.
801 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
802 (HI "TARGET_HIMODE_MATH")
805 ;; Math-dependant single word integer modes without QImode.
806 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
807 SI (DI "TARGET_64BIT")])
809 ;; Double word integer modes.
810 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
811 (TI "TARGET_64BIT")])
813 ;; Double word integer modes as mode attribute.
814 (define_mode_attr DWI [(SI "DI") (DI "TI")])
815 (define_mode_attr dwi [(SI "di") (DI "ti")])
817 ;; Half mode for double word integer modes.
818 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
819 (DI "TARGET_64BIT")])
821 ;; Instruction suffix for integer modes.
822 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
824 ;; Pointer size prefix for integer modes (Intel asm dialect)
825 (define_mode_attr iptrsize [(QI "BYTE")
830 ;; Register class for integer modes.
831 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
833 ;; Immediate operand constraint for integer modes.
834 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
836 ;; General operand constraint for word modes.
837 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
839 ;; Immediate operand constraint for double integer modes.
840 (define_mode_attr di [(SI "iF") (DI "e")])
842 ;; Immediate operand constraint for shifts.
843 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
845 ;; General operand predicate for integer modes.
846 (define_mode_attr general_operand
847 [(QI "general_operand")
848 (HI "general_operand")
849 (SI "general_operand")
850 (DI "x86_64_general_operand")
851 (TI "x86_64_general_operand")])
853 ;; General sign/zero extend operand predicate for integer modes.
854 (define_mode_attr general_szext_operand
855 [(QI "general_operand")
856 (HI "general_operand")
857 (SI "general_operand")
858 (DI "x86_64_szext_general_operand")])
860 ;; Immediate operand predicate for integer modes.
861 (define_mode_attr immediate_operand
862 [(QI "immediate_operand")
863 (HI "immediate_operand")
864 (SI "immediate_operand")
865 (DI "x86_64_immediate_operand")])
867 ;; Nonmemory operand predicate for integer modes.
868 (define_mode_attr nonmemory_operand
869 [(QI "nonmemory_operand")
870 (HI "nonmemory_operand")
871 (SI "nonmemory_operand")
872 (DI "x86_64_nonmemory_operand")])
874 ;; Operand predicate for shifts.
875 (define_mode_attr shift_operand
876 [(QI "nonimmediate_operand")
877 (HI "nonimmediate_operand")
878 (SI "nonimmediate_operand")
879 (DI "shiftdi_operand")
880 (TI "register_operand")])
882 ;; Operand predicate for shift argument.
883 (define_mode_attr shift_immediate_operand
884 [(QI "const_1_to_31_operand")
885 (HI "const_1_to_31_operand")
886 (SI "const_1_to_31_operand")
887 (DI "const_1_to_63_operand")])
889 ;; Input operand predicate for arithmetic left shifts.
890 (define_mode_attr ashl_input_operand
891 [(QI "nonimmediate_operand")
892 (HI "nonimmediate_operand")
893 (SI "nonimmediate_operand")
894 (DI "ashldi_input_operand")
895 (TI "reg_or_pm1_operand")])
897 ;; SSE and x87 SFmode and DFmode floating point modes
898 (define_mode_iterator MODEF [SF DF])
900 ;; All x87 floating point modes
901 (define_mode_iterator X87MODEF [SF DF XF])
903 ;; All integer modes handled by x87 fisttp operator.
904 (define_mode_iterator X87MODEI [HI SI DI])
906 ;; All integer modes handled by integer x87 operators.
907 (define_mode_iterator X87MODEI12 [HI SI])
909 ;; All integer modes handled by SSE cvtts?2si* operators.
910 (define_mode_iterator SSEMODEI24 [SI DI])
912 ;; SSE asm suffix for floating point modes
913 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
915 ;; SSE vector mode corresponding to a scalar mode
916 (define_mode_attr ssevecmode
917 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
919 ;; Instruction suffix for REX 64bit operators.
920 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
922 ;; This mode iterator allows :P to be used for patterns that operate on
923 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
924 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
926 ;; Scheduling descriptions
928 (include "pentium.md")
931 (include "athlon.md")
932 (include "bdver1.md")
937 ;; Operand and operator predicates and constraints
939 (include "predicates.md")
940 (include "constraints.md")
943 ;; Compare and branch/compare and store instructions.
945 (define_expand "cbranch<mode>4"
946 [(set (reg:CC FLAGS_REG)
947 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
948 (match_operand:SDWIM 2 "<general_operand>" "")))
949 (set (pc) (if_then_else
950 (match_operator 0 "ordered_comparison_operator"
951 [(reg:CC FLAGS_REG) (const_int 0)])
952 (label_ref (match_operand 3 "" ""))
956 if (MEM_P (operands[1]) && MEM_P (operands[2]))
957 operands[1] = force_reg (<MODE>mode, operands[1]);
958 ix86_expand_branch (GET_CODE (operands[0]),
959 operands[1], operands[2], operands[3]);
963 (define_expand "cstore<mode>4"
964 [(set (reg:CC FLAGS_REG)
965 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
966 (match_operand:SWIM 3 "<general_operand>" "")))
967 (set (match_operand:QI 0 "register_operand" "")
968 (match_operator 1 "ordered_comparison_operator"
969 [(reg:CC FLAGS_REG) (const_int 0)]))]
972 if (MEM_P (operands[2]) && MEM_P (operands[3]))
973 operands[2] = force_reg (<MODE>mode, operands[2]);
974 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
975 operands[2], operands[3]);
979 (define_expand "cmp<mode>_1"
980 [(set (reg:CC FLAGS_REG)
981 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
982 (match_operand:SWI48 1 "<general_operand>" "")))])
984 (define_insn "*cmp<mode>_ccno_1"
985 [(set (reg FLAGS_REG)
986 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
987 (match_operand:SWI 1 "const0_operand" "")))]
988 "ix86_match_ccmode (insn, CCNOmode)"
990 test{<imodesuffix>}\t%0, %0
991 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
992 [(set_attr "type" "test,icmp")
993 (set_attr "length_immediate" "0,1")
994 (set_attr "mode" "<MODE>")])
996 (define_insn "*cmp<mode>_1"
997 [(set (reg FLAGS_REG)
998 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
999 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1000 "ix86_match_ccmode (insn, CCmode)"
1001 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1002 [(set_attr "type" "icmp")
1003 (set_attr "mode" "<MODE>")])
1005 (define_insn "*cmp<mode>_minus_1"
1006 [(set (reg FLAGS_REG)
1008 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1009 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1011 "ix86_match_ccmode (insn, CCGOCmode)"
1012 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1013 [(set_attr "type" "icmp")
1014 (set_attr "mode" "<MODE>")])
1016 (define_insn "*cmpqi_ext_1"
1017 [(set (reg FLAGS_REG)
1019 (match_operand:QI 0 "general_operand" "Qm")
1022 (match_operand 1 "ext_register_operand" "Q")
1024 (const_int 8)) 0)))]
1025 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1026 "cmp{b}\t{%h1, %0|%0, %h1}"
1027 [(set_attr "type" "icmp")
1028 (set_attr "mode" "QI")])
1030 (define_insn "*cmpqi_ext_1_rex64"
1031 [(set (reg FLAGS_REG)
1033 (match_operand:QI 0 "register_operand" "Q")
1036 (match_operand 1 "ext_register_operand" "Q")
1038 (const_int 8)) 0)))]
1039 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1040 "cmp{b}\t{%h1, %0|%0, %h1}"
1041 [(set_attr "type" "icmp")
1042 (set_attr "mode" "QI")])
1044 (define_insn "*cmpqi_ext_2"
1045 [(set (reg FLAGS_REG)
1049 (match_operand 0 "ext_register_operand" "Q")
1052 (match_operand:QI 1 "const0_operand" "")))]
1053 "ix86_match_ccmode (insn, CCNOmode)"
1055 [(set_attr "type" "test")
1056 (set_attr "length_immediate" "0")
1057 (set_attr "mode" "QI")])
1059 (define_expand "cmpqi_ext_3"
1060 [(set (reg:CC FLAGS_REG)
1064 (match_operand 0 "ext_register_operand" "")
1067 (match_operand:QI 1 "immediate_operand" "")))])
1069 (define_insn "*cmpqi_ext_3_insn"
1070 [(set (reg FLAGS_REG)
1074 (match_operand 0 "ext_register_operand" "Q")
1077 (match_operand:QI 1 "general_operand" "Qmn")))]
1078 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1079 "cmp{b}\t{%1, %h0|%h0, %1}"
1080 [(set_attr "type" "icmp")
1081 (set_attr "modrm" "1")
1082 (set_attr "mode" "QI")])
1084 (define_insn "*cmpqi_ext_3_insn_rex64"
1085 [(set (reg FLAGS_REG)
1089 (match_operand 0 "ext_register_operand" "Q")
1092 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1093 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1094 "cmp{b}\t{%1, %h0|%h0, %1}"
1095 [(set_attr "type" "icmp")
1096 (set_attr "modrm" "1")
1097 (set_attr "mode" "QI")])
1099 (define_insn "*cmpqi_ext_4"
1100 [(set (reg FLAGS_REG)
1104 (match_operand 0 "ext_register_operand" "Q")
1109 (match_operand 1 "ext_register_operand" "Q")
1111 (const_int 8)) 0)))]
1112 "ix86_match_ccmode (insn, CCmode)"
1113 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1114 [(set_attr "type" "icmp")
1115 (set_attr "mode" "QI")])
1117 ;; These implement float point compares.
1118 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1119 ;; which would allow mix and match FP modes on the compares. Which is what
1120 ;; the old patterns did, but with many more of them.
1122 (define_expand "cbranchxf4"
1123 [(set (reg:CC FLAGS_REG)
1124 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1125 (match_operand:XF 2 "nonmemory_operand" "")))
1126 (set (pc) (if_then_else
1127 (match_operator 0 "ix86_fp_comparison_operator"
1130 (label_ref (match_operand 3 "" ""))
1134 ix86_expand_branch (GET_CODE (operands[0]),
1135 operands[1], operands[2], operands[3]);
1139 (define_expand "cstorexf4"
1140 [(set (reg:CC FLAGS_REG)
1141 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1142 (match_operand:XF 3 "nonmemory_operand" "")))
1143 (set (match_operand:QI 0 "register_operand" "")
1144 (match_operator 1 "ix86_fp_comparison_operator"
1149 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1150 operands[2], operands[3]);
1154 (define_expand "cbranch<mode>4"
1155 [(set (reg:CC FLAGS_REG)
1156 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1157 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1158 (set (pc) (if_then_else
1159 (match_operator 0 "ix86_fp_comparison_operator"
1162 (label_ref (match_operand 3 "" ""))
1164 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1166 ix86_expand_branch (GET_CODE (operands[0]),
1167 operands[1], operands[2], operands[3]);
1171 (define_expand "cstore<mode>4"
1172 [(set (reg:CC FLAGS_REG)
1173 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1174 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1175 (set (match_operand:QI 0 "register_operand" "")
1176 (match_operator 1 "ix86_fp_comparison_operator"
1179 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1181 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1182 operands[2], operands[3]);
1186 (define_expand "cbranchcc4"
1187 [(set (pc) (if_then_else
1188 (match_operator 0 "comparison_operator"
1189 [(match_operand 1 "flags_reg_operand" "")
1190 (match_operand 2 "const0_operand" "")])
1191 (label_ref (match_operand 3 "" ""))
1195 ix86_expand_branch (GET_CODE (operands[0]),
1196 operands[1], operands[2], operands[3]);
1200 (define_expand "cstorecc4"
1201 [(set (match_operand:QI 0 "register_operand" "")
1202 (match_operator 1 "comparison_operator"
1203 [(match_operand 2 "flags_reg_operand" "")
1204 (match_operand 3 "const0_operand" "")]))]
1207 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1208 operands[2], operands[3]);
1213 ;; FP compares, step 1:
1214 ;; Set the FP condition codes.
1216 ;; CCFPmode compare with exceptions
1217 ;; CCFPUmode compare with no exceptions
1219 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1220 ;; used to manage the reg stack popping would not be preserved.
1222 (define_insn "*cmpfp_0"
1223 [(set (match_operand:HI 0 "register_operand" "=a")
1226 (match_operand 1 "register_operand" "f")
1227 (match_operand 2 "const0_operand" ""))]
1229 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1230 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1231 "* return output_fp_compare (insn, operands, 0, 0);"
1232 [(set_attr "type" "multi")
1233 (set_attr "unit" "i387")
1235 (cond [(match_operand:SF 1 "" "")
1237 (match_operand:DF 1 "" "")
1240 (const_string "XF")))])
1242 (define_insn_and_split "*cmpfp_0_cc"
1243 [(set (reg:CCFP FLAGS_REG)
1245 (match_operand 1 "register_operand" "f")
1246 (match_operand 2 "const0_operand" "")))
1247 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1248 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1249 && TARGET_SAHF && !TARGET_CMOVE
1250 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1252 "&& reload_completed"
1255 [(compare:CCFP (match_dup 1)(match_dup 2))]
1257 (set (reg:CC FLAGS_REG)
1258 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1260 [(set_attr "type" "multi")
1261 (set_attr "unit" "i387")
1263 (cond [(match_operand:SF 1 "" "")
1265 (match_operand:DF 1 "" "")
1268 (const_string "XF")))])
1270 (define_insn "*cmpfp_xf"
1271 [(set (match_operand:HI 0 "register_operand" "=a")
1274 (match_operand:XF 1 "register_operand" "f")
1275 (match_operand:XF 2 "register_operand" "f"))]
1278 "* return output_fp_compare (insn, operands, 0, 0);"
1279 [(set_attr "type" "multi")
1280 (set_attr "unit" "i387")
1281 (set_attr "mode" "XF")])
1283 (define_insn_and_split "*cmpfp_xf_cc"
1284 [(set (reg:CCFP FLAGS_REG)
1286 (match_operand:XF 1 "register_operand" "f")
1287 (match_operand:XF 2 "register_operand" "f")))
1288 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1290 && TARGET_SAHF && !TARGET_CMOVE"
1292 "&& reload_completed"
1295 [(compare:CCFP (match_dup 1)(match_dup 2))]
1297 (set (reg:CC FLAGS_REG)
1298 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1300 [(set_attr "type" "multi")
1301 (set_attr "unit" "i387")
1302 (set_attr "mode" "XF")])
1304 (define_insn "*cmpfp_<mode>"
1305 [(set (match_operand:HI 0 "register_operand" "=a")
1308 (match_operand:MODEF 1 "register_operand" "f")
1309 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1312 "* return output_fp_compare (insn, operands, 0, 0);"
1313 [(set_attr "type" "multi")
1314 (set_attr "unit" "i387")
1315 (set_attr "mode" "<MODE>")])
1317 (define_insn_and_split "*cmpfp_<mode>_cc"
1318 [(set (reg:CCFP FLAGS_REG)
1320 (match_operand:MODEF 1 "register_operand" "f")
1321 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1322 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1324 && TARGET_SAHF && !TARGET_CMOVE"
1326 "&& reload_completed"
1329 [(compare:CCFP (match_dup 1)(match_dup 2))]
1331 (set (reg:CC FLAGS_REG)
1332 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1334 [(set_attr "type" "multi")
1335 (set_attr "unit" "i387")
1336 (set_attr "mode" "<MODE>")])
1338 (define_insn "*cmpfp_u"
1339 [(set (match_operand:HI 0 "register_operand" "=a")
1342 (match_operand 1 "register_operand" "f")
1343 (match_operand 2 "register_operand" "f"))]
1345 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1346 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1347 "* return output_fp_compare (insn, operands, 0, 1);"
1348 [(set_attr "type" "multi")
1349 (set_attr "unit" "i387")
1351 (cond [(match_operand:SF 1 "" "")
1353 (match_operand:DF 1 "" "")
1356 (const_string "XF")))])
1358 (define_insn_and_split "*cmpfp_u_cc"
1359 [(set (reg:CCFPU FLAGS_REG)
1361 (match_operand 1 "register_operand" "f")
1362 (match_operand 2 "register_operand" "f")))
1363 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1364 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1365 && TARGET_SAHF && !TARGET_CMOVE
1366 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1368 "&& reload_completed"
1371 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1373 (set (reg:CC FLAGS_REG)
1374 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1376 [(set_attr "type" "multi")
1377 (set_attr "unit" "i387")
1379 (cond [(match_operand:SF 1 "" "")
1381 (match_operand:DF 1 "" "")
1384 (const_string "XF")))])
1386 (define_insn "*cmpfp_<mode>"
1387 [(set (match_operand:HI 0 "register_operand" "=a")
1390 (match_operand 1 "register_operand" "f")
1391 (match_operator 3 "float_operator"
1392 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1394 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1395 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1396 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1397 "* return output_fp_compare (insn, operands, 0, 0);"
1398 [(set_attr "type" "multi")
1399 (set_attr "unit" "i387")
1400 (set_attr "fp_int_src" "true")
1401 (set_attr "mode" "<MODE>")])
1403 (define_insn_and_split "*cmpfp_<mode>_cc"
1404 [(set (reg:CCFP FLAGS_REG)
1406 (match_operand 1 "register_operand" "f")
1407 (match_operator 3 "float_operator"
1408 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1409 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1410 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1411 && TARGET_SAHF && !TARGET_CMOVE
1412 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1413 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1415 "&& reload_completed"
1420 (match_op_dup 3 [(match_dup 2)]))]
1422 (set (reg:CC FLAGS_REG)
1423 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1425 [(set_attr "type" "multi")
1426 (set_attr "unit" "i387")
1427 (set_attr "fp_int_src" "true")
1428 (set_attr "mode" "<MODE>")])
1430 ;; FP compares, step 2
1431 ;; Move the fpsw to ax.
1433 (define_insn "x86_fnstsw_1"
1434 [(set (match_operand:HI 0 "register_operand" "=a")
1435 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1438 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1439 (set_attr "mode" "SI")
1440 (set_attr "unit" "i387")])
1442 ;; FP compares, step 3
1443 ;; Get ax into flags, general case.
1445 (define_insn "x86_sahf_1"
1446 [(set (reg:CC FLAGS_REG)
1447 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1451 #ifndef HAVE_AS_IX86_SAHF
1453 return ASM_BYTE "0x9e";
1458 [(set_attr "length" "1")
1459 (set_attr "athlon_decode" "vector")
1460 (set_attr "amdfam10_decode" "direct")
1461 (set_attr "bdver1_decode" "direct")
1462 (set_attr "mode" "SI")])
1464 ;; Pentium Pro can do steps 1 through 3 in one go.
1465 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1466 (define_insn "*cmpfp_i_mixed"
1467 [(set (reg:CCFP FLAGS_REG)
1468 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1469 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1470 "TARGET_MIX_SSE_I387
1471 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1472 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1473 "* return output_fp_compare (insn, operands, 1, 0);"
1474 [(set_attr "type" "fcmp,ssecomi")
1475 (set_attr "prefix" "orig,maybe_vex")
1477 (if_then_else (match_operand:SF 1 "" "")
1479 (const_string "DF")))
1480 (set (attr "prefix_rep")
1481 (if_then_else (eq_attr "type" "ssecomi")
1483 (const_string "*")))
1484 (set (attr "prefix_data16")
1485 (cond [(eq_attr "type" "fcmp")
1487 (eq_attr "mode" "DF")
1490 (const_string "0")))
1491 (set_attr "athlon_decode" "vector")
1492 (set_attr "amdfam10_decode" "direct")
1493 (set_attr "bdver1_decode" "double")])
1495 (define_insn "*cmpfp_i_sse"
1496 [(set (reg:CCFP FLAGS_REG)
1497 (compare:CCFP (match_operand 0 "register_operand" "x")
1498 (match_operand 1 "nonimmediate_operand" "xm")))]
1500 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1501 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1502 "* return output_fp_compare (insn, operands, 1, 0);"
1503 [(set_attr "type" "ssecomi")
1504 (set_attr "prefix" "maybe_vex")
1506 (if_then_else (match_operand:SF 1 "" "")
1508 (const_string "DF")))
1509 (set_attr "prefix_rep" "0")
1510 (set (attr "prefix_data16")
1511 (if_then_else (eq_attr "mode" "DF")
1513 (const_string "0")))
1514 (set_attr "athlon_decode" "vector")
1515 (set_attr "amdfam10_decode" "direct")
1516 (set_attr "bdver1_decode" "double")])
1518 (define_insn "*cmpfp_i_i387"
1519 [(set (reg:CCFP FLAGS_REG)
1520 (compare:CCFP (match_operand 0 "register_operand" "f")
1521 (match_operand 1 "register_operand" "f")))]
1522 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1524 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1525 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1526 "* return output_fp_compare (insn, operands, 1, 0);"
1527 [(set_attr "type" "fcmp")
1529 (cond [(match_operand:SF 1 "" "")
1531 (match_operand:DF 1 "" "")
1534 (const_string "XF")))
1535 (set_attr "athlon_decode" "vector")
1536 (set_attr "amdfam10_decode" "direct")
1537 (set_attr "bdver1_decode" "double")])
1539 (define_insn "*cmpfp_iu_mixed"
1540 [(set (reg:CCFPU FLAGS_REG)
1541 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1542 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1543 "TARGET_MIX_SSE_I387
1544 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1545 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1546 "* return output_fp_compare (insn, operands, 1, 1);"
1547 [(set_attr "type" "fcmp,ssecomi")
1548 (set_attr "prefix" "orig,maybe_vex")
1550 (if_then_else (match_operand:SF 1 "" "")
1552 (const_string "DF")))
1553 (set (attr "prefix_rep")
1554 (if_then_else (eq_attr "type" "ssecomi")
1556 (const_string "*")))
1557 (set (attr "prefix_data16")
1558 (cond [(eq_attr "type" "fcmp")
1560 (eq_attr "mode" "DF")
1563 (const_string "0")))
1564 (set_attr "athlon_decode" "vector")
1565 (set_attr "amdfam10_decode" "direct")
1566 (set_attr "bdver1_decode" "double")])
1568 (define_insn "*cmpfp_iu_sse"
1569 [(set (reg:CCFPU FLAGS_REG)
1570 (compare:CCFPU (match_operand 0 "register_operand" "x")
1571 (match_operand 1 "nonimmediate_operand" "xm")))]
1573 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1574 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1575 "* return output_fp_compare (insn, operands, 1, 1);"
1576 [(set_attr "type" "ssecomi")
1577 (set_attr "prefix" "maybe_vex")
1579 (if_then_else (match_operand:SF 1 "" "")
1581 (const_string "DF")))
1582 (set_attr "prefix_rep" "0")
1583 (set (attr "prefix_data16")
1584 (if_then_else (eq_attr "mode" "DF")
1586 (const_string "0")))
1587 (set_attr "athlon_decode" "vector")
1588 (set_attr "amdfam10_decode" "direct")
1589 (set_attr "bdver1_decode" "double")])
1591 (define_insn "*cmpfp_iu_387"
1592 [(set (reg:CCFPU FLAGS_REG)
1593 (compare:CCFPU (match_operand 0 "register_operand" "f")
1594 (match_operand 1 "register_operand" "f")))]
1595 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1597 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1598 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1599 "* return output_fp_compare (insn, operands, 1, 1);"
1600 [(set_attr "type" "fcmp")
1602 (cond [(match_operand:SF 1 "" "")
1604 (match_operand:DF 1 "" "")
1607 (const_string "XF")))
1608 (set_attr "athlon_decode" "vector")
1609 (set_attr "amdfam10_decode" "direct")
1610 (set_attr "bdver1_decode" "direct")])
1612 ;; Push/pop instructions.
1614 (define_insn "*push<mode>2"
1615 [(set (match_operand:DWI 0 "push_operand" "=<")
1616 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1621 [(set (match_operand:TI 0 "push_operand" "")
1622 (match_operand:TI 1 "general_operand" ""))]
1623 "TARGET_64BIT && reload_completed
1624 && !SSE_REG_P (operands[1])"
1626 "ix86_split_long_move (operands); DONE;")
1628 (define_insn "*pushdi2_rex64"
1629 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1630 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1635 [(set_attr "type" "push,multi")
1636 (set_attr "mode" "DI")])
1638 ;; Convert impossible pushes of immediate to existing instructions.
1639 ;; First try to get scratch register and go through it. In case this
1640 ;; fails, push sign extended lower part first and then overwrite
1641 ;; upper part by 32bit move.
1643 [(match_scratch:DI 2 "r")
1644 (set (match_operand:DI 0 "push_operand" "")
1645 (match_operand:DI 1 "immediate_operand" ""))]
1646 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1647 && !x86_64_immediate_operand (operands[1], DImode)"
1648 [(set (match_dup 2) (match_dup 1))
1649 (set (match_dup 0) (match_dup 2))])
1651 ;; We need to define this as both peepholer and splitter for case
1652 ;; peephole2 pass is not run.
1653 ;; "&& 1" is needed to keep it from matching the previous pattern.
1655 [(set (match_operand:DI 0 "push_operand" "")
1656 (match_operand:DI 1 "immediate_operand" ""))]
1657 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1658 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1659 [(set (match_dup 0) (match_dup 1))
1660 (set (match_dup 2) (match_dup 3))]
1662 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1664 operands[1] = gen_lowpart (DImode, operands[2]);
1665 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1670 [(set (match_operand:DI 0 "push_operand" "")
1671 (match_operand:DI 1 "immediate_operand" ""))]
1672 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1673 ? epilogue_completed : reload_completed)
1674 && !symbolic_operand (operands[1], DImode)
1675 && !x86_64_immediate_operand (operands[1], DImode)"
1676 [(set (match_dup 0) (match_dup 1))
1677 (set (match_dup 2) (match_dup 3))]
1679 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1681 operands[1] = gen_lowpart (DImode, operands[2]);
1682 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1687 [(set (match_operand:DI 0 "push_operand" "")
1688 (match_operand:DI 1 "general_operand" ""))]
1689 "!TARGET_64BIT && reload_completed
1690 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1692 "ix86_split_long_move (operands); DONE;")
1694 (define_insn "*pushsi2"
1695 [(set (match_operand:SI 0 "push_operand" "=<")
1696 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1699 [(set_attr "type" "push")
1700 (set_attr "mode" "SI")])
1702 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1703 ;; "push a byte/word". But actually we use pushl, which has the effect
1704 ;; of rounding the amount pushed up to a word.
1706 ;; For TARGET_64BIT we always round up to 8 bytes.
1707 (define_insn "*push<mode>2_rex64"
1708 [(set (match_operand:SWI124 0 "push_operand" "=X")
1709 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1712 [(set_attr "type" "push")
1713 (set_attr "mode" "DI")])
1715 (define_insn "*push<mode>2"
1716 [(set (match_operand:SWI12 0 "push_operand" "=X")
1717 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1720 [(set_attr "type" "push")
1721 (set_attr "mode" "SI")])
1723 (define_insn "*push<mode>2_prologue"
1724 [(set (match_operand:P 0 "push_operand" "=<")
1725 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1726 (clobber (mem:BLK (scratch)))]
1728 "push{<imodesuffix>}\t%1"
1729 [(set_attr "type" "push")
1730 (set_attr "mode" "<MODE>")])
1732 (define_insn "*pop<mode>1"
1733 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1734 (match_operand:P 1 "pop_operand" ">"))]
1736 "pop{<imodesuffix>}\t%0"
1737 [(set_attr "type" "pop")
1738 (set_attr "mode" "<MODE>")])
1740 (define_insn "*pop<mode>1_epilogue"
1741 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1742 (match_operand:P 1 "pop_operand" ">"))
1743 (clobber (mem:BLK (scratch)))]
1745 "pop{<imodesuffix>}\t%0"
1746 [(set_attr "type" "pop")
1747 (set_attr "mode" "<MODE>")])
1749 ;; Move instructions.
1751 (define_expand "movoi"
1752 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1753 (match_operand:OI 1 "general_operand" ""))]
1755 "ix86_expand_move (OImode, operands); DONE;")
1757 (define_expand "movti"
1758 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1759 (match_operand:TI 1 "nonimmediate_operand" ""))]
1760 "TARGET_64BIT || TARGET_SSE"
1763 ix86_expand_move (TImode, operands);
1764 else if (push_operand (operands[0], TImode))
1765 ix86_expand_push (TImode, operands[1]);
1767 ix86_expand_vector_move (TImode, operands);
1771 ;; This expands to what emit_move_complex would generate if we didn't
1772 ;; have a movti pattern. Having this avoids problems with reload on
1773 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1774 ;; to have around all the time.
1775 (define_expand "movcdi"
1776 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1777 (match_operand:CDI 1 "general_operand" ""))]
1780 if (push_operand (operands[0], CDImode))
1781 emit_move_complex_push (CDImode, operands[0], operands[1]);
1783 emit_move_complex_parts (operands[0], operands[1]);
1787 (define_expand "mov<mode>"
1788 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1789 (match_operand:SWI1248x 1 "general_operand" ""))]
1791 "ix86_expand_move (<MODE>mode, operands); DONE;")
1793 (define_insn "*mov<mode>_xor"
1794 [(set (match_operand:SWI48 0 "register_operand" "=r")
1795 (match_operand:SWI48 1 "const0_operand" ""))
1796 (clobber (reg:CC FLAGS_REG))]
1799 [(set_attr "type" "alu1")
1800 (set_attr "mode" "SI")
1801 (set_attr "length_immediate" "0")])
1803 (define_insn "*mov<mode>_or"
1804 [(set (match_operand:SWI48 0 "register_operand" "=r")
1805 (match_operand:SWI48 1 "const_int_operand" ""))
1806 (clobber (reg:CC FLAGS_REG))]
1808 && operands[1] == constm1_rtx"
1809 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1810 [(set_attr "type" "alu1")
1811 (set_attr "mode" "<MODE>")
1812 (set_attr "length_immediate" "1")])
1814 (define_insn "*movoi_internal_avx"
1815 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1816 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1817 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1819 switch (which_alternative)
1822 return "vxorps\t%0, %0, %0";
1825 if (misaligned_operand (operands[0], OImode)
1826 || misaligned_operand (operands[1], OImode))
1827 return "vmovdqu\t{%1, %0|%0, %1}";
1829 return "vmovdqa\t{%1, %0|%0, %1}";
1834 [(set_attr "type" "sselog1,ssemov,ssemov")
1835 (set_attr "prefix" "vex")
1836 (set_attr "mode" "OI")])
1838 (define_insn "*movti_internal_rex64"
1839 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1840 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1841 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1843 switch (which_alternative)
1849 if (get_attr_mode (insn) == MODE_V4SF)
1850 return "%vxorps\t%0, %d0";
1852 return "%vpxor\t%0, %d0";
1855 /* TDmode values are passed as TImode on the stack. Moving them
1856 to stack may result in unaligned memory access. */
1857 if (misaligned_operand (operands[0], TImode)
1858 || misaligned_operand (operands[1], TImode))
1860 if (get_attr_mode (insn) == MODE_V4SF)
1861 return "%vmovups\t{%1, %0|%0, %1}";
1863 return "%vmovdqu\t{%1, %0|%0, %1}";
1867 if (get_attr_mode (insn) == MODE_V4SF)
1868 return "%vmovaps\t{%1, %0|%0, %1}";
1870 return "%vmovdqa\t{%1, %0|%0, %1}";
1876 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1877 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1879 (cond [(eq_attr "alternative" "2,3")
1881 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1883 (const_string "V4SF")
1884 (const_string "TI"))
1885 (eq_attr "alternative" "4")
1887 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1889 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1891 (const_string "V4SF")
1892 (const_string "TI"))]
1893 (const_string "DI")))])
1896 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1897 (match_operand:TI 1 "general_operand" ""))]
1899 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1901 "ix86_split_long_move (operands); DONE;")
1903 (define_insn "*movti_internal_sse"
1904 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1905 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1906 "TARGET_SSE && !TARGET_64BIT
1907 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1909 switch (which_alternative)
1912 if (get_attr_mode (insn) == MODE_V4SF)
1913 return "%vxorps\t%0, %d0";
1915 return "%vpxor\t%0, %d0";
1918 /* TDmode values are passed as TImode on the stack. Moving them
1919 to stack may result in unaligned memory access. */
1920 if (misaligned_operand (operands[0], TImode)
1921 || misaligned_operand (operands[1], TImode))
1923 if (get_attr_mode (insn) == MODE_V4SF)
1924 return "%vmovups\t{%1, %0|%0, %1}";
1926 return "%vmovdqu\t{%1, %0|%0, %1}";
1930 if (get_attr_mode (insn) == MODE_V4SF)
1931 return "%vmovaps\t{%1, %0|%0, %1}";
1933 return "%vmovdqa\t{%1, %0|%0, %1}";
1939 [(set_attr "type" "sselog1,ssemov,ssemov")
1940 (set_attr "prefix" "maybe_vex")
1942 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1943 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1945 (const_string "V4SF")
1946 (and (eq_attr "alternative" "2")
1947 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1949 (const_string "V4SF")]
1950 (const_string "TI")))])
1952 (define_insn "*movdi_internal_rex64"
1953 [(set (match_operand:DI 0 "nonimmediate_operand"
1954 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1955 (match_operand:DI 1 "general_operand"
1956 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1957 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1959 switch (get_attr_type (insn))
1962 if (SSE_REG_P (operands[0]))
1963 return "movq2dq\t{%1, %0|%0, %1}";
1965 return "movdq2q\t{%1, %0|%0, %1}";
1970 if (get_attr_mode (insn) == MODE_TI)
1971 return "vmovdqa\t{%1, %0|%0, %1}";
1973 return "vmovq\t{%1, %0|%0, %1}";
1976 if (get_attr_mode (insn) == MODE_TI)
1977 return "movdqa\t{%1, %0|%0, %1}";
1981 /* Moves from and into integer register is done using movd
1982 opcode with REX prefix. */
1983 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1984 return "movd\t{%1, %0|%0, %1}";
1985 return "movq\t{%1, %0|%0, %1}";
1988 return "%vpxor\t%0, %d0";
1991 return "pxor\t%0, %0";
1997 return "lea{q}\t{%a1, %0|%0, %a1}";
2000 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2001 if (get_attr_mode (insn) == MODE_SI)
2002 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2003 else if (which_alternative == 2)
2004 return "movabs{q}\t{%1, %0|%0, %1}";
2006 return "mov{q}\t{%1, %0|%0, %1}";
2010 (cond [(eq_attr "alternative" "5")
2011 (const_string "mmx")
2012 (eq_attr "alternative" "6,7,8,9,10")
2013 (const_string "mmxmov")
2014 (eq_attr "alternative" "11")
2015 (const_string "sselog1")
2016 (eq_attr "alternative" "12,13,14,15,16")
2017 (const_string "ssemov")
2018 (eq_attr "alternative" "17,18")
2019 (const_string "ssecvt")
2020 (eq_attr "alternative" "4")
2021 (const_string "multi")
2022 (match_operand:DI 1 "pic_32bit_operand" "")
2023 (const_string "lea")
2025 (const_string "imov")))
2028 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2030 (const_string "*")))
2031 (set (attr "length_immediate")
2033 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2035 (const_string "*")))
2036 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2037 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2038 (set (attr "prefix")
2039 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2040 (const_string "maybe_vex")
2041 (const_string "orig")))
2042 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2044 ;; Convert impossible stores of immediate to existing instructions.
2045 ;; First try to get scratch register and go through it. In case this
2046 ;; fails, move by 32bit parts.
2048 [(match_scratch:DI 2 "r")
2049 (set (match_operand:DI 0 "memory_operand" "")
2050 (match_operand:DI 1 "immediate_operand" ""))]
2051 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2052 && !x86_64_immediate_operand (operands[1], DImode)"
2053 [(set (match_dup 2) (match_dup 1))
2054 (set (match_dup 0) (match_dup 2))])
2056 ;; We need to define this as both peepholer and splitter for case
2057 ;; peephole2 pass is not run.
2058 ;; "&& 1" is needed to keep it from matching the previous pattern.
2060 [(set (match_operand:DI 0 "memory_operand" "")
2061 (match_operand:DI 1 "immediate_operand" ""))]
2062 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2063 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2064 [(set (match_dup 2) (match_dup 3))
2065 (set (match_dup 4) (match_dup 5))]
2066 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2069 [(set (match_operand:DI 0 "memory_operand" "")
2070 (match_operand:DI 1 "immediate_operand" ""))]
2071 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2072 ? epilogue_completed : reload_completed)
2073 && !symbolic_operand (operands[1], DImode)
2074 && !x86_64_immediate_operand (operands[1], DImode)"
2075 [(set (match_dup 2) (match_dup 3))
2076 (set (match_dup 4) (match_dup 5))]
2077 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2079 (define_insn "*movdi_internal"
2080 [(set (match_operand:DI 0 "nonimmediate_operand"
2081 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2082 (match_operand:DI 1 "general_operand"
2083 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2084 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2089 movq\t{%1, %0|%0, %1}
2090 movq\t{%1, %0|%0, %1}
2092 %vmovq\t{%1, %0|%0, %1}
2093 %vmovdqa\t{%1, %0|%0, %1}
2094 %vmovq\t{%1, %0|%0, %1}
2096 movlps\t{%1, %0|%0, %1}
2097 movaps\t{%1, %0|%0, %1}
2098 movlps\t{%1, %0|%0, %1}"
2099 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2100 (set (attr "prefix")
2101 (if_then_else (eq_attr "alternative" "5,6,7,8")
2102 (const_string "vex")
2103 (const_string "orig")))
2104 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2107 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2108 (match_operand:DI 1 "general_operand" ""))]
2109 "!TARGET_64BIT && reload_completed
2110 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2111 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2113 "ix86_split_long_move (operands); DONE;")
2115 (define_insn "*movsi_internal"
2116 [(set (match_operand:SI 0 "nonimmediate_operand"
2117 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2118 (match_operand:SI 1 "general_operand"
2119 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2120 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2122 switch (get_attr_type (insn))
2125 if (get_attr_mode (insn) == MODE_TI)
2126 return "%vpxor\t%0, %d0";
2127 return "%vxorps\t%0, %d0";
2130 switch (get_attr_mode (insn))
2133 return "%vmovdqa\t{%1, %0|%0, %1}";
2135 return "%vmovaps\t{%1, %0|%0, %1}";
2137 return "%vmovd\t{%1, %0|%0, %1}";
2139 return "%vmovss\t{%1, %0|%0, %1}";
2145 return "pxor\t%0, %0";
2148 if (get_attr_mode (insn) == MODE_DI)
2149 return "movq\t{%1, %0|%0, %1}";
2150 return "movd\t{%1, %0|%0, %1}";
2153 return "lea{l}\t{%a1, %0|%0, %a1}";
2156 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2157 return "mov{l}\t{%1, %0|%0, %1}";
2161 (cond [(eq_attr "alternative" "2")
2162 (const_string "mmx")
2163 (eq_attr "alternative" "3,4,5")
2164 (const_string "mmxmov")
2165 (eq_attr "alternative" "6")
2166 (const_string "sselog1")
2167 (eq_attr "alternative" "7,8,9,10,11")
2168 (const_string "ssemov")
2169 (match_operand:DI 1 "pic_32bit_operand" "")
2170 (const_string "lea")
2172 (const_string "imov")))
2173 (set (attr "prefix")
2174 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2175 (const_string "orig")
2176 (const_string "maybe_vex")))
2177 (set (attr "prefix_data16")
2178 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2180 (const_string "*")))
2182 (cond [(eq_attr "alternative" "2,3")
2184 (eq_attr "alternative" "6,7")
2186 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2187 (const_string "V4SF")
2188 (const_string "TI"))
2189 (and (eq_attr "alternative" "8,9,10,11")
2190 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2193 (const_string "SI")))])
2195 (define_insn "*movhi_internal"
2196 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2197 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2198 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2200 switch (get_attr_type (insn))
2203 /* movzwl is faster than movw on p2 due to partial word stalls,
2204 though not as fast as an aligned movl. */
2205 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2207 if (get_attr_mode (insn) == MODE_SI)
2208 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2210 return "mov{w}\t{%1, %0|%0, %1}";
2214 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2216 (const_string "imov")
2217 (and (eq_attr "alternative" "0")
2218 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2220 (eq (symbol_ref "TARGET_HIMODE_MATH")
2222 (const_string "imov")
2223 (and (eq_attr "alternative" "1,2")
2224 (match_operand:HI 1 "aligned_operand" ""))
2225 (const_string "imov")
2226 (and (ne (symbol_ref "TARGET_MOVX")
2228 (eq_attr "alternative" "0,2"))
2229 (const_string "imovx")
2231 (const_string "imov")))
2233 (cond [(eq_attr "type" "imovx")
2235 (and (eq_attr "alternative" "1,2")
2236 (match_operand:HI 1 "aligned_operand" ""))
2238 (and (eq_attr "alternative" "0")
2239 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2241 (eq (symbol_ref "TARGET_HIMODE_MATH")
2245 (const_string "HI")))])
2247 ;; Situation is quite tricky about when to choose full sized (SImode) move
2248 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2249 ;; partial register dependency machines (such as AMD Athlon), where QImode
2250 ;; moves issue extra dependency and for partial register stalls machines
2251 ;; that don't use QImode patterns (and QImode move cause stall on the next
2254 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2255 ;; register stall machines with, where we use QImode instructions, since
2256 ;; partial register stall can be caused there. Then we use movzx.
2257 (define_insn "*movqi_internal"
2258 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2259 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2260 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2262 switch (get_attr_type (insn))
2265 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2266 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2268 if (get_attr_mode (insn) == MODE_SI)
2269 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2271 return "mov{b}\t{%1, %0|%0, %1}";
2275 (cond [(and (eq_attr "alternative" "5")
2276 (not (match_operand:QI 1 "aligned_operand" "")))
2277 (const_string "imovx")
2278 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2280 (const_string "imov")
2281 (and (eq_attr "alternative" "3")
2282 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2284 (eq (symbol_ref "TARGET_QIMODE_MATH")
2286 (const_string "imov")
2287 (eq_attr "alternative" "3,5")
2288 (const_string "imovx")
2289 (and (ne (symbol_ref "TARGET_MOVX")
2291 (eq_attr "alternative" "2"))
2292 (const_string "imovx")
2294 (const_string "imov")))
2296 (cond [(eq_attr "alternative" "3,4,5")
2298 (eq_attr "alternative" "6")
2300 (eq_attr "type" "imovx")
2302 (and (eq_attr "type" "imov")
2303 (and (eq_attr "alternative" "0,1")
2304 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2306 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2308 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2311 ;; Avoid partial register stalls when not using QImode arithmetic
2312 (and (eq_attr "type" "imov")
2313 (and (eq_attr "alternative" "0,1")
2314 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2316 (eq (symbol_ref "TARGET_QIMODE_MATH")
2320 (const_string "QI")))])
2322 ;; Stores and loads of ax to arbitrary constant address.
2323 ;; We fake an second form of instruction to force reload to load address
2324 ;; into register when rax is not available
2325 (define_insn "*movabs<mode>_1"
2326 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2327 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2328 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2330 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2331 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2332 [(set_attr "type" "imov")
2333 (set_attr "modrm" "0,*")
2334 (set_attr "length_address" "8,0")
2335 (set_attr "length_immediate" "0,*")
2336 (set_attr "memory" "store")
2337 (set_attr "mode" "<MODE>")])
2339 (define_insn "*movabs<mode>_2"
2340 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2341 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2342 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2344 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2345 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2346 [(set_attr "type" "imov")
2347 (set_attr "modrm" "0,*")
2348 (set_attr "length_address" "8,0")
2349 (set_attr "length_immediate" "0")
2350 (set_attr "memory" "load")
2351 (set_attr "mode" "<MODE>")])
2353 (define_insn "*swap<mode>"
2354 [(set (match_operand:SWI48 0 "register_operand" "+r")
2355 (match_operand:SWI48 1 "register_operand" "+r"))
2359 "xchg{<imodesuffix>}\t%1, %0"
2360 [(set_attr "type" "imov")
2361 (set_attr "mode" "<MODE>")
2362 (set_attr "pent_pair" "np")
2363 (set_attr "athlon_decode" "vector")
2364 (set_attr "amdfam10_decode" "double")
2365 (set_attr "bdver1_decode" "double")])
2367 (define_insn "*swap<mode>_1"
2368 [(set (match_operand:SWI12 0 "register_operand" "+r")
2369 (match_operand:SWI12 1 "register_operand" "+r"))
2372 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2374 [(set_attr "type" "imov")
2375 (set_attr "mode" "SI")
2376 (set_attr "pent_pair" "np")
2377 (set_attr "athlon_decode" "vector")
2378 (set_attr "amdfam10_decode" "double")
2379 (set_attr "bdver1_decode" "double")])
2381 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2382 ;; is disabled for AMDFAM10
2383 (define_insn "*swap<mode>_2"
2384 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2385 (match_operand:SWI12 1 "register_operand" "+<r>"))
2388 "TARGET_PARTIAL_REG_STALL"
2389 "xchg{<imodesuffix>}\t%1, %0"
2390 [(set_attr "type" "imov")
2391 (set_attr "mode" "<MODE>")
2392 (set_attr "pent_pair" "np")
2393 (set_attr "athlon_decode" "vector")])
2395 (define_expand "movstrict<mode>"
2396 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2397 (match_operand:SWI12 1 "general_operand" ""))]
2400 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2402 /* Don't generate memory->memory moves, go through a register */
2403 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2404 operands[1] = force_reg (<MODE>mode, operands[1]);
2407 (define_insn "*movstrict<mode>_1"
2408 [(set (strict_low_part
2409 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2410 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2411 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2412 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2413 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2414 [(set_attr "type" "imov")
2415 (set_attr "mode" "<MODE>")])
2417 (define_insn "*movstrict<mode>_xor"
2418 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2419 (match_operand:SWI12 1 "const0_operand" ""))
2420 (clobber (reg:CC FLAGS_REG))]
2422 "xor{<imodesuffix>}\t%0, %0"
2423 [(set_attr "type" "alu1")
2424 (set_attr "mode" "<MODE>")
2425 (set_attr "length_immediate" "0")])
2427 (define_insn "*mov<mode>_extv_1"
2428 [(set (match_operand:SWI24 0 "register_operand" "=R")
2429 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2433 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2434 [(set_attr "type" "imovx")
2435 (set_attr "mode" "SI")])
2437 (define_insn "*movqi_extv_1_rex64"
2438 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2439 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2444 switch (get_attr_type (insn))
2447 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2449 return "mov{b}\t{%h1, %0|%0, %h1}";
2453 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2454 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2455 (ne (symbol_ref "TARGET_MOVX")
2457 (const_string "imovx")
2458 (const_string "imov")))
2460 (if_then_else (eq_attr "type" "imovx")
2462 (const_string "QI")))])
2464 (define_insn "*movqi_extv_1"
2465 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2466 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2471 switch (get_attr_type (insn))
2474 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2476 return "mov{b}\t{%h1, %0|%0, %h1}";
2480 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2481 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2482 (ne (symbol_ref "TARGET_MOVX")
2484 (const_string "imovx")
2485 (const_string "imov")))
2487 (if_then_else (eq_attr "type" "imovx")
2489 (const_string "QI")))])
2491 (define_insn "*mov<mode>_extzv_1"
2492 [(set (match_operand:SWI48 0 "register_operand" "=R")
2493 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2497 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2498 [(set_attr "type" "imovx")
2499 (set_attr "mode" "SI")])
2501 (define_insn "*movqi_extzv_2_rex64"
2502 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2504 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2509 switch (get_attr_type (insn))
2512 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2514 return "mov{b}\t{%h1, %0|%0, %h1}";
2518 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2519 (ne (symbol_ref "TARGET_MOVX")
2521 (const_string "imovx")
2522 (const_string "imov")))
2524 (if_then_else (eq_attr "type" "imovx")
2526 (const_string "QI")))])
2528 (define_insn "*movqi_extzv_2"
2529 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2531 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2536 switch (get_attr_type (insn))
2539 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2541 return "mov{b}\t{%h1, %0|%0, %h1}";
2545 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2546 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2547 (ne (symbol_ref "TARGET_MOVX")
2549 (const_string "imovx")
2550 (const_string "imov")))
2552 (if_then_else (eq_attr "type" "imovx")
2554 (const_string "QI")))])
2556 (define_expand "mov<mode>_insv_1"
2557 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2560 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2562 (define_insn "*mov<mode>_insv_1_rex64"
2563 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2566 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2568 "mov{b}\t{%b1, %h0|%h0, %b1}"
2569 [(set_attr "type" "imov")
2570 (set_attr "mode" "QI")])
2572 (define_insn "*movsi_insv_1"
2573 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2576 (match_operand:SI 1 "general_operand" "Qmn"))]
2578 "mov{b}\t{%b1, %h0|%h0, %b1}"
2579 [(set_attr "type" "imov")
2580 (set_attr "mode" "QI")])
2582 (define_insn "*movqi_insv_2"
2583 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2586 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2589 "mov{b}\t{%h1, %h0|%h0, %h1}"
2590 [(set_attr "type" "imov")
2591 (set_attr "mode" "QI")])
2593 ;; Floating point push instructions.
2595 (define_insn "*pushtf"
2596 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2597 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2600 /* This insn should be already split before reg-stack. */
2603 [(set_attr "type" "multi")
2604 (set_attr "unit" "sse,*,*")
2605 (set_attr "mode" "TF,SI,SI")])
2608 [(set (match_operand:TF 0 "push_operand" "")
2609 (match_operand:TF 1 "sse_reg_operand" ""))]
2610 "TARGET_SSE2 && reload_completed"
2611 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2612 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2615 [(set (match_operand:TF 0 "push_operand" "")
2616 (match_operand:TF 1 "general_operand" ""))]
2617 "TARGET_SSE2 && reload_completed
2618 && !SSE_REG_P (operands[1])"
2620 "ix86_split_long_move (operands); DONE;")
2622 (define_insn "*pushxf"
2623 [(set (match_operand:XF 0 "push_operand" "=<,<")
2624 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2625 "optimize_function_for_speed_p (cfun)"
2627 /* This insn should be already split before reg-stack. */
2630 [(set_attr "type" "multi")
2631 (set_attr "unit" "i387,*")
2632 (set_attr "mode" "XF,SI")])
2634 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2635 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2636 ;; Pushing using integer instructions is longer except for constants
2637 ;; and direct memory references (assuming that any given constant is pushed
2638 ;; only once, but this ought to be handled elsewhere).
2640 (define_insn "*pushxf_nointeger"
2641 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2642 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2643 "optimize_function_for_size_p (cfun)"
2645 /* This insn should be already split before reg-stack. */
2648 [(set_attr "type" "multi")
2649 (set_attr "unit" "i387,*,*")
2650 (set_attr "mode" "XF,SI,SI")])
2653 [(set (match_operand:XF 0 "push_operand" "")
2654 (match_operand:XF 1 "fp_register_operand" ""))]
2656 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2657 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2658 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2661 [(set (match_operand:XF 0 "push_operand" "")
2662 (match_operand:XF 1 "general_operand" ""))]
2664 && !FP_REG_P (operands[1])"
2666 "ix86_split_long_move (operands); DONE;")
2668 (define_insn "*pushdf"
2669 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2670 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2671 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2673 /* This insn should be already split before reg-stack. */
2676 [(set_attr "type" "multi")
2677 (set_attr "unit" "i387,*,*")
2678 (set_attr "mode" "DF,SI,DF")])
2680 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2681 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2682 ;; On the average, pushdf using integers can be still shorter. Allow this
2683 ;; pattern for optimize_size too.
2685 (define_insn "*pushdf_nointeger"
2686 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2687 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2688 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2690 /* This insn should be already split before reg-stack. */
2693 [(set_attr "type" "multi")
2694 (set_attr "unit" "i387,*,*,*")
2695 (set_attr "mode" "DF,SI,SI,DF")])
2697 ;; %%% Kill this when call knows how to work this out.
2699 [(set (match_operand:DF 0 "push_operand" "")
2700 (match_operand:DF 1 "any_fp_register_operand" ""))]
2702 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2703 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2706 [(set (match_operand:DF 0 "push_operand" "")
2707 (match_operand:DF 1 "general_operand" ""))]
2709 && !ANY_FP_REG_P (operands[1])"
2711 "ix86_split_long_move (operands); DONE;")
2713 (define_insn "*pushsf_rex64"
2714 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2715 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2718 /* Anything else should be already split before reg-stack. */
2719 gcc_assert (which_alternative == 1);
2720 return "push{q}\t%q1";
2722 [(set_attr "type" "multi,push,multi")
2723 (set_attr "unit" "i387,*,*")
2724 (set_attr "mode" "SF,DI,SF")])
2726 (define_insn "*pushsf"
2727 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2728 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2731 /* Anything else should be already split before reg-stack. */
2732 gcc_assert (which_alternative == 1);
2733 return "push{l}\t%1";
2735 [(set_attr "type" "multi,push,multi")
2736 (set_attr "unit" "i387,*,*")
2737 (set_attr "mode" "SF,SI,SF")])
2740 [(set (match_operand:SF 0 "push_operand" "")
2741 (match_operand:SF 1 "memory_operand" ""))]
2743 && MEM_P (operands[1])
2744 && (operands[2] = find_constant_src (insn))"
2748 ;; %%% Kill this when call knows how to work this out.
2750 [(set (match_operand:SF 0 "push_operand" "")
2751 (match_operand:SF 1 "any_fp_register_operand" ""))]
2753 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2754 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2755 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2757 ;; Floating point move instructions.
2759 (define_expand "movtf"
2760 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2761 (match_operand:TF 1 "nonimmediate_operand" ""))]
2764 ix86_expand_move (TFmode, operands);
2768 (define_expand "mov<mode>"
2769 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2770 (match_operand:X87MODEF 1 "general_operand" ""))]
2772 "ix86_expand_move (<MODE>mode, operands); DONE;")
2774 (define_insn "*movtf_internal"
2775 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2776 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2778 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2780 switch (which_alternative)
2784 if (get_attr_mode (insn) == MODE_V4SF)
2785 return "%vmovaps\t{%1, %0|%0, %1}";
2787 return "%vmovdqa\t{%1, %0|%0, %1}";
2789 if (get_attr_mode (insn) == MODE_V4SF)
2790 return "%vxorps\t%0, %d0";
2792 return "%vpxor\t%0, %d0";
2800 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2801 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2803 (cond [(eq_attr "alternative" "0,2")
2805 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2807 (const_string "V4SF")
2808 (const_string "TI"))
2809 (eq_attr "alternative" "1")
2811 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2813 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2815 (const_string "V4SF")
2816 (const_string "TI"))]
2817 (const_string "DI")))])
2820 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2821 (match_operand:TF 1 "general_operand" ""))]
2823 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2825 "ix86_split_long_move (operands); DONE;")
2827 (define_insn "*movxf_internal"
2828 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2829 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2830 "optimize_function_for_speed_p (cfun)
2831 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2832 && (reload_in_progress || reload_completed
2833 || GET_CODE (operands[1]) != CONST_DOUBLE
2834 || memory_operand (operands[0], XFmode))"
2836 switch (which_alternative)
2840 return output_387_reg_move (insn, operands);
2843 return standard_80387_constant_opcode (operands[1]);
2852 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2853 (set_attr "mode" "XF,XF,XF,SI,SI")])
2855 ;; Do not use integer registers when optimizing for size
2856 (define_insn "*movxf_internal_nointeger"
2857 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2858 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2859 "optimize_function_for_size_p (cfun)
2860 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2861 && (reload_in_progress || reload_completed
2862 || standard_80387_constant_p (operands[1])
2863 || GET_CODE (operands[1]) != CONST_DOUBLE
2864 || memory_operand (operands[0], XFmode))"
2866 switch (which_alternative)
2870 return output_387_reg_move (insn, operands);
2873 return standard_80387_constant_opcode (operands[1]);
2881 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2882 (set_attr "mode" "XF,XF,XF,SI,SI")])
2885 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2886 (match_operand:XF 1 "general_operand" ""))]
2888 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2889 && ! (FP_REG_P (operands[0]) ||
2890 (GET_CODE (operands[0]) == SUBREG
2891 && FP_REG_P (SUBREG_REG (operands[0]))))
2892 && ! (FP_REG_P (operands[1]) ||
2893 (GET_CODE (operands[1]) == SUBREG
2894 && FP_REG_P (SUBREG_REG (operands[1]))))"
2896 "ix86_split_long_move (operands); DONE;")
2898 (define_insn "*movdf_internal_rex64"
2899 [(set (match_operand:DF 0 "nonimmediate_operand"
2900 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2901 (match_operand:DF 1 "general_operand"
2902 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2903 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2904 && (reload_in_progress || reload_completed
2905 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2906 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2907 && optimize_function_for_size_p (cfun)
2908 && standard_80387_constant_p (operands[1]))
2909 || GET_CODE (operands[1]) != CONST_DOUBLE
2910 || memory_operand (operands[0], DFmode))"
2912 switch (which_alternative)
2916 return output_387_reg_move (insn, operands);
2919 return standard_80387_constant_opcode (operands[1]);
2926 switch (get_attr_mode (insn))
2929 return "%vxorps\t%0, %d0";
2931 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2932 return "%vxorps\t%0, %d0";
2934 return "%vxorpd\t%0, %d0";
2936 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2937 return "%vxorps\t%0, %d0";
2939 return "%vpxor\t%0, %d0";
2946 switch (get_attr_mode (insn))
2949 return "%vmovaps\t{%1, %0|%0, %1}";
2951 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2952 return "%vmovaps\t{%1, %0|%0, %1}";
2954 return "%vmovapd\t{%1, %0|%0, %1}";
2956 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2957 return "%vmovaps\t{%1, %0|%0, %1}";
2959 return "%vmovdqa\t{%1, %0|%0, %1}";
2961 return "%vmovq\t{%1, %0|%0, %1}";
2965 if (REG_P (operands[0]) && REG_P (operands[1]))
2966 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2968 return "vmovsd\t{%1, %0|%0, %1}";
2971 return "movsd\t{%1, %0|%0, %1}";
2973 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2975 return "%vmovlps\t{%1, %d0|%d0, %1}";
2982 return "%vmovd\t{%1, %0|%0, %1}";
2988 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2989 (set (attr "prefix")
2990 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2991 (const_string "orig")
2992 (const_string "maybe_vex")))
2993 (set (attr "prefix_data16")
2994 (if_then_else (eq_attr "mode" "V1DF")
2996 (const_string "*")))
2998 (cond [(eq_attr "alternative" "0,1,2")
3000 (eq_attr "alternative" "3,4,9,10")
3003 /* For SSE1, we have many fewer alternatives. */
3004 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3005 (cond [(eq_attr "alternative" "5,6")
3006 (const_string "V4SF")
3008 (const_string "V2SF"))
3010 /* xorps is one byte shorter. */
3011 (eq_attr "alternative" "5")
3012 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3014 (const_string "V4SF")
3015 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3019 (const_string "V2DF"))
3021 /* For architectures resolving dependencies on
3022 whole SSE registers use APD move to break dependency
3023 chains, otherwise use short move to avoid extra work.
3025 movaps encodes one byte shorter. */
3026 (eq_attr "alternative" "6")
3028 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3030 (const_string "V4SF")
3031 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3033 (const_string "V2DF")
3035 (const_string "DF"))
3036 /* For architectures resolving dependencies on register
3037 parts we may avoid extra work to zero out upper part
3039 (eq_attr "alternative" "7")
3041 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3043 (const_string "V1DF")
3044 (const_string "DF"))
3046 (const_string "DF")))])
3048 (define_insn "*movdf_internal"
3049 [(set (match_operand:DF 0 "nonimmediate_operand"
3050 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3051 (match_operand:DF 1 "general_operand"
3052 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3053 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3054 && optimize_function_for_speed_p (cfun)
3055 && TARGET_INTEGER_DFMODE_MOVES
3056 && (reload_in_progress || reload_completed
3057 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3058 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3059 && optimize_function_for_size_p (cfun)
3060 && standard_80387_constant_p (operands[1]))
3061 || GET_CODE (operands[1]) != CONST_DOUBLE
3062 || memory_operand (operands[0], DFmode))"
3064 switch (which_alternative)
3068 return output_387_reg_move (insn, operands);
3071 return standard_80387_constant_opcode (operands[1]);
3078 switch (get_attr_mode (insn))
3081 return "xorps\t%0, %0";
3083 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3084 return "xorps\t%0, %0";
3086 return "xorpd\t%0, %0";
3088 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3089 return "xorps\t%0, %0";
3091 return "pxor\t%0, %0";
3098 switch (get_attr_mode (insn))
3101 return "movaps\t{%1, %0|%0, %1}";
3103 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3104 return "movaps\t{%1, %0|%0, %1}";
3106 return "movapd\t{%1, %0|%0, %1}";
3108 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3109 return "movaps\t{%1, %0|%0, %1}";
3111 return "movdqa\t{%1, %0|%0, %1}";
3113 return "movq\t{%1, %0|%0, %1}";
3115 return "movsd\t{%1, %0|%0, %1}";
3117 return "movlpd\t{%1, %0|%0, %1}";
3119 return "movlps\t{%1, %0|%0, %1}";
3128 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3129 (set (attr "prefix_data16")
3130 (if_then_else (eq_attr "mode" "V1DF")
3132 (const_string "*")))
3134 (cond [(eq_attr "alternative" "0,1,2")
3136 (eq_attr "alternative" "3,4")
3139 /* For SSE1, we have many fewer alternatives. */
3140 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3141 (cond [(eq_attr "alternative" "5,6")
3142 (const_string "V4SF")
3144 (const_string "V2SF"))
3146 /* xorps is one byte shorter. */
3147 (eq_attr "alternative" "5")
3148 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3150 (const_string "V4SF")
3151 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3155 (const_string "V2DF"))
3157 /* For architectures resolving dependencies on
3158 whole SSE registers use APD move to break dependency
3159 chains, otherwise use short move to avoid extra work.
3161 movaps encodes one byte shorter. */
3162 (eq_attr "alternative" "6")
3164 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3166 (const_string "V4SF")
3167 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3169 (const_string "V2DF")
3171 (const_string "DF"))
3172 /* For architectures resolving dependencies on register
3173 parts we may avoid extra work to zero out upper part
3175 (eq_attr "alternative" "7")
3177 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3179 (const_string "V1DF")
3180 (const_string "DF"))
3182 (const_string "DF")))])
3184 ;; Moving is usually shorter when only FP registers are used. This separate
3185 ;; movdf pattern avoids the use of integer registers for FP operations
3186 ;; when optimizing for size.
3188 (define_insn "*movdf_internal_nointeger"
3189 [(set (match_operand:DF 0 "nonimmediate_operand"
3190 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3191 (match_operand:DF 1 "general_operand"
3192 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3193 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3194 && ((optimize_function_for_size_p (cfun)
3195 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3196 && (reload_in_progress || reload_completed
3197 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3198 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3199 && optimize_function_for_size_p (cfun)
3200 && !memory_operand (operands[0], DFmode)
3201 && standard_80387_constant_p (operands[1]))
3202 || GET_CODE (operands[1]) != CONST_DOUBLE
3203 || ((optimize_function_for_size_p (cfun)
3204 || !TARGET_MEMORY_MISMATCH_STALL
3205 || reload_in_progress || reload_completed)
3206 && memory_operand (operands[0], DFmode)))"
3208 switch (which_alternative)
3212 return output_387_reg_move (insn, operands);
3215 return standard_80387_constant_opcode (operands[1]);
3222 switch (get_attr_mode (insn))
3225 return "%vxorps\t%0, %d0";
3227 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3228 return "%vxorps\t%0, %d0";
3230 return "%vxorpd\t%0, %d0";
3232 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3233 return "%vxorps\t%0, %d0";
3235 return "%vpxor\t%0, %d0";
3242 switch (get_attr_mode (insn))
3245 return "%vmovaps\t{%1, %0|%0, %1}";
3247 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3248 return "%vmovaps\t{%1, %0|%0, %1}";
3250 return "%vmovapd\t{%1, %0|%0, %1}";
3252 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3253 return "%vmovaps\t{%1, %0|%0, %1}";
3255 return "%vmovdqa\t{%1, %0|%0, %1}";
3257 return "%vmovq\t{%1, %0|%0, %1}";
3261 if (REG_P (operands[0]) && REG_P (operands[1]))
3262 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3264 return "vmovsd\t{%1, %0|%0, %1}";
3267 return "movsd\t{%1, %0|%0, %1}";
3271 if (REG_P (operands[0]))
3272 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3274 return "vmovlpd\t{%1, %0|%0, %1}";
3277 return "movlpd\t{%1, %0|%0, %1}";
3281 if (REG_P (operands[0]))
3282 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3284 return "vmovlps\t{%1, %0|%0, %1}";
3287 return "movlps\t{%1, %0|%0, %1}";
3296 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3297 (set (attr "prefix")
3298 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3299 (const_string "orig")
3300 (const_string "maybe_vex")))
3301 (set (attr "prefix_data16")
3302 (if_then_else (eq_attr "mode" "V1DF")
3304 (const_string "*")))
3306 (cond [(eq_attr "alternative" "0,1,2")
3308 (eq_attr "alternative" "3,4")
3311 /* For SSE1, we have many fewer alternatives. */
3312 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3313 (cond [(eq_attr "alternative" "5,6")
3314 (const_string "V4SF")
3316 (const_string "V2SF"))
3318 /* xorps is one byte shorter. */
3319 (eq_attr "alternative" "5")
3320 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3322 (const_string "V4SF")
3323 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3327 (const_string "V2DF"))
3329 /* For architectures resolving dependencies on
3330 whole SSE registers use APD move to break dependency
3331 chains, otherwise use short move to avoid extra work.
3333 movaps encodes one byte shorter. */
3334 (eq_attr "alternative" "6")
3336 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3338 (const_string "V4SF")
3339 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3341 (const_string "V2DF")
3343 (const_string "DF"))
3344 /* For architectures resolving dependencies on register
3345 parts we may avoid extra work to zero out upper part
3347 (eq_attr "alternative" "7")
3349 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3351 (const_string "V1DF")
3352 (const_string "DF"))
3354 (const_string "DF")))])
3357 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3358 (match_operand:DF 1 "general_operand" ""))]
3360 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3361 && ! (ANY_FP_REG_P (operands[0]) ||
3362 (GET_CODE (operands[0]) == SUBREG
3363 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3364 && ! (ANY_FP_REG_P (operands[1]) ||
3365 (GET_CODE (operands[1]) == SUBREG
3366 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3368 "ix86_split_long_move (operands); DONE;")
3370 (define_insn "*movsf_internal"
3371 [(set (match_operand:SF 0 "nonimmediate_operand"
3372 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3373 (match_operand:SF 1 "general_operand"
3374 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3375 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3376 && (reload_in_progress || reload_completed
3377 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3378 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3379 && standard_80387_constant_p (operands[1]))
3380 || GET_CODE (operands[1]) != CONST_DOUBLE
3381 || memory_operand (operands[0], SFmode))"
3383 switch (which_alternative)
3387 return output_387_reg_move (insn, operands);
3390 return standard_80387_constant_opcode (operands[1]);
3394 return "mov{l}\t{%1, %0|%0, %1}";
3396 if (get_attr_mode (insn) == MODE_TI)
3397 return "%vpxor\t%0, %d0";
3399 return "%vxorps\t%0, %d0";
3401 if (get_attr_mode (insn) == MODE_V4SF)
3402 return "%vmovaps\t{%1, %0|%0, %1}";
3404 return "%vmovss\t{%1, %d0|%d0, %1}";
3407 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3408 : "vmovss\t{%1, %0|%0, %1}";
3410 return "movss\t{%1, %0|%0, %1}";
3412 return "%vmovss\t{%1, %0|%0, %1}";
3414 case 9: case 10: case 14: case 15:
3415 return "movd\t{%1, %0|%0, %1}";
3417 return "%vmovd\t{%1, %0|%0, %1}";
3420 return "movq\t{%1, %0|%0, %1}";
3426 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3427 (set (attr "prefix")
3428 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3429 (const_string "maybe_vex")
3430 (const_string "orig")))
3432 (cond [(eq_attr "alternative" "3,4,9,10")
3434 (eq_attr "alternative" "5")
3436 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3438 (ne (symbol_ref "TARGET_SSE2")
3440 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3443 (const_string "V4SF"))
3444 /* For architectures resolving dependencies on
3445 whole SSE registers use APS move to break dependency
3446 chains, otherwise use short move to avoid extra work.
3448 Do the same for architectures resolving dependencies on
3449 the parts. While in DF mode it is better to always handle
3450 just register parts, the SF mode is different due to lack
3451 of instructions to load just part of the register. It is
3452 better to maintain the whole registers in single format
3453 to avoid problems on using packed logical operations. */
3454 (eq_attr "alternative" "6")
3456 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3458 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3460 (const_string "V4SF")
3461 (const_string "SF"))
3462 (eq_attr "alternative" "11")
3463 (const_string "DI")]
3464 (const_string "SF")))])
3467 [(set (match_operand 0 "register_operand" "")
3468 (match_operand 1 "memory_operand" ""))]
3470 && MEM_P (operands[1])
3471 && (GET_MODE (operands[0]) == TFmode
3472 || GET_MODE (operands[0]) == XFmode
3473 || GET_MODE (operands[0]) == DFmode
3474 || GET_MODE (operands[0]) == SFmode)
3475 && (operands[2] = find_constant_src (insn))"
3476 [(set (match_dup 0) (match_dup 2))]
3478 rtx c = operands[2];
3479 rtx r = operands[0];
3481 if (GET_CODE (r) == SUBREG)
3486 if (!standard_sse_constant_p (c))
3489 else if (FP_REG_P (r))
3491 if (!standard_80387_constant_p (c))
3494 else if (MMX_REG_P (r))
3499 [(set (match_operand 0 "register_operand" "")
3500 (float_extend (match_operand 1 "memory_operand" "")))]
3502 && MEM_P (operands[1])
3503 && (GET_MODE (operands[0]) == TFmode
3504 || GET_MODE (operands[0]) == XFmode
3505 || GET_MODE (operands[0]) == DFmode
3506 || GET_MODE (operands[0]) == SFmode)
3507 && (operands[2] = find_constant_src (insn))"
3508 [(set (match_dup 0) (match_dup 2))]
3510 rtx c = operands[2];
3511 rtx r = operands[0];
3513 if (GET_CODE (r) == SUBREG)
3518 if (!standard_sse_constant_p (c))
3521 else if (FP_REG_P (r))
3523 if (!standard_80387_constant_p (c))
3526 else if (MMX_REG_P (r))
3530 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3532 [(set (match_operand:X87MODEF 0 "register_operand" "")
3533 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3534 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3535 && (standard_80387_constant_p (operands[1]) == 8
3536 || standard_80387_constant_p (operands[1]) == 9)"
3537 [(set (match_dup 0)(match_dup 1))
3539 (neg:X87MODEF (match_dup 0)))]
3543 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3544 if (real_isnegzero (&r))
3545 operands[1] = CONST0_RTX (<MODE>mode);
3547 operands[1] = CONST1_RTX (<MODE>mode);
3550 (define_insn "swapxf"
3551 [(set (match_operand:XF 0 "register_operand" "+f")
3552 (match_operand:XF 1 "register_operand" "+f"))
3557 if (STACK_TOP_P (operands[0]))
3562 [(set_attr "type" "fxch")
3563 (set_attr "mode" "XF")])
3565 (define_insn "*swap<mode>"
3566 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3567 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3570 "TARGET_80387 || reload_completed"
3572 if (STACK_TOP_P (operands[0]))
3577 [(set_attr "type" "fxch")
3578 (set_attr "mode" "<MODE>")])
3580 ;; Zero extension instructions
3582 (define_expand "zero_extendsidi2"
3583 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3584 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3589 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3594 (define_insn "*zero_extendsidi2_rex64"
3595 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3597 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3600 mov\t{%k1, %k0|%k0, %k1}
3602 movd\t{%1, %0|%0, %1}
3603 movd\t{%1, %0|%0, %1}
3604 %vmovd\t{%1, %0|%0, %1}
3605 %vmovd\t{%1, %0|%0, %1}"
3606 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3607 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3608 (set_attr "prefix_0f" "0,*,*,*,*,*")
3609 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3612 [(set (match_operand:DI 0 "memory_operand" "")
3613 (zero_extend:DI (match_dup 0)))]
3615 [(set (match_dup 4) (const_int 0))]
3616 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3618 ;; %%% Kill me once multi-word ops are sane.
3619 (define_insn "zero_extendsidi2_1"
3620 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3622 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3623 (clobber (reg:CC FLAGS_REG))]
3629 movd\t{%1, %0|%0, %1}
3630 movd\t{%1, %0|%0, %1}
3631 %vmovd\t{%1, %0|%0, %1}
3632 %vmovd\t{%1, %0|%0, %1}"
3633 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3634 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3635 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3638 [(set (match_operand:DI 0 "register_operand" "")
3639 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3640 (clobber (reg:CC FLAGS_REG))]
3641 "!TARGET_64BIT && reload_completed
3642 && true_regnum (operands[0]) == true_regnum (operands[1])"
3643 [(set (match_dup 4) (const_int 0))]
3644 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3647 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3648 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3649 (clobber (reg:CC FLAGS_REG))]
3650 "!TARGET_64BIT && reload_completed
3651 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3652 [(set (match_dup 3) (match_dup 1))
3653 (set (match_dup 4) (const_int 0))]
3654 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3656 (define_insn "zero_extend<mode>di2"
3657 [(set (match_operand:DI 0 "register_operand" "=r")
3659 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3661 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3662 [(set_attr "type" "imovx")
3663 (set_attr "mode" "SI")])
3665 (define_expand "zero_extendhisi2"
3666 [(set (match_operand:SI 0 "register_operand" "")
3667 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3670 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3672 operands[1] = force_reg (HImode, operands[1]);
3673 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3678 (define_insn_and_split "zero_extendhisi2_and"
3679 [(set (match_operand:SI 0 "register_operand" "=r")
3680 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3681 (clobber (reg:CC FLAGS_REG))]
3682 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3684 "&& reload_completed"
3685 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3686 (clobber (reg:CC FLAGS_REG))])]
3688 [(set_attr "type" "alu1")
3689 (set_attr "mode" "SI")])
3691 (define_insn "*zero_extendhisi2_movzwl"
3692 [(set (match_operand:SI 0 "register_operand" "=r")
3693 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3694 "!TARGET_ZERO_EXTEND_WITH_AND
3695 || optimize_function_for_size_p (cfun)"
3696 "movz{wl|x}\t{%1, %0|%0, %1}"
3697 [(set_attr "type" "imovx")
3698 (set_attr "mode" "SI")])
3700 (define_expand "zero_extendqi<mode>2"
3702 [(set (match_operand:SWI24 0 "register_operand" "")
3703 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3704 (clobber (reg:CC FLAGS_REG))])])
3706 (define_insn "*zero_extendqi<mode>2_and"
3707 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3708 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3709 (clobber (reg:CC FLAGS_REG))]
3710 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3712 [(set_attr "type" "alu1")
3713 (set_attr "mode" "<MODE>")])
3715 ;; When source and destination does not overlap, clear destination
3716 ;; first and then do the movb
3718 [(set (match_operand:SWI24 0 "register_operand" "")
3719 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3720 (clobber (reg:CC FLAGS_REG))]
3722 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3723 && ANY_QI_REG_P (operands[0])
3724 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3725 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3726 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3728 operands[2] = gen_lowpart (QImode, operands[0]);
3729 ix86_expand_clear (operands[0]);
3732 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3733 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3734 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3735 (clobber (reg:CC FLAGS_REG))]
3736 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3738 [(set_attr "type" "imovx,alu1")
3739 (set_attr "mode" "<MODE>")])
3741 ;; For the movzbl case strip only the clobber
3743 [(set (match_operand:SWI24 0 "register_operand" "")
3744 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3745 (clobber (reg:CC FLAGS_REG))]
3747 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3748 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3750 (zero_extend:SWI24 (match_dup 1)))])
3752 ; zero extend to SImode to avoid partial register stalls
3753 (define_insn "*zero_extendqi<mode>2_movzbl"
3754 [(set (match_operand:SWI24 0 "register_operand" "=r")
3755 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3757 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3758 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3759 [(set_attr "type" "imovx")
3760 (set_attr "mode" "SI")])
3762 ;; Rest is handled by single and.
3764 [(set (match_operand:SWI24 0 "register_operand" "")
3765 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3766 (clobber (reg:CC FLAGS_REG))]
3768 && true_regnum (operands[0]) == true_regnum (operands[1])"
3769 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3770 (clobber (reg:CC FLAGS_REG))])])
3772 ;; Sign extension instructions
3774 (define_expand "extendsidi2"
3775 [(set (match_operand:DI 0 "register_operand" "")
3776 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3781 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3786 (define_insn "*extendsidi2_rex64"
3787 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3788 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3792 movs{lq|x}\t{%1, %0|%0, %1}"
3793 [(set_attr "type" "imovx")
3794 (set_attr "mode" "DI")
3795 (set_attr "prefix_0f" "0")
3796 (set_attr "modrm" "0,1")])
3798 (define_insn "extendsidi2_1"
3799 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3800 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3801 (clobber (reg:CC FLAGS_REG))
3802 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3806 ;; Extend to memory case when source register does die.
3808 [(set (match_operand:DI 0 "memory_operand" "")
3809 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3810 (clobber (reg:CC FLAGS_REG))
3811 (clobber (match_operand:SI 2 "register_operand" ""))]
3813 && dead_or_set_p (insn, operands[1])
3814 && !reg_mentioned_p (operands[1], operands[0]))"
3815 [(set (match_dup 3) (match_dup 1))
3816 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3817 (clobber (reg:CC FLAGS_REG))])
3818 (set (match_dup 4) (match_dup 1))]
3819 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3821 ;; Extend to memory case when source register does not die.
3823 [(set (match_operand:DI 0 "memory_operand" "")
3824 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3825 (clobber (reg:CC FLAGS_REG))
3826 (clobber (match_operand:SI 2 "register_operand" ""))]
3830 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3832 emit_move_insn (operands[3], operands[1]);
3834 /* Generate a cltd if possible and doing so it profitable. */
3835 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3836 && true_regnum (operands[1]) == AX_REG
3837 && true_regnum (operands[2]) == DX_REG)
3839 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3843 emit_move_insn (operands[2], operands[1]);
3844 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3846 emit_move_insn (operands[4], operands[2]);
3850 ;; Extend to register case. Optimize case where source and destination
3851 ;; registers match and cases where we can use cltd.
3853 [(set (match_operand:DI 0 "register_operand" "")
3854 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3855 (clobber (reg:CC FLAGS_REG))
3856 (clobber (match_scratch:SI 2 ""))]
3860 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3862 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3863 emit_move_insn (operands[3], operands[1]);
3865 /* Generate a cltd if possible and doing so it profitable. */
3866 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3867 && true_regnum (operands[3]) == AX_REG
3868 && true_regnum (operands[4]) == DX_REG)
3870 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3874 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3875 emit_move_insn (operands[4], operands[1]);
3877 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3881 (define_insn "extend<mode>di2"
3882 [(set (match_operand:DI 0 "register_operand" "=r")
3884 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3886 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3887 [(set_attr "type" "imovx")
3888 (set_attr "mode" "DI")])
3890 (define_insn "extendhisi2"
3891 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3892 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3895 switch (get_attr_prefix_0f (insn))
3898 return "{cwtl|cwde}";
3900 return "movs{wl|x}\t{%1, %0|%0, %1}";
3903 [(set_attr "type" "imovx")
3904 (set_attr "mode" "SI")
3905 (set (attr "prefix_0f")
3906 ;; movsx is short decodable while cwtl is vector decoded.
3907 (if_then_else (and (eq_attr "cpu" "!k6")
3908 (eq_attr "alternative" "0"))
3910 (const_string "1")))
3912 (if_then_else (eq_attr "prefix_0f" "0")
3914 (const_string "1")))])
3916 (define_insn "*extendhisi2_zext"
3917 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3920 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3923 switch (get_attr_prefix_0f (insn))
3926 return "{cwtl|cwde}";
3928 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3931 [(set_attr "type" "imovx")
3932 (set_attr "mode" "SI")
3933 (set (attr "prefix_0f")
3934 ;; movsx is short decodable while cwtl is vector decoded.
3935 (if_then_else (and (eq_attr "cpu" "!k6")
3936 (eq_attr "alternative" "0"))
3938 (const_string "1")))
3940 (if_then_else (eq_attr "prefix_0f" "0")
3942 (const_string "1")))])
3944 (define_insn "extendqisi2"
3945 [(set (match_operand:SI 0 "register_operand" "=r")
3946 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3948 "movs{bl|x}\t{%1, %0|%0, %1}"
3949 [(set_attr "type" "imovx")
3950 (set_attr "mode" "SI")])
3952 (define_insn "*extendqisi2_zext"
3953 [(set (match_operand:DI 0 "register_operand" "=r")
3955 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3957 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3958 [(set_attr "type" "imovx")
3959 (set_attr "mode" "SI")])
3961 (define_insn "extendqihi2"
3962 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3963 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3966 switch (get_attr_prefix_0f (insn))
3969 return "{cbtw|cbw}";
3971 return "movs{bw|x}\t{%1, %0|%0, %1}";
3974 [(set_attr "type" "imovx")
3975 (set_attr "mode" "HI")
3976 (set (attr "prefix_0f")
3977 ;; movsx is short decodable while cwtl is vector decoded.
3978 (if_then_else (and (eq_attr "cpu" "!k6")
3979 (eq_attr "alternative" "0"))
3981 (const_string "1")))
3983 (if_then_else (eq_attr "prefix_0f" "0")
3985 (const_string "1")))])
3987 ;; Conversions between float and double.
3989 ;; These are all no-ops in the model used for the 80387.
3990 ;; So just emit moves.
3992 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3994 [(set (match_operand:DF 0 "push_operand" "")
3995 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3997 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3998 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4001 [(set (match_operand:XF 0 "push_operand" "")
4002 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
4004 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4005 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4006 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4008 (define_expand "extendsfdf2"
4009 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4010 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4011 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4013 /* ??? Needed for compress_float_constant since all fp constants
4014 are LEGITIMATE_CONSTANT_P. */
4015 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4017 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4018 && standard_80387_constant_p (operands[1]) > 0)
4020 operands[1] = simplify_const_unary_operation
4021 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4022 emit_move_insn_1 (operands[0], operands[1]);
4025 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4029 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4031 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4033 We do the conversion post reload to avoid producing of 128bit spills
4034 that might lead to ICE on 32bit target. The sequence unlikely combine
4037 [(set (match_operand:DF 0 "register_operand" "")
4039 (match_operand:SF 1 "nonimmediate_operand" "")))]
4040 "TARGET_USE_VECTOR_FP_CONVERTS
4041 && optimize_insn_for_speed_p ()
4042 && reload_completed && SSE_REG_P (operands[0])"
4047 (parallel [(const_int 0) (const_int 1)]))))]
4049 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4050 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4051 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4052 Try to avoid move when unpacking can be done in source. */
4053 if (REG_P (operands[1]))
4055 /* If it is unsafe to overwrite upper half of source, we need
4056 to move to destination and unpack there. */
4057 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4058 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4059 && true_regnum (operands[0]) != true_regnum (operands[1]))
4061 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4062 emit_move_insn (tmp, operands[1]);
4065 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4066 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4070 emit_insn (gen_vec_setv4sf_0 (operands[3],
4071 CONST0_RTX (V4SFmode), operands[1]));
4074 (define_insn "*extendsfdf2_mixed"
4075 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4077 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4078 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4080 switch (which_alternative)
4084 return output_387_reg_move (insn, operands);
4087 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4093 [(set_attr "type" "fmov,fmov,ssecvt")
4094 (set_attr "prefix" "orig,orig,maybe_vex")
4095 (set_attr "mode" "SF,XF,DF")])
4097 (define_insn "*extendsfdf2_sse"
4098 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4099 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4100 "TARGET_SSE2 && TARGET_SSE_MATH"
4101 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4102 [(set_attr "type" "ssecvt")
4103 (set_attr "prefix" "maybe_vex")
4104 (set_attr "mode" "DF")])
4106 (define_insn "*extendsfdf2_i387"
4107 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4108 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4110 "* return output_387_reg_move (insn, operands);"
4111 [(set_attr "type" "fmov")
4112 (set_attr "mode" "SF,XF")])
4114 (define_expand "extend<mode>xf2"
4115 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4116 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4119 /* ??? Needed for compress_float_constant since all fp constants
4120 are LEGITIMATE_CONSTANT_P. */
4121 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4123 if (standard_80387_constant_p (operands[1]) > 0)
4125 operands[1] = simplify_const_unary_operation
4126 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4127 emit_move_insn_1 (operands[0], operands[1]);
4130 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4134 (define_insn "*extend<mode>xf2_i387"
4135 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4137 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4139 "* return output_387_reg_move (insn, operands);"
4140 [(set_attr "type" "fmov")
4141 (set_attr "mode" "<MODE>,XF")])
4143 ;; %%% This seems bad bad news.
4144 ;; This cannot output into an f-reg because there is no way to be sure
4145 ;; of truncating in that case. Otherwise this is just like a simple move
4146 ;; insn. So we pretend we can output to a reg in order to get better
4147 ;; register preferencing, but we really use a stack slot.
4149 ;; Conversion from DFmode to SFmode.
4151 (define_expand "truncdfsf2"
4152 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4154 (match_operand:DF 1 "nonimmediate_operand" "")))]
4155 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4157 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4159 else if (flag_unsafe_math_optimizations)
4163 enum ix86_stack_slot slot = (virtuals_instantiated
4166 rtx temp = assign_386_stack_local (SFmode, slot);
4167 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4172 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4174 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4176 We do the conversion post reload to avoid producing of 128bit spills
4177 that might lead to ICE on 32bit target. The sequence unlikely combine
4180 [(set (match_operand:SF 0 "register_operand" "")
4182 (match_operand:DF 1 "nonimmediate_operand" "")))]
4183 "TARGET_USE_VECTOR_FP_CONVERTS
4184 && optimize_insn_for_speed_p ()
4185 && reload_completed && SSE_REG_P (operands[0])"
4188 (float_truncate:V2SF
4192 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4193 operands[3] = CONST0_RTX (V2SFmode);
4194 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4195 /* Use movsd for loading from memory, unpcklpd for registers.
4196 Try to avoid move when unpacking can be done in source, or SSE3
4197 movddup is available. */
4198 if (REG_P (operands[1]))
4201 && true_regnum (operands[0]) != true_regnum (operands[1])
4202 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4203 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4205 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4206 emit_move_insn (tmp, operands[1]);
4209 else if (!TARGET_SSE3)
4210 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4211 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4214 emit_insn (gen_sse2_loadlpd (operands[4],
4215 CONST0_RTX (V2DFmode), operands[1]));
4218 (define_expand "truncdfsf2_with_temp"
4219 [(parallel [(set (match_operand:SF 0 "" "")
4220 (float_truncate:SF (match_operand:DF 1 "" "")))
4221 (clobber (match_operand:SF 2 "" ""))])])
4223 (define_insn "*truncdfsf_fast_mixed"
4224 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4226 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4227 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4229 switch (which_alternative)
4232 return output_387_reg_move (insn, operands);
4234 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4239 [(set_attr "type" "fmov,ssecvt")
4240 (set_attr "prefix" "orig,maybe_vex")
4241 (set_attr "mode" "SF")])
4243 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4244 ;; because nothing we do here is unsafe.
4245 (define_insn "*truncdfsf_fast_sse"
4246 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4248 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4249 "TARGET_SSE2 && TARGET_SSE_MATH"
4250 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4251 [(set_attr "type" "ssecvt")
4252 (set_attr "prefix" "maybe_vex")
4253 (set_attr "mode" "SF")])
4255 (define_insn "*truncdfsf_fast_i387"
4256 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4258 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4259 "TARGET_80387 && flag_unsafe_math_optimizations"
4260 "* return output_387_reg_move (insn, operands);"
4261 [(set_attr "type" "fmov")
4262 (set_attr "mode" "SF")])
4264 (define_insn "*truncdfsf_mixed"
4265 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4267 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4268 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4269 "TARGET_MIX_SSE_I387"
4271 switch (which_alternative)
4274 return output_387_reg_move (insn, operands);
4276 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4282 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4283 (set_attr "unit" "*,*,i387,i387,i387")
4284 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4285 (set_attr "mode" "SF")])
4287 (define_insn "*truncdfsf_i387"
4288 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4290 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4291 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4294 switch (which_alternative)
4297 return output_387_reg_move (insn, operands);
4303 [(set_attr "type" "fmov,multi,multi,multi")
4304 (set_attr "unit" "*,i387,i387,i387")
4305 (set_attr "mode" "SF")])
4307 (define_insn "*truncdfsf2_i387_1"
4308 [(set (match_operand:SF 0 "memory_operand" "=m")
4310 (match_operand:DF 1 "register_operand" "f")))]
4312 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4313 && !TARGET_MIX_SSE_I387"
4314 "* return output_387_reg_move (insn, operands);"
4315 [(set_attr "type" "fmov")
4316 (set_attr "mode" "SF")])
4319 [(set (match_operand:SF 0 "register_operand" "")
4321 (match_operand:DF 1 "fp_register_operand" "")))
4322 (clobber (match_operand 2 "" ""))]
4324 [(set (match_dup 2) (match_dup 1))
4325 (set (match_dup 0) (match_dup 2))]
4326 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4328 ;; Conversion from XFmode to {SF,DF}mode
4330 (define_expand "truncxf<mode>2"
4331 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4332 (float_truncate:MODEF
4333 (match_operand:XF 1 "register_operand" "")))
4334 (clobber (match_dup 2))])]
4337 if (flag_unsafe_math_optimizations)
4339 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4340 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4341 if (reg != operands[0])
4342 emit_move_insn (operands[0], reg);
4347 enum ix86_stack_slot slot = (virtuals_instantiated
4350 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4354 (define_insn "*truncxfsf2_mixed"
4355 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4357 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4358 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4361 gcc_assert (!which_alternative);
4362 return output_387_reg_move (insn, operands);
4364 [(set_attr "type" "fmov,multi,multi,multi")
4365 (set_attr "unit" "*,i387,i387,i387")
4366 (set_attr "mode" "SF")])
4368 (define_insn "*truncxfdf2_mixed"
4369 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4371 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4372 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4375 gcc_assert (!which_alternative);
4376 return output_387_reg_move (insn, operands);
4378 [(set_attr "type" "fmov,multi,multi,multi")
4379 (set_attr "unit" "*,i387,i387,i387")
4380 (set_attr "mode" "DF")])
4382 (define_insn "truncxf<mode>2_i387_noop"
4383 [(set (match_operand:MODEF 0 "register_operand" "=f")
4384 (float_truncate:MODEF
4385 (match_operand:XF 1 "register_operand" "f")))]
4386 "TARGET_80387 && flag_unsafe_math_optimizations"
4387 "* return output_387_reg_move (insn, operands);"
4388 [(set_attr "type" "fmov")
4389 (set_attr "mode" "<MODE>")])
4391 (define_insn "*truncxf<mode>2_i387"
4392 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4393 (float_truncate:MODEF
4394 (match_operand:XF 1 "register_operand" "f")))]
4396 "* return output_387_reg_move (insn, operands);"
4397 [(set_attr "type" "fmov")
4398 (set_attr "mode" "<MODE>")])
4401 [(set (match_operand:MODEF 0 "register_operand" "")
4402 (float_truncate:MODEF
4403 (match_operand:XF 1 "register_operand" "")))
4404 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4405 "TARGET_80387 && reload_completed"
4406 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4407 (set (match_dup 0) (match_dup 2))])
4410 [(set (match_operand:MODEF 0 "memory_operand" "")
4411 (float_truncate:MODEF
4412 (match_operand:XF 1 "register_operand" "")))
4413 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4415 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4417 ;; Signed conversion to DImode.
4419 (define_expand "fix_truncxfdi2"
4420 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4421 (fix:DI (match_operand:XF 1 "register_operand" "")))
4422 (clobber (reg:CC FLAGS_REG))])]
4427 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4432 (define_expand "fix_trunc<mode>di2"
4433 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4434 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4435 (clobber (reg:CC FLAGS_REG))])]
4436 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4439 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4441 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4444 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4446 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4447 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4448 if (out != operands[0])
4449 emit_move_insn (operands[0], out);
4454 ;; Signed conversion to SImode.
4456 (define_expand "fix_truncxfsi2"
4457 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4458 (fix:SI (match_operand:XF 1 "register_operand" "")))
4459 (clobber (reg:CC FLAGS_REG))])]
4464 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4469 (define_expand "fix_trunc<mode>si2"
4470 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4471 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4472 (clobber (reg:CC FLAGS_REG))])]
4473 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4476 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4478 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4481 if (SSE_FLOAT_MODE_P (<MODE>mode))
4483 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4484 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4485 if (out != operands[0])
4486 emit_move_insn (operands[0], out);
4491 ;; Signed conversion to HImode.
4493 (define_expand "fix_trunc<mode>hi2"
4494 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4495 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4496 (clobber (reg:CC FLAGS_REG))])]
4498 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4502 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4507 ;; Unsigned conversion to SImode.
4509 (define_expand "fixuns_trunc<mode>si2"
4511 [(set (match_operand:SI 0 "register_operand" "")
4513 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4515 (clobber (match_scratch:<ssevecmode> 3 ""))
4516 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4517 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4519 enum machine_mode mode = <MODE>mode;
4520 enum machine_mode vecmode = <ssevecmode>mode;
4521 REAL_VALUE_TYPE TWO31r;
4524 if (optimize_insn_for_size_p ())
4527 real_ldexp (&TWO31r, &dconst1, 31);
4528 two31 = const_double_from_real_value (TWO31r, mode);
4529 two31 = ix86_build_const_vector (vecmode, true, two31);
4530 operands[2] = force_reg (vecmode, two31);
4533 (define_insn_and_split "*fixuns_trunc<mode>_1"
4534 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4536 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4537 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4538 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4539 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4540 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4541 && optimize_function_for_speed_p (cfun)"
4543 "&& reload_completed"
4546 ix86_split_convert_uns_si_sse (operands);
4550 ;; Unsigned conversion to HImode.
4551 ;; Without these patterns, we'll try the unsigned SI conversion which
4552 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4554 (define_expand "fixuns_trunc<mode>hi2"
4556 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4557 (set (match_operand:HI 0 "nonimmediate_operand" "")
4558 (subreg:HI (match_dup 2) 0))]
4559 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4560 "operands[2] = gen_reg_rtx (SImode);")
4562 ;; When SSE is available, it is always faster to use it!
4563 (define_insn "fix_trunc<mode>di_sse"
4564 [(set (match_operand:DI 0 "register_operand" "=r,r")
4565 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4566 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4567 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4568 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4569 [(set_attr "type" "sseicvt")
4570 (set_attr "prefix" "maybe_vex")
4571 (set_attr "prefix_rex" "1")
4572 (set_attr "mode" "<MODE>")
4573 (set_attr "athlon_decode" "double,vector")
4574 (set_attr "amdfam10_decode" "double,double")
4575 (set_attr "bdver1_decode" "double,double")])
4577 (define_insn "fix_trunc<mode>si_sse"
4578 [(set (match_operand:SI 0 "register_operand" "=r,r")
4579 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4580 "SSE_FLOAT_MODE_P (<MODE>mode)
4581 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4582 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4583 [(set_attr "type" "sseicvt")
4584 (set_attr "prefix" "maybe_vex")
4585 (set_attr "mode" "<MODE>")
4586 (set_attr "athlon_decode" "double,vector")
4587 (set_attr "amdfam10_decode" "double,double")
4588 (set_attr "bdver1_decode" "double,double")])
4590 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4592 [(set (match_operand:MODEF 0 "register_operand" "")
4593 (match_operand:MODEF 1 "memory_operand" ""))
4594 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4595 (fix:SSEMODEI24 (match_dup 0)))]
4596 "TARGET_SHORTEN_X87_SSE
4597 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4598 && peep2_reg_dead_p (2, operands[0])"
4599 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4601 ;; Avoid vector decoded forms of the instruction.
4603 [(match_scratch:DF 2 "Y2")
4604 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4605 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4606 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4607 [(set (match_dup 2) (match_dup 1))
4608 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4611 [(match_scratch:SF 2 "x")
4612 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4613 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4614 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4615 [(set (match_dup 2) (match_dup 1))
4616 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4618 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4619 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4620 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4621 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4623 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4624 && (TARGET_64BIT || <MODE>mode != DImode))
4626 && can_create_pseudo_p ()"
4631 if (memory_operand (operands[0], VOIDmode))
4632 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4635 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4636 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4642 [(set_attr "type" "fisttp")
4643 (set_attr "mode" "<MODE>")])
4645 (define_insn "fix_trunc<mode>_i387_fisttp"
4646 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4647 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4648 (clobber (match_scratch:XF 2 "=&1f"))]
4649 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4651 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4652 && (TARGET_64BIT || <MODE>mode != DImode))
4653 && TARGET_SSE_MATH)"
4654 "* return output_fix_trunc (insn, operands, 1);"
4655 [(set_attr "type" "fisttp")
4656 (set_attr "mode" "<MODE>")])
4658 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4659 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4660 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4661 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4662 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4663 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4665 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4666 && (TARGET_64BIT || <MODE>mode != DImode))
4667 && TARGET_SSE_MATH)"
4669 [(set_attr "type" "fisttp")
4670 (set_attr "mode" "<MODE>")])
4673 [(set (match_operand:X87MODEI 0 "register_operand" "")
4674 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4675 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4676 (clobber (match_scratch 3 ""))]
4678 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4679 (clobber (match_dup 3))])
4680 (set (match_dup 0) (match_dup 2))])
4683 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4684 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4685 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4686 (clobber (match_scratch 3 ""))]
4688 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4689 (clobber (match_dup 3))])])
4691 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4692 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4693 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4694 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4695 ;; function in i386.c.
4696 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4697 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4698 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4699 (clobber (reg:CC FLAGS_REG))]
4700 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4702 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4703 && (TARGET_64BIT || <MODE>mode != DImode))
4704 && can_create_pseudo_p ()"
4709 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4711 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4712 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4713 if (memory_operand (operands[0], VOIDmode))
4714 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4715 operands[2], operands[3]));
4718 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4719 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4720 operands[2], operands[3],
4725 [(set_attr "type" "fistp")
4726 (set_attr "i387_cw" "trunc")
4727 (set_attr "mode" "<MODE>")])
4729 (define_insn "fix_truncdi_i387"
4730 [(set (match_operand:DI 0 "memory_operand" "=m")
4731 (fix:DI (match_operand 1 "register_operand" "f")))
4732 (use (match_operand:HI 2 "memory_operand" "m"))
4733 (use (match_operand:HI 3 "memory_operand" "m"))
4734 (clobber (match_scratch:XF 4 "=&1f"))]
4735 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4737 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4738 "* return output_fix_trunc (insn, operands, 0);"
4739 [(set_attr "type" "fistp")
4740 (set_attr "i387_cw" "trunc")
4741 (set_attr "mode" "DI")])
4743 (define_insn "fix_truncdi_i387_with_temp"
4744 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4745 (fix:DI (match_operand 1 "register_operand" "f,f")))
4746 (use (match_operand:HI 2 "memory_operand" "m,m"))
4747 (use (match_operand:HI 3 "memory_operand" "m,m"))
4748 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4749 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4750 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4752 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4754 [(set_attr "type" "fistp")
4755 (set_attr "i387_cw" "trunc")
4756 (set_attr "mode" "DI")])
4759 [(set (match_operand:DI 0 "register_operand" "")
4760 (fix:DI (match_operand 1 "register_operand" "")))
4761 (use (match_operand:HI 2 "memory_operand" ""))
4762 (use (match_operand:HI 3 "memory_operand" ""))
4763 (clobber (match_operand:DI 4 "memory_operand" ""))
4764 (clobber (match_scratch 5 ""))]
4766 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4769 (clobber (match_dup 5))])
4770 (set (match_dup 0) (match_dup 4))])
4773 [(set (match_operand:DI 0 "memory_operand" "")
4774 (fix:DI (match_operand 1 "register_operand" "")))
4775 (use (match_operand:HI 2 "memory_operand" ""))
4776 (use (match_operand:HI 3 "memory_operand" ""))
4777 (clobber (match_operand:DI 4 "memory_operand" ""))
4778 (clobber (match_scratch 5 ""))]
4780 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4783 (clobber (match_dup 5))])])
4785 (define_insn "fix_trunc<mode>_i387"
4786 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4787 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4788 (use (match_operand:HI 2 "memory_operand" "m"))
4789 (use (match_operand:HI 3 "memory_operand" "m"))]
4790 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4792 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4793 "* return output_fix_trunc (insn, operands, 0);"
4794 [(set_attr "type" "fistp")
4795 (set_attr "i387_cw" "trunc")
4796 (set_attr "mode" "<MODE>")])
4798 (define_insn "fix_trunc<mode>_i387_with_temp"
4799 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4800 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4801 (use (match_operand:HI 2 "memory_operand" "m,m"))
4802 (use (match_operand:HI 3 "memory_operand" "m,m"))
4803 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4804 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4806 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4808 [(set_attr "type" "fistp")
4809 (set_attr "i387_cw" "trunc")
4810 (set_attr "mode" "<MODE>")])
4813 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4814 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4815 (use (match_operand:HI 2 "memory_operand" ""))
4816 (use (match_operand:HI 3 "memory_operand" ""))
4817 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4819 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4821 (use (match_dup 3))])
4822 (set (match_dup 0) (match_dup 4))])
4825 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4826 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4827 (use (match_operand:HI 2 "memory_operand" ""))
4828 (use (match_operand:HI 3 "memory_operand" ""))
4829 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4831 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4833 (use (match_dup 3))])])
4835 (define_insn "x86_fnstcw_1"
4836 [(set (match_operand:HI 0 "memory_operand" "=m")
4837 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4840 [(set (attr "length")
4841 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4842 (set_attr "mode" "HI")
4843 (set_attr "unit" "i387")
4844 (set_attr "bdver1_decode" "vector")])
4846 (define_insn "x86_fldcw_1"
4847 [(set (reg:HI FPCR_REG)
4848 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4851 [(set (attr "length")
4852 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4853 (set_attr "mode" "HI")
4854 (set_attr "unit" "i387")
4855 (set_attr "athlon_decode" "vector")
4856 (set_attr "amdfam10_decode" "vector")
4857 (set_attr "bdver1_decode" "vector")])
4859 ;; Conversion between fixed point and floating point.
4861 ;; Even though we only accept memory inputs, the backend _really_
4862 ;; wants to be able to do this between registers.
4864 (define_expand "floathi<mode>2"
4865 [(set (match_operand:X87MODEF 0 "register_operand" "")
4866 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4868 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4869 || TARGET_MIX_SSE_I387)")
4871 ;; Pre-reload splitter to add memory clobber to the pattern.
4872 (define_insn_and_split "*floathi<mode>2_1"
4873 [(set (match_operand:X87MODEF 0 "register_operand" "")
4874 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4876 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4877 || TARGET_MIX_SSE_I387)
4878 && can_create_pseudo_p ()"
4881 [(parallel [(set (match_dup 0)
4882 (float:X87MODEF (match_dup 1)))
4883 (clobber (match_dup 2))])]
4884 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4886 (define_insn "*floathi<mode>2_i387_with_temp"
4887 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4888 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4889 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4891 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4892 || TARGET_MIX_SSE_I387)"
4894 [(set_attr "type" "fmov,multi")
4895 (set_attr "mode" "<MODE>")
4896 (set_attr "unit" "*,i387")
4897 (set_attr "fp_int_src" "true")])
4899 (define_insn "*floathi<mode>2_i387"
4900 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4901 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4903 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4904 || TARGET_MIX_SSE_I387)"
4906 [(set_attr "type" "fmov")
4907 (set_attr "mode" "<MODE>")
4908 (set_attr "fp_int_src" "true")])
4911 [(set (match_operand:X87MODEF 0 "register_operand" "")
4912 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4913 (clobber (match_operand:HI 2 "memory_operand" ""))]
4915 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4916 || TARGET_MIX_SSE_I387)
4917 && reload_completed"
4918 [(set (match_dup 2) (match_dup 1))
4919 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4922 [(set (match_operand:X87MODEF 0 "register_operand" "")
4923 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4924 (clobber (match_operand:HI 2 "memory_operand" ""))]
4926 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4927 || TARGET_MIX_SSE_I387)
4928 && reload_completed"
4929 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4931 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4932 [(set (match_operand:X87MODEF 0 "register_operand" "")
4934 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4936 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4937 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4939 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4940 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4941 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4943 rtx reg = gen_reg_rtx (XFmode);
4946 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4948 if (<X87MODEF:MODE>mode == SFmode)
4949 insn = gen_truncxfsf2 (operands[0], reg);
4950 else if (<X87MODEF:MODE>mode == DFmode)
4951 insn = gen_truncxfdf2 (operands[0], reg);
4960 ;; Pre-reload splitter to add memory clobber to the pattern.
4961 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4962 [(set (match_operand:X87MODEF 0 "register_operand" "")
4963 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4965 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4966 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4967 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4968 || TARGET_MIX_SSE_I387))
4969 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4970 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4971 && ((<SSEMODEI24:MODE>mode == SImode
4972 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4973 && optimize_function_for_speed_p (cfun)
4974 && flag_trapping_math)
4975 || !(TARGET_INTER_UNIT_CONVERSIONS
4976 || optimize_function_for_size_p (cfun)))))
4977 && can_create_pseudo_p ()"
4980 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4981 (clobber (match_dup 2))])]
4983 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4985 /* Avoid store forwarding (partial memory) stall penalty
4986 by passing DImode value through XMM registers. */
4987 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4988 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4989 && optimize_function_for_speed_p (cfun))
4991 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4998 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4999 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5001 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5002 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5003 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5004 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5006 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5007 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5008 (set_attr "unit" "*,i387,*,*,*")
5009 (set_attr "athlon_decode" "*,*,double,direct,double")
5010 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5011 (set_attr "bdver1_decode" "*,*,double,direct,double")
5012 (set_attr "fp_int_src" "true")])
5014 (define_insn "*floatsi<mode>2_vector_mixed"
5015 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5016 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5017 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5018 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5022 [(set_attr "type" "fmov,sseicvt")
5023 (set_attr "mode" "<MODE>,<ssevecmode>")
5024 (set_attr "unit" "i387,*")
5025 (set_attr "athlon_decode" "*,direct")
5026 (set_attr "amdfam10_decode" "*,double")
5027 (set_attr "bdver1_decode" "*,direct")
5028 (set_attr "fp_int_src" "true")])
5030 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5031 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5033 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5034 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5035 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5036 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5038 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5039 (set_attr "mode" "<MODEF:MODE>")
5040 (set_attr "unit" "*,i387,*,*")
5041 (set_attr "athlon_decode" "*,*,double,direct")
5042 (set_attr "amdfam10_decode" "*,*,vector,double")
5043 (set_attr "bdver1_decode" "*,*,double,direct")
5044 (set_attr "fp_int_src" "true")])
5047 [(set (match_operand:MODEF 0 "register_operand" "")
5048 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5049 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5050 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5051 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5052 && TARGET_INTER_UNIT_CONVERSIONS
5054 && (SSE_REG_P (operands[0])
5055 || (GET_CODE (operands[0]) == SUBREG
5056 && SSE_REG_P (operands[0])))"
5057 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5060 [(set (match_operand:MODEF 0 "register_operand" "")
5061 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5062 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5063 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5064 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5065 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5067 && (SSE_REG_P (operands[0])
5068 || (GET_CODE (operands[0]) == SUBREG
5069 && SSE_REG_P (operands[0])))"
5070 [(set (match_dup 2) (match_dup 1))
5071 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5073 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5074 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5076 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5077 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5078 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5079 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5082 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5083 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5084 [(set_attr "type" "fmov,sseicvt,sseicvt")
5085 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5086 (set_attr "mode" "<MODEF:MODE>")
5087 (set (attr "prefix_rex")
5089 (and (eq_attr "prefix" "maybe_vex")
5090 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5092 (const_string "*")))
5093 (set_attr "unit" "i387,*,*")
5094 (set_attr "athlon_decode" "*,double,direct")
5095 (set_attr "amdfam10_decode" "*,vector,double")
5096 (set_attr "bdver1_decode" "*,double,direct")
5097 (set_attr "fp_int_src" "true")])
5099 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5100 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5102 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5103 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5104 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5105 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5108 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5109 [(set_attr "type" "fmov,sseicvt")
5110 (set_attr "prefix" "orig,maybe_vex")
5111 (set_attr "mode" "<MODEF:MODE>")
5112 (set (attr "prefix_rex")
5114 (and (eq_attr "prefix" "maybe_vex")
5115 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5117 (const_string "*")))
5118 (set_attr "athlon_decode" "*,direct")
5119 (set_attr "amdfam10_decode" "*,double")
5120 (set_attr "bdver1_decode" "*,direct")
5121 (set_attr "fp_int_src" "true")])
5123 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5124 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5126 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5127 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5128 "TARGET_SSE2 && TARGET_SSE_MATH
5129 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5131 [(set_attr "type" "sseicvt")
5132 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5133 (set_attr "athlon_decode" "double,direct,double")
5134 (set_attr "amdfam10_decode" "vector,double,double")
5135 (set_attr "bdver1_decode" "double,direct,double")
5136 (set_attr "fp_int_src" "true")])
5138 (define_insn "*floatsi<mode>2_vector_sse"
5139 [(set (match_operand:MODEF 0 "register_operand" "=x")
5140 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5141 "TARGET_SSE2 && TARGET_SSE_MATH
5142 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5144 [(set_attr "type" "sseicvt")
5145 (set_attr "mode" "<MODE>")
5146 (set_attr "athlon_decode" "direct")
5147 (set_attr "amdfam10_decode" "double")
5148 (set_attr "bdver1_decode" "direct")
5149 (set_attr "fp_int_src" "true")])
5152 [(set (match_operand:MODEF 0 "register_operand" "")
5153 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5154 (clobber (match_operand:SI 2 "memory_operand" ""))]
5155 "TARGET_SSE2 && TARGET_SSE_MATH
5156 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5158 && (SSE_REG_P (operands[0])
5159 || (GET_CODE (operands[0]) == SUBREG
5160 && SSE_REG_P (operands[0])))"
5163 rtx op1 = operands[1];
5165 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5167 if (GET_CODE (op1) == SUBREG)
5168 op1 = SUBREG_REG (op1);
5170 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5172 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5173 emit_insn (gen_sse2_loadld (operands[4],
5174 CONST0_RTX (V4SImode), operands[1]));
5176 /* We can ignore possible trapping value in the
5177 high part of SSE register for non-trapping math. */
5178 else if (SSE_REG_P (op1) && !flag_trapping_math)
5179 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5182 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5183 emit_move_insn (operands[2], operands[1]);
5184 emit_insn (gen_sse2_loadld (operands[4],
5185 CONST0_RTX (V4SImode), operands[2]));
5188 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5193 [(set (match_operand:MODEF 0 "register_operand" "")
5194 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5195 (clobber (match_operand:SI 2 "memory_operand" ""))]
5196 "TARGET_SSE2 && TARGET_SSE_MATH
5197 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5199 && (SSE_REG_P (operands[0])
5200 || (GET_CODE (operands[0]) == SUBREG
5201 && SSE_REG_P (operands[0])))"
5204 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5206 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5208 emit_insn (gen_sse2_loadld (operands[4],
5209 CONST0_RTX (V4SImode), operands[1]));
5211 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5216 [(set (match_operand:MODEF 0 "register_operand" "")
5217 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5218 "TARGET_SSE2 && TARGET_SSE_MATH
5219 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5221 && (SSE_REG_P (operands[0])
5222 || (GET_CODE (operands[0]) == SUBREG
5223 && SSE_REG_P (operands[0])))"
5226 rtx op1 = operands[1];
5228 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5230 if (GET_CODE (op1) == SUBREG)
5231 op1 = SUBREG_REG (op1);
5233 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5235 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5236 emit_insn (gen_sse2_loadld (operands[4],
5237 CONST0_RTX (V4SImode), operands[1]));
5239 /* We can ignore possible trapping value in the
5240 high part of SSE register for non-trapping math. */
5241 else if (SSE_REG_P (op1) && !flag_trapping_math)
5242 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5246 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5251 [(set (match_operand:MODEF 0 "register_operand" "")
5252 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5253 "TARGET_SSE2 && TARGET_SSE_MATH
5254 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5256 && (SSE_REG_P (operands[0])
5257 || (GET_CODE (operands[0]) == SUBREG
5258 && SSE_REG_P (operands[0])))"
5261 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5263 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5265 emit_insn (gen_sse2_loadld (operands[4],
5266 CONST0_RTX (V4SImode), operands[1]));
5268 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5272 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5273 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5275 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5276 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5277 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5278 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5280 [(set_attr "type" "sseicvt")
5281 (set_attr "mode" "<MODEF:MODE>")
5282 (set_attr "athlon_decode" "double,direct")
5283 (set_attr "amdfam10_decode" "vector,double")
5284 (set_attr "bdver1_decode" "double,direct")
5285 (set_attr "fp_int_src" "true")])
5287 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5288 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5290 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5291 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5292 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5293 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5294 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5295 [(set_attr "type" "sseicvt")
5296 (set_attr "prefix" "maybe_vex")
5297 (set_attr "mode" "<MODEF:MODE>")
5298 (set (attr "prefix_rex")
5300 (and (eq_attr "prefix" "maybe_vex")
5301 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5303 (const_string "*")))
5304 (set_attr "athlon_decode" "double,direct")
5305 (set_attr "amdfam10_decode" "vector,double")
5306 (set_attr "bdver1_decode" "double,direct")
5307 (set_attr "fp_int_src" "true")])
5310 [(set (match_operand:MODEF 0 "register_operand" "")
5311 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5312 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5313 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5314 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5315 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5317 && (SSE_REG_P (operands[0])
5318 || (GET_CODE (operands[0]) == SUBREG
5319 && SSE_REG_P (operands[0])))"
5320 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5322 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5323 [(set (match_operand:MODEF 0 "register_operand" "=x")
5325 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5326 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5327 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5328 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5329 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5330 [(set_attr "type" "sseicvt")
5331 (set_attr "prefix" "maybe_vex")
5332 (set_attr "mode" "<MODEF:MODE>")
5333 (set (attr "prefix_rex")
5335 (and (eq_attr "prefix" "maybe_vex")
5336 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5338 (const_string "*")))
5339 (set_attr "athlon_decode" "direct")
5340 (set_attr "amdfam10_decode" "double")
5341 (set_attr "bdver1_decode" "direct")
5342 (set_attr "fp_int_src" "true")])
5345 [(set (match_operand:MODEF 0 "register_operand" "")
5346 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5347 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5348 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5349 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5350 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5352 && (SSE_REG_P (operands[0])
5353 || (GET_CODE (operands[0]) == SUBREG
5354 && SSE_REG_P (operands[0])))"
5355 [(set (match_dup 2) (match_dup 1))
5356 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5359 [(set (match_operand:MODEF 0 "register_operand" "")
5360 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5361 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5362 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5363 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5365 && (SSE_REG_P (operands[0])
5366 || (GET_CODE (operands[0]) == SUBREG
5367 && SSE_REG_P (operands[0])))"
5368 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5370 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5371 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5373 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5374 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5376 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5380 [(set_attr "type" "fmov,multi")
5381 (set_attr "mode" "<X87MODEF:MODE>")
5382 (set_attr "unit" "*,i387")
5383 (set_attr "fp_int_src" "true")])
5385 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5386 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5388 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5390 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5392 [(set_attr "type" "fmov")
5393 (set_attr "mode" "<X87MODEF:MODE>")
5394 (set_attr "fp_int_src" "true")])
5397 [(set (match_operand:X87MODEF 0 "register_operand" "")
5398 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5399 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5401 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5403 && FP_REG_P (operands[0])"
5404 [(set (match_dup 2) (match_dup 1))
5405 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5408 [(set (match_operand:X87MODEF 0 "register_operand" "")
5409 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5410 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5412 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5414 && FP_REG_P (operands[0])"
5415 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5417 ;; Avoid store forwarding (partial memory) stall penalty
5418 ;; by passing DImode value through XMM registers. */
5420 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5421 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5423 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5424 (clobber (match_scratch:V4SI 3 "=X,x"))
5425 (clobber (match_scratch:V4SI 4 "=X,x"))
5426 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5427 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5428 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5429 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5431 [(set_attr "type" "multi")
5432 (set_attr "mode" "<X87MODEF:MODE>")
5433 (set_attr "unit" "i387")
5434 (set_attr "fp_int_src" "true")])
5437 [(set (match_operand:X87MODEF 0 "register_operand" "")
5438 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5439 (clobber (match_scratch:V4SI 3 ""))
5440 (clobber (match_scratch:V4SI 4 ""))
5441 (clobber (match_operand:DI 2 "memory_operand" ""))]
5442 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5443 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5444 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5446 && FP_REG_P (operands[0])"
5447 [(set (match_dup 2) (match_dup 3))
5448 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5450 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5451 Assemble the 64-bit DImode value in an xmm register. */
5452 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5453 gen_rtx_SUBREG (SImode, operands[1], 0)));
5454 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5455 gen_rtx_SUBREG (SImode, operands[1], 4)));
5456 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5459 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5463 [(set (match_operand:X87MODEF 0 "register_operand" "")
5464 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5465 (clobber (match_scratch:V4SI 3 ""))
5466 (clobber (match_scratch:V4SI 4 ""))
5467 (clobber (match_operand:DI 2 "memory_operand" ""))]
5468 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5469 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5470 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5472 && FP_REG_P (operands[0])"
5473 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5475 ;; Avoid store forwarding (partial memory) stall penalty by extending
5476 ;; SImode value to DImode through XMM register instead of pushing two
5477 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5478 ;; targets benefit from this optimization. Also note that fild
5479 ;; loads from memory only.
5481 (define_insn "*floatunssi<mode>2_1"
5482 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5483 (unsigned_float:X87MODEF
5484 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5485 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5486 (clobber (match_scratch:SI 3 "=X,x"))]
5488 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5491 [(set_attr "type" "multi")
5492 (set_attr "mode" "<MODE>")])
5495 [(set (match_operand:X87MODEF 0 "register_operand" "")
5496 (unsigned_float:X87MODEF
5497 (match_operand:SI 1 "register_operand" "")))
5498 (clobber (match_operand:DI 2 "memory_operand" ""))
5499 (clobber (match_scratch:SI 3 ""))]
5501 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5503 && reload_completed"
5504 [(set (match_dup 2) (match_dup 1))
5506 (float:X87MODEF (match_dup 2)))]
5507 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5510 [(set (match_operand:X87MODEF 0 "register_operand" "")
5511 (unsigned_float:X87MODEF
5512 (match_operand:SI 1 "memory_operand" "")))
5513 (clobber (match_operand:DI 2 "memory_operand" ""))
5514 (clobber (match_scratch:SI 3 ""))]
5516 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5518 && reload_completed"
5519 [(set (match_dup 2) (match_dup 3))
5521 (float:X87MODEF (match_dup 2)))]
5523 emit_move_insn (operands[3], operands[1]);
5524 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5527 (define_expand "floatunssi<mode>2"
5529 [(set (match_operand:X87MODEF 0 "register_operand" "")
5530 (unsigned_float:X87MODEF
5531 (match_operand:SI 1 "nonimmediate_operand" "")))
5532 (clobber (match_dup 2))
5533 (clobber (match_scratch:SI 3 ""))])]
5535 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5537 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5539 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5541 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5546 enum ix86_stack_slot slot = (virtuals_instantiated
5549 operands[2] = assign_386_stack_local (DImode, slot);
5553 (define_expand "floatunsdisf2"
5554 [(use (match_operand:SF 0 "register_operand" ""))
5555 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5556 "TARGET_64BIT && TARGET_SSE_MATH"
5557 "x86_emit_floatuns (operands); DONE;")
5559 (define_expand "floatunsdidf2"
5560 [(use (match_operand:DF 0 "register_operand" ""))
5561 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5562 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5563 && TARGET_SSE2 && TARGET_SSE_MATH"
5566 x86_emit_floatuns (operands);
5568 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5574 (define_expand "add<mode>3"
5575 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5576 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5577 (match_operand:SDWIM 2 "<general_operand>" "")))]
5579 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5581 (define_insn_and_split "*add<dwi>3_doubleword"
5582 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5584 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5585 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5586 (clobber (reg:CC FLAGS_REG))]
5587 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5590 [(parallel [(set (reg:CC FLAGS_REG)
5591 (unspec:CC [(match_dup 1) (match_dup 2)]
5594 (plus:DWIH (match_dup 1) (match_dup 2)))])
5595 (parallel [(set (match_dup 3)
5599 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5601 (clobber (reg:CC FLAGS_REG))])]
5602 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5604 (define_insn "*add<mode>3_cc"
5605 [(set (reg:CC FLAGS_REG)
5607 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5608 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5610 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5611 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5612 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5613 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5614 [(set_attr "type" "alu")
5615 (set_attr "mode" "<MODE>")])
5617 (define_insn "addqi3_cc"
5618 [(set (reg:CC FLAGS_REG)
5620 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5621 (match_operand:QI 2 "general_operand" "qn,qm")]
5623 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5624 (plus:QI (match_dup 1) (match_dup 2)))]
5625 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5626 "add{b}\t{%2, %0|%0, %2}"
5627 [(set_attr "type" "alu")
5628 (set_attr "mode" "QI")])
5630 (define_insn "*lea_1"
5631 [(set (match_operand:P 0 "register_operand" "=r")
5632 (match_operand:P 1 "no_seg_address_operand" "p"))]
5634 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5635 [(set_attr "type" "lea")
5636 (set_attr "mode" "<MODE>")])
5638 (define_insn "*lea_2"
5639 [(set (match_operand:SI 0 "register_operand" "=r")
5640 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5642 "lea{l}\t{%a1, %0|%0, %a1}"
5643 [(set_attr "type" "lea")
5644 (set_attr "mode" "SI")])
5646 (define_insn "*lea_2_zext"
5647 [(set (match_operand:DI 0 "register_operand" "=r")
5649 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5651 "lea{l}\t{%a1, %k0|%k0, %a1}"
5652 [(set_attr "type" "lea")
5653 (set_attr "mode" "SI")])
5655 (define_insn "*add<mode>_1"
5656 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5658 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5659 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5660 (clobber (reg:CC FLAGS_REG))]
5661 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5663 switch (get_attr_type (insn))
5669 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5670 if (operands[2] == const1_rtx)
5671 return "inc{<imodesuffix>}\t%0";
5674 gcc_assert (operands[2] == constm1_rtx);
5675 return "dec{<imodesuffix>}\t%0";
5679 /* For most processors, ADD is faster than LEA. This alternative
5680 was added to use ADD as much as possible. */
5681 if (which_alternative == 2)
5684 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5687 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5688 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5689 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5691 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5695 (cond [(eq_attr "alternative" "3")
5696 (const_string "lea")
5697 (match_operand:SWI48 2 "incdec_operand" "")
5698 (const_string "incdec")
5700 (const_string "alu")))
5701 (set (attr "length_immediate")
5703 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5705 (const_string "*")))
5706 (set_attr "mode" "<MODE>")])
5708 ;; It may seem that nonimmediate operand is proper one for operand 1.
5709 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5710 ;; we take care in ix86_binary_operator_ok to not allow two memory
5711 ;; operands so proper swapping will be done in reload. This allow
5712 ;; patterns constructed from addsi_1 to match.
5714 (define_insn "*addsi_1_zext"
5715 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5717 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5718 (match_operand:SI 2 "general_operand" "g,0,li"))))
5719 (clobber (reg:CC FLAGS_REG))]
5720 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5722 switch (get_attr_type (insn))
5728 if (operands[2] == const1_rtx)
5729 return "inc{l}\t%k0";
5732 gcc_assert (operands[2] == constm1_rtx);
5733 return "dec{l}\t%k0";
5737 /* For most processors, ADD is faster than LEA. This alternative
5738 was added to use ADD as much as possible. */
5739 if (which_alternative == 1)
5742 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5745 if (x86_maybe_negate_const_int (&operands[2], SImode))
5746 return "sub{l}\t{%2, %k0|%k0, %2}";
5748 return "add{l}\t{%2, %k0|%k0, %2}";
5752 (cond [(eq_attr "alternative" "2")
5753 (const_string "lea")
5754 (match_operand:SI 2 "incdec_operand" "")
5755 (const_string "incdec")
5757 (const_string "alu")))
5758 (set (attr "length_immediate")
5760 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5762 (const_string "*")))
5763 (set_attr "mode" "SI")])
5765 (define_insn "*addhi_1"
5766 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5767 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5768 (match_operand:HI 2 "general_operand" "rn,rm")))
5769 (clobber (reg:CC FLAGS_REG))]
5770 "TARGET_PARTIAL_REG_STALL
5771 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5773 switch (get_attr_type (insn))
5776 if (operands[2] == const1_rtx)
5777 return "inc{w}\t%0";
5780 gcc_assert (operands[2] == constm1_rtx);
5781 return "dec{w}\t%0";
5785 if (x86_maybe_negate_const_int (&operands[2], HImode))
5786 return "sub{w}\t{%2, %0|%0, %2}";
5788 return "add{w}\t{%2, %0|%0, %2}";
5792 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5793 (const_string "incdec")
5794 (const_string "alu")))
5795 (set (attr "length_immediate")
5797 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5799 (const_string "*")))
5800 (set_attr "mode" "HI")])
5802 (define_insn "*addhi_1_lea"
5803 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5804 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5805 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5806 (clobber (reg:CC FLAGS_REG))]
5807 "!TARGET_PARTIAL_REG_STALL
5808 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5810 switch (get_attr_type (insn))
5816 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5817 if (operands[2] == const1_rtx)
5818 return "inc{w}\t%0";
5821 gcc_assert (operands[2] == constm1_rtx);
5822 return "dec{w}\t%0";
5826 /* For most processors, ADD is faster than LEA. This alternative
5827 was added to use ADD as much as possible. */
5828 if (which_alternative == 2)
5831 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5834 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5835 if (x86_maybe_negate_const_int (&operands[2], HImode))
5836 return "sub{w}\t{%2, %0|%0, %2}";
5838 return "add{w}\t{%2, %0|%0, %2}";
5842 (cond [(eq_attr "alternative" "3")
5843 (const_string "lea")
5844 (match_operand:HI 2 "incdec_operand" "")
5845 (const_string "incdec")
5847 (const_string "alu")))
5848 (set (attr "length_immediate")
5850 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5852 (const_string "*")))
5853 (set_attr "mode" "HI,HI,HI,SI")])
5855 ;; %%% Potential partial reg stall on alternative 2. What to do?
5856 (define_insn "*addqi_1"
5857 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5858 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5859 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5860 (clobber (reg:CC FLAGS_REG))]
5861 "TARGET_PARTIAL_REG_STALL
5862 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5864 int widen = (which_alternative == 2);
5865 switch (get_attr_type (insn))
5868 if (operands[2] == const1_rtx)
5869 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5872 gcc_assert (operands[2] == constm1_rtx);
5873 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5877 if (x86_maybe_negate_const_int (&operands[2], QImode))
5880 return "sub{l}\t{%2, %k0|%k0, %2}";
5882 return "sub{b}\t{%2, %0|%0, %2}";
5885 return "add{l}\t{%k2, %k0|%k0, %k2}";
5887 return "add{b}\t{%2, %0|%0, %2}";
5891 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5892 (const_string "incdec")
5893 (const_string "alu")))
5894 (set (attr "length_immediate")
5896 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5898 (const_string "*")))
5899 (set_attr "mode" "QI,QI,SI")])
5901 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5902 (define_insn "*addqi_1_lea"
5903 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5904 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5905 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5906 (clobber (reg:CC FLAGS_REG))]
5907 "!TARGET_PARTIAL_REG_STALL
5908 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5910 int widen = (which_alternative == 3 || which_alternative == 4);
5912 switch (get_attr_type (insn))
5918 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5919 if (operands[2] == const1_rtx)
5920 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5923 gcc_assert (operands[2] == constm1_rtx);
5924 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5928 /* For most processors, ADD is faster than LEA. These alternatives
5929 were added to use ADD as much as possible. */
5930 if (which_alternative == 2 || which_alternative == 4)
5933 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5936 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5937 if (x86_maybe_negate_const_int (&operands[2], QImode))
5940 return "sub{l}\t{%2, %k0|%k0, %2}";
5942 return "sub{b}\t{%2, %0|%0, %2}";
5945 return "add{l}\t{%k2, %k0|%k0, %k2}";
5947 return "add{b}\t{%2, %0|%0, %2}";
5951 (cond [(eq_attr "alternative" "5")
5952 (const_string "lea")
5953 (match_operand:QI 2 "incdec_operand" "")
5954 (const_string "incdec")
5956 (const_string "alu")))
5957 (set (attr "length_immediate")
5959 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5961 (const_string "*")))
5962 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5964 (define_insn "*addqi_1_slp"
5965 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5966 (plus:QI (match_dup 0)
5967 (match_operand:QI 1 "general_operand" "qn,qnm")))
5968 (clobber (reg:CC FLAGS_REG))]
5969 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5970 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5972 switch (get_attr_type (insn))
5975 if (operands[1] == const1_rtx)
5976 return "inc{b}\t%0";
5979 gcc_assert (operands[1] == constm1_rtx);
5980 return "dec{b}\t%0";
5984 if (x86_maybe_negate_const_int (&operands[1], QImode))
5985 return "sub{b}\t{%1, %0|%0, %1}";
5987 return "add{b}\t{%1, %0|%0, %1}";
5991 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5992 (const_string "incdec")
5993 (const_string "alu1")))
5994 (set (attr "memory")
5995 (if_then_else (match_operand 1 "memory_operand" "")
5996 (const_string "load")
5997 (const_string "none")))
5998 (set_attr "mode" "QI")])
6000 ;; Convert lea to the lea pattern to avoid flags dependency.
6002 [(set (match_operand 0 "register_operand" "")
6003 (plus (match_operand 1 "register_operand" "")
6004 (match_operand 2 "nonmemory_operand" "")))
6005 (clobber (reg:CC FLAGS_REG))]
6006 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6010 enum machine_mode mode = GET_MODE (operands[0]);
6012 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6013 may confuse gen_lowpart. */
6016 operands[1] = gen_lowpart (Pmode, operands[1]);
6017 operands[2] = gen_lowpart (Pmode, operands[2]);
6020 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6022 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6023 operands[0] = gen_lowpart (SImode, operands[0]);
6025 if (TARGET_64BIT && mode != Pmode)
6026 pat = gen_rtx_SUBREG (SImode, pat, 0);
6028 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6032 ;; Convert lea to the lea pattern to avoid flags dependency.
6033 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6034 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6036 [(set (match_operand:DI 0 "register_operand" "")
6037 (plus:DI (match_operand:DI 1 "register_operand" "")
6038 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6039 (clobber (reg:CC FLAGS_REG))]
6040 "TARGET_64BIT && reload_completed
6041 && true_regnum (operands[0]) != true_regnum (operands[1])"
6043 (plus:DI (match_dup 1) (match_dup 2)))])
6045 ;; Convert lea to the lea pattern to avoid flags dependency.
6047 [(set (match_operand:DI 0 "register_operand" "")
6049 (plus:SI (match_operand:SI 1 "register_operand" "")
6050 (match_operand:SI 2 "nonmemory_operand" ""))))
6051 (clobber (reg:CC FLAGS_REG))]
6052 "TARGET_64BIT && reload_completed
6053 && ix86_lea_for_add_ok (insn, operands)"
6055 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6057 operands[1] = gen_lowpart (DImode, operands[1]);
6058 operands[2] = gen_lowpart (DImode, operands[2]);
6061 (define_insn "*add<mode>_2"
6062 [(set (reg FLAGS_REG)
6065 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6066 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6068 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6069 (plus:SWI (match_dup 1) (match_dup 2)))]
6070 "ix86_match_ccmode (insn, CCGOCmode)
6071 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6073 switch (get_attr_type (insn))
6076 if (operands[2] == const1_rtx)
6077 return "inc{<imodesuffix>}\t%0";
6080 gcc_assert (operands[2] == constm1_rtx);
6081 return "dec{<imodesuffix>}\t%0";
6085 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6086 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6088 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6092 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6093 (const_string "incdec")
6094 (const_string "alu")))
6095 (set (attr "length_immediate")
6097 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6099 (const_string "*")))
6100 (set_attr "mode" "<MODE>")])
6102 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6103 (define_insn "*addsi_2_zext"
6104 [(set (reg FLAGS_REG)
6106 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6107 (match_operand:SI 2 "general_operand" "g"))
6109 (set (match_operand:DI 0 "register_operand" "=r")
6110 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6111 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6112 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6114 switch (get_attr_type (insn))
6117 if (operands[2] == const1_rtx)
6118 return "inc{l}\t%k0";
6121 gcc_assert (operands[2] == constm1_rtx);
6122 return "dec{l}\t%k0";
6126 if (x86_maybe_negate_const_int (&operands[2], SImode))
6127 return "sub{l}\t{%2, %k0|%k0, %2}";
6129 return "add{l}\t{%2, %k0|%k0, %2}";
6133 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6134 (const_string "incdec")
6135 (const_string "alu")))
6136 (set (attr "length_immediate")
6138 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6140 (const_string "*")))
6141 (set_attr "mode" "SI")])
6143 (define_insn "*add<mode>_3"
6144 [(set (reg FLAGS_REG)
6146 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6147 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6148 (clobber (match_scratch:SWI 0 "=<r>"))]
6149 "ix86_match_ccmode (insn, CCZmode)
6150 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6152 switch (get_attr_type (insn))
6155 if (operands[2] == const1_rtx)
6156 return "inc{<imodesuffix>}\t%0";
6159 gcc_assert (operands[2] == constm1_rtx);
6160 return "dec{<imodesuffix>}\t%0";
6164 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6165 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6167 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6171 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6172 (const_string "incdec")
6173 (const_string "alu")))
6174 (set (attr "length_immediate")
6176 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6178 (const_string "*")))
6179 (set_attr "mode" "<MODE>")])
6181 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6182 (define_insn "*addsi_3_zext"
6183 [(set (reg FLAGS_REG)
6185 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6186 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6187 (set (match_operand:DI 0 "register_operand" "=r")
6188 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6189 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6190 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6192 switch (get_attr_type (insn))
6195 if (operands[2] == const1_rtx)
6196 return "inc{l}\t%k0";
6199 gcc_assert (operands[2] == constm1_rtx);
6200 return "dec{l}\t%k0";
6204 if (x86_maybe_negate_const_int (&operands[2], SImode))
6205 return "sub{l}\t{%2, %k0|%k0, %2}";
6207 return "add{l}\t{%2, %k0|%k0, %2}";
6211 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6212 (const_string "incdec")
6213 (const_string "alu")))
6214 (set (attr "length_immediate")
6216 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6218 (const_string "*")))
6219 (set_attr "mode" "SI")])
6221 ; For comparisons against 1, -1 and 128, we may generate better code
6222 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6223 ; is matched then. We can't accept general immediate, because for
6224 ; case of overflows, the result is messed up.
6225 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6226 ; only for comparisons not depending on it.
6228 (define_insn "*adddi_4"
6229 [(set (reg FLAGS_REG)
6231 (match_operand:DI 1 "nonimmediate_operand" "0")
6232 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6233 (clobber (match_scratch:DI 0 "=rm"))]
6235 && ix86_match_ccmode (insn, CCGCmode)"
6237 switch (get_attr_type (insn))
6240 if (operands[2] == constm1_rtx)
6241 return "inc{q}\t%0";
6244 gcc_assert (operands[2] == const1_rtx);
6245 return "dec{q}\t%0";
6249 if (x86_maybe_negate_const_int (&operands[2], DImode))
6250 return "add{q}\t{%2, %0|%0, %2}";
6252 return "sub{q}\t{%2, %0|%0, %2}";
6256 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6257 (const_string "incdec")
6258 (const_string "alu")))
6259 (set (attr "length_immediate")
6261 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6263 (const_string "*")))
6264 (set_attr "mode" "DI")])
6266 ; For comparisons against 1, -1 and 128, we may generate better code
6267 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6268 ; is matched then. We can't accept general immediate, because for
6269 ; case of overflows, the result is messed up.
6270 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6271 ; only for comparisons not depending on it.
6273 (define_insn "*add<mode>_4"
6274 [(set (reg FLAGS_REG)
6276 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6277 (match_operand:SWI124 2 "const_int_operand" "n")))
6278 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6279 "ix86_match_ccmode (insn, CCGCmode)"
6281 switch (get_attr_type (insn))
6284 if (operands[2] == constm1_rtx)
6285 return "inc{<imodesuffix>}\t%0";
6288 gcc_assert (operands[2] == const1_rtx);
6289 return "dec{<imodesuffix>}\t%0";
6293 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6294 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6296 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6300 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6301 (const_string "incdec")
6302 (const_string "alu")))
6303 (set (attr "length_immediate")
6305 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6307 (const_string "*")))
6308 (set_attr "mode" "<MODE>")])
6310 (define_insn "*add<mode>_5"
6311 [(set (reg FLAGS_REG)
6314 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6315 (match_operand:SWI 2 "<general_operand>" "<g>"))
6317 (clobber (match_scratch:SWI 0 "=<r>"))]
6318 "ix86_match_ccmode (insn, CCGOCmode)
6319 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6321 switch (get_attr_type (insn))
6324 if (operands[2] == const1_rtx)
6325 return "inc{<imodesuffix>}\t%0";
6328 gcc_assert (operands[2] == constm1_rtx);
6329 return "dec{<imodesuffix>}\t%0";
6333 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6334 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6336 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6340 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6341 (const_string "incdec")
6342 (const_string "alu")))
6343 (set (attr "length_immediate")
6345 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6347 (const_string "*")))
6348 (set_attr "mode" "<MODE>")])
6350 (define_insn "*addqi_ext_1_rex64"
6351 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6356 (match_operand 1 "ext_register_operand" "0")
6359 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6360 (clobber (reg:CC FLAGS_REG))]
6363 switch (get_attr_type (insn))
6366 if (operands[2] == const1_rtx)
6367 return "inc{b}\t%h0";
6370 gcc_assert (operands[2] == constm1_rtx);
6371 return "dec{b}\t%h0";
6375 return "add{b}\t{%2, %h0|%h0, %2}";
6379 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6380 (const_string "incdec")
6381 (const_string "alu")))
6382 (set_attr "modrm" "1")
6383 (set_attr "mode" "QI")])
6385 (define_insn "addqi_ext_1"
6386 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6391 (match_operand 1 "ext_register_operand" "0")
6394 (match_operand:QI 2 "general_operand" "Qmn")))
6395 (clobber (reg:CC FLAGS_REG))]
6398 switch (get_attr_type (insn))
6401 if (operands[2] == const1_rtx)
6402 return "inc{b}\t%h0";
6405 gcc_assert (operands[2] == constm1_rtx);
6406 return "dec{b}\t%h0";
6410 return "add{b}\t{%2, %h0|%h0, %2}";
6414 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6415 (const_string "incdec")
6416 (const_string "alu")))
6417 (set_attr "modrm" "1")
6418 (set_attr "mode" "QI")])
6420 (define_insn "*addqi_ext_2"
6421 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6426 (match_operand 1 "ext_register_operand" "%0")
6430 (match_operand 2 "ext_register_operand" "Q")
6433 (clobber (reg:CC FLAGS_REG))]
6435 "add{b}\t{%h2, %h0|%h0, %h2}"
6436 [(set_attr "type" "alu")
6437 (set_attr "mode" "QI")])
6439 ;; The lea patterns for non-Pmodes needs to be matched by
6440 ;; several insns converted to real lea by splitters.
6442 (define_insn_and_split "*lea_general_1"
6443 [(set (match_operand 0 "register_operand" "=r")
6444 (plus (plus (match_operand 1 "index_register_operand" "l")
6445 (match_operand 2 "register_operand" "r"))
6446 (match_operand 3 "immediate_operand" "i")))]
6447 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6448 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6449 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6450 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6451 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6452 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6453 || GET_MODE (operands[3]) == VOIDmode)"
6455 "&& reload_completed"
6459 operands[0] = gen_lowpart (SImode, operands[0]);
6460 operands[1] = gen_lowpart (Pmode, operands[1]);
6461 operands[2] = gen_lowpart (Pmode, operands[2]);
6462 operands[3] = gen_lowpart (Pmode, operands[3]);
6463 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6465 if (Pmode != SImode)
6466 pat = gen_rtx_SUBREG (SImode, pat, 0);
6467 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6470 [(set_attr "type" "lea")
6471 (set_attr "mode" "SI")])
6473 (define_insn_and_split "*lea_general_1_zext"
6474 [(set (match_operand:DI 0 "register_operand" "=r")
6477 (match_operand:SI 1 "index_register_operand" "l")
6478 (match_operand:SI 2 "register_operand" "r"))
6479 (match_operand:SI 3 "immediate_operand" "i"))))]
6482 "&& reload_completed"
6484 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6486 (match_dup 3)) 0)))]
6488 operands[1] = gen_lowpart (Pmode, operands[1]);
6489 operands[2] = gen_lowpart (Pmode, operands[2]);
6490 operands[3] = gen_lowpart (Pmode, operands[3]);
6492 [(set_attr "type" "lea")
6493 (set_attr "mode" "SI")])
6495 (define_insn_and_split "*lea_general_2"
6496 [(set (match_operand 0 "register_operand" "=r")
6497 (plus (mult (match_operand 1 "index_register_operand" "l")
6498 (match_operand 2 "const248_operand" "i"))
6499 (match_operand 3 "nonmemory_operand" "ri")))]
6500 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6501 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6502 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6503 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6504 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6505 || GET_MODE (operands[3]) == VOIDmode)"
6507 "&& reload_completed"
6511 operands[0] = gen_lowpart (SImode, operands[0]);
6512 operands[1] = gen_lowpart (Pmode, operands[1]);
6513 operands[3] = gen_lowpart (Pmode, operands[3]);
6514 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6516 if (Pmode != SImode)
6517 pat = gen_rtx_SUBREG (SImode, pat, 0);
6518 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6521 [(set_attr "type" "lea")
6522 (set_attr "mode" "SI")])
6524 (define_insn_and_split "*lea_general_2_zext"
6525 [(set (match_operand:DI 0 "register_operand" "=r")
6528 (match_operand:SI 1 "index_register_operand" "l")
6529 (match_operand:SI 2 "const248_operand" "n"))
6530 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6533 "&& reload_completed"
6535 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6537 (match_dup 3)) 0)))]
6539 operands[1] = gen_lowpart (Pmode, operands[1]);
6540 operands[3] = gen_lowpart (Pmode, operands[3]);
6542 [(set_attr "type" "lea")
6543 (set_attr "mode" "SI")])
6545 (define_insn_and_split "*lea_general_3"
6546 [(set (match_operand 0 "register_operand" "=r")
6547 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6548 (match_operand 2 "const248_operand" "i"))
6549 (match_operand 3 "register_operand" "r"))
6550 (match_operand 4 "immediate_operand" "i")))]
6551 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6552 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6553 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6554 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6555 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6557 "&& reload_completed"
6561 operands[0] = gen_lowpart (SImode, operands[0]);
6562 operands[1] = gen_lowpart (Pmode, operands[1]);
6563 operands[3] = gen_lowpart (Pmode, operands[3]);
6564 operands[4] = gen_lowpart (Pmode, operands[4]);
6565 pat = gen_rtx_PLUS (Pmode,
6566 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6570 if (Pmode != SImode)
6571 pat = gen_rtx_SUBREG (SImode, pat, 0);
6572 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6575 [(set_attr "type" "lea")
6576 (set_attr "mode" "SI")])
6578 (define_insn_and_split "*lea_general_3_zext"
6579 [(set (match_operand:DI 0 "register_operand" "=r")
6583 (match_operand:SI 1 "index_register_operand" "l")
6584 (match_operand:SI 2 "const248_operand" "n"))
6585 (match_operand:SI 3 "register_operand" "r"))
6586 (match_operand:SI 4 "immediate_operand" "i"))))]
6589 "&& reload_completed"
6591 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6594 (match_dup 4)) 0)))]
6596 operands[1] = gen_lowpart (Pmode, operands[1]);
6597 operands[3] = gen_lowpart (Pmode, operands[3]);
6598 operands[4] = gen_lowpart (Pmode, operands[4]);
6600 [(set_attr "type" "lea")
6601 (set_attr "mode" "SI")])
6603 ;; Subtract instructions
6605 (define_expand "sub<mode>3"
6606 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6607 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6608 (match_operand:SDWIM 2 "<general_operand>" "")))]
6610 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6612 (define_insn_and_split "*sub<dwi>3_doubleword"
6613 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6615 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6616 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6617 (clobber (reg:CC FLAGS_REG))]
6618 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6621 [(parallel [(set (reg:CC FLAGS_REG)
6622 (compare:CC (match_dup 1) (match_dup 2)))
6624 (minus:DWIH (match_dup 1) (match_dup 2)))])
6625 (parallel [(set (match_dup 3)
6629 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6631 (clobber (reg:CC FLAGS_REG))])]
6632 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6634 (define_insn "*sub<mode>_1"
6635 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6637 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6638 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6639 (clobber (reg:CC FLAGS_REG))]
6640 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6641 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6642 [(set_attr "type" "alu")
6643 (set_attr "mode" "<MODE>")])
6645 (define_insn "*subsi_1_zext"
6646 [(set (match_operand:DI 0 "register_operand" "=r")
6648 (minus:SI (match_operand:SI 1 "register_operand" "0")
6649 (match_operand:SI 2 "general_operand" "g"))))
6650 (clobber (reg:CC FLAGS_REG))]
6651 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6652 "sub{l}\t{%2, %k0|%k0, %2}"
6653 [(set_attr "type" "alu")
6654 (set_attr "mode" "SI")])
6656 (define_insn "*subqi_1_slp"
6657 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6658 (minus:QI (match_dup 0)
6659 (match_operand:QI 1 "general_operand" "qn,qm")))
6660 (clobber (reg:CC FLAGS_REG))]
6661 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6662 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6663 "sub{b}\t{%1, %0|%0, %1}"
6664 [(set_attr "type" "alu1")
6665 (set_attr "mode" "QI")])
6667 (define_insn "*sub<mode>_2"
6668 [(set (reg FLAGS_REG)
6671 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6672 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6674 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6675 (minus:SWI (match_dup 1) (match_dup 2)))]
6676 "ix86_match_ccmode (insn, CCGOCmode)
6677 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6678 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6679 [(set_attr "type" "alu")
6680 (set_attr "mode" "<MODE>")])
6682 (define_insn "*subsi_2_zext"
6683 [(set (reg FLAGS_REG)
6685 (minus:SI (match_operand:SI 1 "register_operand" "0")
6686 (match_operand:SI 2 "general_operand" "g"))
6688 (set (match_operand:DI 0 "register_operand" "=r")
6690 (minus:SI (match_dup 1)
6692 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6693 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6694 "sub{l}\t{%2, %k0|%k0, %2}"
6695 [(set_attr "type" "alu")
6696 (set_attr "mode" "SI")])
6698 (define_insn "*sub<mode>_3"
6699 [(set (reg FLAGS_REG)
6700 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6701 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6702 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6703 (minus:SWI (match_dup 1) (match_dup 2)))]
6704 "ix86_match_ccmode (insn, CCmode)
6705 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6706 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6707 [(set_attr "type" "alu")
6708 (set_attr "mode" "<MODE>")])
6710 (define_insn "*subsi_3_zext"
6711 [(set (reg FLAGS_REG)
6712 (compare (match_operand:SI 1 "register_operand" "0")
6713 (match_operand:SI 2 "general_operand" "g")))
6714 (set (match_operand:DI 0 "register_operand" "=r")
6716 (minus:SI (match_dup 1)
6718 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6719 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6720 "sub{l}\t{%2, %1|%1, %2}"
6721 [(set_attr "type" "alu")
6722 (set_attr "mode" "SI")])
6724 ;; Add with carry and subtract with borrow
6726 (define_expand "<plusminus_insn><mode>3_carry"
6728 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6730 (match_operand:SWI 1 "nonimmediate_operand" "")
6731 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6732 [(match_operand 3 "flags_reg_operand" "")
6734 (match_operand:SWI 2 "<general_operand>" ""))))
6735 (clobber (reg:CC FLAGS_REG))])]
6736 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6738 (define_insn "*<plusminus_insn><mode>3_carry"
6739 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6741 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6743 (match_operator 3 "ix86_carry_flag_operator"
6744 [(reg FLAGS_REG) (const_int 0)])
6745 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6746 (clobber (reg:CC FLAGS_REG))]
6747 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6748 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6749 [(set_attr "type" "alu")
6750 (set_attr "use_carry" "1")
6751 (set_attr "pent_pair" "pu")
6752 (set_attr "mode" "<MODE>")])
6754 (define_insn "*addsi3_carry_zext"
6755 [(set (match_operand:DI 0 "register_operand" "=r")
6757 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6758 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6759 [(reg FLAGS_REG) (const_int 0)])
6760 (match_operand:SI 2 "general_operand" "g")))))
6761 (clobber (reg:CC FLAGS_REG))]
6762 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6763 "adc{l}\t{%2, %k0|%k0, %2}"
6764 [(set_attr "type" "alu")
6765 (set_attr "use_carry" "1")
6766 (set_attr "pent_pair" "pu")
6767 (set_attr "mode" "SI")])
6769 (define_insn "*subsi3_carry_zext"
6770 [(set (match_operand:DI 0 "register_operand" "=r")
6772 (minus:SI (match_operand:SI 1 "register_operand" "0")
6773 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6774 [(reg FLAGS_REG) (const_int 0)])
6775 (match_operand:SI 2 "general_operand" "g")))))
6776 (clobber (reg:CC FLAGS_REG))]
6777 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6778 "sbb{l}\t{%2, %k0|%k0, %2}"
6779 [(set_attr "type" "alu")
6780 (set_attr "pent_pair" "pu")
6781 (set_attr "mode" "SI")])
6783 ;; Overflow setting add and subtract instructions
6785 (define_insn "*add<mode>3_cconly_overflow"
6786 [(set (reg:CCC FLAGS_REG)
6789 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6790 (match_operand:SWI 2 "<general_operand>" "<g>"))
6792 (clobber (match_scratch:SWI 0 "=<r>"))]
6793 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6794 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6795 [(set_attr "type" "alu")
6796 (set_attr "mode" "<MODE>")])
6798 (define_insn "*sub<mode>3_cconly_overflow"
6799 [(set (reg:CCC FLAGS_REG)
6802 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6803 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6806 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6807 [(set_attr "type" "icmp")
6808 (set_attr "mode" "<MODE>")])
6810 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6811 [(set (reg:CCC FLAGS_REG)
6814 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6815 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6817 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6818 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6819 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6820 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6821 [(set_attr "type" "alu")
6822 (set_attr "mode" "<MODE>")])
6824 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6825 [(set (reg:CCC FLAGS_REG)
6828 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6829 (match_operand:SI 2 "general_operand" "g"))
6831 (set (match_operand:DI 0 "register_operand" "=r")
6832 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6833 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6834 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6835 [(set_attr "type" "alu")
6836 (set_attr "mode" "SI")])
6838 ;; The patterns that match these are at the end of this file.
6840 (define_expand "<plusminus_insn>xf3"
6841 [(set (match_operand:XF 0 "register_operand" "")
6843 (match_operand:XF 1 "register_operand" "")
6844 (match_operand:XF 2 "register_operand" "")))]
6847 (define_expand "<plusminus_insn><mode>3"
6848 [(set (match_operand:MODEF 0 "register_operand" "")
6850 (match_operand:MODEF 1 "register_operand" "")
6851 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6852 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6853 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6855 ;; Multiply instructions
6857 (define_expand "mul<mode>3"
6858 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6860 (match_operand:SWIM248 1 "register_operand" "")
6861 (match_operand:SWIM248 2 "<general_operand>" "")))
6862 (clobber (reg:CC FLAGS_REG))])])
6864 (define_expand "mulqi3"
6865 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6867 (match_operand:QI 1 "register_operand" "")
6868 (match_operand:QI 2 "nonimmediate_operand" "")))
6869 (clobber (reg:CC FLAGS_REG))])]
6870 "TARGET_QIMODE_MATH")
6873 ;; IMUL reg32/64, reg32/64, imm8 Direct
6874 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6875 ;; IMUL reg32/64, reg32/64, imm32 Direct
6876 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6877 ;; IMUL reg32/64, reg32/64 Direct
6878 ;; IMUL reg32/64, mem32/64 Direct
6880 ;; On BDVER1, all above IMULs use DirectPath
6882 (define_insn "*mul<mode>3_1"
6883 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6885 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6886 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6887 (clobber (reg:CC FLAGS_REG))]
6888 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6890 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6891 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6892 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6893 [(set_attr "type" "imul")
6894 (set_attr "prefix_0f" "0,0,1")
6895 (set (attr "athlon_decode")
6896 (cond [(eq_attr "cpu" "athlon")
6897 (const_string "vector")
6898 (eq_attr "alternative" "1")
6899 (const_string "vector")
6900 (and (eq_attr "alternative" "2")
6901 (match_operand 1 "memory_operand" ""))
6902 (const_string "vector")]
6903 (const_string "direct")))
6904 (set (attr "amdfam10_decode")
6905 (cond [(and (eq_attr "alternative" "0,1")
6906 (match_operand 1 "memory_operand" ""))
6907 (const_string "vector")]
6908 (const_string "direct")))
6909 (set_attr "bdver1_decode" "direct")
6910 (set_attr "mode" "<MODE>")])
6912 (define_insn "*mulsi3_1_zext"
6913 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6915 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6916 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6917 (clobber (reg:CC FLAGS_REG))]
6919 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6921 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6922 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6923 imul{l}\t{%2, %k0|%k0, %2}"
6924 [(set_attr "type" "imul")
6925 (set_attr "prefix_0f" "0,0,1")
6926 (set (attr "athlon_decode")
6927 (cond [(eq_attr "cpu" "athlon")
6928 (const_string "vector")
6929 (eq_attr "alternative" "1")
6930 (const_string "vector")
6931 (and (eq_attr "alternative" "2")
6932 (match_operand 1 "memory_operand" ""))
6933 (const_string "vector")]
6934 (const_string "direct")))
6935 (set (attr "amdfam10_decode")
6936 (cond [(and (eq_attr "alternative" "0,1")
6937 (match_operand 1 "memory_operand" ""))
6938 (const_string "vector")]
6939 (const_string "direct")))
6940 (set_attr "bdver1_decode" "direct")
6941 (set_attr "mode" "SI")])
6944 ;; IMUL reg16, reg16, imm8 VectorPath
6945 ;; IMUL reg16, mem16, imm8 VectorPath
6946 ;; IMUL reg16, reg16, imm16 VectorPath
6947 ;; IMUL reg16, mem16, imm16 VectorPath
6948 ;; IMUL reg16, reg16 Direct
6949 ;; IMUL reg16, mem16 Direct
6951 ;; On BDVER1, all HI MULs use DoublePath
6953 (define_insn "*mulhi3_1"
6954 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6955 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6956 (match_operand:HI 2 "general_operand" "K,n,mr")))
6957 (clobber (reg:CC FLAGS_REG))]
6959 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6961 imul{w}\t{%2, %1, %0|%0, %1, %2}
6962 imul{w}\t{%2, %1, %0|%0, %1, %2}
6963 imul{w}\t{%2, %0|%0, %2}"
6964 [(set_attr "type" "imul")
6965 (set_attr "prefix_0f" "0,0,1")
6966 (set (attr "athlon_decode")
6967 (cond [(eq_attr "cpu" "athlon")
6968 (const_string "vector")
6969 (eq_attr "alternative" "1,2")
6970 (const_string "vector")]
6971 (const_string "direct")))
6972 (set (attr "amdfam10_decode")
6973 (cond [(eq_attr "alternative" "0,1")
6974 (const_string "vector")]
6975 (const_string "direct")))
6976 (set_attr "bdver1_decode" "double")
6977 (set_attr "mode" "HI")])
6979 ;;On AMDFAM10 and BDVER1
6983 (define_insn "*mulqi3_1"
6984 [(set (match_operand:QI 0 "register_operand" "=a")
6985 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6986 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6987 (clobber (reg:CC FLAGS_REG))]
6989 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6991 [(set_attr "type" "imul")
6992 (set_attr "length_immediate" "0")
6993 (set (attr "athlon_decode")
6994 (if_then_else (eq_attr "cpu" "athlon")
6995 (const_string "vector")
6996 (const_string "direct")))
6997 (set_attr "amdfam10_decode" "direct")
6998 (set_attr "bdver1_decode" "direct")
6999 (set_attr "mode" "QI")])
7001 (define_expand "<u>mul<mode><dwi>3"
7002 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7005 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7007 (match_operand:DWIH 2 "register_operand" ""))))
7008 (clobber (reg:CC FLAGS_REG))])])
7010 (define_expand "<u>mulqihi3"
7011 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7014 (match_operand:QI 1 "nonimmediate_operand" ""))
7016 (match_operand:QI 2 "register_operand" ""))))
7017 (clobber (reg:CC FLAGS_REG))])]
7018 "TARGET_QIMODE_MATH")
7020 (define_insn "*<u>mul<mode><dwi>3_1"
7021 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7024 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7026 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7027 (clobber (reg:CC FLAGS_REG))]
7028 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7029 "<sgnprefix>mul{<imodesuffix>}\t%2"
7030 [(set_attr "type" "imul")
7031 (set_attr "length_immediate" "0")
7032 (set (attr "athlon_decode")
7033 (if_then_else (eq_attr "cpu" "athlon")
7034 (const_string "vector")
7035 (const_string "double")))
7036 (set_attr "amdfam10_decode" "double")
7037 (set_attr "bdver1_decode" "direct")
7038 (set_attr "mode" "<MODE>")])
7040 (define_insn "*<u>mulqihi3_1"
7041 [(set (match_operand:HI 0 "register_operand" "=a")
7044 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7046 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7047 (clobber (reg:CC FLAGS_REG))]
7049 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7050 "<sgnprefix>mul{b}\t%2"
7051 [(set_attr "type" "imul")
7052 (set_attr "length_immediate" "0")
7053 (set (attr "athlon_decode")
7054 (if_then_else (eq_attr "cpu" "athlon")
7055 (const_string "vector")
7056 (const_string "direct")))
7057 (set_attr "amdfam10_decode" "direct")
7058 (set_attr "bdver1_decode" "direct")
7059 (set_attr "mode" "QI")])
7061 (define_expand "<s>mul<mode>3_highpart"
7062 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7067 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7069 (match_operand:SWI48 2 "register_operand" "")))
7071 (clobber (match_scratch:SWI48 3 ""))
7072 (clobber (reg:CC FLAGS_REG))])]
7074 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7076 (define_insn "*<s>muldi3_highpart_1"
7077 [(set (match_operand:DI 0 "register_operand" "=d")
7082 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7084 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7086 (clobber (match_scratch:DI 3 "=1"))
7087 (clobber (reg:CC FLAGS_REG))]
7089 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7090 "<sgnprefix>mul{q}\t%2"
7091 [(set_attr "type" "imul")
7092 (set_attr "length_immediate" "0")
7093 (set (attr "athlon_decode")
7094 (if_then_else (eq_attr "cpu" "athlon")
7095 (const_string "vector")
7096 (const_string "double")))
7097 (set_attr "amdfam10_decode" "double")
7098 (set_attr "bdver1_decode" "direct")
7099 (set_attr "mode" "DI")])
7101 (define_insn "*<s>mulsi3_highpart_1"
7102 [(set (match_operand:SI 0 "register_operand" "=d")
7107 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7109 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7111 (clobber (match_scratch:SI 3 "=1"))
7112 (clobber (reg:CC FLAGS_REG))]
7113 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7114 "<sgnprefix>mul{l}\t%2"
7115 [(set_attr "type" "imul")
7116 (set_attr "length_immediate" "0")
7117 (set (attr "athlon_decode")
7118 (if_then_else (eq_attr "cpu" "athlon")
7119 (const_string "vector")
7120 (const_string "double")))
7121 (set_attr "amdfam10_decode" "double")
7122 (set_attr "bdver1_decode" "direct")
7123 (set_attr "mode" "SI")])
7125 (define_insn "*<s>mulsi3_highpart_zext"
7126 [(set (match_operand:DI 0 "register_operand" "=d")
7127 (zero_extend:DI (truncate:SI
7129 (mult:DI (any_extend:DI
7130 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7132 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7134 (clobber (match_scratch:SI 3 "=1"))
7135 (clobber (reg:CC FLAGS_REG))]
7137 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7138 "<sgnprefix>mul{l}\t%2"
7139 [(set_attr "type" "imul")
7140 (set_attr "length_immediate" "0")
7141 (set (attr "athlon_decode")
7142 (if_then_else (eq_attr "cpu" "athlon")
7143 (const_string "vector")
7144 (const_string "double")))
7145 (set_attr "amdfam10_decode" "double")
7146 (set_attr "bdver1_decode" "direct")
7147 (set_attr "mode" "SI")])
7149 ;; The patterns that match these are at the end of this file.
7151 (define_expand "mulxf3"
7152 [(set (match_operand:XF 0 "register_operand" "")
7153 (mult:XF (match_operand:XF 1 "register_operand" "")
7154 (match_operand:XF 2 "register_operand" "")))]
7157 (define_expand "mul<mode>3"
7158 [(set (match_operand:MODEF 0 "register_operand" "")
7159 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7160 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7161 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7162 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7164 ;; Divide instructions
7166 ;; The patterns that match these are at the end of this file.
7168 (define_expand "divxf3"
7169 [(set (match_operand:XF 0 "register_operand" "")
7170 (div:XF (match_operand:XF 1 "register_operand" "")
7171 (match_operand:XF 2 "register_operand" "")))]
7174 (define_expand "divdf3"
7175 [(set (match_operand:DF 0 "register_operand" "")
7176 (div:DF (match_operand:DF 1 "register_operand" "")
7177 (match_operand:DF 2 "nonimmediate_operand" "")))]
7178 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7179 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7181 (define_expand "divsf3"
7182 [(set (match_operand:SF 0 "register_operand" "")
7183 (div:SF (match_operand:SF 1 "register_operand" "")
7184 (match_operand:SF 2 "nonimmediate_operand" "")))]
7185 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7188 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7189 && flag_finite_math_only && !flag_trapping_math
7190 && flag_unsafe_math_optimizations)
7192 ix86_emit_swdivsf (operands[0], operands[1],
7193 operands[2], SFmode);
7198 ;; Divmod instructions.
7200 (define_expand "divmod<mode>4"
7201 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7203 (match_operand:SWIM248 1 "register_operand" "")
7204 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7205 (set (match_operand:SWIM248 3 "register_operand" "")
7206 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7207 (clobber (reg:CC FLAGS_REG))])])
7209 ;; Split with 8bit unsigned divide:
7210 ;; if (dividend an divisor are in [0-255])
7211 ;; use 8bit unsigned integer divide
7213 ;; use original integer divide
7215 [(set (match_operand:SWI48 0 "register_operand" "")
7216 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7217 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7218 (set (match_operand:SWI48 1 "register_operand" "")
7219 (mod:SWI48 (match_dup 2) (match_dup 3)))
7220 (clobber (reg:CC FLAGS_REG))]
7221 "TARGET_USE_8BIT_IDIV
7222 && TARGET_QIMODE_MATH
7223 && can_create_pseudo_p ()
7224 && !optimize_insn_for_size_p ()"
7226 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7228 (define_insn_and_split "divmod<mode>4_1"
7229 [(set (match_operand:SWI48 0 "register_operand" "=a")
7230 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7231 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7232 (set (match_operand:SWI48 1 "register_operand" "=&d")
7233 (mod:SWI48 (match_dup 2) (match_dup 3)))
7234 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7235 (clobber (reg:CC FLAGS_REG))]
7239 [(parallel [(set (match_dup 1)
7240 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7241 (clobber (reg:CC FLAGS_REG))])
7242 (parallel [(set (match_dup 0)
7243 (div:SWI48 (match_dup 2) (match_dup 3)))
7245 (mod:SWI48 (match_dup 2) (match_dup 3)))
7247 (clobber (reg:CC FLAGS_REG))])]
7249 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7251 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7252 operands[4] = operands[2];
7255 /* Avoid use of cltd in favor of a mov+shift. */
7256 emit_move_insn (operands[1], operands[2]);
7257 operands[4] = operands[1];
7260 [(set_attr "type" "multi")
7261 (set_attr "mode" "<MODE>")])
7263 (define_insn_and_split "*divmod<mode>4"
7264 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7265 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7266 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7267 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7268 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7269 (clobber (reg:CC FLAGS_REG))]
7273 [(parallel [(set (match_dup 1)
7274 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7275 (clobber (reg:CC FLAGS_REG))])
7276 (parallel [(set (match_dup 0)
7277 (div:SWIM248 (match_dup 2) (match_dup 3)))
7279 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7281 (clobber (reg:CC FLAGS_REG))])]
7283 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7285 if (<MODE>mode != HImode
7286 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7287 operands[4] = operands[2];
7290 /* Avoid use of cltd in favor of a mov+shift. */
7291 emit_move_insn (operands[1], operands[2]);
7292 operands[4] = operands[1];
7295 [(set_attr "type" "multi")
7296 (set_attr "mode" "<MODE>")])
7298 (define_insn "*divmod<mode>4_noext"
7299 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7300 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7301 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7302 (set (match_operand:SWIM248 1 "register_operand" "=d")
7303 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7304 (use (match_operand:SWIM248 4 "register_operand" "1"))
7305 (clobber (reg:CC FLAGS_REG))]
7307 "idiv{<imodesuffix>}\t%3"
7308 [(set_attr "type" "idiv")
7309 (set_attr "mode" "<MODE>")])
7311 (define_expand "divmodqi4"
7312 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7314 (match_operand:QI 1 "register_operand" "")
7315 (match_operand:QI 2 "nonimmediate_operand" "")))
7316 (set (match_operand:QI 3 "register_operand" "")
7317 (mod:QI (match_dup 1) (match_dup 2)))
7318 (clobber (reg:CC FLAGS_REG))])]
7319 "TARGET_QIMODE_MATH"
7324 tmp0 = gen_reg_rtx (HImode);
7325 tmp1 = gen_reg_rtx (HImode);
7327 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7329 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7330 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7332 /* Extract remainder from AH. */
7333 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7334 insn = emit_move_insn (operands[3], tmp1);
7336 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7337 set_unique_reg_note (insn, REG_EQUAL, mod);
7339 /* Extract quotient from AL. */
7340 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7342 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7343 set_unique_reg_note (insn, REG_EQUAL, div);
7348 ;; Divide AX by r/m8, with result stored in
7351 ;; Change div/mod to HImode and extend the second argument to HImode
7352 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7353 ;; combine may fail.
7354 (define_insn "divmodhiqi3"
7355 [(set (match_operand:HI 0 "register_operand" "=a")
7360 (mod:HI (match_operand:HI 1 "register_operand" "0")
7362 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7366 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7367 (clobber (reg:CC FLAGS_REG))]
7368 "TARGET_QIMODE_MATH"
7370 [(set_attr "type" "idiv")
7371 (set_attr "mode" "QI")])
7373 (define_expand "udivmod<mode>4"
7374 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7376 (match_operand:SWIM248 1 "register_operand" "")
7377 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7378 (set (match_operand:SWIM248 3 "register_operand" "")
7379 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7380 (clobber (reg:CC FLAGS_REG))])])
7382 ;; Split with 8bit unsigned divide:
7383 ;; if (dividend an divisor are in [0-255])
7384 ;; use 8bit unsigned integer divide
7386 ;; use original integer divide
7388 [(set (match_operand:SWI48 0 "register_operand" "")
7389 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7390 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7391 (set (match_operand:SWI48 1 "register_operand" "")
7392 (umod:SWI48 (match_dup 2) (match_dup 3)))
7393 (clobber (reg:CC FLAGS_REG))]
7394 "TARGET_USE_8BIT_IDIV
7395 && TARGET_QIMODE_MATH
7396 && can_create_pseudo_p ()
7397 && !optimize_insn_for_size_p ()"
7399 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7401 (define_insn_and_split "udivmod<mode>4_1"
7402 [(set (match_operand:SWI48 0 "register_operand" "=a")
7403 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7404 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7405 (set (match_operand:SWI48 1 "register_operand" "=&d")
7406 (umod:SWI48 (match_dup 2) (match_dup 3)))
7407 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7408 (clobber (reg:CC FLAGS_REG))]
7412 [(set (match_dup 1) (const_int 0))
7413 (parallel [(set (match_dup 0)
7414 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7416 (umod:SWI48 (match_dup 2) (match_dup 3)))
7418 (clobber (reg:CC FLAGS_REG))])]
7420 [(set_attr "type" "multi")
7421 (set_attr "mode" "<MODE>")])
7423 (define_insn_and_split "*udivmod<mode>4"
7424 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7425 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7426 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7427 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7428 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7429 (clobber (reg:CC FLAGS_REG))]
7433 [(set (match_dup 1) (const_int 0))
7434 (parallel [(set (match_dup 0)
7435 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7437 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7439 (clobber (reg:CC FLAGS_REG))])]
7441 [(set_attr "type" "multi")
7442 (set_attr "mode" "<MODE>")])
7444 (define_insn "*udivmod<mode>4_noext"
7445 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7446 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7447 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7448 (set (match_operand:SWIM248 1 "register_operand" "=d")
7449 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7450 (use (match_operand:SWIM248 4 "register_operand" "1"))
7451 (clobber (reg:CC FLAGS_REG))]
7453 "div{<imodesuffix>}\t%3"
7454 [(set_attr "type" "idiv")
7455 (set_attr "mode" "<MODE>")])
7457 (define_expand "udivmodqi4"
7458 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7460 (match_operand:QI 1 "register_operand" "")
7461 (match_operand:QI 2 "nonimmediate_operand" "")))
7462 (set (match_operand:QI 3 "register_operand" "")
7463 (umod:QI (match_dup 1) (match_dup 2)))
7464 (clobber (reg:CC FLAGS_REG))])]
7465 "TARGET_QIMODE_MATH"
7470 tmp0 = gen_reg_rtx (HImode);
7471 tmp1 = gen_reg_rtx (HImode);
7473 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7475 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7476 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7478 /* Extract remainder from AH. */
7479 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7480 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7481 insn = emit_move_insn (operands[3], tmp1);
7483 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7484 set_unique_reg_note (insn, REG_EQUAL, mod);
7486 /* Extract quotient from AL. */
7487 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7489 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7490 set_unique_reg_note (insn, REG_EQUAL, div);
7495 (define_insn "udivmodhiqi3"
7496 [(set (match_operand:HI 0 "register_operand" "=a")
7501 (mod:HI (match_operand:HI 1 "register_operand" "0")
7503 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7507 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7508 (clobber (reg:CC FLAGS_REG))]
7509 "TARGET_QIMODE_MATH"
7511 [(set_attr "type" "idiv")
7512 (set_attr "mode" "QI")])
7514 ;; We cannot use div/idiv for double division, because it causes
7515 ;; "division by zero" on the overflow and that's not what we expect
7516 ;; from truncate. Because true (non truncating) double division is
7517 ;; never generated, we can't create this insn anyway.
7520 ; [(set (match_operand:SI 0 "register_operand" "=a")
7522 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7524 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7525 ; (set (match_operand:SI 3 "register_operand" "=d")
7527 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7528 ; (clobber (reg:CC FLAGS_REG))]
7530 ; "div{l}\t{%2, %0|%0, %2}"
7531 ; [(set_attr "type" "idiv")])
7533 ;;- Logical AND instructions
7535 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7536 ;; Note that this excludes ah.
7538 (define_expand "testsi_ccno_1"
7539 [(set (reg:CCNO FLAGS_REG)
7541 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7542 (match_operand:SI 1 "nonmemory_operand" ""))
7545 (define_expand "testqi_ccz_1"
7546 [(set (reg:CCZ FLAGS_REG)
7547 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7548 (match_operand:QI 1 "nonmemory_operand" ""))
7551 (define_expand "testdi_ccno_1"
7552 [(set (reg:CCNO FLAGS_REG)
7554 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7555 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7557 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7559 (define_insn "*testdi_1"
7560 [(set (reg FLAGS_REG)
7563 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7564 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7566 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7567 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7569 test{l}\t{%k1, %k0|%k0, %k1}
7570 test{l}\t{%k1, %k0|%k0, %k1}
7571 test{q}\t{%1, %0|%0, %1}
7572 test{q}\t{%1, %0|%0, %1}
7573 test{q}\t{%1, %0|%0, %1}"
7574 [(set_attr "type" "test")
7575 (set_attr "modrm" "0,1,0,1,1")
7576 (set_attr "mode" "SI,SI,DI,DI,DI")])
7578 (define_insn "*testqi_1_maybe_si"
7579 [(set (reg FLAGS_REG)
7582 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7583 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7585 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7586 && ix86_match_ccmode (insn,
7587 CONST_INT_P (operands[1])
7588 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7590 if (which_alternative == 3)
7592 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7593 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7594 return "test{l}\t{%1, %k0|%k0, %1}";
7596 return "test{b}\t{%1, %0|%0, %1}";
7598 [(set_attr "type" "test")
7599 (set_attr "modrm" "0,1,1,1")
7600 (set_attr "mode" "QI,QI,QI,SI")
7601 (set_attr "pent_pair" "uv,np,uv,np")])
7603 (define_insn "*test<mode>_1"
7604 [(set (reg FLAGS_REG)
7607 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7608 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7610 "ix86_match_ccmode (insn, CCNOmode)
7611 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7612 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7613 [(set_attr "type" "test")
7614 (set_attr "modrm" "0,1,1")
7615 (set_attr "mode" "<MODE>")
7616 (set_attr "pent_pair" "uv,np,uv")])
7618 (define_expand "testqi_ext_ccno_0"
7619 [(set (reg:CCNO FLAGS_REG)
7623 (match_operand 0 "ext_register_operand" "")
7626 (match_operand 1 "const_int_operand" ""))
7629 (define_insn "*testqi_ext_0"
7630 [(set (reg FLAGS_REG)
7634 (match_operand 0 "ext_register_operand" "Q")
7637 (match_operand 1 "const_int_operand" "n"))
7639 "ix86_match_ccmode (insn, CCNOmode)"
7640 "test{b}\t{%1, %h0|%h0, %1}"
7641 [(set_attr "type" "test")
7642 (set_attr "mode" "QI")
7643 (set_attr "length_immediate" "1")
7644 (set_attr "modrm" "1")
7645 (set_attr "pent_pair" "np")])
7647 (define_insn "*testqi_ext_1_rex64"
7648 [(set (reg FLAGS_REG)
7652 (match_operand 0 "ext_register_operand" "Q")
7656 (match_operand:QI 1 "register_operand" "Q")))
7658 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7659 "test{b}\t{%1, %h0|%h0, %1}"
7660 [(set_attr "type" "test")
7661 (set_attr "mode" "QI")])
7663 (define_insn "*testqi_ext_1"
7664 [(set (reg FLAGS_REG)
7668 (match_operand 0 "ext_register_operand" "Q")
7672 (match_operand:QI 1 "general_operand" "Qm")))
7674 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7675 "test{b}\t{%1, %h0|%h0, %1}"
7676 [(set_attr "type" "test")
7677 (set_attr "mode" "QI")])
7679 (define_insn "*testqi_ext_2"
7680 [(set (reg FLAGS_REG)
7684 (match_operand 0 "ext_register_operand" "Q")
7688 (match_operand 1 "ext_register_operand" "Q")
7692 "ix86_match_ccmode (insn, CCNOmode)"
7693 "test{b}\t{%h1, %h0|%h0, %h1}"
7694 [(set_attr "type" "test")
7695 (set_attr "mode" "QI")])
7697 (define_insn "*testqi_ext_3_rex64"
7698 [(set (reg FLAGS_REG)
7699 (compare (zero_extract:DI
7700 (match_operand 0 "nonimmediate_operand" "rm")
7701 (match_operand:DI 1 "const_int_operand" "")
7702 (match_operand:DI 2 "const_int_operand" ""))
7705 && ix86_match_ccmode (insn, CCNOmode)
7706 && INTVAL (operands[1]) > 0
7707 && INTVAL (operands[2]) >= 0
7708 /* Ensure that resulting mask is zero or sign extended operand. */
7709 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7710 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7711 && INTVAL (operands[1]) > 32))
7712 && (GET_MODE (operands[0]) == SImode
7713 || GET_MODE (operands[0]) == DImode
7714 || GET_MODE (operands[0]) == HImode
7715 || GET_MODE (operands[0]) == QImode)"
7718 ;; Combine likes to form bit extractions for some tests. Humor it.
7719 (define_insn "*testqi_ext_3"
7720 [(set (reg FLAGS_REG)
7721 (compare (zero_extract:SI
7722 (match_operand 0 "nonimmediate_operand" "rm")
7723 (match_operand:SI 1 "const_int_operand" "")
7724 (match_operand:SI 2 "const_int_operand" ""))
7726 "ix86_match_ccmode (insn, CCNOmode)
7727 && INTVAL (operands[1]) > 0
7728 && INTVAL (operands[2]) >= 0
7729 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7730 && (GET_MODE (operands[0]) == SImode
7731 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7732 || GET_MODE (operands[0]) == HImode
7733 || GET_MODE (operands[0]) == QImode)"
7737 [(set (match_operand 0 "flags_reg_operand" "")
7738 (match_operator 1 "compare_operator"
7740 (match_operand 2 "nonimmediate_operand" "")
7741 (match_operand 3 "const_int_operand" "")
7742 (match_operand 4 "const_int_operand" ""))
7744 "ix86_match_ccmode (insn, CCNOmode)"
7745 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7747 rtx val = operands[2];
7748 HOST_WIDE_INT len = INTVAL (operands[3]);
7749 HOST_WIDE_INT pos = INTVAL (operands[4]);
7751 enum machine_mode mode, submode;
7753 mode = GET_MODE (val);
7756 /* ??? Combine likes to put non-volatile mem extractions in QImode
7757 no matter the size of the test. So find a mode that works. */
7758 if (! MEM_VOLATILE_P (val))
7760 mode = smallest_mode_for_size (pos + len, MODE_INT);
7761 val = adjust_address (val, mode, 0);
7764 else if (GET_CODE (val) == SUBREG
7765 && (submode = GET_MODE (SUBREG_REG (val)),
7766 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7767 && pos + len <= GET_MODE_BITSIZE (submode)
7768 && GET_MODE_CLASS (submode) == MODE_INT)
7770 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7772 val = SUBREG_REG (val);
7774 else if (mode == HImode && pos + len <= 8)
7776 /* Small HImode tests can be converted to QImode. */
7778 val = gen_lowpart (QImode, val);
7781 if (len == HOST_BITS_PER_WIDE_INT)
7784 mask = ((HOST_WIDE_INT)1 << len) - 1;
7787 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7790 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7791 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7792 ;; this is relatively important trick.
7793 ;; Do the conversion only post-reload to avoid limiting of the register class
7796 [(set (match_operand 0 "flags_reg_operand" "")
7797 (match_operator 1 "compare_operator"
7798 [(and (match_operand 2 "register_operand" "")
7799 (match_operand 3 "const_int_operand" ""))
7802 && QI_REG_P (operands[2])
7803 && GET_MODE (operands[2]) != QImode
7804 && ((ix86_match_ccmode (insn, CCZmode)
7805 && !(INTVAL (operands[3]) & ~(255 << 8)))
7806 || (ix86_match_ccmode (insn, CCNOmode)
7807 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7810 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7813 "operands[2] = gen_lowpart (SImode, operands[2]);
7814 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7817 [(set (match_operand 0 "flags_reg_operand" "")
7818 (match_operator 1 "compare_operator"
7819 [(and (match_operand 2 "nonimmediate_operand" "")
7820 (match_operand 3 "const_int_operand" ""))
7823 && GET_MODE (operands[2]) != QImode
7824 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7825 && ((ix86_match_ccmode (insn, CCZmode)
7826 && !(INTVAL (operands[3]) & ~255))
7827 || (ix86_match_ccmode (insn, CCNOmode)
7828 && !(INTVAL (operands[3]) & ~127)))"
7830 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7832 "operands[2] = gen_lowpart (QImode, operands[2]);
7833 operands[3] = gen_lowpart (QImode, operands[3]);")
7835 ;; %%% This used to optimize known byte-wide and operations to memory,
7836 ;; and sometimes to QImode registers. If this is considered useful,
7837 ;; it should be done with splitters.
7839 (define_expand "and<mode>3"
7840 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7841 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7842 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7844 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7846 (define_insn "*anddi_1"
7847 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7849 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7850 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7851 (clobber (reg:CC FLAGS_REG))]
7852 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7854 switch (get_attr_type (insn))
7858 enum machine_mode mode;
7860 gcc_assert (CONST_INT_P (operands[2]));
7861 if (INTVAL (operands[2]) == 0xff)
7865 gcc_assert (INTVAL (operands[2]) == 0xffff);
7869 operands[1] = gen_lowpart (mode, operands[1]);
7871 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7873 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7877 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7878 if (get_attr_mode (insn) == MODE_SI)
7879 return "and{l}\t{%k2, %k0|%k0, %k2}";
7881 return "and{q}\t{%2, %0|%0, %2}";
7884 [(set_attr "type" "alu,alu,alu,imovx")
7885 (set_attr "length_immediate" "*,*,*,0")
7886 (set (attr "prefix_rex")
7888 (and (eq_attr "type" "imovx")
7889 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7890 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7892 (const_string "*")))
7893 (set_attr "mode" "SI,DI,DI,SI")])
7895 (define_insn "*andsi_1"
7896 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7897 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7898 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7899 (clobber (reg:CC FLAGS_REG))]
7900 "ix86_binary_operator_ok (AND, SImode, operands)"
7902 switch (get_attr_type (insn))
7906 enum machine_mode mode;
7908 gcc_assert (CONST_INT_P (operands[2]));
7909 if (INTVAL (operands[2]) == 0xff)
7913 gcc_assert (INTVAL (operands[2]) == 0xffff);
7917 operands[1] = gen_lowpart (mode, operands[1]);
7919 return "movz{bl|x}\t{%1, %0|%0, %1}";
7921 return "movz{wl|x}\t{%1, %0|%0, %1}";
7925 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7926 return "and{l}\t{%2, %0|%0, %2}";
7929 [(set_attr "type" "alu,alu,imovx")
7930 (set (attr "prefix_rex")
7932 (and (eq_attr "type" "imovx")
7933 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7934 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7936 (const_string "*")))
7937 (set_attr "length_immediate" "*,*,0")
7938 (set_attr "mode" "SI")])
7940 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7941 (define_insn "*andsi_1_zext"
7942 [(set (match_operand:DI 0 "register_operand" "=r")
7944 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7945 (match_operand:SI 2 "general_operand" "g"))))
7946 (clobber (reg:CC FLAGS_REG))]
7947 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7948 "and{l}\t{%2, %k0|%k0, %2}"
7949 [(set_attr "type" "alu")
7950 (set_attr "mode" "SI")])
7952 (define_insn "*andhi_1"
7953 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7954 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7955 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7956 (clobber (reg:CC FLAGS_REG))]
7957 "ix86_binary_operator_ok (AND, HImode, operands)"
7959 switch (get_attr_type (insn))
7962 gcc_assert (CONST_INT_P (operands[2]));
7963 gcc_assert (INTVAL (operands[2]) == 0xff);
7964 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7967 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7969 return "and{w}\t{%2, %0|%0, %2}";
7972 [(set_attr "type" "alu,alu,imovx")
7973 (set_attr "length_immediate" "*,*,0")
7974 (set (attr "prefix_rex")
7976 (and (eq_attr "type" "imovx")
7977 (match_operand 1 "ext_QIreg_nomode_operand" ""))
7979 (const_string "*")))
7980 (set_attr "mode" "HI,HI,SI")])
7982 ;; %%% Potential partial reg stall on alternative 2. What to do?
7983 (define_insn "*andqi_1"
7984 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7985 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7986 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7987 (clobber (reg:CC FLAGS_REG))]
7988 "ix86_binary_operator_ok (AND, QImode, operands)"
7990 and{b}\t{%2, %0|%0, %2}
7991 and{b}\t{%2, %0|%0, %2}
7992 and{l}\t{%k2, %k0|%k0, %k2}"
7993 [(set_attr "type" "alu")
7994 (set_attr "mode" "QI,QI,SI")])
7996 (define_insn "*andqi_1_slp"
7997 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7998 (and:QI (match_dup 0)
7999 (match_operand:QI 1 "general_operand" "qn,qmn")))
8000 (clobber (reg:CC FLAGS_REG))]
8001 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8002 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8003 "and{b}\t{%1, %0|%0, %1}"
8004 [(set_attr "type" "alu1")
8005 (set_attr "mode" "QI")])
8008 [(set (match_operand 0 "register_operand" "")
8010 (const_int -65536)))
8011 (clobber (reg:CC FLAGS_REG))]
8012 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8013 || optimize_function_for_size_p (cfun)"
8014 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8015 "operands[1] = gen_lowpart (HImode, operands[0]);")
8018 [(set (match_operand 0 "ext_register_operand" "")
8021 (clobber (reg:CC FLAGS_REG))]
8022 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8023 && reload_completed"
8024 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8025 "operands[1] = gen_lowpart (QImode, operands[0]);")
8028 [(set (match_operand 0 "ext_register_operand" "")
8030 (const_int -65281)))
8031 (clobber (reg:CC FLAGS_REG))]
8032 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8033 && reload_completed"
8034 [(parallel [(set (zero_extract:SI (match_dup 0)
8038 (zero_extract:SI (match_dup 0)
8041 (zero_extract:SI (match_dup 0)
8044 (clobber (reg:CC FLAGS_REG))])]
8045 "operands[0] = gen_lowpart (SImode, operands[0]);")
8047 (define_insn "*anddi_2"
8048 [(set (reg FLAGS_REG)
8051 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8052 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8054 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8055 (and:DI (match_dup 1) (match_dup 2)))]
8056 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8057 && ix86_binary_operator_ok (AND, DImode, operands)"
8059 and{l}\t{%k2, %k0|%k0, %k2}
8060 and{q}\t{%2, %0|%0, %2}
8061 and{q}\t{%2, %0|%0, %2}"
8062 [(set_attr "type" "alu")
8063 (set_attr "mode" "SI,DI,DI")])
8065 (define_insn "*andqi_2_maybe_si"
8066 [(set (reg FLAGS_REG)
8068 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8069 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8071 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8072 (and:QI (match_dup 1) (match_dup 2)))]
8073 "ix86_binary_operator_ok (AND, QImode, operands)
8074 && ix86_match_ccmode (insn,
8075 CONST_INT_P (operands[2])
8076 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8078 if (which_alternative == 2)
8080 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8081 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8082 return "and{l}\t{%2, %k0|%k0, %2}";
8084 return "and{b}\t{%2, %0|%0, %2}";
8086 [(set_attr "type" "alu")
8087 (set_attr "mode" "QI,QI,SI")])
8089 (define_insn "*and<mode>_2"
8090 [(set (reg FLAGS_REG)
8091 (compare (and:SWI124
8092 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8093 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8095 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8096 (and:SWI124 (match_dup 1) (match_dup 2)))]
8097 "ix86_match_ccmode (insn, CCNOmode)
8098 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8099 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8100 [(set_attr "type" "alu")
8101 (set_attr "mode" "<MODE>")])
8103 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8104 (define_insn "*andsi_2_zext"
8105 [(set (reg FLAGS_REG)
8107 (match_operand:SI 1 "nonimmediate_operand" "%0")
8108 (match_operand:SI 2 "general_operand" "g"))
8110 (set (match_operand:DI 0 "register_operand" "=r")
8111 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8112 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8113 && ix86_binary_operator_ok (AND, SImode, operands)"
8114 "and{l}\t{%2, %k0|%k0, %2}"
8115 [(set_attr "type" "alu")
8116 (set_attr "mode" "SI")])
8118 (define_insn "*andqi_2_slp"
8119 [(set (reg FLAGS_REG)
8121 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8122 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8124 (set (strict_low_part (match_dup 0))
8125 (and:QI (match_dup 0) (match_dup 1)))]
8126 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8127 && ix86_match_ccmode (insn, CCNOmode)
8128 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8129 "and{b}\t{%1, %0|%0, %1}"
8130 [(set_attr "type" "alu1")
8131 (set_attr "mode" "QI")])
8133 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8134 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8135 ;; for a QImode operand, which of course failed.
8136 (define_insn "andqi_ext_0"
8137 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8142 (match_operand 1 "ext_register_operand" "0")
8145 (match_operand 2 "const_int_operand" "n")))
8146 (clobber (reg:CC FLAGS_REG))]
8148 "and{b}\t{%2, %h0|%h0, %2}"
8149 [(set_attr "type" "alu")
8150 (set_attr "length_immediate" "1")
8151 (set_attr "modrm" "1")
8152 (set_attr "mode" "QI")])
8154 ;; Generated by peephole translating test to and. This shows up
8155 ;; often in fp comparisons.
8156 (define_insn "*andqi_ext_0_cc"
8157 [(set (reg FLAGS_REG)
8161 (match_operand 1 "ext_register_operand" "0")
8164 (match_operand 2 "const_int_operand" "n"))
8166 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8175 "ix86_match_ccmode (insn, CCNOmode)"
8176 "and{b}\t{%2, %h0|%h0, %2}"
8177 [(set_attr "type" "alu")
8178 (set_attr "length_immediate" "1")
8179 (set_attr "modrm" "1")
8180 (set_attr "mode" "QI")])
8182 (define_insn "*andqi_ext_1_rex64"
8183 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8188 (match_operand 1 "ext_register_operand" "0")
8192 (match_operand 2 "ext_register_operand" "Q"))))
8193 (clobber (reg:CC FLAGS_REG))]
8195 "and{b}\t{%2, %h0|%h0, %2}"
8196 [(set_attr "type" "alu")
8197 (set_attr "length_immediate" "0")
8198 (set_attr "mode" "QI")])
8200 (define_insn "*andqi_ext_1"
8201 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8206 (match_operand 1 "ext_register_operand" "0")
8210 (match_operand:QI 2 "general_operand" "Qm"))))
8211 (clobber (reg:CC FLAGS_REG))]
8213 "and{b}\t{%2, %h0|%h0, %2}"
8214 [(set_attr "type" "alu")
8215 (set_attr "length_immediate" "0")
8216 (set_attr "mode" "QI")])
8218 (define_insn "*andqi_ext_2"
8219 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8224 (match_operand 1 "ext_register_operand" "%0")
8228 (match_operand 2 "ext_register_operand" "Q")
8231 (clobber (reg:CC FLAGS_REG))]
8233 "and{b}\t{%h2, %h0|%h0, %h2}"
8234 [(set_attr "type" "alu")
8235 (set_attr "length_immediate" "0")
8236 (set_attr "mode" "QI")])
8238 ;; Convert wide AND instructions with immediate operand to shorter QImode
8239 ;; equivalents when possible.
8240 ;; Don't do the splitting with memory operands, since it introduces risk
8241 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8242 ;; for size, but that can (should?) be handled by generic code instead.
8244 [(set (match_operand 0 "register_operand" "")
8245 (and (match_operand 1 "register_operand" "")
8246 (match_operand 2 "const_int_operand" "")))
8247 (clobber (reg:CC FLAGS_REG))]
8249 && QI_REG_P (operands[0])
8250 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8251 && !(~INTVAL (operands[2]) & ~(255 << 8))
8252 && GET_MODE (operands[0]) != QImode"
8253 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8254 (and:SI (zero_extract:SI (match_dup 1)
8255 (const_int 8) (const_int 8))
8257 (clobber (reg:CC FLAGS_REG))])]
8258 "operands[0] = gen_lowpart (SImode, operands[0]);
8259 operands[1] = gen_lowpart (SImode, operands[1]);
8260 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8262 ;; Since AND can be encoded with sign extended immediate, this is only
8263 ;; profitable when 7th bit is not set.
8265 [(set (match_operand 0 "register_operand" "")
8266 (and (match_operand 1 "general_operand" "")
8267 (match_operand 2 "const_int_operand" "")))
8268 (clobber (reg:CC FLAGS_REG))]
8270 && ANY_QI_REG_P (operands[0])
8271 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8272 && !(~INTVAL (operands[2]) & ~255)
8273 && !(INTVAL (operands[2]) & 128)
8274 && GET_MODE (operands[0]) != QImode"
8275 [(parallel [(set (strict_low_part (match_dup 0))
8276 (and:QI (match_dup 1)
8278 (clobber (reg:CC FLAGS_REG))])]
8279 "operands[0] = gen_lowpart (QImode, operands[0]);
8280 operands[1] = gen_lowpart (QImode, operands[1]);
8281 operands[2] = gen_lowpart (QImode, operands[2]);")
8283 ;; Logical inclusive and exclusive OR instructions
8285 ;; %%% This used to optimize known byte-wide and operations to memory.
8286 ;; If this is considered useful, it should be done with splitters.
8288 (define_expand "<code><mode>3"
8289 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8290 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8291 (match_operand:SWIM 2 "<general_operand>" "")))]
8293 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8295 (define_insn "*<code><mode>_1"
8296 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8298 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8299 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8300 (clobber (reg:CC FLAGS_REG))]
8301 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8302 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8303 [(set_attr "type" "alu")
8304 (set_attr "mode" "<MODE>")])
8306 ;; %%% Potential partial reg stall on alternative 2. What to do?
8307 (define_insn "*<code>qi_1"
8308 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8309 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8310 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8311 (clobber (reg:CC FLAGS_REG))]
8312 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8314 <logic>{b}\t{%2, %0|%0, %2}
8315 <logic>{b}\t{%2, %0|%0, %2}
8316 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8317 [(set_attr "type" "alu")
8318 (set_attr "mode" "QI,QI,SI")])
8320 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8321 (define_insn "*<code>si_1_zext"
8322 [(set (match_operand:DI 0 "register_operand" "=r")
8324 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8325 (match_operand:SI 2 "general_operand" "g"))))
8326 (clobber (reg:CC FLAGS_REG))]
8327 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8328 "<logic>{l}\t{%2, %k0|%k0, %2}"
8329 [(set_attr "type" "alu")
8330 (set_attr "mode" "SI")])
8332 (define_insn "*<code>si_1_zext_imm"
8333 [(set (match_operand:DI 0 "register_operand" "=r")
8335 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8336 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8337 (clobber (reg:CC FLAGS_REG))]
8338 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8339 "<logic>{l}\t{%2, %k0|%k0, %2}"
8340 [(set_attr "type" "alu")
8341 (set_attr "mode" "SI")])
8343 (define_insn "*<code>qi_1_slp"
8344 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8345 (any_or:QI (match_dup 0)
8346 (match_operand:QI 1 "general_operand" "qmn,qn")))
8347 (clobber (reg:CC FLAGS_REG))]
8348 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8349 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8350 "<logic>{b}\t{%1, %0|%0, %1}"
8351 [(set_attr "type" "alu1")
8352 (set_attr "mode" "QI")])
8354 (define_insn "*<code><mode>_2"
8355 [(set (reg FLAGS_REG)
8356 (compare (any_or:SWI
8357 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8358 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8360 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8361 (any_or:SWI (match_dup 1) (match_dup 2)))]
8362 "ix86_match_ccmode (insn, CCNOmode)
8363 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8364 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8365 [(set_attr "type" "alu")
8366 (set_attr "mode" "<MODE>")])
8368 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8369 ;; ??? Special case for immediate operand is missing - it is tricky.
8370 (define_insn "*<code>si_2_zext"
8371 [(set (reg FLAGS_REG)
8372 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8373 (match_operand:SI 2 "general_operand" "g"))
8375 (set (match_operand:DI 0 "register_operand" "=r")
8376 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8377 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8378 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8379 "<logic>{l}\t{%2, %k0|%k0, %2}"
8380 [(set_attr "type" "alu")
8381 (set_attr "mode" "SI")])
8383 (define_insn "*<code>si_2_zext_imm"
8384 [(set (reg FLAGS_REG)
8386 (match_operand:SI 1 "nonimmediate_operand" "%0")
8387 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8389 (set (match_operand:DI 0 "register_operand" "=r")
8390 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8391 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8392 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8393 "<logic>{l}\t{%2, %k0|%k0, %2}"
8394 [(set_attr "type" "alu")
8395 (set_attr "mode" "SI")])
8397 (define_insn "*<code>qi_2_slp"
8398 [(set (reg FLAGS_REG)
8399 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8400 (match_operand:QI 1 "general_operand" "qmn,qn"))
8402 (set (strict_low_part (match_dup 0))
8403 (any_or:QI (match_dup 0) (match_dup 1)))]
8404 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8405 && ix86_match_ccmode (insn, CCNOmode)
8406 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8407 "<logic>{b}\t{%1, %0|%0, %1}"
8408 [(set_attr "type" "alu1")
8409 (set_attr "mode" "QI")])
8411 (define_insn "*<code><mode>_3"
8412 [(set (reg FLAGS_REG)
8413 (compare (any_or:SWI
8414 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8415 (match_operand:SWI 2 "<general_operand>" "<g>"))
8417 (clobber (match_scratch:SWI 0 "=<r>"))]
8418 "ix86_match_ccmode (insn, CCNOmode)
8419 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8420 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8421 [(set_attr "type" "alu")
8422 (set_attr "mode" "<MODE>")])
8424 (define_insn "*<code>qi_ext_0"
8425 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8430 (match_operand 1 "ext_register_operand" "0")
8433 (match_operand 2 "const_int_operand" "n")))
8434 (clobber (reg:CC FLAGS_REG))]
8435 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8436 "<logic>{b}\t{%2, %h0|%h0, %2}"
8437 [(set_attr "type" "alu")
8438 (set_attr "length_immediate" "1")
8439 (set_attr "modrm" "1")
8440 (set_attr "mode" "QI")])
8442 (define_insn "*<code>qi_ext_1_rex64"
8443 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8448 (match_operand 1 "ext_register_operand" "0")
8452 (match_operand 2 "ext_register_operand" "Q"))))
8453 (clobber (reg:CC FLAGS_REG))]
8455 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8456 "<logic>{b}\t{%2, %h0|%h0, %2}"
8457 [(set_attr "type" "alu")
8458 (set_attr "length_immediate" "0")
8459 (set_attr "mode" "QI")])
8461 (define_insn "*<code>qi_ext_1"
8462 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8467 (match_operand 1 "ext_register_operand" "0")
8471 (match_operand:QI 2 "general_operand" "Qm"))))
8472 (clobber (reg:CC FLAGS_REG))]
8474 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8475 "<logic>{b}\t{%2, %h0|%h0, %2}"
8476 [(set_attr "type" "alu")
8477 (set_attr "length_immediate" "0")
8478 (set_attr "mode" "QI")])
8480 (define_insn "*<code>qi_ext_2"
8481 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8485 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8488 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8491 (clobber (reg:CC FLAGS_REG))]
8492 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8493 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8494 [(set_attr "type" "alu")
8495 (set_attr "length_immediate" "0")
8496 (set_attr "mode" "QI")])
8499 [(set (match_operand 0 "register_operand" "")
8500 (any_or (match_operand 1 "register_operand" "")
8501 (match_operand 2 "const_int_operand" "")))
8502 (clobber (reg:CC FLAGS_REG))]
8504 && QI_REG_P (operands[0])
8505 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8506 && !(INTVAL (operands[2]) & ~(255 << 8))
8507 && GET_MODE (operands[0]) != QImode"
8508 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8509 (any_or:SI (zero_extract:SI (match_dup 1)
8510 (const_int 8) (const_int 8))
8512 (clobber (reg:CC FLAGS_REG))])]
8513 "operands[0] = gen_lowpart (SImode, operands[0]);
8514 operands[1] = gen_lowpart (SImode, operands[1]);
8515 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8517 ;; Since OR can be encoded with sign extended immediate, this is only
8518 ;; profitable when 7th bit is set.
8520 [(set (match_operand 0 "register_operand" "")
8521 (any_or (match_operand 1 "general_operand" "")
8522 (match_operand 2 "const_int_operand" "")))
8523 (clobber (reg:CC FLAGS_REG))]
8525 && ANY_QI_REG_P (operands[0])
8526 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8527 && !(INTVAL (operands[2]) & ~255)
8528 && (INTVAL (operands[2]) & 128)
8529 && GET_MODE (operands[0]) != QImode"
8530 [(parallel [(set (strict_low_part (match_dup 0))
8531 (any_or:QI (match_dup 1)
8533 (clobber (reg:CC FLAGS_REG))])]
8534 "operands[0] = gen_lowpart (QImode, operands[0]);
8535 operands[1] = gen_lowpart (QImode, operands[1]);
8536 operands[2] = gen_lowpart (QImode, operands[2]);")
8538 (define_expand "xorqi_cc_ext_1"
8540 (set (reg:CCNO FLAGS_REG)
8544 (match_operand 1 "ext_register_operand" "")
8547 (match_operand:QI 2 "general_operand" ""))
8549 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8559 (define_insn "*xorqi_cc_ext_1_rex64"
8560 [(set (reg FLAGS_REG)
8564 (match_operand 1 "ext_register_operand" "0")
8567 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8569 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8578 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8579 "xor{b}\t{%2, %h0|%h0, %2}"
8580 [(set_attr "type" "alu")
8581 (set_attr "modrm" "1")
8582 (set_attr "mode" "QI")])
8584 (define_insn "*xorqi_cc_ext_1"
8585 [(set (reg FLAGS_REG)
8589 (match_operand 1 "ext_register_operand" "0")
8592 (match_operand:QI 2 "general_operand" "qmn"))
8594 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8603 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8604 "xor{b}\t{%2, %h0|%h0, %2}"
8605 [(set_attr "type" "alu")
8606 (set_attr "modrm" "1")
8607 (set_attr "mode" "QI")])
8609 ;; Negation instructions
8611 (define_expand "neg<mode>2"
8612 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8613 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8615 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8617 (define_insn_and_split "*neg<dwi>2_doubleword"
8618 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8619 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8620 (clobber (reg:CC FLAGS_REG))]
8621 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8625 [(set (reg:CCZ FLAGS_REG)
8626 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8627 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8630 (plus:DWIH (match_dup 3)
8631 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8633 (clobber (reg:CC FLAGS_REG))])
8636 (neg:DWIH (match_dup 2)))
8637 (clobber (reg:CC FLAGS_REG))])]
8638 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8640 (define_insn "*neg<mode>2_1"
8641 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8642 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8643 (clobber (reg:CC FLAGS_REG))]
8644 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8645 "neg{<imodesuffix>}\t%0"
8646 [(set_attr "type" "negnot")
8647 (set_attr "mode" "<MODE>")])
8649 ;; Combine is quite creative about this pattern.
8650 (define_insn "*negsi2_1_zext"
8651 [(set (match_operand:DI 0 "register_operand" "=r")
8653 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8656 (clobber (reg:CC FLAGS_REG))]
8657 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8659 [(set_attr "type" "negnot")
8660 (set_attr "mode" "SI")])
8662 ;; The problem with neg is that it does not perform (compare x 0),
8663 ;; it really performs (compare 0 x), which leaves us with the zero
8664 ;; flag being the only useful item.
8666 (define_insn "*neg<mode>2_cmpz"
8667 [(set (reg:CCZ FLAGS_REG)
8669 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8671 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8672 (neg:SWI (match_dup 1)))]
8673 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8674 "neg{<imodesuffix>}\t%0"
8675 [(set_attr "type" "negnot")
8676 (set_attr "mode" "<MODE>")])
8678 (define_insn "*negsi2_cmpz_zext"
8679 [(set (reg:CCZ FLAGS_REG)
8683 (match_operand:DI 1 "register_operand" "0")
8687 (set (match_operand:DI 0 "register_operand" "=r")
8688 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8691 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8693 [(set_attr "type" "negnot")
8694 (set_attr "mode" "SI")])
8696 ;; Changing of sign for FP values is doable using integer unit too.
8698 (define_expand "<code><mode>2"
8699 [(set (match_operand:X87MODEF 0 "register_operand" "")
8700 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8701 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8702 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8704 (define_insn "*absneg<mode>2_mixed"
8705 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8706 (match_operator:MODEF 3 "absneg_operator"
8707 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8708 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8709 (clobber (reg:CC FLAGS_REG))]
8710 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8713 (define_insn "*absneg<mode>2_sse"
8714 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8715 (match_operator:MODEF 3 "absneg_operator"
8716 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8717 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8718 (clobber (reg:CC FLAGS_REG))]
8719 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8722 (define_insn "*absneg<mode>2_i387"
8723 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8724 (match_operator:X87MODEF 3 "absneg_operator"
8725 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8726 (use (match_operand 2 "" ""))
8727 (clobber (reg:CC FLAGS_REG))]
8728 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8731 (define_expand "<code>tf2"
8732 [(set (match_operand:TF 0 "register_operand" "")
8733 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8735 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8737 (define_insn "*absnegtf2_sse"
8738 [(set (match_operand:TF 0 "register_operand" "=x,x")
8739 (match_operator:TF 3 "absneg_operator"
8740 [(match_operand:TF 1 "register_operand" "0,x")]))
8741 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8742 (clobber (reg:CC FLAGS_REG))]
8746 ;; Splitters for fp abs and neg.
8749 [(set (match_operand 0 "fp_register_operand" "")
8750 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8751 (use (match_operand 2 "" ""))
8752 (clobber (reg:CC FLAGS_REG))]
8754 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8757 [(set (match_operand 0 "register_operand" "")
8758 (match_operator 3 "absneg_operator"
8759 [(match_operand 1 "register_operand" "")]))
8760 (use (match_operand 2 "nonimmediate_operand" ""))
8761 (clobber (reg:CC FLAGS_REG))]
8762 "reload_completed && SSE_REG_P (operands[0])"
8763 [(set (match_dup 0) (match_dup 3))]
8765 enum machine_mode mode = GET_MODE (operands[0]);
8766 enum machine_mode vmode = GET_MODE (operands[2]);
8769 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8770 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8771 if (operands_match_p (operands[0], operands[2]))
8774 operands[1] = operands[2];
8777 if (GET_CODE (operands[3]) == ABS)
8778 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8780 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8785 [(set (match_operand:SF 0 "register_operand" "")
8786 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8787 (use (match_operand:V4SF 2 "" ""))
8788 (clobber (reg:CC FLAGS_REG))]
8790 [(parallel [(set (match_dup 0) (match_dup 1))
8791 (clobber (reg:CC FLAGS_REG))])]
8794 operands[0] = gen_lowpart (SImode, operands[0]);
8795 if (GET_CODE (operands[1]) == ABS)
8797 tmp = gen_int_mode (0x7fffffff, SImode);
8798 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8802 tmp = gen_int_mode (0x80000000, SImode);
8803 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8809 [(set (match_operand:DF 0 "register_operand" "")
8810 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8811 (use (match_operand 2 "" ""))
8812 (clobber (reg:CC FLAGS_REG))]
8814 [(parallel [(set (match_dup 0) (match_dup 1))
8815 (clobber (reg:CC FLAGS_REG))])]
8820 tmp = gen_lowpart (DImode, operands[0]);
8821 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8824 if (GET_CODE (operands[1]) == ABS)
8827 tmp = gen_rtx_NOT (DImode, tmp);
8831 operands[0] = gen_highpart (SImode, operands[0]);
8832 if (GET_CODE (operands[1]) == ABS)
8834 tmp = gen_int_mode (0x7fffffff, SImode);
8835 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8839 tmp = gen_int_mode (0x80000000, SImode);
8840 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8847 [(set (match_operand:XF 0 "register_operand" "")
8848 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8849 (use (match_operand 2 "" ""))
8850 (clobber (reg:CC FLAGS_REG))]
8852 [(parallel [(set (match_dup 0) (match_dup 1))
8853 (clobber (reg:CC FLAGS_REG))])]
8856 operands[0] = gen_rtx_REG (SImode,
8857 true_regnum (operands[0])
8858 + (TARGET_64BIT ? 1 : 2));
8859 if (GET_CODE (operands[1]) == ABS)
8861 tmp = GEN_INT (0x7fff);
8862 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8866 tmp = GEN_INT (0x8000);
8867 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8872 ;; Conditionalize these after reload. If they match before reload, we
8873 ;; lose the clobber and ability to use integer instructions.
8875 (define_insn "*<code><mode>2_1"
8876 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8877 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8879 && (reload_completed
8880 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8881 "f<absneg_mnemonic>"
8882 [(set_attr "type" "fsgn")
8883 (set_attr "mode" "<MODE>")])
8885 (define_insn "*<code>extendsfdf2"
8886 [(set (match_operand:DF 0 "register_operand" "=f")
8887 (absneg:DF (float_extend:DF
8888 (match_operand:SF 1 "register_operand" "0"))))]
8889 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8890 "f<absneg_mnemonic>"
8891 [(set_attr "type" "fsgn")
8892 (set_attr "mode" "DF")])
8894 (define_insn "*<code>extendsfxf2"
8895 [(set (match_operand:XF 0 "register_operand" "=f")
8896 (absneg:XF (float_extend:XF
8897 (match_operand:SF 1 "register_operand" "0"))))]
8899 "f<absneg_mnemonic>"
8900 [(set_attr "type" "fsgn")
8901 (set_attr "mode" "XF")])
8903 (define_insn "*<code>extenddfxf2"
8904 [(set (match_operand:XF 0 "register_operand" "=f")
8905 (absneg:XF (float_extend:XF
8906 (match_operand:DF 1 "register_operand" "0"))))]
8908 "f<absneg_mnemonic>"
8909 [(set_attr "type" "fsgn")
8910 (set_attr "mode" "XF")])
8912 ;; Copysign instructions
8914 (define_mode_iterator CSGNMODE [SF DF TF])
8915 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8917 (define_expand "copysign<mode>3"
8918 [(match_operand:CSGNMODE 0 "register_operand" "")
8919 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8920 (match_operand:CSGNMODE 2 "register_operand" "")]
8921 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8922 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8923 "ix86_expand_copysign (operands); DONE;")
8925 (define_insn_and_split "copysign<mode>3_const"
8926 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8928 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8929 (match_operand:CSGNMODE 2 "register_operand" "0")
8930 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8932 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8933 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8935 "&& reload_completed"
8937 "ix86_split_copysign_const (operands); DONE;")
8939 (define_insn "copysign<mode>3_var"
8940 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8942 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8943 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8944 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8945 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8947 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8948 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8949 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8953 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8955 [(match_operand:CSGNMODE 2 "register_operand" "")
8956 (match_operand:CSGNMODE 3 "register_operand" "")
8957 (match_operand:<CSGNVMODE> 4 "" "")
8958 (match_operand:<CSGNVMODE> 5 "" "")]
8960 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8961 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8962 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8963 && reload_completed"
8965 "ix86_split_copysign_var (operands); DONE;")
8967 ;; One complement instructions
8969 (define_expand "one_cmpl<mode>2"
8970 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8971 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8973 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8975 (define_insn "*one_cmpl<mode>2_1"
8976 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8977 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8978 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8979 "not{<imodesuffix>}\t%0"
8980 [(set_attr "type" "negnot")
8981 (set_attr "mode" "<MODE>")])
8983 ;; %%% Potential partial reg stall on alternative 1. What to do?
8984 (define_insn "*one_cmplqi2_1"
8985 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8986 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8987 "ix86_unary_operator_ok (NOT, QImode, operands)"
8991 [(set_attr "type" "negnot")
8992 (set_attr "mode" "QI,SI")])
8994 ;; ??? Currently never generated - xor is used instead.
8995 (define_insn "*one_cmplsi2_1_zext"
8996 [(set (match_operand:DI 0 "register_operand" "=r")
8998 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8999 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9001 [(set_attr "type" "negnot")
9002 (set_attr "mode" "SI")])
9004 (define_insn "*one_cmpl<mode>2_2"
9005 [(set (reg FLAGS_REG)
9006 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9008 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9009 (not:SWI (match_dup 1)))]
9010 "ix86_match_ccmode (insn, CCNOmode)
9011 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9013 [(set_attr "type" "alu1")
9014 (set_attr "mode" "<MODE>")])
9017 [(set (match_operand 0 "flags_reg_operand" "")
9018 (match_operator 2 "compare_operator"
9019 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9021 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9022 (not:SWI (match_dup 3)))]
9023 "ix86_match_ccmode (insn, CCNOmode)"
9024 [(parallel [(set (match_dup 0)
9025 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9028 (xor:SWI (match_dup 3) (const_int -1)))])])
9030 ;; ??? Currently never generated - xor is used instead.
9031 (define_insn "*one_cmplsi2_2_zext"
9032 [(set (reg FLAGS_REG)
9033 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9035 (set (match_operand:DI 0 "register_operand" "=r")
9036 (zero_extend:DI (not:SI (match_dup 1))))]
9037 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9038 && ix86_unary_operator_ok (NOT, SImode, operands)"
9040 [(set_attr "type" "alu1")
9041 (set_attr "mode" "SI")])
9044 [(set (match_operand 0 "flags_reg_operand" "")
9045 (match_operator 2 "compare_operator"
9046 [(not:SI (match_operand:SI 3 "register_operand" ""))
9048 (set (match_operand:DI 1 "register_operand" "")
9049 (zero_extend:DI (not:SI (match_dup 3))))]
9050 "ix86_match_ccmode (insn, CCNOmode)"
9051 [(parallel [(set (match_dup 0)
9052 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9055 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9057 ;; Shift instructions
9059 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9060 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9061 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9062 ;; from the assembler input.
9064 ;; This instruction shifts the target reg/mem as usual, but instead of
9065 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9066 ;; is a left shift double, bits are taken from the high order bits of
9067 ;; reg, else if the insn is a shift right double, bits are taken from the
9068 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9069 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9071 ;; Since sh[lr]d does not change the `reg' operand, that is done
9072 ;; separately, making all shifts emit pairs of shift double and normal
9073 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9074 ;; support a 63 bit shift, each shift where the count is in a reg expands
9075 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9077 ;; If the shift count is a constant, we need never emit more than one
9078 ;; shift pair, instead using moves and sign extension for counts greater
9081 (define_expand "ashl<mode>3"
9082 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9083 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9084 (match_operand:QI 2 "nonmemory_operand" "")))]
9086 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9088 (define_insn "*ashl<mode>3_doubleword"
9089 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9090 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9091 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9092 (clobber (reg:CC FLAGS_REG))]
9095 [(set_attr "type" "multi")])
9098 [(set (match_operand:DWI 0 "register_operand" "")
9099 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9100 (match_operand:QI 2 "nonmemory_operand" "")))
9101 (clobber (reg:CC FLAGS_REG))]
9102 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9104 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9106 ;; By default we don't ask for a scratch register, because when DWImode
9107 ;; values are manipulated, registers are already at a premium. But if
9108 ;; we have one handy, we won't turn it away.
9111 [(match_scratch:DWIH 3 "r")
9112 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9114 (match_operand:<DWI> 1 "nonmemory_operand" "")
9115 (match_operand:QI 2 "nonmemory_operand" "")))
9116 (clobber (reg:CC FLAGS_REG))])
9120 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9122 (define_insn "x86_64_shld"
9123 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9124 (ior:DI (ashift:DI (match_dup 0)
9125 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9126 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9127 (minus:QI (const_int 64) (match_dup 2)))))
9128 (clobber (reg:CC FLAGS_REG))]
9130 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9131 [(set_attr "type" "ishift")
9132 (set_attr "prefix_0f" "1")
9133 (set_attr "mode" "DI")
9134 (set_attr "athlon_decode" "vector")
9135 (set_attr "amdfam10_decode" "vector")
9136 (set_attr "bdver1_decode" "vector")])
9138 (define_insn "x86_shld"
9139 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9140 (ior:SI (ashift:SI (match_dup 0)
9141 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9142 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9143 (minus:QI (const_int 32) (match_dup 2)))))
9144 (clobber (reg:CC FLAGS_REG))]
9146 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9147 [(set_attr "type" "ishift")
9148 (set_attr "prefix_0f" "1")
9149 (set_attr "mode" "SI")
9150 (set_attr "pent_pair" "np")
9151 (set_attr "athlon_decode" "vector")
9152 (set_attr "amdfam10_decode" "vector")
9153 (set_attr "bdver1_decode" "vector")])
9155 (define_expand "x86_shift<mode>_adj_1"
9156 [(set (reg:CCZ FLAGS_REG)
9157 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9160 (set (match_operand:SWI48 0 "register_operand" "")
9161 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9162 (match_operand:SWI48 1 "register_operand" "")
9165 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9166 (match_operand:SWI48 3 "register_operand" "r")
9169 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9171 (define_expand "x86_shift<mode>_adj_2"
9172 [(use (match_operand:SWI48 0 "register_operand" ""))
9173 (use (match_operand:SWI48 1 "register_operand" ""))
9174 (use (match_operand:QI 2 "register_operand" ""))]
9177 rtx label = gen_label_rtx ();
9180 emit_insn (gen_testqi_ccz_1 (operands[2],
9181 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9183 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9184 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9185 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9186 gen_rtx_LABEL_REF (VOIDmode, label),
9188 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9189 JUMP_LABEL (tmp) = label;
9191 emit_move_insn (operands[0], operands[1]);
9192 ix86_expand_clear (operands[1]);
9195 LABEL_NUSES (label) = 1;
9200 ;; Avoid useless masking of count operand.
9201 (define_insn_and_split "*ashl<mode>3_mask"
9202 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9204 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9207 (match_operand:SI 2 "nonimmediate_operand" "c")
9208 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9209 (clobber (reg:CC FLAGS_REG))]
9210 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9211 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9212 == GET_MODE_BITSIZE (<MODE>mode)-1"
9215 [(parallel [(set (match_dup 0)
9216 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9217 (clobber (reg:CC FLAGS_REG))])]
9219 if (can_create_pseudo_p ())
9220 operands [2] = force_reg (SImode, operands[2]);
9222 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9224 [(set_attr "type" "ishift")
9225 (set_attr "mode" "<MODE>")])
9227 (define_insn "*ashl<mode>3_1"
9228 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9229 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9230 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9231 (clobber (reg:CC FLAGS_REG))]
9232 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9234 switch (get_attr_type (insn))
9240 gcc_assert (operands[2] == const1_rtx);
9241 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9242 return "add{<imodesuffix>}\t%0, %0";
9245 if (operands[2] == const1_rtx
9246 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9247 return "sal{<imodesuffix>}\t%0";
9249 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9253 (cond [(eq_attr "alternative" "1")
9254 (const_string "lea")
9255 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9257 (match_operand 0 "register_operand" ""))
9258 (match_operand 2 "const1_operand" ""))
9259 (const_string "alu")
9261 (const_string "ishift")))
9262 (set (attr "length_immediate")
9264 (ior (eq_attr "type" "alu")
9265 (and (eq_attr "type" "ishift")
9266 (and (match_operand 2 "const1_operand" "")
9267 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9270 (const_string "*")))
9271 (set_attr "mode" "<MODE>")])
9273 (define_insn "*ashlsi3_1_zext"
9274 [(set (match_operand:DI 0 "register_operand" "=r,r")
9276 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9277 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9278 (clobber (reg:CC FLAGS_REG))]
9279 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9281 switch (get_attr_type (insn))
9287 gcc_assert (operands[2] == const1_rtx);
9288 return "add{l}\t%k0, %k0";
9291 if (operands[2] == const1_rtx
9292 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9293 return "sal{l}\t%k0";
9295 return "sal{l}\t{%2, %k0|%k0, %2}";
9299 (cond [(eq_attr "alternative" "1")
9300 (const_string "lea")
9301 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9303 (match_operand 2 "const1_operand" ""))
9304 (const_string "alu")
9306 (const_string "ishift")))
9307 (set (attr "length_immediate")
9309 (ior (eq_attr "type" "alu")
9310 (and (eq_attr "type" "ishift")
9311 (and (match_operand 2 "const1_operand" "")
9312 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9315 (const_string "*")))
9316 (set_attr "mode" "SI")])
9318 (define_insn "*ashlhi3_1"
9319 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9320 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9321 (match_operand:QI 2 "nonmemory_operand" "cI")))
9322 (clobber (reg:CC FLAGS_REG))]
9323 "TARGET_PARTIAL_REG_STALL
9324 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9326 switch (get_attr_type (insn))
9329 gcc_assert (operands[2] == const1_rtx);
9330 return "add{w}\t%0, %0";
9333 if (operands[2] == const1_rtx
9334 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9335 return "sal{w}\t%0";
9337 return "sal{w}\t{%2, %0|%0, %2}";
9341 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9343 (match_operand 0 "register_operand" ""))
9344 (match_operand 2 "const1_operand" ""))
9345 (const_string "alu")
9347 (const_string "ishift")))
9348 (set (attr "length_immediate")
9350 (ior (eq_attr "type" "alu")
9351 (and (eq_attr "type" "ishift")
9352 (and (match_operand 2 "const1_operand" "")
9353 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9356 (const_string "*")))
9357 (set_attr "mode" "HI")])
9359 (define_insn "*ashlhi3_1_lea"
9360 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9361 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9362 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9363 (clobber (reg:CC FLAGS_REG))]
9364 "!TARGET_PARTIAL_REG_STALL
9365 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9367 switch (get_attr_type (insn))
9373 gcc_assert (operands[2] == const1_rtx);
9374 return "add{w}\t%0, %0";
9377 if (operands[2] == const1_rtx
9378 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9379 return "sal{w}\t%0";
9381 return "sal{w}\t{%2, %0|%0, %2}";
9385 (cond [(eq_attr "alternative" "1")
9386 (const_string "lea")
9387 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9389 (match_operand 0 "register_operand" ""))
9390 (match_operand 2 "const1_operand" ""))
9391 (const_string "alu")
9393 (const_string "ishift")))
9394 (set (attr "length_immediate")
9396 (ior (eq_attr "type" "alu")
9397 (and (eq_attr "type" "ishift")
9398 (and (match_operand 2 "const1_operand" "")
9399 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9402 (const_string "*")))
9403 (set_attr "mode" "HI,SI")])
9405 (define_insn "*ashlqi3_1"
9406 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9407 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9408 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9409 (clobber (reg:CC FLAGS_REG))]
9410 "TARGET_PARTIAL_REG_STALL
9411 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9413 switch (get_attr_type (insn))
9416 gcc_assert (operands[2] == const1_rtx);
9417 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9418 return "add{l}\t%k0, %k0";
9420 return "add{b}\t%0, %0";
9423 if (operands[2] == const1_rtx
9424 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9426 if (get_attr_mode (insn) == MODE_SI)
9427 return "sal{l}\t%k0";
9429 return "sal{b}\t%0";
9433 if (get_attr_mode (insn) == MODE_SI)
9434 return "sal{l}\t{%2, %k0|%k0, %2}";
9436 return "sal{b}\t{%2, %0|%0, %2}";
9441 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9443 (match_operand 0 "register_operand" ""))
9444 (match_operand 2 "const1_operand" ""))
9445 (const_string "alu")
9447 (const_string "ishift")))
9448 (set (attr "length_immediate")
9450 (ior (eq_attr "type" "alu")
9451 (and (eq_attr "type" "ishift")
9452 (and (match_operand 2 "const1_operand" "")
9453 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9456 (const_string "*")))
9457 (set_attr "mode" "QI,SI")])
9459 ;; %%% Potential partial reg stall on alternative 2. What to do?
9460 (define_insn "*ashlqi3_1_lea"
9461 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9462 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9463 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9464 (clobber (reg:CC FLAGS_REG))]
9465 "!TARGET_PARTIAL_REG_STALL
9466 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9468 switch (get_attr_type (insn))
9474 gcc_assert (operands[2] == const1_rtx);
9475 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9476 return "add{l}\t%k0, %k0";
9478 return "add{b}\t%0, %0";
9481 if (operands[2] == const1_rtx
9482 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9484 if (get_attr_mode (insn) == MODE_SI)
9485 return "sal{l}\t%k0";
9487 return "sal{b}\t%0";
9491 if (get_attr_mode (insn) == MODE_SI)
9492 return "sal{l}\t{%2, %k0|%k0, %2}";
9494 return "sal{b}\t{%2, %0|%0, %2}";
9499 (cond [(eq_attr "alternative" "2")
9500 (const_string "lea")
9501 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9503 (match_operand 0 "register_operand" ""))
9504 (match_operand 2 "const1_operand" ""))
9505 (const_string "alu")
9507 (const_string "ishift")))
9508 (set (attr "length_immediate")
9510 (ior (eq_attr "type" "alu")
9511 (and (eq_attr "type" "ishift")
9512 (and (match_operand 2 "const1_operand" "")
9513 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9516 (const_string "*")))
9517 (set_attr "mode" "QI,SI,SI")])
9519 (define_insn "*ashlqi3_1_slp"
9520 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9521 (ashift:QI (match_dup 0)
9522 (match_operand:QI 1 "nonmemory_operand" "cI")))
9523 (clobber (reg:CC FLAGS_REG))]
9524 "(optimize_function_for_size_p (cfun)
9525 || !TARGET_PARTIAL_FLAG_REG_STALL
9526 || (operands[1] == const1_rtx
9528 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9530 switch (get_attr_type (insn))
9533 gcc_assert (operands[1] == const1_rtx);
9534 return "add{b}\t%0, %0";
9537 if (operands[1] == const1_rtx
9538 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9539 return "sal{b}\t%0";
9541 return "sal{b}\t{%1, %0|%0, %1}";
9545 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9547 (match_operand 0 "register_operand" ""))
9548 (match_operand 1 "const1_operand" ""))
9549 (const_string "alu")
9551 (const_string "ishift1")))
9552 (set (attr "length_immediate")
9554 (ior (eq_attr "type" "alu")
9555 (and (eq_attr "type" "ishift1")
9556 (and (match_operand 1 "const1_operand" "")
9557 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9560 (const_string "*")))
9561 (set_attr "mode" "QI")])
9563 ;; Convert lea to the lea pattern to avoid flags dependency.
9565 [(set (match_operand 0 "register_operand" "")
9566 (ashift (match_operand 1 "index_register_operand" "")
9567 (match_operand:QI 2 "const_int_operand" "")))
9568 (clobber (reg:CC FLAGS_REG))]
9570 && true_regnum (operands[0]) != true_regnum (operands[1])"
9574 enum machine_mode mode = GET_MODE (operands[0]);
9577 operands[1] = gen_lowpart (Pmode, operands[1]);
9578 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9580 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9582 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9583 operands[0] = gen_lowpart (SImode, operands[0]);
9585 if (TARGET_64BIT && mode != Pmode)
9586 pat = gen_rtx_SUBREG (SImode, pat, 0);
9588 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9592 ;; Convert lea to the lea pattern to avoid flags dependency.
9594 [(set (match_operand:DI 0 "register_operand" "")
9596 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9597 (match_operand:QI 2 "const_int_operand" ""))))
9598 (clobber (reg:CC FLAGS_REG))]
9599 "TARGET_64BIT && reload_completed
9600 && true_regnum (operands[0]) != true_regnum (operands[1])"
9602 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9604 operands[1] = gen_lowpart (DImode, operands[1]);
9605 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9608 ;; This pattern can't accept a variable shift count, since shifts by
9609 ;; zero don't affect the flags. We assume that shifts by constant
9610 ;; zero are optimized away.
9611 (define_insn "*ashl<mode>3_cmp"
9612 [(set (reg FLAGS_REG)
9614 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9615 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9617 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9618 (ashift:SWI (match_dup 1) (match_dup 2)))]
9619 "(optimize_function_for_size_p (cfun)
9620 || !TARGET_PARTIAL_FLAG_REG_STALL
9621 || (operands[2] == const1_rtx
9623 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9624 && ix86_match_ccmode (insn, CCGOCmode)
9625 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9627 switch (get_attr_type (insn))
9630 gcc_assert (operands[2] == const1_rtx);
9631 return "add{<imodesuffix>}\t%0, %0";
9634 if (operands[2] == const1_rtx
9635 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9636 return "sal{<imodesuffix>}\t%0";
9638 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9642 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9644 (match_operand 0 "register_operand" ""))
9645 (match_operand 2 "const1_operand" ""))
9646 (const_string "alu")
9648 (const_string "ishift")))
9649 (set (attr "length_immediate")
9651 (ior (eq_attr "type" "alu")
9652 (and (eq_attr "type" "ishift")
9653 (and (match_operand 2 "const1_operand" "")
9654 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9657 (const_string "*")))
9658 (set_attr "mode" "<MODE>")])
9660 (define_insn "*ashlsi3_cmp_zext"
9661 [(set (reg FLAGS_REG)
9663 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9664 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9666 (set (match_operand:DI 0 "register_operand" "=r")
9667 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9669 && (optimize_function_for_size_p (cfun)
9670 || !TARGET_PARTIAL_FLAG_REG_STALL
9671 || (operands[2] == const1_rtx
9673 || TARGET_DOUBLE_WITH_ADD)))
9674 && ix86_match_ccmode (insn, CCGOCmode)
9675 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9677 switch (get_attr_type (insn))
9680 gcc_assert (operands[2] == const1_rtx);
9681 return "add{l}\t%k0, %k0";
9684 if (operands[2] == const1_rtx
9685 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9686 return "sal{l}\t%k0";
9688 return "sal{l}\t{%2, %k0|%k0, %2}";
9692 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9694 (match_operand 2 "const1_operand" ""))
9695 (const_string "alu")
9697 (const_string "ishift")))
9698 (set (attr "length_immediate")
9700 (ior (eq_attr "type" "alu")
9701 (and (eq_attr "type" "ishift")
9702 (and (match_operand 2 "const1_operand" "")
9703 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9706 (const_string "*")))
9707 (set_attr "mode" "SI")])
9709 (define_insn "*ashl<mode>3_cconly"
9710 [(set (reg FLAGS_REG)
9712 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9713 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9715 (clobber (match_scratch:SWI 0 "=<r>"))]
9716 "(optimize_function_for_size_p (cfun)
9717 || !TARGET_PARTIAL_FLAG_REG_STALL
9718 || (operands[2] == const1_rtx
9720 || TARGET_DOUBLE_WITH_ADD)))
9721 && ix86_match_ccmode (insn, CCGOCmode)
9722 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9724 switch (get_attr_type (insn))
9727 gcc_assert (operands[2] == const1_rtx);
9728 return "add{<imodesuffix>}\t%0, %0";
9731 if (operands[2] == const1_rtx
9732 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9733 return "sal{<imodesuffix>}\t%0";
9735 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9739 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9741 (match_operand 0 "register_operand" ""))
9742 (match_operand 2 "const1_operand" ""))
9743 (const_string "alu")
9745 (const_string "ishift")))
9746 (set (attr "length_immediate")
9748 (ior (eq_attr "type" "alu")
9749 (and (eq_attr "type" "ishift")
9750 (and (match_operand 2 "const1_operand" "")
9751 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9754 (const_string "*")))
9755 (set_attr "mode" "<MODE>")])
9757 ;; See comment above `ashl<mode>3' about how this works.
9759 (define_expand "<shiftrt_insn><mode>3"
9760 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9761 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9762 (match_operand:QI 2 "nonmemory_operand" "")))]
9764 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9766 ;; Avoid useless masking of count operand.
9767 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9768 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9770 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9773 (match_operand:SI 2 "nonimmediate_operand" "c")
9774 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9775 (clobber (reg:CC FLAGS_REG))]
9776 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9777 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9778 == GET_MODE_BITSIZE (<MODE>mode)-1"
9781 [(parallel [(set (match_dup 0)
9782 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9783 (clobber (reg:CC FLAGS_REG))])]
9785 if (can_create_pseudo_p ())
9786 operands [2] = force_reg (SImode, operands[2]);
9788 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9790 [(set_attr "type" "ishift")
9791 (set_attr "mode" "<MODE>")])
9793 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9794 [(set (match_operand:DWI 0 "register_operand" "=r")
9795 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9796 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9797 (clobber (reg:CC FLAGS_REG))]
9800 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9802 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9803 [(set_attr "type" "multi")])
9805 ;; By default we don't ask for a scratch register, because when DWImode
9806 ;; values are manipulated, registers are already at a premium. But if
9807 ;; we have one handy, we won't turn it away.
9810 [(match_scratch:DWIH 3 "r")
9811 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9813 (match_operand:<DWI> 1 "register_operand" "")
9814 (match_operand:QI 2 "nonmemory_operand" "")))
9815 (clobber (reg:CC FLAGS_REG))])
9819 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9821 (define_insn "x86_64_shrd"
9822 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9823 (ior:DI (ashiftrt:DI (match_dup 0)
9824 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9825 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9826 (minus:QI (const_int 64) (match_dup 2)))))
9827 (clobber (reg:CC FLAGS_REG))]
9829 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9830 [(set_attr "type" "ishift")
9831 (set_attr "prefix_0f" "1")
9832 (set_attr "mode" "DI")
9833 (set_attr "athlon_decode" "vector")
9834 (set_attr "amdfam10_decode" "vector")
9835 (set_attr "bdver1_decode" "vector")])
9837 (define_insn "x86_shrd"
9838 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9839 (ior:SI (ashiftrt:SI (match_dup 0)
9840 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9841 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9842 (minus:QI (const_int 32) (match_dup 2)))))
9843 (clobber (reg:CC FLAGS_REG))]
9845 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9846 [(set_attr "type" "ishift")
9847 (set_attr "prefix_0f" "1")
9848 (set_attr "mode" "SI")
9849 (set_attr "pent_pair" "np")
9850 (set_attr "athlon_decode" "vector")
9851 (set_attr "amdfam10_decode" "vector")
9852 (set_attr "bdver1_decode" "vector")])
9854 (define_insn "ashrdi3_cvt"
9855 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9856 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9857 (match_operand:QI 2 "const_int_operand" "")))
9858 (clobber (reg:CC FLAGS_REG))]
9859 "TARGET_64BIT && INTVAL (operands[2]) == 63
9860 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9861 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9864 sar{q}\t{%2, %0|%0, %2}"
9865 [(set_attr "type" "imovx,ishift")
9866 (set_attr "prefix_0f" "0,*")
9867 (set_attr "length_immediate" "0,*")
9868 (set_attr "modrm" "0,1")
9869 (set_attr "mode" "DI")])
9871 (define_insn "ashrsi3_cvt"
9872 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9873 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9874 (match_operand:QI 2 "const_int_operand" "")))
9875 (clobber (reg:CC FLAGS_REG))]
9876 "INTVAL (operands[2]) == 31
9877 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9878 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9881 sar{l}\t{%2, %0|%0, %2}"
9882 [(set_attr "type" "imovx,ishift")
9883 (set_attr "prefix_0f" "0,*")
9884 (set_attr "length_immediate" "0,*")
9885 (set_attr "modrm" "0,1")
9886 (set_attr "mode" "SI")])
9888 (define_insn "*ashrsi3_cvt_zext"
9889 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9891 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9892 (match_operand:QI 2 "const_int_operand" ""))))
9893 (clobber (reg:CC FLAGS_REG))]
9894 "TARGET_64BIT && INTVAL (operands[2]) == 31
9895 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9896 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9899 sar{l}\t{%2, %k0|%k0, %2}"
9900 [(set_attr "type" "imovx,ishift")
9901 (set_attr "prefix_0f" "0,*")
9902 (set_attr "length_immediate" "0,*")
9903 (set_attr "modrm" "0,1")
9904 (set_attr "mode" "SI")])
9906 (define_expand "x86_shift<mode>_adj_3"
9907 [(use (match_operand:SWI48 0 "register_operand" ""))
9908 (use (match_operand:SWI48 1 "register_operand" ""))
9909 (use (match_operand:QI 2 "register_operand" ""))]
9912 rtx label = gen_label_rtx ();
9915 emit_insn (gen_testqi_ccz_1 (operands[2],
9916 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9918 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9919 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9920 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9921 gen_rtx_LABEL_REF (VOIDmode, label),
9923 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9924 JUMP_LABEL (tmp) = label;
9926 emit_move_insn (operands[0], operands[1]);
9927 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9928 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9930 LABEL_NUSES (label) = 1;
9935 (define_insn "*<shiftrt_insn><mode>3_1"
9936 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9937 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9938 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9939 (clobber (reg:CC FLAGS_REG))]
9940 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9942 if (operands[2] == const1_rtx
9943 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9944 return "<shiftrt>{<imodesuffix>}\t%0";
9946 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9948 [(set_attr "type" "ishift")
9949 (set (attr "length_immediate")
9951 (and (match_operand 2 "const1_operand" "")
9952 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9955 (const_string "*")))
9956 (set_attr "mode" "<MODE>")])
9958 (define_insn "*<shiftrt_insn>si3_1_zext"
9959 [(set (match_operand:DI 0 "register_operand" "=r")
9961 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9962 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9963 (clobber (reg:CC FLAGS_REG))]
9964 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9966 if (operands[2] == const1_rtx
9967 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9968 return "<shiftrt>{l}\t%k0";
9970 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9972 [(set_attr "type" "ishift")
9973 (set (attr "length_immediate")
9975 (and (match_operand 2 "const1_operand" "")
9976 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9979 (const_string "*")))
9980 (set_attr "mode" "SI")])
9982 (define_insn "*<shiftrt_insn>qi3_1_slp"
9983 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9984 (any_shiftrt:QI (match_dup 0)
9985 (match_operand:QI 1 "nonmemory_operand" "cI")))
9986 (clobber (reg:CC FLAGS_REG))]
9987 "(optimize_function_for_size_p (cfun)
9988 || !TARGET_PARTIAL_REG_STALL
9989 || (operands[1] == const1_rtx
9992 if (operands[1] == const1_rtx
9993 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9994 return "<shiftrt>{b}\t%0";
9996 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9998 [(set_attr "type" "ishift1")
9999 (set (attr "length_immediate")
10001 (and (match_operand 1 "const1_operand" "")
10002 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10005 (const_string "*")))
10006 (set_attr "mode" "QI")])
10008 ;; This pattern can't accept a variable shift count, since shifts by
10009 ;; zero don't affect the flags. We assume that shifts by constant
10010 ;; zero are optimized away.
10011 (define_insn "*<shiftrt_insn><mode>3_cmp"
10012 [(set (reg FLAGS_REG)
10015 (match_operand:SWI 1 "nonimmediate_operand" "0")
10016 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10018 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10019 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10020 "(optimize_function_for_size_p (cfun)
10021 || !TARGET_PARTIAL_FLAG_REG_STALL
10022 || (operands[2] == const1_rtx
10024 && ix86_match_ccmode (insn, CCGOCmode)
10025 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10027 if (operands[2] == const1_rtx
10028 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10029 return "<shiftrt>{<imodesuffix>}\t%0";
10031 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10033 [(set_attr "type" "ishift")
10034 (set (attr "length_immediate")
10036 (and (match_operand 2 "const1_operand" "")
10037 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10040 (const_string "*")))
10041 (set_attr "mode" "<MODE>")])
10043 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10044 [(set (reg FLAGS_REG)
10046 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10047 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10049 (set (match_operand:DI 0 "register_operand" "=r")
10050 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10052 && (optimize_function_for_size_p (cfun)
10053 || !TARGET_PARTIAL_FLAG_REG_STALL
10054 || (operands[2] == const1_rtx
10056 && ix86_match_ccmode (insn, CCGOCmode)
10057 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10059 if (operands[2] == const1_rtx
10060 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10061 return "<shiftrt>{l}\t%k0";
10063 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10065 [(set_attr "type" "ishift")
10066 (set (attr "length_immediate")
10068 (and (match_operand 2 "const1_operand" "")
10069 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10072 (const_string "*")))
10073 (set_attr "mode" "SI")])
10075 (define_insn "*<shiftrt_insn><mode>3_cconly"
10076 [(set (reg FLAGS_REG)
10079 (match_operand:SWI 1 "nonimmediate_operand" "0")
10080 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10082 (clobber (match_scratch:SWI 0 "=<r>"))]
10083 "(optimize_function_for_size_p (cfun)
10084 || !TARGET_PARTIAL_FLAG_REG_STALL
10085 || (operands[2] == const1_rtx
10087 && ix86_match_ccmode (insn, CCGOCmode)
10088 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10090 if (operands[2] == const1_rtx
10091 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10092 return "<shiftrt>{<imodesuffix>}\t%0";
10094 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10096 [(set_attr "type" "ishift")
10097 (set (attr "length_immediate")
10099 (and (match_operand 2 "const1_operand" "")
10100 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10103 (const_string "*")))
10104 (set_attr "mode" "<MODE>")])
10106 ;; Rotate instructions
10108 (define_expand "<rotate_insn>ti3"
10109 [(set (match_operand:TI 0 "register_operand" "")
10110 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10111 (match_operand:QI 2 "nonmemory_operand" "")))]
10114 if (const_1_to_63_operand (operands[2], VOIDmode))
10115 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10116 (operands[0], operands[1], operands[2]));
10123 (define_expand "<rotate_insn>di3"
10124 [(set (match_operand:DI 0 "shiftdi_operand" "")
10125 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10126 (match_operand:QI 2 "nonmemory_operand" "")))]
10130 ix86_expand_binary_operator (<CODE>, DImode, operands);
10131 else if (const_1_to_31_operand (operands[2], VOIDmode))
10132 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10133 (operands[0], operands[1], operands[2]));
10140 (define_expand "<rotate_insn><mode>3"
10141 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10142 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10143 (match_operand:QI 2 "nonmemory_operand" "")))]
10145 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10147 ;; Avoid useless masking of count operand.
10148 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10149 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10151 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10154 (match_operand:SI 2 "nonimmediate_operand" "c")
10155 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10156 (clobber (reg:CC FLAGS_REG))]
10157 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10158 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10159 == GET_MODE_BITSIZE (<MODE>mode)-1"
10162 [(parallel [(set (match_dup 0)
10163 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10164 (clobber (reg:CC FLAGS_REG))])]
10166 if (can_create_pseudo_p ())
10167 operands [2] = force_reg (SImode, operands[2]);
10169 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10171 [(set_attr "type" "rotate")
10172 (set_attr "mode" "<MODE>")])
10174 ;; Implement rotation using two double-precision
10175 ;; shift instructions and a scratch register.
10177 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10178 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10179 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10180 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10181 (clobber (reg:CC FLAGS_REG))
10182 (clobber (match_scratch:DWIH 3 "=&r"))]
10186 [(set (match_dup 3) (match_dup 4))
10188 [(set (match_dup 4)
10189 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10190 (lshiftrt:DWIH (match_dup 5)
10191 (minus:QI (match_dup 6) (match_dup 2)))))
10192 (clobber (reg:CC FLAGS_REG))])
10194 [(set (match_dup 5)
10195 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10196 (lshiftrt:DWIH (match_dup 3)
10197 (minus:QI (match_dup 6) (match_dup 2)))))
10198 (clobber (reg:CC FLAGS_REG))])]
10200 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10202 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10205 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10206 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10207 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10208 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10209 (clobber (reg:CC FLAGS_REG))
10210 (clobber (match_scratch:DWIH 3 "=&r"))]
10214 [(set (match_dup 3) (match_dup 4))
10216 [(set (match_dup 4)
10217 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10218 (ashift:DWIH (match_dup 5)
10219 (minus:QI (match_dup 6) (match_dup 2)))))
10220 (clobber (reg:CC FLAGS_REG))])
10222 [(set (match_dup 5)
10223 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10224 (ashift:DWIH (match_dup 3)
10225 (minus:QI (match_dup 6) (match_dup 2)))))
10226 (clobber (reg:CC FLAGS_REG))])]
10228 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10230 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10233 (define_insn "*<rotate_insn><mode>3_1"
10234 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10235 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10236 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10237 (clobber (reg:CC FLAGS_REG))]
10238 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10240 if (operands[2] == const1_rtx
10241 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10242 return "<rotate>{<imodesuffix>}\t%0";
10244 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10246 [(set_attr "type" "rotate")
10247 (set (attr "length_immediate")
10249 (and (match_operand 2 "const1_operand" "")
10250 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10253 (const_string "*")))
10254 (set_attr "mode" "<MODE>")])
10256 (define_insn "*<rotate_insn>si3_1_zext"
10257 [(set (match_operand:DI 0 "register_operand" "=r")
10259 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10260 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10261 (clobber (reg:CC FLAGS_REG))]
10262 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10264 if (operands[2] == const1_rtx
10265 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10266 return "<rotate>{l}\t%k0";
10268 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10270 [(set_attr "type" "rotate")
10271 (set (attr "length_immediate")
10273 (and (match_operand 2 "const1_operand" "")
10274 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10277 (const_string "*")))
10278 (set_attr "mode" "SI")])
10280 (define_insn "*<rotate_insn>qi3_1_slp"
10281 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10282 (any_rotate:QI (match_dup 0)
10283 (match_operand:QI 1 "nonmemory_operand" "cI")))
10284 (clobber (reg:CC FLAGS_REG))]
10285 "(optimize_function_for_size_p (cfun)
10286 || !TARGET_PARTIAL_REG_STALL
10287 || (operands[1] == const1_rtx
10288 && TARGET_SHIFT1))"
10290 if (operands[1] == const1_rtx
10291 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10292 return "<rotate>{b}\t%0";
10294 return "<rotate>{b}\t{%1, %0|%0, %1}";
10296 [(set_attr "type" "rotate1")
10297 (set (attr "length_immediate")
10299 (and (match_operand 1 "const1_operand" "")
10300 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10303 (const_string "*")))
10304 (set_attr "mode" "QI")])
10307 [(set (match_operand:HI 0 "register_operand" "")
10308 (any_rotate:HI (match_dup 0) (const_int 8)))
10309 (clobber (reg:CC FLAGS_REG))]
10311 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10312 [(parallel [(set (strict_low_part (match_dup 0))
10313 (bswap:HI (match_dup 0)))
10314 (clobber (reg:CC FLAGS_REG))])])
10316 ;; Bit set / bit test instructions
10318 (define_expand "extv"
10319 [(set (match_operand:SI 0 "register_operand" "")
10320 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10321 (match_operand:SI 2 "const8_operand" "")
10322 (match_operand:SI 3 "const8_operand" "")))]
10325 /* Handle extractions from %ah et al. */
10326 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10329 /* From mips.md: extract_bit_field doesn't verify that our source
10330 matches the predicate, so check it again here. */
10331 if (! ext_register_operand (operands[1], VOIDmode))
10335 (define_expand "extzv"
10336 [(set (match_operand:SI 0 "register_operand" "")
10337 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10338 (match_operand:SI 2 "const8_operand" "")
10339 (match_operand:SI 3 "const8_operand" "")))]
10342 /* Handle extractions from %ah et al. */
10343 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10346 /* From mips.md: extract_bit_field doesn't verify that our source
10347 matches the predicate, so check it again here. */
10348 if (! ext_register_operand (operands[1], VOIDmode))
10352 (define_expand "insv"
10353 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10354 (match_operand 1 "const8_operand" "")
10355 (match_operand 2 "const8_operand" ""))
10356 (match_operand 3 "register_operand" ""))]
10359 rtx (*gen_mov_insv_1) (rtx, rtx);
10361 /* Handle insertions to %ah et al. */
10362 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10365 /* From mips.md: insert_bit_field doesn't verify that our source
10366 matches the predicate, so check it again here. */
10367 if (! ext_register_operand (operands[0], VOIDmode))
10370 gen_mov_insv_1 = (TARGET_64BIT
10371 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10373 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10377 ;; %%% bts, btr, btc, bt.
10378 ;; In general these instructions are *slow* when applied to memory,
10379 ;; since they enforce atomic operation. When applied to registers,
10380 ;; it depends on the cpu implementation. They're never faster than
10381 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10382 ;; no point. But in 64-bit, we can't hold the relevant immediates
10383 ;; within the instruction itself, so operating on bits in the high
10384 ;; 32-bits of a register becomes easier.
10386 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10387 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10388 ;; negdf respectively, so they can never be disabled entirely.
10390 (define_insn "*btsq"
10391 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10393 (match_operand:DI 1 "const_0_to_63_operand" ""))
10395 (clobber (reg:CC FLAGS_REG))]
10396 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10397 "bts{q}\t{%1, %0|%0, %1}"
10398 [(set_attr "type" "alu1")
10399 (set_attr "prefix_0f" "1")
10400 (set_attr "mode" "DI")])
10402 (define_insn "*btrq"
10403 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10405 (match_operand:DI 1 "const_0_to_63_operand" ""))
10407 (clobber (reg:CC FLAGS_REG))]
10408 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10409 "btr{q}\t{%1, %0|%0, %1}"
10410 [(set_attr "type" "alu1")
10411 (set_attr "prefix_0f" "1")
10412 (set_attr "mode" "DI")])
10414 (define_insn "*btcq"
10415 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10417 (match_operand:DI 1 "const_0_to_63_operand" ""))
10418 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10419 (clobber (reg:CC FLAGS_REG))]
10420 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10421 "btc{q}\t{%1, %0|%0, %1}"
10422 [(set_attr "type" "alu1")
10423 (set_attr "prefix_0f" "1")
10424 (set_attr "mode" "DI")])
10426 ;; Allow Nocona to avoid these instructions if a register is available.
10429 [(match_scratch:DI 2 "r")
10430 (parallel [(set (zero_extract:DI
10431 (match_operand:DI 0 "register_operand" "")
10433 (match_operand:DI 1 "const_0_to_63_operand" ""))
10435 (clobber (reg:CC FLAGS_REG))])]
10436 "TARGET_64BIT && !TARGET_USE_BT"
10439 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10442 if (HOST_BITS_PER_WIDE_INT >= 64)
10443 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10444 else if (i < HOST_BITS_PER_WIDE_INT)
10445 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10447 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10449 op1 = immed_double_const (lo, hi, DImode);
10452 emit_move_insn (operands[2], op1);
10456 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10461 [(match_scratch:DI 2 "r")
10462 (parallel [(set (zero_extract:DI
10463 (match_operand:DI 0 "register_operand" "")
10465 (match_operand:DI 1 "const_0_to_63_operand" ""))
10467 (clobber (reg:CC FLAGS_REG))])]
10468 "TARGET_64BIT && !TARGET_USE_BT"
10471 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10474 if (HOST_BITS_PER_WIDE_INT >= 64)
10475 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10476 else if (i < HOST_BITS_PER_WIDE_INT)
10477 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10479 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10481 op1 = immed_double_const (~lo, ~hi, DImode);
10484 emit_move_insn (operands[2], op1);
10488 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10493 [(match_scratch:DI 2 "r")
10494 (parallel [(set (zero_extract:DI
10495 (match_operand:DI 0 "register_operand" "")
10497 (match_operand:DI 1 "const_0_to_63_operand" ""))
10498 (not:DI (zero_extract:DI
10499 (match_dup 0) (const_int 1) (match_dup 1))))
10500 (clobber (reg:CC FLAGS_REG))])]
10501 "TARGET_64BIT && !TARGET_USE_BT"
10504 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10507 if (HOST_BITS_PER_WIDE_INT >= 64)
10508 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10509 else if (i < HOST_BITS_PER_WIDE_INT)
10510 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10512 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10514 op1 = immed_double_const (lo, hi, DImode);
10517 emit_move_insn (operands[2], op1);
10521 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10525 (define_insn "*bt<mode>"
10526 [(set (reg:CCC FLAGS_REG)
10528 (zero_extract:SWI48
10529 (match_operand:SWI48 0 "register_operand" "r")
10531 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10533 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10534 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10535 [(set_attr "type" "alu1")
10536 (set_attr "prefix_0f" "1")
10537 (set_attr "mode" "<MODE>")])
10539 ;; Store-flag instructions.
10541 ;; For all sCOND expanders, also expand the compare or test insn that
10542 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10544 (define_insn_and_split "*setcc_di_1"
10545 [(set (match_operand:DI 0 "register_operand" "=q")
10546 (match_operator:DI 1 "ix86_comparison_operator"
10547 [(reg FLAGS_REG) (const_int 0)]))]
10548 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10550 "&& reload_completed"
10551 [(set (match_dup 2) (match_dup 1))
10552 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10554 PUT_MODE (operands[1], QImode);
10555 operands[2] = gen_lowpart (QImode, operands[0]);
10558 (define_insn_and_split "*setcc_si_1_and"
10559 [(set (match_operand:SI 0 "register_operand" "=q")
10560 (match_operator:SI 1 "ix86_comparison_operator"
10561 [(reg FLAGS_REG) (const_int 0)]))
10562 (clobber (reg:CC FLAGS_REG))]
10563 "!TARGET_PARTIAL_REG_STALL
10564 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10566 "&& reload_completed"
10567 [(set (match_dup 2) (match_dup 1))
10568 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10569 (clobber (reg:CC FLAGS_REG))])]
10571 PUT_MODE (operands[1], QImode);
10572 operands[2] = gen_lowpart (QImode, operands[0]);
10575 (define_insn_and_split "*setcc_si_1_movzbl"
10576 [(set (match_operand:SI 0 "register_operand" "=q")
10577 (match_operator:SI 1 "ix86_comparison_operator"
10578 [(reg FLAGS_REG) (const_int 0)]))]
10579 "!TARGET_PARTIAL_REG_STALL
10580 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10582 "&& reload_completed"
10583 [(set (match_dup 2) (match_dup 1))
10584 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10586 PUT_MODE (operands[1], QImode);
10587 operands[2] = gen_lowpart (QImode, operands[0]);
10590 (define_insn "*setcc_qi"
10591 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10592 (match_operator:QI 1 "ix86_comparison_operator"
10593 [(reg FLAGS_REG) (const_int 0)]))]
10596 [(set_attr "type" "setcc")
10597 (set_attr "mode" "QI")])
10599 (define_insn "*setcc_qi_slp"
10600 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10601 (match_operator:QI 1 "ix86_comparison_operator"
10602 [(reg FLAGS_REG) (const_int 0)]))]
10605 [(set_attr "type" "setcc")
10606 (set_attr "mode" "QI")])
10608 ;; In general it is not safe to assume too much about CCmode registers,
10609 ;; so simplify-rtx stops when it sees a second one. Under certain
10610 ;; conditions this is safe on x86, so help combine not create
10617 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10618 (ne:QI (match_operator 1 "ix86_comparison_operator"
10619 [(reg FLAGS_REG) (const_int 0)])
10622 [(set (match_dup 0) (match_dup 1))]
10623 "PUT_MODE (operands[1], QImode);")
10626 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10627 (ne:QI (match_operator 1 "ix86_comparison_operator"
10628 [(reg FLAGS_REG) (const_int 0)])
10631 [(set (match_dup 0) (match_dup 1))]
10632 "PUT_MODE (operands[1], QImode);")
10635 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10636 (eq:QI (match_operator 1 "ix86_comparison_operator"
10637 [(reg FLAGS_REG) (const_int 0)])
10640 [(set (match_dup 0) (match_dup 1))]
10642 rtx new_op1 = copy_rtx (operands[1]);
10643 operands[1] = new_op1;
10644 PUT_MODE (new_op1, QImode);
10645 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10646 GET_MODE (XEXP (new_op1, 0))));
10648 /* Make sure that (a) the CCmode we have for the flags is strong
10649 enough for the reversed compare or (b) we have a valid FP compare. */
10650 if (! ix86_comparison_operator (new_op1, VOIDmode))
10655 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10656 (eq:QI (match_operator 1 "ix86_comparison_operator"
10657 [(reg FLAGS_REG) (const_int 0)])
10660 [(set (match_dup 0) (match_dup 1))]
10662 rtx new_op1 = copy_rtx (operands[1]);
10663 operands[1] = new_op1;
10664 PUT_MODE (new_op1, QImode);
10665 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10666 GET_MODE (XEXP (new_op1, 0))));
10668 /* Make sure that (a) the CCmode we have for the flags is strong
10669 enough for the reversed compare or (b) we have a valid FP compare. */
10670 if (! ix86_comparison_operator (new_op1, VOIDmode))
10674 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10675 ;; subsequent logical operations are used to imitate conditional moves.
10676 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10679 (define_insn "*avx_setcc<mode>"
10680 [(set (match_operand:MODEF 0 "register_operand" "=x")
10681 (match_operator:MODEF 1 "avx_comparison_float_operator"
10682 [(match_operand:MODEF 2 "register_operand" "x")
10683 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10685 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10686 [(set_attr "type" "ssecmp")
10687 (set_attr "prefix" "vex")
10688 (set_attr "length_immediate" "1")
10689 (set_attr "mode" "<MODE>")])
10691 (define_insn "*sse_setcc<mode>"
10692 [(set (match_operand:MODEF 0 "register_operand" "=x")
10693 (match_operator:MODEF 1 "sse_comparison_operator"
10694 [(match_operand:MODEF 2 "register_operand" "0")
10695 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10696 "SSE_FLOAT_MODE_P (<MODE>mode)"
10697 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10698 [(set_attr "type" "ssecmp")
10699 (set_attr "length_immediate" "1")
10700 (set_attr "mode" "<MODE>")])
10702 ;; Basic conditional jump instructions.
10703 ;; We ignore the overflow flag for signed branch instructions.
10705 (define_insn "*jcc_1"
10707 (if_then_else (match_operator 1 "ix86_comparison_operator"
10708 [(reg FLAGS_REG) (const_int 0)])
10709 (label_ref (match_operand 0 "" ""))
10713 [(set_attr "type" "ibr")
10714 (set_attr "modrm" "0")
10715 (set (attr "length")
10716 (if_then_else (and (ge (minus (match_dup 0) (pc))
10718 (lt (minus (match_dup 0) (pc))
10723 (define_insn "*jcc_2"
10725 (if_then_else (match_operator 1 "ix86_comparison_operator"
10726 [(reg FLAGS_REG) (const_int 0)])
10728 (label_ref (match_operand 0 "" ""))))]
10731 [(set_attr "type" "ibr")
10732 (set_attr "modrm" "0")
10733 (set (attr "length")
10734 (if_then_else (and (ge (minus (match_dup 0) (pc))
10736 (lt (minus (match_dup 0) (pc))
10741 ;; In general it is not safe to assume too much about CCmode registers,
10742 ;; so simplify-rtx stops when it sees a second one. Under certain
10743 ;; conditions this is safe on x86, so help combine not create
10751 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10752 [(reg FLAGS_REG) (const_int 0)])
10754 (label_ref (match_operand 1 "" ""))
10758 (if_then_else (match_dup 0)
10759 (label_ref (match_dup 1))
10761 "PUT_MODE (operands[0], VOIDmode);")
10765 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10766 [(reg FLAGS_REG) (const_int 0)])
10768 (label_ref (match_operand 1 "" ""))
10772 (if_then_else (match_dup 0)
10773 (label_ref (match_dup 1))
10776 rtx new_op0 = copy_rtx (operands[0]);
10777 operands[0] = new_op0;
10778 PUT_MODE (new_op0, VOIDmode);
10779 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10780 GET_MODE (XEXP (new_op0, 0))));
10782 /* Make sure that (a) the CCmode we have for the flags is strong
10783 enough for the reversed compare or (b) we have a valid FP compare. */
10784 if (! ix86_comparison_operator (new_op0, VOIDmode))
10788 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10789 ;; pass generates from shift insn with QImode operand. Actually, the mode
10790 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10791 ;; appropriate modulo of the bit offset value.
10793 (define_insn_and_split "*jcc_bt<mode>"
10795 (if_then_else (match_operator 0 "bt_comparison_operator"
10796 [(zero_extract:SWI48
10797 (match_operand:SWI48 1 "register_operand" "r")
10800 (match_operand:QI 2 "register_operand" "r")))
10802 (label_ref (match_operand 3 "" ""))
10804 (clobber (reg:CC FLAGS_REG))]
10805 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10808 [(set (reg:CCC FLAGS_REG)
10810 (zero_extract:SWI48
10816 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10817 (label_ref (match_dup 3))
10820 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10822 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10825 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10826 ;; also for DImode, this is what combine produces.
10827 (define_insn_and_split "*jcc_bt<mode>_mask"
10829 (if_then_else (match_operator 0 "bt_comparison_operator"
10830 [(zero_extract:SWI48
10831 (match_operand:SWI48 1 "register_operand" "r")
10834 (match_operand:SI 2 "register_operand" "r")
10835 (match_operand:SI 3 "const_int_operand" "n")))])
10836 (label_ref (match_operand 4 "" ""))
10838 (clobber (reg:CC FLAGS_REG))]
10839 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10840 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10841 == GET_MODE_BITSIZE (<MODE>mode)-1"
10844 [(set (reg:CCC FLAGS_REG)
10846 (zero_extract:SWI48
10852 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10853 (label_ref (match_dup 4))
10856 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10858 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10861 (define_insn_and_split "*jcc_btsi_1"
10863 (if_then_else (match_operator 0 "bt_comparison_operator"
10866 (match_operand:SI 1 "register_operand" "r")
10867 (match_operand:QI 2 "register_operand" "r"))
10870 (label_ref (match_operand 3 "" ""))
10872 (clobber (reg:CC FLAGS_REG))]
10873 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10876 [(set (reg:CCC FLAGS_REG)
10884 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10885 (label_ref (match_dup 3))
10888 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10890 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10893 ;; avoid useless masking of bit offset operand
10894 (define_insn_and_split "*jcc_btsi_mask_1"
10897 (match_operator 0 "bt_comparison_operator"
10900 (match_operand:SI 1 "register_operand" "r")
10903 (match_operand:SI 2 "register_operand" "r")
10904 (match_operand:SI 3 "const_int_operand" "n")) 0))
10907 (label_ref (match_operand 4 "" ""))
10909 (clobber (reg:CC FLAGS_REG))]
10910 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10911 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10914 [(set (reg:CCC FLAGS_REG)
10922 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10923 (label_ref (match_dup 4))
10925 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10927 ;; Define combination compare-and-branch fp compare instructions to help
10930 (define_insn "*fp_jcc_1_387"
10932 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10933 [(match_operand 1 "register_operand" "f")
10934 (match_operand 2 "nonimmediate_operand" "fm")])
10935 (label_ref (match_operand 3 "" ""))
10937 (clobber (reg:CCFP FPSR_REG))
10938 (clobber (reg:CCFP FLAGS_REG))
10939 (clobber (match_scratch:HI 4 "=a"))]
10941 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10942 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10943 && SELECT_CC_MODE (GET_CODE (operands[0]),
10944 operands[1], operands[2]) == CCFPmode
10948 (define_insn "*fp_jcc_1r_387"
10950 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10951 [(match_operand 1 "register_operand" "f")
10952 (match_operand 2 "nonimmediate_operand" "fm")])
10954 (label_ref (match_operand 3 "" ""))))
10955 (clobber (reg:CCFP FPSR_REG))
10956 (clobber (reg:CCFP FLAGS_REG))
10957 (clobber (match_scratch:HI 4 "=a"))]
10959 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10960 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10961 && SELECT_CC_MODE (GET_CODE (operands[0]),
10962 operands[1], operands[2]) == CCFPmode
10966 (define_insn "*fp_jcc_2_387"
10968 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10969 [(match_operand 1 "register_operand" "f")
10970 (match_operand 2 "register_operand" "f")])
10971 (label_ref (match_operand 3 "" ""))
10973 (clobber (reg:CCFP FPSR_REG))
10974 (clobber (reg:CCFP FLAGS_REG))
10975 (clobber (match_scratch:HI 4 "=a"))]
10976 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10977 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10981 (define_insn "*fp_jcc_2r_387"
10983 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10984 [(match_operand 1 "register_operand" "f")
10985 (match_operand 2 "register_operand" "f")])
10987 (label_ref (match_operand 3 "" ""))))
10988 (clobber (reg:CCFP FPSR_REG))
10989 (clobber (reg:CCFP FLAGS_REG))
10990 (clobber (match_scratch:HI 4 "=a"))]
10991 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10992 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10996 (define_insn "*fp_jcc_3_387"
10998 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10999 [(match_operand 1 "register_operand" "f")
11000 (match_operand 2 "const0_operand" "")])
11001 (label_ref (match_operand 3 "" ""))
11003 (clobber (reg:CCFP FPSR_REG))
11004 (clobber (reg:CCFP FLAGS_REG))
11005 (clobber (match_scratch:HI 4 "=a"))]
11006 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11007 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11008 && SELECT_CC_MODE (GET_CODE (operands[0]),
11009 operands[1], operands[2]) == CCFPmode
11015 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11016 [(match_operand 1 "register_operand" "")
11017 (match_operand 2 "nonimmediate_operand" "")])
11018 (match_operand 3 "" "")
11019 (match_operand 4 "" "")))
11020 (clobber (reg:CCFP FPSR_REG))
11021 (clobber (reg:CCFP FLAGS_REG))]
11025 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11026 operands[3], operands[4], NULL_RTX, NULL_RTX);
11032 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11033 [(match_operand 1 "register_operand" "")
11034 (match_operand 2 "general_operand" "")])
11035 (match_operand 3 "" "")
11036 (match_operand 4 "" "")))
11037 (clobber (reg:CCFP FPSR_REG))
11038 (clobber (reg:CCFP FLAGS_REG))
11039 (clobber (match_scratch:HI 5 "=a"))]
11043 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11044 operands[3], operands[4], operands[5], NULL_RTX);
11048 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11049 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11050 ;; with a precedence over other operators and is always put in the first
11051 ;; place. Swap condition and operands to match ficom instruction.
11053 (define_insn "*fp_jcc_4_<mode>_387"
11056 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11057 [(match_operator 1 "float_operator"
11058 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11059 (match_operand 3 "register_operand" "f,f")])
11060 (label_ref (match_operand 4 "" ""))
11062 (clobber (reg:CCFP FPSR_REG))
11063 (clobber (reg:CCFP FLAGS_REG))
11064 (clobber (match_scratch:HI 5 "=a,a"))]
11065 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11066 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11067 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11068 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11075 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11076 [(match_operator 1 "float_operator"
11077 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11078 (match_operand 3 "register_operand" "")])
11079 (match_operand 4 "" "")
11080 (match_operand 5 "" "")))
11081 (clobber (reg:CCFP FPSR_REG))
11082 (clobber (reg:CCFP FLAGS_REG))
11083 (clobber (match_scratch:HI 6 "=a"))]
11087 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11089 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11090 operands[3], operands[7],
11091 operands[4], operands[5], operands[6], NULL_RTX);
11095 ;; %%% Kill this when reload knows how to do it.
11099 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11100 [(match_operator 1 "float_operator"
11101 [(match_operand:X87MODEI12 2 "register_operand" "")])
11102 (match_operand 3 "register_operand" "")])
11103 (match_operand 4 "" "")
11104 (match_operand 5 "" "")))
11105 (clobber (reg:CCFP FPSR_REG))
11106 (clobber (reg:CCFP FLAGS_REG))
11107 (clobber (match_scratch:HI 6 "=a"))]
11111 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11112 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11114 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11115 operands[3], operands[7],
11116 operands[4], operands[5], operands[6], operands[2]);
11120 ;; Unconditional and other jump instructions
11122 (define_insn "jump"
11124 (label_ref (match_operand 0 "" "")))]
11127 [(set_attr "type" "ibr")
11128 (set (attr "length")
11129 (if_then_else (and (ge (minus (match_dup 0) (pc))
11131 (lt (minus (match_dup 0) (pc))
11135 (set_attr "modrm" "0")])
11137 (define_expand "indirect_jump"
11138 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11142 (define_insn "*indirect_jump"
11143 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11146 [(set_attr "type" "ibr")
11147 (set_attr "length_immediate" "0")])
11149 (define_expand "tablejump"
11150 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11151 (use (label_ref (match_operand 1 "" "")))])]
11154 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11155 relative. Convert the relative address to an absolute address. */
11159 enum rtx_code code;
11161 /* We can't use @GOTOFF for text labels on VxWorks;
11162 see gotoff_operand. */
11163 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11167 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11169 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11173 op1 = pic_offset_table_rtx;
11178 op0 = pic_offset_table_rtx;
11182 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11187 (define_insn "*tablejump_1"
11188 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11189 (use (label_ref (match_operand 1 "" "")))]
11192 [(set_attr "type" "ibr")
11193 (set_attr "length_immediate" "0")])
11195 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11198 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11199 (set (match_operand:QI 1 "register_operand" "")
11200 (match_operator:QI 2 "ix86_comparison_operator"
11201 [(reg FLAGS_REG) (const_int 0)]))
11202 (set (match_operand 3 "q_regs_operand" "")
11203 (zero_extend (match_dup 1)))]
11204 "(peep2_reg_dead_p (3, operands[1])
11205 || operands_match_p (operands[1], operands[3]))
11206 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11207 [(set (match_dup 4) (match_dup 0))
11208 (set (strict_low_part (match_dup 5))
11211 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11212 operands[5] = gen_lowpart (QImode, operands[3]);
11213 ix86_expand_clear (operands[3]);
11216 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11219 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11220 (set (match_operand:QI 1 "register_operand" "")
11221 (match_operator:QI 2 "ix86_comparison_operator"
11222 [(reg FLAGS_REG) (const_int 0)]))
11223 (parallel [(set (match_operand 3 "q_regs_operand" "")
11224 (zero_extend (match_dup 1)))
11225 (clobber (reg:CC FLAGS_REG))])]
11226 "(peep2_reg_dead_p (3, operands[1])
11227 || operands_match_p (operands[1], operands[3]))
11228 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11229 [(set (match_dup 4) (match_dup 0))
11230 (set (strict_low_part (match_dup 5))
11233 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11234 operands[5] = gen_lowpart (QImode, operands[3]);
11235 ix86_expand_clear (operands[3]);
11238 ;; Call instructions.
11240 ;; The predicates normally associated with named expanders are not properly
11241 ;; checked for calls. This is a bug in the generic code, but it isn't that
11242 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11244 ;; P6 processors will jump to the address after the decrement when %esp
11245 ;; is used as a call operand, so they will execute return address as a code.
11246 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11248 ;; Call subroutine returning no value.
11250 (define_expand "call_pop"
11251 [(parallel [(call (match_operand:QI 0 "" "")
11252 (match_operand:SI 1 "" ""))
11253 (set (reg:SI SP_REG)
11254 (plus:SI (reg:SI SP_REG)
11255 (match_operand:SI 3 "" "")))])]
11258 ix86_expand_call (NULL, operands[0], operands[1],
11259 operands[2], operands[3], 0);
11263 (define_insn "*call_pop_0"
11264 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11265 (match_operand:SI 1 "" ""))
11266 (set (reg:SI SP_REG)
11267 (plus:SI (reg:SI SP_REG)
11268 (match_operand:SI 2 "immediate_operand" "")))]
11271 if (SIBLING_CALL_P (insn))
11274 return "call\t%P0";
11276 [(set_attr "type" "call")])
11278 (define_insn "*call_pop_1"
11279 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11280 (match_operand:SI 1 "" ""))
11281 (set (reg:SI SP_REG)
11282 (plus:SI (reg:SI SP_REG)
11283 (match_operand:SI 2 "immediate_operand" "i")))]
11284 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11286 if (constant_call_address_operand (operands[0], Pmode))
11287 return "call\t%P0";
11288 return "call\t%A0";
11290 [(set_attr "type" "call")])
11292 (define_insn "*sibcall_pop_1"
11293 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11294 (match_operand:SI 1 "" ""))
11295 (set (reg:SI SP_REG)
11296 (plus:SI (reg:SI SP_REG)
11297 (match_operand:SI 2 "immediate_operand" "i,i")))]
11298 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11302 [(set_attr "type" "call")])
11304 (define_expand "call"
11305 [(call (match_operand:QI 0 "" "")
11306 (match_operand 1 "" ""))
11307 (use (match_operand 2 "" ""))]
11310 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11314 (define_expand "sibcall"
11315 [(call (match_operand:QI 0 "" "")
11316 (match_operand 1 "" ""))
11317 (use (match_operand 2 "" ""))]
11320 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11324 (define_insn "*call_0"
11325 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11326 (match_operand 1 "" ""))]
11328 { return ix86_output_call_insn (insn, operands[0], 0); }
11329 [(set_attr "type" "call")])
11331 (define_insn "*call_1"
11332 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11333 (match_operand 1 "" ""))]
11334 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11335 { return ix86_output_call_insn (insn, operands[0], 0); }
11336 [(set_attr "type" "call")])
11338 (define_insn "*sibcall_1"
11339 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11340 (match_operand 1 "" ""))]
11341 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11342 { return ix86_output_call_insn (insn, operands[0], 0); }
11343 [(set_attr "type" "call")])
11345 (define_insn "*call_1_rex64"
11346 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11347 (match_operand 1 "" ""))]
11348 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11349 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11350 { return ix86_output_call_insn (insn, operands[0], 0); }
11351 [(set_attr "type" "call")])
11353 (define_insn "*call_1_rex64_ms_sysv"
11354 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11355 (match_operand 1 "" ""))
11356 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11357 (clobber (reg:TI XMM6_REG))
11358 (clobber (reg:TI XMM7_REG))
11359 (clobber (reg:TI XMM8_REG))
11360 (clobber (reg:TI XMM9_REG))
11361 (clobber (reg:TI XMM10_REG))
11362 (clobber (reg:TI XMM11_REG))
11363 (clobber (reg:TI XMM12_REG))
11364 (clobber (reg:TI XMM13_REG))
11365 (clobber (reg:TI XMM14_REG))
11366 (clobber (reg:TI XMM15_REG))
11367 (clobber (reg:DI SI_REG))
11368 (clobber (reg:DI DI_REG))]
11369 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11370 { return ix86_output_call_insn (insn, operands[0], 0); }
11371 [(set_attr "type" "call")])
11373 (define_insn "*call_1_rex64_large"
11374 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11375 (match_operand 1 "" ""))]
11376 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11377 { return ix86_output_call_insn (insn, operands[0], 0); }
11378 [(set_attr "type" "call")])
11380 (define_insn "*sibcall_1_rex64"
11381 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11382 (match_operand 1 "" ""))]
11383 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11384 { return ix86_output_call_insn (insn, operands[0], 0); }
11385 [(set_attr "type" "call")])
11387 ;; Call subroutine, returning value in operand 0
11388 (define_expand "call_value_pop"
11389 [(parallel [(set (match_operand 0 "" "")
11390 (call (match_operand:QI 1 "" "")
11391 (match_operand:SI 2 "" "")))
11392 (set (reg:SI SP_REG)
11393 (plus:SI (reg:SI SP_REG)
11394 (match_operand:SI 4 "" "")))])]
11397 ix86_expand_call (operands[0], operands[1], operands[2],
11398 operands[3], operands[4], 0);
11402 (define_expand "call_value"
11403 [(set (match_operand 0 "" "")
11404 (call (match_operand:QI 1 "" "")
11405 (match_operand:SI 2 "" "")))
11406 (use (match_operand:SI 3 "" ""))]
11407 ;; Operand 3 is not used on the i386.
11410 ix86_expand_call (operands[0], operands[1], operands[2],
11411 operands[3], NULL, 0);
11415 (define_expand "sibcall_value"
11416 [(set (match_operand 0 "" "")
11417 (call (match_operand:QI 1 "" "")
11418 (match_operand:SI 2 "" "")))
11419 (use (match_operand:SI 3 "" ""))]
11420 ;; Operand 3 is not used on the i386.
11423 ix86_expand_call (operands[0], operands[1], operands[2],
11424 operands[3], NULL, 1);
11428 ;; Call subroutine returning any type.
11430 (define_expand "untyped_call"
11431 [(parallel [(call (match_operand 0 "" "")
11433 (match_operand 1 "" "")
11434 (match_operand 2 "" "")])]
11439 /* In order to give reg-stack an easier job in validating two
11440 coprocessor registers as containing a possible return value,
11441 simply pretend the untyped call returns a complex long double
11444 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11445 and should have the default ABI. */
11447 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11448 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11449 operands[0], const0_rtx,
11450 GEN_INT ((TARGET_64BIT
11451 ? (ix86_abi == SYSV_ABI
11452 ? X86_64_SSE_REGPARM_MAX
11453 : X86_64_MS_SSE_REGPARM_MAX)
11454 : X86_32_SSE_REGPARM_MAX)
11458 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11460 rtx set = XVECEXP (operands[2], 0, i);
11461 emit_move_insn (SET_DEST (set), SET_SRC (set));
11464 /* The optimizer does not know that the call sets the function value
11465 registers we stored in the result block. We avoid problems by
11466 claiming that all hard registers are used and clobbered at this
11468 emit_insn (gen_blockage ());
11473 ;; Prologue and epilogue instructions
11475 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11476 ;; all of memory. This blocks insns from being moved across this point.
11478 (define_insn "blockage"
11479 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11482 [(set_attr "length" "0")])
11484 ;; Do not schedule instructions accessing memory across this point.
11486 (define_expand "memory_blockage"
11487 [(set (match_dup 0)
11488 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11491 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11492 MEM_VOLATILE_P (operands[0]) = 1;
11495 (define_insn "*memory_blockage"
11496 [(set (match_operand:BLK 0 "" "")
11497 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11500 [(set_attr "length" "0")])
11502 ;; As USE insns aren't meaningful after reload, this is used instead
11503 ;; to prevent deleting instructions setting registers for PIC code
11504 (define_insn "prologue_use"
11505 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11508 [(set_attr "length" "0")])
11510 ;; Insn emitted into the body of a function to return from a function.
11511 ;; This is only done if the function's epilogue is known to be simple.
11512 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11514 (define_expand "return"
11516 "ix86_can_use_return_insn_p ()"
11518 if (crtl->args.pops_args)
11520 rtx popc = GEN_INT (crtl->args.pops_args);
11521 emit_jump_insn (gen_return_pop_internal (popc));
11526 (define_insn "return_internal"
11530 [(set_attr "length" "1")
11531 (set_attr "atom_unit" "jeu")
11532 (set_attr "length_immediate" "0")
11533 (set_attr "modrm" "0")])
11535 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11536 ;; instruction Athlon and K8 have.
11538 (define_insn "return_internal_long"
11540 (unspec [(const_int 0)] UNSPEC_REP)]
11543 [(set_attr "length" "2")
11544 (set_attr "atom_unit" "jeu")
11545 (set_attr "length_immediate" "0")
11546 (set_attr "prefix_rep" "1")
11547 (set_attr "modrm" "0")])
11549 (define_insn "return_pop_internal"
11551 (use (match_operand:SI 0 "const_int_operand" ""))]
11554 [(set_attr "length" "3")
11555 (set_attr "atom_unit" "jeu")
11556 (set_attr "length_immediate" "2")
11557 (set_attr "modrm" "0")])
11559 (define_insn "return_indirect_internal"
11561 (use (match_operand:SI 0 "register_operand" "r"))]
11564 [(set_attr "type" "ibr")
11565 (set_attr "length_immediate" "0")])
11571 [(set_attr "length" "1")
11572 (set_attr "length_immediate" "0")
11573 (set_attr "modrm" "0")])
11575 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11576 (define_insn "nops"
11577 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11581 int num = INTVAL (operands[0]);
11583 gcc_assert (num >= 1 && num <= 8);
11586 fputs ("\tnop\n", asm_out_file);
11590 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11591 (set_attr "length_immediate" "0")
11592 (set_attr "modrm" "0")])
11594 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11595 ;; branch prediction penalty for the third jump in a 16-byte
11599 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11602 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11603 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11605 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11606 The align insn is used to avoid 3 jump instructions in the row to improve
11607 branch prediction and the benefits hardly outweigh the cost of extra 8
11608 nops on the average inserted by full alignment pseudo operation. */
11612 [(set_attr "length" "16")])
11614 (define_expand "prologue"
11617 "ix86_expand_prologue (); DONE;")
11619 (define_insn "set_got"
11620 [(set (match_operand:SI 0 "register_operand" "=r")
11621 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11622 (clobber (reg:CC FLAGS_REG))]
11624 "* return output_set_got (operands[0], NULL_RTX);"
11625 [(set_attr "type" "multi")
11626 (set_attr "length" "12")])
11628 (define_insn "set_got_labelled"
11629 [(set (match_operand:SI 0 "register_operand" "=r")
11630 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11632 (clobber (reg:CC FLAGS_REG))]
11634 "* return output_set_got (operands[0], operands[1]);"
11635 [(set_attr "type" "multi")
11636 (set_attr "length" "12")])
11638 (define_insn "set_got_rex64"
11639 [(set (match_operand:DI 0 "register_operand" "=r")
11640 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11642 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11643 [(set_attr "type" "lea")
11644 (set_attr "length_address" "4")
11645 (set_attr "mode" "DI")])
11647 (define_insn "set_rip_rex64"
11648 [(set (match_operand:DI 0 "register_operand" "=r")
11649 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11651 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11652 [(set_attr "type" "lea")
11653 (set_attr "length_address" "4")
11654 (set_attr "mode" "DI")])
11656 (define_insn "set_got_offset_rex64"
11657 [(set (match_operand:DI 0 "register_operand" "=r")
11659 [(label_ref (match_operand 1 "" ""))]
11660 UNSPEC_SET_GOT_OFFSET))]
11662 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11663 [(set_attr "type" "imov")
11664 (set_attr "length_immediate" "0")
11665 (set_attr "length_address" "8")
11666 (set_attr "mode" "DI")])
11668 (define_expand "epilogue"
11671 "ix86_expand_epilogue (1); DONE;")
11673 (define_expand "sibcall_epilogue"
11676 "ix86_expand_epilogue (0); DONE;")
11678 (define_expand "eh_return"
11679 [(use (match_operand 0 "register_operand" ""))]
11682 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11684 /* Tricky bit: we write the address of the handler to which we will
11685 be returning into someone else's stack frame, one word below the
11686 stack address we wish to restore. */
11687 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11688 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11689 tmp = gen_rtx_MEM (Pmode, tmp);
11690 emit_move_insn (tmp, ra);
11692 emit_jump_insn (gen_eh_return_internal ());
11697 (define_insn_and_split "eh_return_internal"
11701 "epilogue_completed"
11703 "ix86_expand_epilogue (2); DONE;")
11705 (define_insn "leave"
11706 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11707 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11708 (clobber (mem:BLK (scratch)))]
11711 [(set_attr "type" "leave")])
11713 (define_insn "leave_rex64"
11714 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11715 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11716 (clobber (mem:BLK (scratch)))]
11719 [(set_attr "type" "leave")])
11721 ;; Handle -fsplit-stack.
11723 (define_expand "split_stack_prologue"
11727 ix86_expand_split_stack_prologue ();
11731 ;; In order to support the call/return predictor, we use a return
11732 ;; instruction which the middle-end doesn't see.
11733 (define_insn "split_stack_return"
11734 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11735 UNSPECV_SPLIT_STACK_RETURN)]
11738 if (operands[0] == const0_rtx)
11743 [(set_attr "atom_unit" "jeu")
11744 (set_attr "modrm" "0")
11745 (set (attr "length")
11746 (if_then_else (match_operand:SI 0 "const0_operand" "")
11749 (set (attr "length_immediate")
11750 (if_then_else (match_operand:SI 0 "const0_operand" "")
11754 ;; If there are operand 0 bytes available on the stack, jump to
11757 (define_expand "split_stack_space_check"
11758 [(set (pc) (if_then_else
11759 (ltu (minus (reg SP_REG)
11760 (match_operand 0 "register_operand" ""))
11761 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11762 (label_ref (match_operand 1 "" ""))
11766 rtx reg, size, limit;
11768 reg = gen_reg_rtx (Pmode);
11769 size = force_reg (Pmode, operands[0]);
11770 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11771 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11772 UNSPEC_STACK_CHECK);
11773 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11774 ix86_expand_branch (GEU, reg, limit, operands[1]);
11779 ;; Bit manipulation instructions.
11781 (define_expand "ffs<mode>2"
11782 [(set (match_dup 2) (const_int -1))
11783 (parallel [(set (reg:CCZ FLAGS_REG)
11785 (match_operand:SWI48 1 "nonimmediate_operand" "")
11787 (set (match_operand:SWI48 0 "register_operand" "")
11788 (ctz:SWI48 (match_dup 1)))])
11789 (set (match_dup 0) (if_then_else:SWI48
11790 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11793 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11794 (clobber (reg:CC FLAGS_REG))])]
11797 if (<MODE>mode == SImode && !TARGET_CMOVE)
11799 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11802 operands[2] = gen_reg_rtx (<MODE>mode);
11805 (define_insn_and_split "ffssi2_no_cmove"
11806 [(set (match_operand:SI 0 "register_operand" "=r")
11807 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11808 (clobber (match_scratch:SI 2 "=&q"))
11809 (clobber (reg:CC FLAGS_REG))]
11812 "&& reload_completed"
11813 [(parallel [(set (reg:CCZ FLAGS_REG)
11814 (compare:CCZ (match_dup 1) (const_int 0)))
11815 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11816 (set (strict_low_part (match_dup 3))
11817 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11818 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11819 (clobber (reg:CC FLAGS_REG))])
11820 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11821 (clobber (reg:CC FLAGS_REG))])
11822 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11823 (clobber (reg:CC FLAGS_REG))])]
11825 operands[3] = gen_lowpart (QImode, operands[2]);
11826 ix86_expand_clear (operands[2]);
11829 (define_insn "*ffs<mode>_1"
11830 [(set (reg:CCZ FLAGS_REG)
11831 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11833 (set (match_operand:SWI48 0 "register_operand" "=r")
11834 (ctz:SWI48 (match_dup 1)))]
11836 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11837 [(set_attr "type" "alu1")
11838 (set_attr "prefix_0f" "1")
11839 (set_attr "mode" "<MODE>")])
11841 (define_insn "ctz<mode>2"
11842 [(set (match_operand:SWI48 0 "register_operand" "=r")
11843 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11844 (clobber (reg:CC FLAGS_REG))]
11846 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11847 [(set_attr "type" "alu1")
11848 (set_attr "prefix_0f" "1")
11849 (set_attr "mode" "<MODE>")])
11851 (define_expand "clz<mode>2"
11853 [(set (match_operand:SWI248 0 "register_operand" "")
11856 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11857 (clobber (reg:CC FLAGS_REG))])
11859 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11860 (clobber (reg:CC FLAGS_REG))])]
11865 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11868 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11871 (define_insn "clz<mode>2_abm"
11872 [(set (match_operand:SWI248 0 "register_operand" "=r")
11873 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11874 (clobber (reg:CC FLAGS_REG))]
11876 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11877 [(set_attr "prefix_rep" "1")
11878 (set_attr "type" "bitmanip")
11879 (set_attr "mode" "<MODE>")])
11881 (define_insn "bsr_rex64"
11882 [(set (match_operand:DI 0 "register_operand" "=r")
11883 (minus:DI (const_int 63)
11884 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11885 (clobber (reg:CC FLAGS_REG))]
11887 "bsr{q}\t{%1, %0|%0, %1}"
11888 [(set_attr "type" "alu1")
11889 (set_attr "prefix_0f" "1")
11890 (set_attr "mode" "DI")])
11893 [(set (match_operand:SI 0 "register_operand" "=r")
11894 (minus:SI (const_int 31)
11895 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11896 (clobber (reg:CC FLAGS_REG))]
11898 "bsr{l}\t{%1, %0|%0, %1}"
11899 [(set_attr "type" "alu1")
11900 (set_attr "prefix_0f" "1")
11901 (set_attr "mode" "SI")])
11903 (define_insn "*bsrhi"
11904 [(set (match_operand:HI 0 "register_operand" "=r")
11905 (minus:HI (const_int 15)
11906 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11907 (clobber (reg:CC FLAGS_REG))]
11909 "bsr{w}\t{%1, %0|%0, %1}"
11910 [(set_attr "type" "alu1")
11911 (set_attr "prefix_0f" "1")
11912 (set_attr "mode" "HI")])
11914 (define_insn "popcount<mode>2"
11915 [(set (match_operand:SWI248 0 "register_operand" "=r")
11917 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11918 (clobber (reg:CC FLAGS_REG))]
11922 return "popcnt\t{%1, %0|%0, %1}";
11924 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11927 [(set_attr "prefix_rep" "1")
11928 (set_attr "type" "bitmanip")
11929 (set_attr "mode" "<MODE>")])
11931 (define_insn "*popcount<mode>2_cmp"
11932 [(set (reg FLAGS_REG)
11935 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11937 (set (match_operand:SWI248 0 "register_operand" "=r")
11938 (popcount:SWI248 (match_dup 1)))]
11939 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11942 return "popcnt\t{%1, %0|%0, %1}";
11944 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11947 [(set_attr "prefix_rep" "1")
11948 (set_attr "type" "bitmanip")
11949 (set_attr "mode" "<MODE>")])
11951 (define_insn "*popcountsi2_cmp_zext"
11952 [(set (reg FLAGS_REG)
11954 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11956 (set (match_operand:DI 0 "register_operand" "=r")
11957 (zero_extend:DI(popcount:SI (match_dup 1))))]
11958 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11961 return "popcnt\t{%1, %0|%0, %1}";
11963 return "popcnt{l}\t{%1, %0|%0, %1}";
11966 [(set_attr "prefix_rep" "1")
11967 (set_attr "type" "bitmanip")
11968 (set_attr "mode" "SI")])
11970 (define_expand "bswap<mode>2"
11971 [(set (match_operand:SWI48 0 "register_operand" "")
11972 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11975 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11977 rtx x = operands[0];
11979 emit_move_insn (x, operands[1]);
11980 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11981 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11982 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11987 (define_insn "*bswap<mode>2_movbe"
11988 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11989 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11991 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11994 movbe\t{%1, %0|%0, %1}
11995 movbe\t{%1, %0|%0, %1}"
11996 [(set_attr "type" "bitmanip,imov,imov")
11997 (set_attr "modrm" "0,1,1")
11998 (set_attr "prefix_0f" "*,1,1")
11999 (set_attr "prefix_extra" "*,1,1")
12000 (set_attr "mode" "<MODE>")])
12002 (define_insn "*bswap<mode>2_1"
12003 [(set (match_operand:SWI48 0 "register_operand" "=r")
12004 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12007 [(set_attr "type" "bitmanip")
12008 (set_attr "modrm" "0")
12009 (set_attr "mode" "<MODE>")])
12011 (define_insn "*bswaphi_lowpart_1"
12012 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12013 (bswap:HI (match_dup 0)))
12014 (clobber (reg:CC FLAGS_REG))]
12015 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12017 xchg{b}\t{%h0, %b0|%b0, %h0}
12018 rol{w}\t{$8, %0|%0, 8}"
12019 [(set_attr "length" "2,4")
12020 (set_attr "mode" "QI,HI")])
12022 (define_insn "bswaphi_lowpart"
12023 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12024 (bswap:HI (match_dup 0)))
12025 (clobber (reg:CC FLAGS_REG))]
12027 "rol{w}\t{$8, %0|%0, 8}"
12028 [(set_attr "length" "4")
12029 (set_attr "mode" "HI")])
12031 (define_expand "paritydi2"
12032 [(set (match_operand:DI 0 "register_operand" "")
12033 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12036 rtx scratch = gen_reg_rtx (QImode);
12039 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12040 NULL_RTX, operands[1]));
12042 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12043 gen_rtx_REG (CCmode, FLAGS_REG),
12045 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12048 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12051 rtx tmp = gen_reg_rtx (SImode);
12053 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12054 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12059 (define_expand "paritysi2"
12060 [(set (match_operand:SI 0 "register_operand" "")
12061 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12064 rtx scratch = gen_reg_rtx (QImode);
12067 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12069 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12070 gen_rtx_REG (CCmode, FLAGS_REG),
12072 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12074 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12078 (define_insn_and_split "paritydi2_cmp"
12079 [(set (reg:CC FLAGS_REG)
12080 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12082 (clobber (match_scratch:DI 0 "=r"))
12083 (clobber (match_scratch:SI 1 "=&r"))
12084 (clobber (match_scratch:HI 2 "=Q"))]
12087 "&& reload_completed"
12089 [(set (match_dup 1)
12090 (xor:SI (match_dup 1) (match_dup 4)))
12091 (clobber (reg:CC FLAGS_REG))])
12093 [(set (reg:CC FLAGS_REG)
12094 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12095 (clobber (match_dup 1))
12096 (clobber (match_dup 2))])]
12098 operands[4] = gen_lowpart (SImode, operands[3]);
12102 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12103 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12106 operands[1] = gen_highpart (SImode, operands[3]);
12109 (define_insn_and_split "paritysi2_cmp"
12110 [(set (reg:CC FLAGS_REG)
12111 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12113 (clobber (match_scratch:SI 0 "=r"))
12114 (clobber (match_scratch:HI 1 "=&Q"))]
12117 "&& reload_completed"
12119 [(set (match_dup 1)
12120 (xor:HI (match_dup 1) (match_dup 3)))
12121 (clobber (reg:CC FLAGS_REG))])
12123 [(set (reg:CC FLAGS_REG)
12124 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12125 (clobber (match_dup 1))])]
12127 operands[3] = gen_lowpart (HImode, operands[2]);
12129 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12130 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12133 (define_insn "*parityhi2_cmp"
12134 [(set (reg:CC FLAGS_REG)
12135 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12137 (clobber (match_scratch:HI 0 "=Q"))]
12139 "xor{b}\t{%h0, %b0|%b0, %h0}"
12140 [(set_attr "length" "2")
12141 (set_attr "mode" "HI")])
12143 ;; Thread-local storage patterns for ELF.
12145 ;; Note that these code sequences must appear exactly as shown
12146 ;; in order to allow linker relaxation.
12148 (define_insn "*tls_global_dynamic_32_gnu"
12149 [(set (match_operand:SI 0 "register_operand" "=a")
12150 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12151 (match_operand:SI 2 "tls_symbolic_operand" "")
12152 (match_operand:SI 3 "call_insn_operand" "")]
12154 (clobber (match_scratch:SI 4 "=d"))
12155 (clobber (match_scratch:SI 5 "=c"))
12156 (clobber (reg:CC FLAGS_REG))]
12157 "!TARGET_64BIT && TARGET_GNU_TLS"
12158 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12159 [(set_attr "type" "multi")
12160 (set_attr "length" "12")])
12162 (define_expand "tls_global_dynamic_32"
12163 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12166 (match_operand:SI 1 "tls_symbolic_operand" "")
12169 (clobber (match_scratch:SI 4 ""))
12170 (clobber (match_scratch:SI 5 ""))
12171 (clobber (reg:CC FLAGS_REG))])]
12175 operands[2] = pic_offset_table_rtx;
12178 operands[2] = gen_reg_rtx (Pmode);
12179 emit_insn (gen_set_got (operands[2]));
12181 if (TARGET_GNU2_TLS)
12183 emit_insn (gen_tls_dynamic_gnu2_32
12184 (operands[0], operands[1], operands[2]));
12187 operands[3] = ix86_tls_get_addr ();
12190 (define_insn "*tls_global_dynamic_64"
12191 [(set (match_operand:DI 0 "register_operand" "=a")
12192 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12193 (match_operand:DI 3 "" "")))
12194 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12197 { 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"; }
12198 [(set_attr "type" "multi")
12199 (set_attr "length" "16")])
12201 (define_expand "tls_global_dynamic_64"
12202 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12203 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12204 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12208 if (TARGET_GNU2_TLS)
12210 emit_insn (gen_tls_dynamic_gnu2_64
12211 (operands[0], operands[1]));
12214 operands[2] = ix86_tls_get_addr ();
12217 (define_insn "*tls_local_dynamic_base_32_gnu"
12218 [(set (match_operand:SI 0 "register_operand" "=a")
12219 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12220 (match_operand:SI 2 "call_insn_operand" "")]
12221 UNSPEC_TLS_LD_BASE))
12222 (clobber (match_scratch:SI 3 "=d"))
12223 (clobber (match_scratch:SI 4 "=c"))
12224 (clobber (reg:CC FLAGS_REG))]
12225 "!TARGET_64BIT && TARGET_GNU_TLS"
12226 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12227 [(set_attr "type" "multi")
12228 (set_attr "length" "11")])
12230 (define_expand "tls_local_dynamic_base_32"
12231 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12232 (unspec:SI [(match_dup 1) (match_dup 2)]
12233 UNSPEC_TLS_LD_BASE))
12234 (clobber (match_scratch:SI 3 ""))
12235 (clobber (match_scratch:SI 4 ""))
12236 (clobber (reg:CC FLAGS_REG))])]
12240 operands[1] = pic_offset_table_rtx;
12243 operands[1] = gen_reg_rtx (Pmode);
12244 emit_insn (gen_set_got (operands[1]));
12246 if (TARGET_GNU2_TLS)
12248 emit_insn (gen_tls_dynamic_gnu2_32
12249 (operands[0], ix86_tls_module_base (), operands[1]));
12252 operands[2] = ix86_tls_get_addr ();
12255 (define_insn "*tls_local_dynamic_base_64"
12256 [(set (match_operand:DI 0 "register_operand" "=a")
12257 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12258 (match_operand:DI 2 "" "")))
12259 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12261 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12262 [(set_attr "type" "multi")
12263 (set_attr "length" "12")])
12265 (define_expand "tls_local_dynamic_base_64"
12266 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12267 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12268 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12271 if (TARGET_GNU2_TLS)
12273 emit_insn (gen_tls_dynamic_gnu2_64
12274 (operands[0], ix86_tls_module_base ()));
12277 operands[1] = ix86_tls_get_addr ();
12280 ;; Local dynamic of a single variable is a lose. Show combine how
12281 ;; to convert that back to global dynamic.
12283 (define_insn_and_split "*tls_local_dynamic_32_once"
12284 [(set (match_operand:SI 0 "register_operand" "=a")
12285 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12286 (match_operand:SI 2 "call_insn_operand" "")]
12287 UNSPEC_TLS_LD_BASE)
12288 (const:SI (unspec:SI
12289 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12291 (clobber (match_scratch:SI 4 "=d"))
12292 (clobber (match_scratch:SI 5 "=c"))
12293 (clobber (reg:CC FLAGS_REG))]
12297 [(parallel [(set (match_dup 0)
12298 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12300 (clobber (match_dup 4))
12301 (clobber (match_dup 5))
12302 (clobber (reg:CC FLAGS_REG))])])
12304 ;; Segment register for the thread base ptr load
12305 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12307 ;; Load and add the thread base pointer from %gs:0.
12308 (define_insn "*load_tp_<mode>"
12309 [(set (match_operand:P 0 "register_operand" "=r")
12310 (unspec:P [(const_int 0)] UNSPEC_TP))]
12312 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12313 [(set_attr "type" "imov")
12314 (set_attr "modrm" "0")
12315 (set_attr "length" "7")
12316 (set_attr "memory" "load")
12317 (set_attr "imm_disp" "false")])
12319 (define_insn "*add_tp_<mode>"
12320 [(set (match_operand:P 0 "register_operand" "=r")
12321 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12322 (match_operand:P 1 "register_operand" "0")))
12323 (clobber (reg:CC FLAGS_REG))]
12325 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12326 [(set_attr "type" "alu")
12327 (set_attr "modrm" "0")
12328 (set_attr "length" "7")
12329 (set_attr "memory" "load")
12330 (set_attr "imm_disp" "false")])
12332 ;; GNU2 TLS patterns can be split.
12334 (define_expand "tls_dynamic_gnu2_32"
12335 [(set (match_dup 3)
12336 (plus:SI (match_operand:SI 2 "register_operand" "")
12338 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12341 [(set (match_operand:SI 0 "register_operand" "")
12342 (unspec:SI [(match_dup 1) (match_dup 3)
12343 (match_dup 2) (reg:SI SP_REG)]
12345 (clobber (reg:CC FLAGS_REG))])]
12346 "!TARGET_64BIT && TARGET_GNU2_TLS"
12348 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12349 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12352 (define_insn "*tls_dynamic_lea_32"
12353 [(set (match_operand:SI 0 "register_operand" "=r")
12354 (plus:SI (match_operand:SI 1 "register_operand" "b")
12356 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12357 UNSPEC_TLSDESC))))]
12358 "!TARGET_64BIT && TARGET_GNU2_TLS"
12359 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12360 [(set_attr "type" "lea")
12361 (set_attr "mode" "SI")
12362 (set_attr "length" "6")
12363 (set_attr "length_address" "4")])
12365 (define_insn "*tls_dynamic_call_32"
12366 [(set (match_operand:SI 0 "register_operand" "=a")
12367 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12368 (match_operand:SI 2 "register_operand" "0")
12369 ;; we have to make sure %ebx still points to the GOT
12370 (match_operand:SI 3 "register_operand" "b")
12373 (clobber (reg:CC FLAGS_REG))]
12374 "!TARGET_64BIT && TARGET_GNU2_TLS"
12375 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12376 [(set_attr "type" "call")
12377 (set_attr "length" "2")
12378 (set_attr "length_address" "0")])
12380 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12381 [(set (match_operand:SI 0 "register_operand" "=&a")
12383 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12384 (match_operand:SI 4 "" "")
12385 (match_operand:SI 2 "register_operand" "b")
12388 (const:SI (unspec:SI
12389 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12391 (clobber (reg:CC FLAGS_REG))]
12392 "!TARGET_64BIT && TARGET_GNU2_TLS"
12395 [(set (match_dup 0) (match_dup 5))]
12397 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12398 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12401 (define_expand "tls_dynamic_gnu2_64"
12402 [(set (match_dup 2)
12403 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12406 [(set (match_operand:DI 0 "register_operand" "")
12407 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12409 (clobber (reg:CC FLAGS_REG))])]
12410 "TARGET_64BIT && TARGET_GNU2_TLS"
12412 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12413 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12416 (define_insn "*tls_dynamic_lea_64"
12417 [(set (match_operand:DI 0 "register_operand" "=r")
12418 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12420 "TARGET_64BIT && TARGET_GNU2_TLS"
12421 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12422 [(set_attr "type" "lea")
12423 (set_attr "mode" "DI")
12424 (set_attr "length" "7")
12425 (set_attr "length_address" "4")])
12427 (define_insn "*tls_dynamic_call_64"
12428 [(set (match_operand:DI 0 "register_operand" "=a")
12429 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12430 (match_operand:DI 2 "register_operand" "0")
12433 (clobber (reg:CC FLAGS_REG))]
12434 "TARGET_64BIT && TARGET_GNU2_TLS"
12435 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12436 [(set_attr "type" "call")
12437 (set_attr "length" "2")
12438 (set_attr "length_address" "0")])
12440 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12441 [(set (match_operand:DI 0 "register_operand" "=&a")
12443 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12444 (match_operand:DI 3 "" "")
12447 (const:DI (unspec:DI
12448 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12450 (clobber (reg:CC FLAGS_REG))]
12451 "TARGET_64BIT && TARGET_GNU2_TLS"
12454 [(set (match_dup 0) (match_dup 4))]
12456 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12457 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12460 ;; These patterns match the binary 387 instructions for addM3, subM3,
12461 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12462 ;; SFmode. The first is the normal insn, the second the same insn but
12463 ;; with one operand a conversion, and the third the same insn but with
12464 ;; the other operand a conversion. The conversion may be SFmode or
12465 ;; SImode if the target mode DFmode, but only SImode if the target mode
12468 ;; Gcc is slightly more smart about handling normal two address instructions
12469 ;; so use special patterns for add and mull.
12471 (define_insn "*fop_<mode>_comm_mixed_avx"
12472 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12473 (match_operator:MODEF 3 "binary_fp_operator"
12474 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12475 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12476 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12477 && COMMUTATIVE_ARITH_P (operands[3])
12478 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12479 "* return output_387_binary_op (insn, operands);"
12480 [(set (attr "type")
12481 (if_then_else (eq_attr "alternative" "1")
12482 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12483 (const_string "ssemul")
12484 (const_string "sseadd"))
12485 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12486 (const_string "fmul")
12487 (const_string "fop"))))
12488 (set_attr "prefix" "orig,maybe_vex")
12489 (set_attr "mode" "<MODE>")])
12491 (define_insn "*fop_<mode>_comm_mixed"
12492 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12493 (match_operator:MODEF 3 "binary_fp_operator"
12494 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12495 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12496 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12497 && COMMUTATIVE_ARITH_P (operands[3])
12498 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12499 "* return output_387_binary_op (insn, operands);"
12500 [(set (attr "type")
12501 (if_then_else (eq_attr "alternative" "1")
12502 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12503 (const_string "ssemul")
12504 (const_string "sseadd"))
12505 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12506 (const_string "fmul")
12507 (const_string "fop"))))
12508 (set_attr "mode" "<MODE>")])
12510 (define_insn "*fop_<mode>_comm_avx"
12511 [(set (match_operand:MODEF 0 "register_operand" "=x")
12512 (match_operator:MODEF 3 "binary_fp_operator"
12513 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12514 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12515 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12516 && COMMUTATIVE_ARITH_P (operands[3])
12517 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12518 "* return output_387_binary_op (insn, operands);"
12519 [(set (attr "type")
12520 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12521 (const_string "ssemul")
12522 (const_string "sseadd")))
12523 (set_attr "prefix" "vex")
12524 (set_attr "mode" "<MODE>")])
12526 (define_insn "*fop_<mode>_comm_sse"
12527 [(set (match_operand:MODEF 0 "register_operand" "=x")
12528 (match_operator:MODEF 3 "binary_fp_operator"
12529 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12530 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12531 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12532 && COMMUTATIVE_ARITH_P (operands[3])
12533 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12534 "* return output_387_binary_op (insn, operands);"
12535 [(set (attr "type")
12536 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12537 (const_string "ssemul")
12538 (const_string "sseadd")))
12539 (set_attr "mode" "<MODE>")])
12541 (define_insn "*fop_<mode>_comm_i387"
12542 [(set (match_operand:MODEF 0 "register_operand" "=f")
12543 (match_operator:MODEF 3 "binary_fp_operator"
12544 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12545 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12546 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12547 && COMMUTATIVE_ARITH_P (operands[3])
12548 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12549 "* return output_387_binary_op (insn, operands);"
12550 [(set (attr "type")
12551 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12552 (const_string "fmul")
12553 (const_string "fop")))
12554 (set_attr "mode" "<MODE>")])
12556 (define_insn "*fop_<mode>_1_mixed_avx"
12557 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12558 (match_operator:MODEF 3 "binary_fp_operator"
12559 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12560 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12561 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12562 && !COMMUTATIVE_ARITH_P (operands[3])
12563 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12564 "* return output_387_binary_op (insn, operands);"
12565 [(set (attr "type")
12566 (cond [(and (eq_attr "alternative" "2")
12567 (match_operand:MODEF 3 "mult_operator" ""))
12568 (const_string "ssemul")
12569 (and (eq_attr "alternative" "2")
12570 (match_operand:MODEF 3 "div_operator" ""))
12571 (const_string "ssediv")
12572 (eq_attr "alternative" "2")
12573 (const_string "sseadd")
12574 (match_operand:MODEF 3 "mult_operator" "")
12575 (const_string "fmul")
12576 (match_operand:MODEF 3 "div_operator" "")
12577 (const_string "fdiv")
12579 (const_string "fop")))
12580 (set_attr "prefix" "orig,orig,maybe_vex")
12581 (set_attr "mode" "<MODE>")])
12583 (define_insn "*fop_<mode>_1_mixed"
12584 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12585 (match_operator:MODEF 3 "binary_fp_operator"
12586 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12587 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12588 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12589 && !COMMUTATIVE_ARITH_P (operands[3])
12590 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12591 "* return output_387_binary_op (insn, operands);"
12592 [(set (attr "type")
12593 (cond [(and (eq_attr "alternative" "2")
12594 (match_operand:MODEF 3 "mult_operator" ""))
12595 (const_string "ssemul")
12596 (and (eq_attr "alternative" "2")
12597 (match_operand:MODEF 3 "div_operator" ""))
12598 (const_string "ssediv")
12599 (eq_attr "alternative" "2")
12600 (const_string "sseadd")
12601 (match_operand:MODEF 3 "mult_operator" "")
12602 (const_string "fmul")
12603 (match_operand:MODEF 3 "div_operator" "")
12604 (const_string "fdiv")
12606 (const_string "fop")))
12607 (set_attr "mode" "<MODE>")])
12609 (define_insn "*rcpsf2_sse"
12610 [(set (match_operand:SF 0 "register_operand" "=x")
12611 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12614 "%vrcpss\t{%1, %d0|%d0, %1}"
12615 [(set_attr "type" "sse")
12616 (set_attr "atom_sse_attr" "rcp")
12617 (set_attr "prefix" "maybe_vex")
12618 (set_attr "mode" "SF")])
12620 (define_insn "*fop_<mode>_1_avx"
12621 [(set (match_operand:MODEF 0 "register_operand" "=x")
12622 (match_operator:MODEF 3 "binary_fp_operator"
12623 [(match_operand:MODEF 1 "register_operand" "x")
12624 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12625 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12626 && !COMMUTATIVE_ARITH_P (operands[3])"
12627 "* return output_387_binary_op (insn, operands);"
12628 [(set (attr "type")
12629 (cond [(match_operand:MODEF 3 "mult_operator" "")
12630 (const_string "ssemul")
12631 (match_operand:MODEF 3 "div_operator" "")
12632 (const_string "ssediv")
12634 (const_string "sseadd")))
12635 (set_attr "prefix" "vex")
12636 (set_attr "mode" "<MODE>")])
12638 (define_insn "*fop_<mode>_1_sse"
12639 [(set (match_operand:MODEF 0 "register_operand" "=x")
12640 (match_operator:MODEF 3 "binary_fp_operator"
12641 [(match_operand:MODEF 1 "register_operand" "0")
12642 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12643 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12644 && !COMMUTATIVE_ARITH_P (operands[3])"
12645 "* return output_387_binary_op (insn, operands);"
12646 [(set (attr "type")
12647 (cond [(match_operand:MODEF 3 "mult_operator" "")
12648 (const_string "ssemul")
12649 (match_operand:MODEF 3 "div_operator" "")
12650 (const_string "ssediv")
12652 (const_string "sseadd")))
12653 (set_attr "mode" "<MODE>")])
12655 ;; This pattern is not fully shadowed by the pattern above.
12656 (define_insn "*fop_<mode>_1_i387"
12657 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12658 (match_operator:MODEF 3 "binary_fp_operator"
12659 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12660 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12661 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12662 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12663 && !COMMUTATIVE_ARITH_P (operands[3])
12664 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12665 "* return output_387_binary_op (insn, operands);"
12666 [(set (attr "type")
12667 (cond [(match_operand:MODEF 3 "mult_operator" "")
12668 (const_string "fmul")
12669 (match_operand:MODEF 3 "div_operator" "")
12670 (const_string "fdiv")
12672 (const_string "fop")))
12673 (set_attr "mode" "<MODE>")])
12675 ;; ??? Add SSE splitters for these!
12676 (define_insn "*fop_<MODEF:mode>_2_i387"
12677 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12678 (match_operator:MODEF 3 "binary_fp_operator"
12680 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12681 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12682 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12683 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12684 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12685 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12686 [(set (attr "type")
12687 (cond [(match_operand:MODEF 3 "mult_operator" "")
12688 (const_string "fmul")
12689 (match_operand:MODEF 3 "div_operator" "")
12690 (const_string "fdiv")
12692 (const_string "fop")))
12693 (set_attr "fp_int_src" "true")
12694 (set_attr "mode" "<X87MODEI12:MODE>")])
12696 (define_insn "*fop_<MODEF:mode>_3_i387"
12697 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12698 (match_operator:MODEF 3 "binary_fp_operator"
12699 [(match_operand:MODEF 1 "register_operand" "0,0")
12701 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12702 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12703 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12704 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12705 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12706 [(set (attr "type")
12707 (cond [(match_operand:MODEF 3 "mult_operator" "")
12708 (const_string "fmul")
12709 (match_operand:MODEF 3 "div_operator" "")
12710 (const_string "fdiv")
12712 (const_string "fop")))
12713 (set_attr "fp_int_src" "true")
12714 (set_attr "mode" "<MODE>")])
12716 (define_insn "*fop_df_4_i387"
12717 [(set (match_operand:DF 0 "register_operand" "=f,f")
12718 (match_operator:DF 3 "binary_fp_operator"
12720 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12721 (match_operand:DF 2 "register_operand" "0,f")]))]
12722 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12723 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12724 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12725 "* return output_387_binary_op (insn, operands);"
12726 [(set (attr "type")
12727 (cond [(match_operand:DF 3 "mult_operator" "")
12728 (const_string "fmul")
12729 (match_operand:DF 3 "div_operator" "")
12730 (const_string "fdiv")
12732 (const_string "fop")))
12733 (set_attr "mode" "SF")])
12735 (define_insn "*fop_df_5_i387"
12736 [(set (match_operand:DF 0 "register_operand" "=f,f")
12737 (match_operator:DF 3 "binary_fp_operator"
12738 [(match_operand:DF 1 "register_operand" "0,f")
12740 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12741 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12742 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12743 "* return output_387_binary_op (insn, operands);"
12744 [(set (attr "type")
12745 (cond [(match_operand:DF 3 "mult_operator" "")
12746 (const_string "fmul")
12747 (match_operand:DF 3 "div_operator" "")
12748 (const_string "fdiv")
12750 (const_string "fop")))
12751 (set_attr "mode" "SF")])
12753 (define_insn "*fop_df_6_i387"
12754 [(set (match_operand:DF 0 "register_operand" "=f,f")
12755 (match_operator:DF 3 "binary_fp_operator"
12757 (match_operand:SF 1 "register_operand" "0,f"))
12759 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12760 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12761 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12762 "* return output_387_binary_op (insn, operands);"
12763 [(set (attr "type")
12764 (cond [(match_operand:DF 3 "mult_operator" "")
12765 (const_string "fmul")
12766 (match_operand:DF 3 "div_operator" "")
12767 (const_string "fdiv")
12769 (const_string "fop")))
12770 (set_attr "mode" "SF")])
12772 (define_insn "*fop_xf_comm_i387"
12773 [(set (match_operand:XF 0 "register_operand" "=f")
12774 (match_operator:XF 3 "binary_fp_operator"
12775 [(match_operand:XF 1 "register_operand" "%0")
12776 (match_operand:XF 2 "register_operand" "f")]))]
12778 && COMMUTATIVE_ARITH_P (operands[3])"
12779 "* return output_387_binary_op (insn, operands);"
12780 [(set (attr "type")
12781 (if_then_else (match_operand:XF 3 "mult_operator" "")
12782 (const_string "fmul")
12783 (const_string "fop")))
12784 (set_attr "mode" "XF")])
12786 (define_insn "*fop_xf_1_i387"
12787 [(set (match_operand:XF 0 "register_operand" "=f,f")
12788 (match_operator:XF 3 "binary_fp_operator"
12789 [(match_operand:XF 1 "register_operand" "0,f")
12790 (match_operand:XF 2 "register_operand" "f,0")]))]
12792 && !COMMUTATIVE_ARITH_P (operands[3])"
12793 "* return output_387_binary_op (insn, operands);"
12794 [(set (attr "type")
12795 (cond [(match_operand:XF 3 "mult_operator" "")
12796 (const_string "fmul")
12797 (match_operand:XF 3 "div_operator" "")
12798 (const_string "fdiv")
12800 (const_string "fop")))
12801 (set_attr "mode" "XF")])
12803 (define_insn "*fop_xf_2_i387"
12804 [(set (match_operand:XF 0 "register_operand" "=f,f")
12805 (match_operator:XF 3 "binary_fp_operator"
12807 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12808 (match_operand:XF 2 "register_operand" "0,0")]))]
12809 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12810 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12811 [(set (attr "type")
12812 (cond [(match_operand:XF 3 "mult_operator" "")
12813 (const_string "fmul")
12814 (match_operand:XF 3 "div_operator" "")
12815 (const_string "fdiv")
12817 (const_string "fop")))
12818 (set_attr "fp_int_src" "true")
12819 (set_attr "mode" "<MODE>")])
12821 (define_insn "*fop_xf_3_i387"
12822 [(set (match_operand:XF 0 "register_operand" "=f,f")
12823 (match_operator:XF 3 "binary_fp_operator"
12824 [(match_operand:XF 1 "register_operand" "0,0")
12826 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12827 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12828 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12829 [(set (attr "type")
12830 (cond [(match_operand:XF 3 "mult_operator" "")
12831 (const_string "fmul")
12832 (match_operand:XF 3 "div_operator" "")
12833 (const_string "fdiv")
12835 (const_string "fop")))
12836 (set_attr "fp_int_src" "true")
12837 (set_attr "mode" "<MODE>")])
12839 (define_insn "*fop_xf_4_i387"
12840 [(set (match_operand:XF 0 "register_operand" "=f,f")
12841 (match_operator:XF 3 "binary_fp_operator"
12843 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12844 (match_operand:XF 2 "register_operand" "0,f")]))]
12846 "* return output_387_binary_op (insn, operands);"
12847 [(set (attr "type")
12848 (cond [(match_operand:XF 3 "mult_operator" "")
12849 (const_string "fmul")
12850 (match_operand:XF 3 "div_operator" "")
12851 (const_string "fdiv")
12853 (const_string "fop")))
12854 (set_attr "mode" "<MODE>")])
12856 (define_insn "*fop_xf_5_i387"
12857 [(set (match_operand:XF 0 "register_operand" "=f,f")
12858 (match_operator:XF 3 "binary_fp_operator"
12859 [(match_operand:XF 1 "register_operand" "0,f")
12861 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12863 "* return output_387_binary_op (insn, operands);"
12864 [(set (attr "type")
12865 (cond [(match_operand:XF 3 "mult_operator" "")
12866 (const_string "fmul")
12867 (match_operand:XF 3 "div_operator" "")
12868 (const_string "fdiv")
12870 (const_string "fop")))
12871 (set_attr "mode" "<MODE>")])
12873 (define_insn "*fop_xf_6_i387"
12874 [(set (match_operand:XF 0 "register_operand" "=f,f")
12875 (match_operator:XF 3 "binary_fp_operator"
12877 (match_operand:MODEF 1 "register_operand" "0,f"))
12879 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12881 "* return output_387_binary_op (insn, operands);"
12882 [(set (attr "type")
12883 (cond [(match_operand:XF 3 "mult_operator" "")
12884 (const_string "fmul")
12885 (match_operand:XF 3 "div_operator" "")
12886 (const_string "fdiv")
12888 (const_string "fop")))
12889 (set_attr "mode" "<MODE>")])
12892 [(set (match_operand 0 "register_operand" "")
12893 (match_operator 3 "binary_fp_operator"
12894 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12895 (match_operand 2 "register_operand" "")]))]
12897 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12898 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12901 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12902 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12903 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12904 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12905 GET_MODE (operands[3]),
12908 ix86_free_from_memory (GET_MODE (operands[1]));
12913 [(set (match_operand 0 "register_operand" "")
12914 (match_operator 3 "binary_fp_operator"
12915 [(match_operand 1 "register_operand" "")
12916 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12918 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12919 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12922 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12923 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12924 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12925 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12926 GET_MODE (operands[3]),
12929 ix86_free_from_memory (GET_MODE (operands[2]));
12933 ;; FPU special functions.
12935 ;; This pattern implements a no-op XFmode truncation for
12936 ;; all fancy i386 XFmode math functions.
12938 (define_insn "truncxf<mode>2_i387_noop_unspec"
12939 [(set (match_operand:MODEF 0 "register_operand" "=f")
12940 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12941 UNSPEC_TRUNC_NOOP))]
12942 "TARGET_USE_FANCY_MATH_387"
12943 "* return output_387_reg_move (insn, operands);"
12944 [(set_attr "type" "fmov")
12945 (set_attr "mode" "<MODE>")])
12947 (define_insn "sqrtxf2"
12948 [(set (match_operand:XF 0 "register_operand" "=f")
12949 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12950 "TARGET_USE_FANCY_MATH_387"
12952 [(set_attr "type" "fpspc")
12953 (set_attr "mode" "XF")
12954 (set_attr "athlon_decode" "direct")
12955 (set_attr "amdfam10_decode" "direct")
12956 (set_attr "bdver1_decode" "direct")])
12958 (define_insn "sqrt_extend<mode>xf2_i387"
12959 [(set (match_operand:XF 0 "register_operand" "=f")
12962 (match_operand:MODEF 1 "register_operand" "0"))))]
12963 "TARGET_USE_FANCY_MATH_387"
12965 [(set_attr "type" "fpspc")
12966 (set_attr "mode" "XF")
12967 (set_attr "athlon_decode" "direct")
12968 (set_attr "amdfam10_decode" "direct")
12969 (set_attr "bdver1_decode" "direct")])
12971 (define_insn "*rsqrtsf2_sse"
12972 [(set (match_operand:SF 0 "register_operand" "=x")
12973 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12976 "%vrsqrtss\t{%1, %d0|%d0, %1}"
12977 [(set_attr "type" "sse")
12978 (set_attr "atom_sse_attr" "rcp")
12979 (set_attr "prefix" "maybe_vex")
12980 (set_attr "mode" "SF")])
12982 (define_expand "rsqrtsf2"
12983 [(set (match_operand:SF 0 "register_operand" "")
12984 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
12988 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12992 (define_insn "*sqrt<mode>2_sse"
12993 [(set (match_operand:MODEF 0 "register_operand" "=x")
12995 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12996 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12997 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
12998 [(set_attr "type" "sse")
12999 (set_attr "atom_sse_attr" "sqrt")
13000 (set_attr "prefix" "maybe_vex")
13001 (set_attr "mode" "<MODE>")
13002 (set_attr "athlon_decode" "*")
13003 (set_attr "amdfam10_decode" "*")
13004 (set_attr "bdver1_decode" "*")])
13006 (define_expand "sqrt<mode>2"
13007 [(set (match_operand:MODEF 0 "register_operand" "")
13009 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13010 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13011 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13013 if (<MODE>mode == SFmode
13014 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13015 && flag_finite_math_only && !flag_trapping_math
13016 && flag_unsafe_math_optimizations)
13018 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13022 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13024 rtx op0 = gen_reg_rtx (XFmode);
13025 rtx op1 = force_reg (<MODE>mode, operands[1]);
13027 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13028 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13033 (define_insn "fpremxf4_i387"
13034 [(set (match_operand:XF 0 "register_operand" "=f")
13035 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13036 (match_operand:XF 3 "register_operand" "1")]
13038 (set (match_operand:XF 1 "register_operand" "=u")
13039 (unspec:XF [(match_dup 2) (match_dup 3)]
13041 (set (reg:CCFP FPSR_REG)
13042 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13044 "TARGET_USE_FANCY_MATH_387"
13046 [(set_attr "type" "fpspc")
13047 (set_attr "mode" "XF")])
13049 (define_expand "fmodxf3"
13050 [(use (match_operand:XF 0 "register_operand" ""))
13051 (use (match_operand:XF 1 "general_operand" ""))
13052 (use (match_operand:XF 2 "general_operand" ""))]
13053 "TARGET_USE_FANCY_MATH_387"
13055 rtx label = gen_label_rtx ();
13057 rtx op1 = gen_reg_rtx (XFmode);
13058 rtx op2 = gen_reg_rtx (XFmode);
13060 emit_move_insn (op2, operands[2]);
13061 emit_move_insn (op1, operands[1]);
13063 emit_label (label);
13064 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13065 ix86_emit_fp_unordered_jump (label);
13066 LABEL_NUSES (label) = 1;
13068 emit_move_insn (operands[0], op1);
13072 (define_expand "fmod<mode>3"
13073 [(use (match_operand:MODEF 0 "register_operand" ""))
13074 (use (match_operand:MODEF 1 "general_operand" ""))
13075 (use (match_operand:MODEF 2 "general_operand" ""))]
13076 "TARGET_USE_FANCY_MATH_387"
13078 rtx (*gen_truncxf) (rtx, rtx);
13080 rtx label = gen_label_rtx ();
13082 rtx op1 = gen_reg_rtx (XFmode);
13083 rtx op2 = gen_reg_rtx (XFmode);
13085 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13086 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13088 emit_label (label);
13089 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13090 ix86_emit_fp_unordered_jump (label);
13091 LABEL_NUSES (label) = 1;
13093 /* Truncate the result properly for strict SSE math. */
13094 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13095 && !TARGET_MIX_SSE_I387)
13096 gen_truncxf = gen_truncxf<mode>2;
13098 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13100 emit_insn (gen_truncxf (operands[0], op1));
13104 (define_insn "fprem1xf4_i387"
13105 [(set (match_operand:XF 0 "register_operand" "=f")
13106 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13107 (match_operand:XF 3 "register_operand" "1")]
13109 (set (match_operand:XF 1 "register_operand" "=u")
13110 (unspec:XF [(match_dup 2) (match_dup 3)]
13112 (set (reg:CCFP FPSR_REG)
13113 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13115 "TARGET_USE_FANCY_MATH_387"
13117 [(set_attr "type" "fpspc")
13118 (set_attr "mode" "XF")])
13120 (define_expand "remainderxf3"
13121 [(use (match_operand:XF 0 "register_operand" ""))
13122 (use (match_operand:XF 1 "general_operand" ""))
13123 (use (match_operand:XF 2 "general_operand" ""))]
13124 "TARGET_USE_FANCY_MATH_387"
13126 rtx label = gen_label_rtx ();
13128 rtx op1 = gen_reg_rtx (XFmode);
13129 rtx op2 = gen_reg_rtx (XFmode);
13131 emit_move_insn (op2, operands[2]);
13132 emit_move_insn (op1, operands[1]);
13134 emit_label (label);
13135 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13136 ix86_emit_fp_unordered_jump (label);
13137 LABEL_NUSES (label) = 1;
13139 emit_move_insn (operands[0], op1);
13143 (define_expand "remainder<mode>3"
13144 [(use (match_operand:MODEF 0 "register_operand" ""))
13145 (use (match_operand:MODEF 1 "general_operand" ""))
13146 (use (match_operand:MODEF 2 "general_operand" ""))]
13147 "TARGET_USE_FANCY_MATH_387"
13149 rtx (*gen_truncxf) (rtx, rtx);
13151 rtx label = gen_label_rtx ();
13153 rtx op1 = gen_reg_rtx (XFmode);
13154 rtx op2 = gen_reg_rtx (XFmode);
13156 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13157 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13159 emit_label (label);
13161 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13162 ix86_emit_fp_unordered_jump (label);
13163 LABEL_NUSES (label) = 1;
13165 /* Truncate the result properly for strict SSE math. */
13166 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13167 && !TARGET_MIX_SSE_I387)
13168 gen_truncxf = gen_truncxf<mode>2;
13170 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13172 emit_insn (gen_truncxf (operands[0], op1));
13176 (define_insn "*sinxf2_i387"
13177 [(set (match_operand:XF 0 "register_operand" "=f")
13178 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13179 "TARGET_USE_FANCY_MATH_387
13180 && flag_unsafe_math_optimizations"
13182 [(set_attr "type" "fpspc")
13183 (set_attr "mode" "XF")])
13185 (define_insn "*sin_extend<mode>xf2_i387"
13186 [(set (match_operand:XF 0 "register_operand" "=f")
13187 (unspec:XF [(float_extend:XF
13188 (match_operand:MODEF 1 "register_operand" "0"))]
13190 "TARGET_USE_FANCY_MATH_387
13191 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13192 || TARGET_MIX_SSE_I387)
13193 && flag_unsafe_math_optimizations"
13195 [(set_attr "type" "fpspc")
13196 (set_attr "mode" "XF")])
13198 (define_insn "*cosxf2_i387"
13199 [(set (match_operand:XF 0 "register_operand" "=f")
13200 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13201 "TARGET_USE_FANCY_MATH_387
13202 && flag_unsafe_math_optimizations"
13204 [(set_attr "type" "fpspc")
13205 (set_attr "mode" "XF")])
13207 (define_insn "*cos_extend<mode>xf2_i387"
13208 [(set (match_operand:XF 0 "register_operand" "=f")
13209 (unspec:XF [(float_extend:XF
13210 (match_operand:MODEF 1 "register_operand" "0"))]
13212 "TARGET_USE_FANCY_MATH_387
13213 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13214 || TARGET_MIX_SSE_I387)
13215 && flag_unsafe_math_optimizations"
13217 [(set_attr "type" "fpspc")
13218 (set_attr "mode" "XF")])
13220 ;; When sincos pattern is defined, sin and cos builtin functions will be
13221 ;; expanded to sincos pattern with one of its outputs left unused.
13222 ;; CSE pass will figure out if two sincos patterns can be combined,
13223 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13224 ;; depending on the unused output.
13226 (define_insn "sincosxf3"
13227 [(set (match_operand:XF 0 "register_operand" "=f")
13228 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13229 UNSPEC_SINCOS_COS))
13230 (set (match_operand:XF 1 "register_operand" "=u")
13231 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13232 "TARGET_USE_FANCY_MATH_387
13233 && flag_unsafe_math_optimizations"
13235 [(set_attr "type" "fpspc")
13236 (set_attr "mode" "XF")])
13239 [(set (match_operand:XF 0 "register_operand" "")
13240 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13241 UNSPEC_SINCOS_COS))
13242 (set (match_operand:XF 1 "register_operand" "")
13243 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13244 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13245 && !(reload_completed || reload_in_progress)"
13246 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13249 [(set (match_operand:XF 0 "register_operand" "")
13250 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13251 UNSPEC_SINCOS_COS))
13252 (set (match_operand:XF 1 "register_operand" "")
13253 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13254 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13255 && !(reload_completed || reload_in_progress)"
13256 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13258 (define_insn "sincos_extend<mode>xf3_i387"
13259 [(set (match_operand:XF 0 "register_operand" "=f")
13260 (unspec:XF [(float_extend:XF
13261 (match_operand:MODEF 2 "register_operand" "0"))]
13262 UNSPEC_SINCOS_COS))
13263 (set (match_operand:XF 1 "register_operand" "=u")
13264 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13265 "TARGET_USE_FANCY_MATH_387
13266 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13267 || TARGET_MIX_SSE_I387)
13268 && flag_unsafe_math_optimizations"
13270 [(set_attr "type" "fpspc")
13271 (set_attr "mode" "XF")])
13274 [(set (match_operand:XF 0 "register_operand" "")
13275 (unspec:XF [(float_extend:XF
13276 (match_operand:MODEF 2 "register_operand" ""))]
13277 UNSPEC_SINCOS_COS))
13278 (set (match_operand:XF 1 "register_operand" "")
13279 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13280 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13281 && !(reload_completed || reload_in_progress)"
13282 [(set (match_dup 1)
13283 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13286 [(set (match_operand:XF 0 "register_operand" "")
13287 (unspec:XF [(float_extend:XF
13288 (match_operand:MODEF 2 "register_operand" ""))]
13289 UNSPEC_SINCOS_COS))
13290 (set (match_operand:XF 1 "register_operand" "")
13291 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13292 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13293 && !(reload_completed || reload_in_progress)"
13294 [(set (match_dup 0)
13295 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13297 (define_expand "sincos<mode>3"
13298 [(use (match_operand:MODEF 0 "register_operand" ""))
13299 (use (match_operand:MODEF 1 "register_operand" ""))
13300 (use (match_operand:MODEF 2 "register_operand" ""))]
13301 "TARGET_USE_FANCY_MATH_387
13302 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13303 || TARGET_MIX_SSE_I387)
13304 && flag_unsafe_math_optimizations"
13306 rtx op0 = gen_reg_rtx (XFmode);
13307 rtx op1 = gen_reg_rtx (XFmode);
13309 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13310 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13311 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13315 (define_insn "fptanxf4_i387"
13316 [(set (match_operand:XF 0 "register_operand" "=f")
13317 (match_operand:XF 3 "const_double_operand" "F"))
13318 (set (match_operand:XF 1 "register_operand" "=u")
13319 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13321 "TARGET_USE_FANCY_MATH_387
13322 && flag_unsafe_math_optimizations
13323 && standard_80387_constant_p (operands[3]) == 2"
13325 [(set_attr "type" "fpspc")
13326 (set_attr "mode" "XF")])
13328 (define_insn "fptan_extend<mode>xf4_i387"
13329 [(set (match_operand:MODEF 0 "register_operand" "=f")
13330 (match_operand:MODEF 3 "const_double_operand" "F"))
13331 (set (match_operand:XF 1 "register_operand" "=u")
13332 (unspec:XF [(float_extend:XF
13333 (match_operand:MODEF 2 "register_operand" "0"))]
13335 "TARGET_USE_FANCY_MATH_387
13336 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13337 || TARGET_MIX_SSE_I387)
13338 && flag_unsafe_math_optimizations
13339 && standard_80387_constant_p (operands[3]) == 2"
13341 [(set_attr "type" "fpspc")
13342 (set_attr "mode" "XF")])
13344 (define_expand "tanxf2"
13345 [(use (match_operand:XF 0 "register_operand" ""))
13346 (use (match_operand:XF 1 "register_operand" ""))]
13347 "TARGET_USE_FANCY_MATH_387
13348 && flag_unsafe_math_optimizations"
13350 rtx one = gen_reg_rtx (XFmode);
13351 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13353 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13357 (define_expand "tan<mode>2"
13358 [(use (match_operand:MODEF 0 "register_operand" ""))
13359 (use (match_operand:MODEF 1 "register_operand" ""))]
13360 "TARGET_USE_FANCY_MATH_387
13361 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13362 || TARGET_MIX_SSE_I387)
13363 && flag_unsafe_math_optimizations"
13365 rtx op0 = gen_reg_rtx (XFmode);
13367 rtx one = gen_reg_rtx (<MODE>mode);
13368 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13370 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13371 operands[1], op2));
13372 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13376 (define_insn "*fpatanxf3_i387"
13377 [(set (match_operand:XF 0 "register_operand" "=f")
13378 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13379 (match_operand:XF 2 "register_operand" "u")]
13381 (clobber (match_scratch:XF 3 "=2"))]
13382 "TARGET_USE_FANCY_MATH_387
13383 && flag_unsafe_math_optimizations"
13385 [(set_attr "type" "fpspc")
13386 (set_attr "mode" "XF")])
13388 (define_insn "fpatan_extend<mode>xf3_i387"
13389 [(set (match_operand:XF 0 "register_operand" "=f")
13390 (unspec:XF [(float_extend:XF
13391 (match_operand:MODEF 1 "register_operand" "0"))
13393 (match_operand:MODEF 2 "register_operand" "u"))]
13395 (clobber (match_scratch:XF 3 "=2"))]
13396 "TARGET_USE_FANCY_MATH_387
13397 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13398 || TARGET_MIX_SSE_I387)
13399 && flag_unsafe_math_optimizations"
13401 [(set_attr "type" "fpspc")
13402 (set_attr "mode" "XF")])
13404 (define_expand "atan2xf3"
13405 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13406 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13407 (match_operand:XF 1 "register_operand" "")]
13409 (clobber (match_scratch:XF 3 ""))])]
13410 "TARGET_USE_FANCY_MATH_387
13411 && flag_unsafe_math_optimizations")
13413 (define_expand "atan2<mode>3"
13414 [(use (match_operand:MODEF 0 "register_operand" ""))
13415 (use (match_operand:MODEF 1 "register_operand" ""))
13416 (use (match_operand:MODEF 2 "register_operand" ""))]
13417 "TARGET_USE_FANCY_MATH_387
13418 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13419 || TARGET_MIX_SSE_I387)
13420 && flag_unsafe_math_optimizations"
13422 rtx op0 = gen_reg_rtx (XFmode);
13424 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13425 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13429 (define_expand "atanxf2"
13430 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13431 (unspec:XF [(match_dup 2)
13432 (match_operand:XF 1 "register_operand" "")]
13434 (clobber (match_scratch:XF 3 ""))])]
13435 "TARGET_USE_FANCY_MATH_387
13436 && flag_unsafe_math_optimizations"
13438 operands[2] = gen_reg_rtx (XFmode);
13439 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13442 (define_expand "atan<mode>2"
13443 [(use (match_operand:MODEF 0 "register_operand" ""))
13444 (use (match_operand:MODEF 1 "register_operand" ""))]
13445 "TARGET_USE_FANCY_MATH_387
13446 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13447 || TARGET_MIX_SSE_I387)
13448 && flag_unsafe_math_optimizations"
13450 rtx op0 = gen_reg_rtx (XFmode);
13452 rtx op2 = gen_reg_rtx (<MODE>mode);
13453 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13455 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13456 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13460 (define_expand "asinxf2"
13461 [(set (match_dup 2)
13462 (mult:XF (match_operand:XF 1 "register_operand" "")
13464 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13465 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13466 (parallel [(set (match_operand:XF 0 "register_operand" "")
13467 (unspec:XF [(match_dup 5) (match_dup 1)]
13469 (clobber (match_scratch:XF 6 ""))])]
13470 "TARGET_USE_FANCY_MATH_387
13471 && flag_unsafe_math_optimizations"
13475 if (optimize_insn_for_size_p ())
13478 for (i = 2; i < 6; i++)
13479 operands[i] = gen_reg_rtx (XFmode);
13481 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13484 (define_expand "asin<mode>2"
13485 [(use (match_operand:MODEF 0 "register_operand" ""))
13486 (use (match_operand:MODEF 1 "general_operand" ""))]
13487 "TARGET_USE_FANCY_MATH_387
13488 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13489 || TARGET_MIX_SSE_I387)
13490 && flag_unsafe_math_optimizations"
13492 rtx op0 = gen_reg_rtx (XFmode);
13493 rtx op1 = gen_reg_rtx (XFmode);
13495 if (optimize_insn_for_size_p ())
13498 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13499 emit_insn (gen_asinxf2 (op0, op1));
13500 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13504 (define_expand "acosxf2"
13505 [(set (match_dup 2)
13506 (mult:XF (match_operand:XF 1 "register_operand" "")
13508 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13509 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13510 (parallel [(set (match_operand:XF 0 "register_operand" "")
13511 (unspec:XF [(match_dup 1) (match_dup 5)]
13513 (clobber (match_scratch:XF 6 ""))])]
13514 "TARGET_USE_FANCY_MATH_387
13515 && flag_unsafe_math_optimizations"
13519 if (optimize_insn_for_size_p ())
13522 for (i = 2; i < 6; i++)
13523 operands[i] = gen_reg_rtx (XFmode);
13525 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13528 (define_expand "acos<mode>2"
13529 [(use (match_operand:MODEF 0 "register_operand" ""))
13530 (use (match_operand:MODEF 1 "general_operand" ""))]
13531 "TARGET_USE_FANCY_MATH_387
13532 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13533 || TARGET_MIX_SSE_I387)
13534 && flag_unsafe_math_optimizations"
13536 rtx op0 = gen_reg_rtx (XFmode);
13537 rtx op1 = gen_reg_rtx (XFmode);
13539 if (optimize_insn_for_size_p ())
13542 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13543 emit_insn (gen_acosxf2 (op0, op1));
13544 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13548 (define_insn "fyl2xxf3_i387"
13549 [(set (match_operand:XF 0 "register_operand" "=f")
13550 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13551 (match_operand:XF 2 "register_operand" "u")]
13553 (clobber (match_scratch:XF 3 "=2"))]
13554 "TARGET_USE_FANCY_MATH_387
13555 && flag_unsafe_math_optimizations"
13557 [(set_attr "type" "fpspc")
13558 (set_attr "mode" "XF")])
13560 (define_insn "fyl2x_extend<mode>xf3_i387"
13561 [(set (match_operand:XF 0 "register_operand" "=f")
13562 (unspec:XF [(float_extend:XF
13563 (match_operand:MODEF 1 "register_operand" "0"))
13564 (match_operand:XF 2 "register_operand" "u")]
13566 (clobber (match_scratch:XF 3 "=2"))]
13567 "TARGET_USE_FANCY_MATH_387
13568 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13569 || TARGET_MIX_SSE_I387)
13570 && flag_unsafe_math_optimizations"
13572 [(set_attr "type" "fpspc")
13573 (set_attr "mode" "XF")])
13575 (define_expand "logxf2"
13576 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13577 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13578 (match_dup 2)] UNSPEC_FYL2X))
13579 (clobber (match_scratch:XF 3 ""))])]
13580 "TARGET_USE_FANCY_MATH_387
13581 && flag_unsafe_math_optimizations"
13583 operands[2] = gen_reg_rtx (XFmode);
13584 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13587 (define_expand "log<mode>2"
13588 [(use (match_operand:MODEF 0 "register_operand" ""))
13589 (use (match_operand:MODEF 1 "register_operand" ""))]
13590 "TARGET_USE_FANCY_MATH_387
13591 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13592 || TARGET_MIX_SSE_I387)
13593 && flag_unsafe_math_optimizations"
13595 rtx op0 = gen_reg_rtx (XFmode);
13597 rtx op2 = gen_reg_rtx (XFmode);
13598 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13600 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13601 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13605 (define_expand "log10xf2"
13606 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13607 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13608 (match_dup 2)] UNSPEC_FYL2X))
13609 (clobber (match_scratch:XF 3 ""))])]
13610 "TARGET_USE_FANCY_MATH_387
13611 && flag_unsafe_math_optimizations"
13613 operands[2] = gen_reg_rtx (XFmode);
13614 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13617 (define_expand "log10<mode>2"
13618 [(use (match_operand:MODEF 0 "register_operand" ""))
13619 (use (match_operand:MODEF 1 "register_operand" ""))]
13620 "TARGET_USE_FANCY_MATH_387
13621 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13622 || TARGET_MIX_SSE_I387)
13623 && flag_unsafe_math_optimizations"
13625 rtx op0 = gen_reg_rtx (XFmode);
13627 rtx op2 = gen_reg_rtx (XFmode);
13628 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13630 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13631 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13635 (define_expand "log2xf2"
13636 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13637 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13638 (match_dup 2)] UNSPEC_FYL2X))
13639 (clobber (match_scratch:XF 3 ""))])]
13640 "TARGET_USE_FANCY_MATH_387
13641 && flag_unsafe_math_optimizations"
13643 operands[2] = gen_reg_rtx (XFmode);
13644 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13647 (define_expand "log2<mode>2"
13648 [(use (match_operand:MODEF 0 "register_operand" ""))
13649 (use (match_operand:MODEF 1 "register_operand" ""))]
13650 "TARGET_USE_FANCY_MATH_387
13651 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13652 || TARGET_MIX_SSE_I387)
13653 && flag_unsafe_math_optimizations"
13655 rtx op0 = gen_reg_rtx (XFmode);
13657 rtx op2 = gen_reg_rtx (XFmode);
13658 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13660 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13661 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13665 (define_insn "fyl2xp1xf3_i387"
13666 [(set (match_operand:XF 0 "register_operand" "=f")
13667 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13668 (match_operand:XF 2 "register_operand" "u")]
13670 (clobber (match_scratch:XF 3 "=2"))]
13671 "TARGET_USE_FANCY_MATH_387
13672 && flag_unsafe_math_optimizations"
13674 [(set_attr "type" "fpspc")
13675 (set_attr "mode" "XF")])
13677 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13678 [(set (match_operand:XF 0 "register_operand" "=f")
13679 (unspec:XF [(float_extend:XF
13680 (match_operand:MODEF 1 "register_operand" "0"))
13681 (match_operand:XF 2 "register_operand" "u")]
13683 (clobber (match_scratch:XF 3 "=2"))]
13684 "TARGET_USE_FANCY_MATH_387
13685 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13686 || TARGET_MIX_SSE_I387)
13687 && flag_unsafe_math_optimizations"
13689 [(set_attr "type" "fpspc")
13690 (set_attr "mode" "XF")])
13692 (define_expand "log1pxf2"
13693 [(use (match_operand:XF 0 "register_operand" ""))
13694 (use (match_operand:XF 1 "register_operand" ""))]
13695 "TARGET_USE_FANCY_MATH_387
13696 && flag_unsafe_math_optimizations"
13698 if (optimize_insn_for_size_p ())
13701 ix86_emit_i387_log1p (operands[0], operands[1]);
13705 (define_expand "log1p<mode>2"
13706 [(use (match_operand:MODEF 0 "register_operand" ""))
13707 (use (match_operand:MODEF 1 "register_operand" ""))]
13708 "TARGET_USE_FANCY_MATH_387
13709 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13710 || TARGET_MIX_SSE_I387)
13711 && flag_unsafe_math_optimizations"
13715 if (optimize_insn_for_size_p ())
13718 op0 = gen_reg_rtx (XFmode);
13720 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13722 ix86_emit_i387_log1p (op0, operands[1]);
13723 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13727 (define_insn "fxtractxf3_i387"
13728 [(set (match_operand:XF 0 "register_operand" "=f")
13729 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13730 UNSPEC_XTRACT_FRACT))
13731 (set (match_operand:XF 1 "register_operand" "=u")
13732 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13733 "TARGET_USE_FANCY_MATH_387
13734 && flag_unsafe_math_optimizations"
13736 [(set_attr "type" "fpspc")
13737 (set_attr "mode" "XF")])
13739 (define_insn "fxtract_extend<mode>xf3_i387"
13740 [(set (match_operand:XF 0 "register_operand" "=f")
13741 (unspec:XF [(float_extend:XF
13742 (match_operand:MODEF 2 "register_operand" "0"))]
13743 UNSPEC_XTRACT_FRACT))
13744 (set (match_operand:XF 1 "register_operand" "=u")
13745 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13746 "TARGET_USE_FANCY_MATH_387
13747 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13748 || TARGET_MIX_SSE_I387)
13749 && flag_unsafe_math_optimizations"
13751 [(set_attr "type" "fpspc")
13752 (set_attr "mode" "XF")])
13754 (define_expand "logbxf2"
13755 [(parallel [(set (match_dup 2)
13756 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13757 UNSPEC_XTRACT_FRACT))
13758 (set (match_operand:XF 0 "register_operand" "")
13759 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13760 "TARGET_USE_FANCY_MATH_387
13761 && flag_unsafe_math_optimizations"
13762 "operands[2] = gen_reg_rtx (XFmode);")
13764 (define_expand "logb<mode>2"
13765 [(use (match_operand:MODEF 0 "register_operand" ""))
13766 (use (match_operand:MODEF 1 "register_operand" ""))]
13767 "TARGET_USE_FANCY_MATH_387
13768 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13769 || TARGET_MIX_SSE_I387)
13770 && flag_unsafe_math_optimizations"
13772 rtx op0 = gen_reg_rtx (XFmode);
13773 rtx op1 = gen_reg_rtx (XFmode);
13775 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13776 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13780 (define_expand "ilogbxf2"
13781 [(use (match_operand:SI 0 "register_operand" ""))
13782 (use (match_operand:XF 1 "register_operand" ""))]
13783 "TARGET_USE_FANCY_MATH_387
13784 && flag_unsafe_math_optimizations"
13788 if (optimize_insn_for_size_p ())
13791 op0 = gen_reg_rtx (XFmode);
13792 op1 = gen_reg_rtx (XFmode);
13794 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13795 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13799 (define_expand "ilogb<mode>2"
13800 [(use (match_operand:SI 0 "register_operand" ""))
13801 (use (match_operand:MODEF 1 "register_operand" ""))]
13802 "TARGET_USE_FANCY_MATH_387
13803 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13804 || TARGET_MIX_SSE_I387)
13805 && flag_unsafe_math_optimizations"
13809 if (optimize_insn_for_size_p ())
13812 op0 = gen_reg_rtx (XFmode);
13813 op1 = gen_reg_rtx (XFmode);
13815 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13816 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13820 (define_insn "*f2xm1xf2_i387"
13821 [(set (match_operand:XF 0 "register_operand" "=f")
13822 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13824 "TARGET_USE_FANCY_MATH_387
13825 && flag_unsafe_math_optimizations"
13827 [(set_attr "type" "fpspc")
13828 (set_attr "mode" "XF")])
13830 (define_insn "*fscalexf4_i387"
13831 [(set (match_operand:XF 0 "register_operand" "=f")
13832 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13833 (match_operand:XF 3 "register_operand" "1")]
13834 UNSPEC_FSCALE_FRACT))
13835 (set (match_operand:XF 1 "register_operand" "=u")
13836 (unspec:XF [(match_dup 2) (match_dup 3)]
13837 UNSPEC_FSCALE_EXP))]
13838 "TARGET_USE_FANCY_MATH_387
13839 && flag_unsafe_math_optimizations"
13841 [(set_attr "type" "fpspc")
13842 (set_attr "mode" "XF")])
13844 (define_expand "expNcorexf3"
13845 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13846 (match_operand:XF 2 "register_operand" "")))
13847 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13848 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13849 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13850 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13851 (parallel [(set (match_operand:XF 0 "register_operand" "")
13852 (unspec:XF [(match_dup 8) (match_dup 4)]
13853 UNSPEC_FSCALE_FRACT))
13855 (unspec:XF [(match_dup 8) (match_dup 4)]
13856 UNSPEC_FSCALE_EXP))])]
13857 "TARGET_USE_FANCY_MATH_387
13858 && flag_unsafe_math_optimizations"
13862 if (optimize_insn_for_size_p ())
13865 for (i = 3; i < 10; i++)
13866 operands[i] = gen_reg_rtx (XFmode);
13868 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13871 (define_expand "expxf2"
13872 [(use (match_operand:XF 0 "register_operand" ""))
13873 (use (match_operand:XF 1 "register_operand" ""))]
13874 "TARGET_USE_FANCY_MATH_387
13875 && flag_unsafe_math_optimizations"
13879 if (optimize_insn_for_size_p ())
13882 op2 = gen_reg_rtx (XFmode);
13883 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13885 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13889 (define_expand "exp<mode>2"
13890 [(use (match_operand:MODEF 0 "register_operand" ""))
13891 (use (match_operand:MODEF 1 "general_operand" ""))]
13892 "TARGET_USE_FANCY_MATH_387
13893 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13894 || TARGET_MIX_SSE_I387)
13895 && flag_unsafe_math_optimizations"
13899 if (optimize_insn_for_size_p ())
13902 op0 = gen_reg_rtx (XFmode);
13903 op1 = gen_reg_rtx (XFmode);
13905 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13906 emit_insn (gen_expxf2 (op0, op1));
13907 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13911 (define_expand "exp10xf2"
13912 [(use (match_operand:XF 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 op2 = gen_reg_rtx (XFmode);
13923 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13925 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13929 (define_expand "exp10<mode>2"
13930 [(use (match_operand:MODEF 0 "register_operand" ""))
13931 (use (match_operand:MODEF 1 "general_operand" ""))]
13932 "TARGET_USE_FANCY_MATH_387
13933 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13934 || TARGET_MIX_SSE_I387)
13935 && flag_unsafe_math_optimizations"
13939 if (optimize_insn_for_size_p ())
13942 op0 = gen_reg_rtx (XFmode);
13943 op1 = gen_reg_rtx (XFmode);
13945 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13946 emit_insn (gen_exp10xf2 (op0, op1));
13947 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13951 (define_expand "exp2xf2"
13952 [(use (match_operand:XF 0 "register_operand" ""))
13953 (use (match_operand:XF 1 "register_operand" ""))]
13954 "TARGET_USE_FANCY_MATH_387
13955 && flag_unsafe_math_optimizations"
13959 if (optimize_insn_for_size_p ())
13962 op2 = gen_reg_rtx (XFmode);
13963 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13965 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13969 (define_expand "exp2<mode>2"
13970 [(use (match_operand:MODEF 0 "register_operand" ""))
13971 (use (match_operand:MODEF 1 "general_operand" ""))]
13972 "TARGET_USE_FANCY_MATH_387
13973 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13974 || TARGET_MIX_SSE_I387)
13975 && flag_unsafe_math_optimizations"
13979 if (optimize_insn_for_size_p ())
13982 op0 = gen_reg_rtx (XFmode);
13983 op1 = gen_reg_rtx (XFmode);
13985 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13986 emit_insn (gen_exp2xf2 (op0, op1));
13987 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13991 (define_expand "expm1xf2"
13992 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13994 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13995 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13996 (set (match_dup 9) (float_extend:XF (match_dup 13)))
13997 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13998 (parallel [(set (match_dup 7)
13999 (unspec:XF [(match_dup 6) (match_dup 4)]
14000 UNSPEC_FSCALE_FRACT))
14002 (unspec:XF [(match_dup 6) (match_dup 4)]
14003 UNSPEC_FSCALE_EXP))])
14004 (parallel [(set (match_dup 10)
14005 (unspec:XF [(match_dup 9) (match_dup 8)]
14006 UNSPEC_FSCALE_FRACT))
14007 (set (match_dup 11)
14008 (unspec:XF [(match_dup 9) (match_dup 8)]
14009 UNSPEC_FSCALE_EXP))])
14010 (set (match_dup 12) (minus:XF (match_dup 10)
14011 (float_extend:XF (match_dup 13))))
14012 (set (match_operand:XF 0 "register_operand" "")
14013 (plus:XF (match_dup 12) (match_dup 7)))]
14014 "TARGET_USE_FANCY_MATH_387
14015 && flag_unsafe_math_optimizations"
14019 if (optimize_insn_for_size_p ())
14022 for (i = 2; i < 13; i++)
14023 operands[i] = gen_reg_rtx (XFmode);
14026 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14028 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14031 (define_expand "expm1<mode>2"
14032 [(use (match_operand:MODEF 0 "register_operand" ""))
14033 (use (match_operand:MODEF 1 "general_operand" ""))]
14034 "TARGET_USE_FANCY_MATH_387
14035 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14036 || TARGET_MIX_SSE_I387)
14037 && flag_unsafe_math_optimizations"
14041 if (optimize_insn_for_size_p ())
14044 op0 = gen_reg_rtx (XFmode);
14045 op1 = gen_reg_rtx (XFmode);
14047 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14048 emit_insn (gen_expm1xf2 (op0, op1));
14049 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14053 (define_expand "ldexpxf3"
14054 [(set (match_dup 3)
14055 (float:XF (match_operand:SI 2 "register_operand" "")))
14056 (parallel [(set (match_operand:XF 0 " register_operand" "")
14057 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14059 UNSPEC_FSCALE_FRACT))
14061 (unspec:XF [(match_dup 1) (match_dup 3)]
14062 UNSPEC_FSCALE_EXP))])]
14063 "TARGET_USE_FANCY_MATH_387
14064 && flag_unsafe_math_optimizations"
14066 if (optimize_insn_for_size_p ())
14069 operands[3] = gen_reg_rtx (XFmode);
14070 operands[4] = gen_reg_rtx (XFmode);
14073 (define_expand "ldexp<mode>3"
14074 [(use (match_operand:MODEF 0 "register_operand" ""))
14075 (use (match_operand:MODEF 1 "general_operand" ""))
14076 (use (match_operand:SI 2 "register_operand" ""))]
14077 "TARGET_USE_FANCY_MATH_387
14078 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14079 || TARGET_MIX_SSE_I387)
14080 && flag_unsafe_math_optimizations"
14084 if (optimize_insn_for_size_p ())
14087 op0 = gen_reg_rtx (XFmode);
14088 op1 = gen_reg_rtx (XFmode);
14090 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14091 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14092 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14096 (define_expand "scalbxf3"
14097 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14098 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14099 (match_operand:XF 2 "register_operand" "")]
14100 UNSPEC_FSCALE_FRACT))
14102 (unspec:XF [(match_dup 1) (match_dup 2)]
14103 UNSPEC_FSCALE_EXP))])]
14104 "TARGET_USE_FANCY_MATH_387
14105 && flag_unsafe_math_optimizations"
14107 if (optimize_insn_for_size_p ())
14110 operands[3] = gen_reg_rtx (XFmode);
14113 (define_expand "scalb<mode>3"
14114 [(use (match_operand:MODEF 0 "register_operand" ""))
14115 (use (match_operand:MODEF 1 "general_operand" ""))
14116 (use (match_operand:MODEF 2 "general_operand" ""))]
14117 "TARGET_USE_FANCY_MATH_387
14118 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14119 || TARGET_MIX_SSE_I387)
14120 && flag_unsafe_math_optimizations"
14124 if (optimize_insn_for_size_p ())
14127 op0 = gen_reg_rtx (XFmode);
14128 op1 = gen_reg_rtx (XFmode);
14129 op2 = gen_reg_rtx (XFmode);
14131 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14132 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14133 emit_insn (gen_scalbxf3 (op0, op1, op2));
14134 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14138 (define_expand "significandxf2"
14139 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14140 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14141 UNSPEC_XTRACT_FRACT))
14143 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14144 "TARGET_USE_FANCY_MATH_387
14145 && flag_unsafe_math_optimizations"
14146 "operands[2] = gen_reg_rtx (XFmode);")
14148 (define_expand "significand<mode>2"
14149 [(use (match_operand:MODEF 0 "register_operand" ""))
14150 (use (match_operand:MODEF 1 "register_operand" ""))]
14151 "TARGET_USE_FANCY_MATH_387
14152 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14153 || TARGET_MIX_SSE_I387)
14154 && flag_unsafe_math_optimizations"
14156 rtx op0 = gen_reg_rtx (XFmode);
14157 rtx op1 = gen_reg_rtx (XFmode);
14159 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14160 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14165 (define_insn "sse4_1_round<mode>2"
14166 [(set (match_operand:MODEF 0 "register_operand" "=x")
14167 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14168 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14171 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14172 [(set_attr "type" "ssecvt")
14173 (set_attr "prefix_extra" "1")
14174 (set_attr "prefix" "maybe_vex")
14175 (set_attr "mode" "<MODE>")])
14177 (define_insn "rintxf2"
14178 [(set (match_operand:XF 0 "register_operand" "=f")
14179 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14181 "TARGET_USE_FANCY_MATH_387
14182 && flag_unsafe_math_optimizations"
14184 [(set_attr "type" "fpspc")
14185 (set_attr "mode" "XF")])
14187 (define_expand "rint<mode>2"
14188 [(use (match_operand:MODEF 0 "register_operand" ""))
14189 (use (match_operand:MODEF 1 "register_operand" ""))]
14190 "(TARGET_USE_FANCY_MATH_387
14191 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14192 || TARGET_MIX_SSE_I387)
14193 && flag_unsafe_math_optimizations)
14194 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14195 && !flag_trapping_math)"
14197 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14198 && !flag_trapping_math)
14200 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14203 emit_insn (gen_sse4_1_round<mode>2
14204 (operands[0], operands[1], GEN_INT (0x04)));
14206 ix86_expand_rint (operand0, operand1);
14210 rtx op0 = gen_reg_rtx (XFmode);
14211 rtx op1 = gen_reg_rtx (XFmode);
14213 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14214 emit_insn (gen_rintxf2 (op0, op1));
14216 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14221 (define_expand "round<mode>2"
14222 [(match_operand:MODEF 0 "register_operand" "")
14223 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14224 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14225 && !flag_trapping_math && !flag_rounding_math"
14227 if (optimize_insn_for_size_p ())
14229 if (TARGET_64BIT || (<MODE>mode != DFmode))
14230 ix86_expand_round (operand0, operand1);
14232 ix86_expand_rounddf_32 (operand0, operand1);
14236 (define_insn_and_split "*fistdi2_1"
14237 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14238 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14240 "TARGET_USE_FANCY_MATH_387
14241 && can_create_pseudo_p ()"
14246 if (memory_operand (operands[0], VOIDmode))
14247 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14250 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14251 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14256 [(set_attr "type" "fpspc")
14257 (set_attr "mode" "DI")])
14259 (define_insn "fistdi2"
14260 [(set (match_operand:DI 0 "memory_operand" "=m")
14261 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14263 (clobber (match_scratch:XF 2 "=&1f"))]
14264 "TARGET_USE_FANCY_MATH_387"
14265 "* return output_fix_trunc (insn, operands, 0);"
14266 [(set_attr "type" "fpspc")
14267 (set_attr "mode" "DI")])
14269 (define_insn "fistdi2_with_temp"
14270 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14271 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14273 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14274 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14275 "TARGET_USE_FANCY_MATH_387"
14277 [(set_attr "type" "fpspc")
14278 (set_attr "mode" "DI")])
14281 [(set (match_operand:DI 0 "register_operand" "")
14282 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14284 (clobber (match_operand:DI 2 "memory_operand" ""))
14285 (clobber (match_scratch 3 ""))]
14287 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14288 (clobber (match_dup 3))])
14289 (set (match_dup 0) (match_dup 2))])
14292 [(set (match_operand:DI 0 "memory_operand" "")
14293 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14295 (clobber (match_operand:DI 2 "memory_operand" ""))
14296 (clobber (match_scratch 3 ""))]
14298 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14299 (clobber (match_dup 3))])])
14301 (define_insn_and_split "*fist<mode>2_1"
14302 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14303 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14305 "TARGET_USE_FANCY_MATH_387
14306 && can_create_pseudo_p ()"
14311 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14312 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14316 [(set_attr "type" "fpspc")
14317 (set_attr "mode" "<MODE>")])
14319 (define_insn "fist<mode>2"
14320 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14321 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14323 "TARGET_USE_FANCY_MATH_387"
14324 "* return output_fix_trunc (insn, operands, 0);"
14325 [(set_attr "type" "fpspc")
14326 (set_attr "mode" "<MODE>")])
14328 (define_insn "fist<mode>2_with_temp"
14329 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14330 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14332 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14333 "TARGET_USE_FANCY_MATH_387"
14335 [(set_attr "type" "fpspc")
14336 (set_attr "mode" "<MODE>")])
14339 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14340 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14342 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14344 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14345 (set (match_dup 0) (match_dup 2))])
14348 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14349 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14351 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14353 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14355 (define_expand "lrintxf<mode>2"
14356 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14357 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14359 "TARGET_USE_FANCY_MATH_387")
14361 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14362 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14363 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14364 UNSPEC_FIX_NOTRUNC))]
14365 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14366 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14368 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14369 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14370 (match_operand:MODEF 1 "register_operand" "")]
14371 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14372 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14373 && !flag_trapping_math && !flag_rounding_math"
14375 if (optimize_insn_for_size_p ())
14377 ix86_expand_lround (operand0, operand1);
14381 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14382 (define_insn_and_split "frndintxf2_floor"
14383 [(set (match_operand:XF 0 "register_operand" "")
14384 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14385 UNSPEC_FRNDINT_FLOOR))
14386 (clobber (reg:CC FLAGS_REG))]
14387 "TARGET_USE_FANCY_MATH_387
14388 && flag_unsafe_math_optimizations
14389 && can_create_pseudo_p ()"
14394 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14396 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14397 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14399 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14400 operands[2], operands[3]));
14403 [(set_attr "type" "frndint")
14404 (set_attr "i387_cw" "floor")
14405 (set_attr "mode" "XF")])
14407 (define_insn "frndintxf2_floor_i387"
14408 [(set (match_operand:XF 0 "register_operand" "=f")
14409 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14410 UNSPEC_FRNDINT_FLOOR))
14411 (use (match_operand:HI 2 "memory_operand" "m"))
14412 (use (match_operand:HI 3 "memory_operand" "m"))]
14413 "TARGET_USE_FANCY_MATH_387
14414 && flag_unsafe_math_optimizations"
14415 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14416 [(set_attr "type" "frndint")
14417 (set_attr "i387_cw" "floor")
14418 (set_attr "mode" "XF")])
14420 (define_expand "floorxf2"
14421 [(use (match_operand:XF 0 "register_operand" ""))
14422 (use (match_operand:XF 1 "register_operand" ""))]
14423 "TARGET_USE_FANCY_MATH_387
14424 && flag_unsafe_math_optimizations"
14426 if (optimize_insn_for_size_p ())
14428 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14432 (define_expand "floor<mode>2"
14433 [(use (match_operand:MODEF 0 "register_operand" ""))
14434 (use (match_operand:MODEF 1 "register_operand" ""))]
14435 "(TARGET_USE_FANCY_MATH_387
14436 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14437 || TARGET_MIX_SSE_I387)
14438 && flag_unsafe_math_optimizations)
14439 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14440 && !flag_trapping_math)"
14442 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14443 && !flag_trapping_math
14444 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14446 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14449 emit_insn (gen_sse4_1_round<mode>2
14450 (operands[0], operands[1], GEN_INT (0x01)));
14451 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14452 ix86_expand_floorceil (operand0, operand1, true);
14454 ix86_expand_floorceildf_32 (operand0, operand1, true);
14460 if (optimize_insn_for_size_p ())
14463 op0 = gen_reg_rtx (XFmode);
14464 op1 = gen_reg_rtx (XFmode);
14465 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14466 emit_insn (gen_frndintxf2_floor (op0, op1));
14468 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14473 (define_insn_and_split "*fist<mode>2_floor_1"
14474 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14475 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14476 UNSPEC_FIST_FLOOR))
14477 (clobber (reg:CC FLAGS_REG))]
14478 "TARGET_USE_FANCY_MATH_387
14479 && flag_unsafe_math_optimizations
14480 && can_create_pseudo_p ()"
14485 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14487 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14488 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14489 if (memory_operand (operands[0], VOIDmode))
14490 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14491 operands[2], operands[3]));
14494 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14495 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14496 operands[2], operands[3],
14501 [(set_attr "type" "fistp")
14502 (set_attr "i387_cw" "floor")
14503 (set_attr "mode" "<MODE>")])
14505 (define_insn "fistdi2_floor"
14506 [(set (match_operand:DI 0 "memory_operand" "=m")
14507 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14508 UNSPEC_FIST_FLOOR))
14509 (use (match_operand:HI 2 "memory_operand" "m"))
14510 (use (match_operand:HI 3 "memory_operand" "m"))
14511 (clobber (match_scratch:XF 4 "=&1f"))]
14512 "TARGET_USE_FANCY_MATH_387
14513 && flag_unsafe_math_optimizations"
14514 "* return output_fix_trunc (insn, operands, 0);"
14515 [(set_attr "type" "fistp")
14516 (set_attr "i387_cw" "floor")
14517 (set_attr "mode" "DI")])
14519 (define_insn "fistdi2_floor_with_temp"
14520 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14521 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14522 UNSPEC_FIST_FLOOR))
14523 (use (match_operand:HI 2 "memory_operand" "m,m"))
14524 (use (match_operand:HI 3 "memory_operand" "m,m"))
14525 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14526 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14527 "TARGET_USE_FANCY_MATH_387
14528 && flag_unsafe_math_optimizations"
14530 [(set_attr "type" "fistp")
14531 (set_attr "i387_cw" "floor")
14532 (set_attr "mode" "DI")])
14535 [(set (match_operand:DI 0 "register_operand" "")
14536 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14537 UNSPEC_FIST_FLOOR))
14538 (use (match_operand:HI 2 "memory_operand" ""))
14539 (use (match_operand:HI 3 "memory_operand" ""))
14540 (clobber (match_operand:DI 4 "memory_operand" ""))
14541 (clobber (match_scratch 5 ""))]
14543 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14544 (use (match_dup 2))
14545 (use (match_dup 3))
14546 (clobber (match_dup 5))])
14547 (set (match_dup 0) (match_dup 4))])
14550 [(set (match_operand:DI 0 "memory_operand" "")
14551 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14552 UNSPEC_FIST_FLOOR))
14553 (use (match_operand:HI 2 "memory_operand" ""))
14554 (use (match_operand:HI 3 "memory_operand" ""))
14555 (clobber (match_operand:DI 4 "memory_operand" ""))
14556 (clobber (match_scratch 5 ""))]
14558 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14559 (use (match_dup 2))
14560 (use (match_dup 3))
14561 (clobber (match_dup 5))])])
14563 (define_insn "fist<mode>2_floor"
14564 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14565 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14566 UNSPEC_FIST_FLOOR))
14567 (use (match_operand:HI 2 "memory_operand" "m"))
14568 (use (match_operand:HI 3 "memory_operand" "m"))]
14569 "TARGET_USE_FANCY_MATH_387
14570 && flag_unsafe_math_optimizations"
14571 "* return output_fix_trunc (insn, operands, 0);"
14572 [(set_attr "type" "fistp")
14573 (set_attr "i387_cw" "floor")
14574 (set_attr "mode" "<MODE>")])
14576 (define_insn "fist<mode>2_floor_with_temp"
14577 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14578 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14579 UNSPEC_FIST_FLOOR))
14580 (use (match_operand:HI 2 "memory_operand" "m,m"))
14581 (use (match_operand:HI 3 "memory_operand" "m,m"))
14582 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14583 "TARGET_USE_FANCY_MATH_387
14584 && flag_unsafe_math_optimizations"
14586 [(set_attr "type" "fistp")
14587 (set_attr "i387_cw" "floor")
14588 (set_attr "mode" "<MODE>")])
14591 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14592 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14593 UNSPEC_FIST_FLOOR))
14594 (use (match_operand:HI 2 "memory_operand" ""))
14595 (use (match_operand:HI 3 "memory_operand" ""))
14596 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14598 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14599 UNSPEC_FIST_FLOOR))
14600 (use (match_dup 2))
14601 (use (match_dup 3))])
14602 (set (match_dup 0) (match_dup 4))])
14605 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14606 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14607 UNSPEC_FIST_FLOOR))
14608 (use (match_operand:HI 2 "memory_operand" ""))
14609 (use (match_operand:HI 3 "memory_operand" ""))
14610 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14612 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14613 UNSPEC_FIST_FLOOR))
14614 (use (match_dup 2))
14615 (use (match_dup 3))])])
14617 (define_expand "lfloorxf<mode>2"
14618 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14619 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14620 UNSPEC_FIST_FLOOR))
14621 (clobber (reg:CC FLAGS_REG))])]
14622 "TARGET_USE_FANCY_MATH_387
14623 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14624 && flag_unsafe_math_optimizations")
14626 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14627 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14628 (match_operand:MODEF 1 "register_operand" "")]
14629 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14630 && !flag_trapping_math"
14632 if (TARGET_64BIT && optimize_insn_for_size_p ())
14634 ix86_expand_lfloorceil (operand0, operand1, true);
14638 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14639 (define_insn_and_split "frndintxf2_ceil"
14640 [(set (match_operand:XF 0 "register_operand" "")
14641 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14642 UNSPEC_FRNDINT_CEIL))
14643 (clobber (reg:CC FLAGS_REG))]
14644 "TARGET_USE_FANCY_MATH_387
14645 && flag_unsafe_math_optimizations
14646 && can_create_pseudo_p ()"
14651 ix86_optimize_mode_switching[I387_CEIL] = 1;
14653 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14654 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14656 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14657 operands[2], operands[3]));
14660 [(set_attr "type" "frndint")
14661 (set_attr "i387_cw" "ceil")
14662 (set_attr "mode" "XF")])
14664 (define_insn "frndintxf2_ceil_i387"
14665 [(set (match_operand:XF 0 "register_operand" "=f")
14666 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14667 UNSPEC_FRNDINT_CEIL))
14668 (use (match_operand:HI 2 "memory_operand" "m"))
14669 (use (match_operand:HI 3 "memory_operand" "m"))]
14670 "TARGET_USE_FANCY_MATH_387
14671 && flag_unsafe_math_optimizations"
14672 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14673 [(set_attr "type" "frndint")
14674 (set_attr "i387_cw" "ceil")
14675 (set_attr "mode" "XF")])
14677 (define_expand "ceilxf2"
14678 [(use (match_operand:XF 0 "register_operand" ""))
14679 (use (match_operand:XF 1 "register_operand" ""))]
14680 "TARGET_USE_FANCY_MATH_387
14681 && flag_unsafe_math_optimizations"
14683 if (optimize_insn_for_size_p ())
14685 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14689 (define_expand "ceil<mode>2"
14690 [(use (match_operand:MODEF 0 "register_operand" ""))
14691 (use (match_operand:MODEF 1 "register_operand" ""))]
14692 "(TARGET_USE_FANCY_MATH_387
14693 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14694 || TARGET_MIX_SSE_I387)
14695 && flag_unsafe_math_optimizations)
14696 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14697 && !flag_trapping_math)"
14699 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14700 && !flag_trapping_math
14701 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14704 emit_insn (gen_sse4_1_round<mode>2
14705 (operands[0], operands[1], GEN_INT (0x02)));
14706 else if (optimize_insn_for_size_p ())
14708 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14709 ix86_expand_floorceil (operand0, operand1, false);
14711 ix86_expand_floorceildf_32 (operand0, operand1, false);
14717 if (optimize_insn_for_size_p ())
14720 op0 = gen_reg_rtx (XFmode);
14721 op1 = gen_reg_rtx (XFmode);
14722 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14723 emit_insn (gen_frndintxf2_ceil (op0, op1));
14725 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14730 (define_insn_and_split "*fist<mode>2_ceil_1"
14731 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14732 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14734 (clobber (reg:CC FLAGS_REG))]
14735 "TARGET_USE_FANCY_MATH_387
14736 && flag_unsafe_math_optimizations
14737 && can_create_pseudo_p ()"
14742 ix86_optimize_mode_switching[I387_CEIL] = 1;
14744 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14745 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14746 if (memory_operand (operands[0], VOIDmode))
14747 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14748 operands[2], operands[3]));
14751 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14752 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14753 operands[2], operands[3],
14758 [(set_attr "type" "fistp")
14759 (set_attr "i387_cw" "ceil")
14760 (set_attr "mode" "<MODE>")])
14762 (define_insn "fistdi2_ceil"
14763 [(set (match_operand:DI 0 "memory_operand" "=m")
14764 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14766 (use (match_operand:HI 2 "memory_operand" "m"))
14767 (use (match_operand:HI 3 "memory_operand" "m"))
14768 (clobber (match_scratch:XF 4 "=&1f"))]
14769 "TARGET_USE_FANCY_MATH_387
14770 && flag_unsafe_math_optimizations"
14771 "* return output_fix_trunc (insn, operands, 0);"
14772 [(set_attr "type" "fistp")
14773 (set_attr "i387_cw" "ceil")
14774 (set_attr "mode" "DI")])
14776 (define_insn "fistdi2_ceil_with_temp"
14777 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14778 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14780 (use (match_operand:HI 2 "memory_operand" "m,m"))
14781 (use (match_operand:HI 3 "memory_operand" "m,m"))
14782 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14783 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14784 "TARGET_USE_FANCY_MATH_387
14785 && flag_unsafe_math_optimizations"
14787 [(set_attr "type" "fistp")
14788 (set_attr "i387_cw" "ceil")
14789 (set_attr "mode" "DI")])
14792 [(set (match_operand:DI 0 "register_operand" "")
14793 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14795 (use (match_operand:HI 2 "memory_operand" ""))
14796 (use (match_operand:HI 3 "memory_operand" ""))
14797 (clobber (match_operand:DI 4 "memory_operand" ""))
14798 (clobber (match_scratch 5 ""))]
14800 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14801 (use (match_dup 2))
14802 (use (match_dup 3))
14803 (clobber (match_dup 5))])
14804 (set (match_dup 0) (match_dup 4))])
14807 [(set (match_operand:DI 0 "memory_operand" "")
14808 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14810 (use (match_operand:HI 2 "memory_operand" ""))
14811 (use (match_operand:HI 3 "memory_operand" ""))
14812 (clobber (match_operand:DI 4 "memory_operand" ""))
14813 (clobber (match_scratch 5 ""))]
14815 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14816 (use (match_dup 2))
14817 (use (match_dup 3))
14818 (clobber (match_dup 5))])])
14820 (define_insn "fist<mode>2_ceil"
14821 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14822 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14824 (use (match_operand:HI 2 "memory_operand" "m"))
14825 (use (match_operand:HI 3 "memory_operand" "m"))]
14826 "TARGET_USE_FANCY_MATH_387
14827 && flag_unsafe_math_optimizations"
14828 "* return output_fix_trunc (insn, operands, 0);"
14829 [(set_attr "type" "fistp")
14830 (set_attr "i387_cw" "ceil")
14831 (set_attr "mode" "<MODE>")])
14833 (define_insn "fist<mode>2_ceil_with_temp"
14834 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14835 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14837 (use (match_operand:HI 2 "memory_operand" "m,m"))
14838 (use (match_operand:HI 3 "memory_operand" "m,m"))
14839 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14840 "TARGET_USE_FANCY_MATH_387
14841 && flag_unsafe_math_optimizations"
14843 [(set_attr "type" "fistp")
14844 (set_attr "i387_cw" "ceil")
14845 (set_attr "mode" "<MODE>")])
14848 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14849 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14851 (use (match_operand:HI 2 "memory_operand" ""))
14852 (use (match_operand:HI 3 "memory_operand" ""))
14853 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14855 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14857 (use (match_dup 2))
14858 (use (match_dup 3))])
14859 (set (match_dup 0) (match_dup 4))])
14862 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14863 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14865 (use (match_operand:HI 2 "memory_operand" ""))
14866 (use (match_operand:HI 3 "memory_operand" ""))
14867 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14869 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14871 (use (match_dup 2))
14872 (use (match_dup 3))])])
14874 (define_expand "lceilxf<mode>2"
14875 [(parallel [(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 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14881 && flag_unsafe_math_optimizations")
14883 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14884 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14885 (match_operand:MODEF 1 "register_operand" "")]
14886 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14887 && !flag_trapping_math"
14889 ix86_expand_lfloorceil (operand0, operand1, false);
14893 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14894 (define_insn_and_split "frndintxf2_trunc"
14895 [(set (match_operand:XF 0 "register_operand" "")
14896 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14897 UNSPEC_FRNDINT_TRUNC))
14898 (clobber (reg:CC FLAGS_REG))]
14899 "TARGET_USE_FANCY_MATH_387
14900 && flag_unsafe_math_optimizations
14901 && can_create_pseudo_p ()"
14906 ix86_optimize_mode_switching[I387_TRUNC] = 1;
14908 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14909 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14911 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14912 operands[2], operands[3]));
14915 [(set_attr "type" "frndint")
14916 (set_attr "i387_cw" "trunc")
14917 (set_attr "mode" "XF")])
14919 (define_insn "frndintxf2_trunc_i387"
14920 [(set (match_operand:XF 0 "register_operand" "=f")
14921 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14922 UNSPEC_FRNDINT_TRUNC))
14923 (use (match_operand:HI 2 "memory_operand" "m"))
14924 (use (match_operand:HI 3 "memory_operand" "m"))]
14925 "TARGET_USE_FANCY_MATH_387
14926 && flag_unsafe_math_optimizations"
14927 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14928 [(set_attr "type" "frndint")
14929 (set_attr "i387_cw" "trunc")
14930 (set_attr "mode" "XF")])
14932 (define_expand "btruncxf2"
14933 [(use (match_operand:XF 0 "register_operand" ""))
14934 (use (match_operand:XF 1 "register_operand" ""))]
14935 "TARGET_USE_FANCY_MATH_387
14936 && flag_unsafe_math_optimizations"
14938 if (optimize_insn_for_size_p ())
14940 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14944 (define_expand "btrunc<mode>2"
14945 [(use (match_operand:MODEF 0 "register_operand" ""))
14946 (use (match_operand:MODEF 1 "register_operand" ""))]
14947 "(TARGET_USE_FANCY_MATH_387
14948 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14949 || TARGET_MIX_SSE_I387)
14950 && flag_unsafe_math_optimizations)
14951 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14952 && !flag_trapping_math)"
14954 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14955 && !flag_trapping_math
14956 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14959 emit_insn (gen_sse4_1_round<mode>2
14960 (operands[0], operands[1], GEN_INT (0x03)));
14961 else if (optimize_insn_for_size_p ())
14963 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14964 ix86_expand_trunc (operand0, operand1);
14966 ix86_expand_truncdf_32 (operand0, operand1);
14972 if (optimize_insn_for_size_p ())
14975 op0 = gen_reg_rtx (XFmode);
14976 op1 = gen_reg_rtx (XFmode);
14977 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14978 emit_insn (gen_frndintxf2_trunc (op0, op1));
14980 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14985 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14986 (define_insn_and_split "frndintxf2_mask_pm"
14987 [(set (match_operand:XF 0 "register_operand" "")
14988 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14989 UNSPEC_FRNDINT_MASK_PM))
14990 (clobber (reg:CC FLAGS_REG))]
14991 "TARGET_USE_FANCY_MATH_387
14992 && flag_unsafe_math_optimizations
14993 && can_create_pseudo_p ()"
14998 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15000 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15001 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15003 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15004 operands[2], operands[3]));
15007 [(set_attr "type" "frndint")
15008 (set_attr "i387_cw" "mask_pm")
15009 (set_attr "mode" "XF")])
15011 (define_insn "frndintxf2_mask_pm_i387"
15012 [(set (match_operand:XF 0 "register_operand" "=f")
15013 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15014 UNSPEC_FRNDINT_MASK_PM))
15015 (use (match_operand:HI 2 "memory_operand" "m"))
15016 (use (match_operand:HI 3 "memory_operand" "m"))]
15017 "TARGET_USE_FANCY_MATH_387
15018 && flag_unsafe_math_optimizations"
15019 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15020 [(set_attr "type" "frndint")
15021 (set_attr "i387_cw" "mask_pm")
15022 (set_attr "mode" "XF")])
15024 (define_expand "nearbyintxf2"
15025 [(use (match_operand:XF 0 "register_operand" ""))
15026 (use (match_operand:XF 1 "register_operand" ""))]
15027 "TARGET_USE_FANCY_MATH_387
15028 && flag_unsafe_math_optimizations"
15030 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15034 (define_expand "nearbyint<mode>2"
15035 [(use (match_operand:MODEF 0 "register_operand" ""))
15036 (use (match_operand:MODEF 1 "register_operand" ""))]
15037 "TARGET_USE_FANCY_MATH_387
15038 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15039 || TARGET_MIX_SSE_I387)
15040 && flag_unsafe_math_optimizations"
15042 rtx op0 = gen_reg_rtx (XFmode);
15043 rtx op1 = gen_reg_rtx (XFmode);
15045 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15046 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15048 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15052 (define_insn "fxam<mode>2_i387"
15053 [(set (match_operand:HI 0 "register_operand" "=a")
15055 [(match_operand:X87MODEF 1 "register_operand" "f")]
15057 "TARGET_USE_FANCY_MATH_387"
15058 "fxam\n\tfnstsw\t%0"
15059 [(set_attr "type" "multi")
15060 (set_attr "length" "4")
15061 (set_attr "unit" "i387")
15062 (set_attr "mode" "<MODE>")])
15064 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15065 [(set (match_operand:HI 0 "register_operand" "")
15067 [(match_operand:MODEF 1 "memory_operand" "")]
15069 "TARGET_USE_FANCY_MATH_387
15070 && can_create_pseudo_p ()"
15073 [(set (match_dup 2)(match_dup 1))
15075 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15077 operands[2] = gen_reg_rtx (<MODE>mode);
15079 MEM_VOLATILE_P (operands[1]) = 1;
15081 [(set_attr "type" "multi")
15082 (set_attr "unit" "i387")
15083 (set_attr "mode" "<MODE>")])
15085 (define_expand "isinfxf2"
15086 [(use (match_operand:SI 0 "register_operand" ""))
15087 (use (match_operand:XF 1 "register_operand" ""))]
15088 "TARGET_USE_FANCY_MATH_387
15089 && TARGET_C99_FUNCTIONS"
15091 rtx mask = GEN_INT (0x45);
15092 rtx val = GEN_INT (0x05);
15096 rtx scratch = gen_reg_rtx (HImode);
15097 rtx res = gen_reg_rtx (QImode);
15099 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15101 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15102 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15103 cond = gen_rtx_fmt_ee (EQ, QImode,
15104 gen_rtx_REG (CCmode, FLAGS_REG),
15106 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15107 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15111 (define_expand "isinf<mode>2"
15112 [(use (match_operand:SI 0 "register_operand" ""))
15113 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15114 "TARGET_USE_FANCY_MATH_387
15115 && TARGET_C99_FUNCTIONS
15116 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15118 rtx mask = GEN_INT (0x45);
15119 rtx val = GEN_INT (0x05);
15123 rtx scratch = gen_reg_rtx (HImode);
15124 rtx res = gen_reg_rtx (QImode);
15126 /* Remove excess precision by forcing value through memory. */
15127 if (memory_operand (operands[1], VOIDmode))
15128 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15131 enum ix86_stack_slot slot = (virtuals_instantiated
15134 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15136 emit_move_insn (temp, operands[1]);
15137 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15140 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15141 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15142 cond = gen_rtx_fmt_ee (EQ, QImode,
15143 gen_rtx_REG (CCmode, FLAGS_REG),
15145 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15146 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15150 (define_expand "signbitxf2"
15151 [(use (match_operand:SI 0 "register_operand" ""))
15152 (use (match_operand:XF 1 "register_operand" ""))]
15153 "TARGET_USE_FANCY_MATH_387"
15155 rtx scratch = gen_reg_rtx (HImode);
15157 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15158 emit_insn (gen_andsi3 (operands[0],
15159 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15163 (define_insn "movmsk_df"
15164 [(set (match_operand:SI 0 "register_operand" "=r")
15166 [(match_operand:DF 1 "register_operand" "x")]
15168 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15169 "%vmovmskpd\t{%1, %0|%0, %1}"
15170 [(set_attr "type" "ssemov")
15171 (set_attr "prefix" "maybe_vex")
15172 (set_attr "mode" "DF")])
15174 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15175 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15176 (define_expand "signbitdf2"
15177 [(use (match_operand:SI 0 "register_operand" ""))
15178 (use (match_operand:DF 1 "register_operand" ""))]
15179 "TARGET_USE_FANCY_MATH_387
15180 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15182 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15184 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15185 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15189 rtx scratch = gen_reg_rtx (HImode);
15191 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15192 emit_insn (gen_andsi3 (operands[0],
15193 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15198 (define_expand "signbitsf2"
15199 [(use (match_operand:SI 0 "register_operand" ""))
15200 (use (match_operand:SF 1 "register_operand" ""))]
15201 "TARGET_USE_FANCY_MATH_387
15202 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15204 rtx scratch = gen_reg_rtx (HImode);
15206 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15207 emit_insn (gen_andsi3 (operands[0],
15208 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15212 ;; Block operation instructions
15215 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15218 [(set_attr "length" "1")
15219 (set_attr "length_immediate" "0")
15220 (set_attr "modrm" "0")])
15222 (define_expand "movmem<mode>"
15223 [(use (match_operand:BLK 0 "memory_operand" ""))
15224 (use (match_operand:BLK 1 "memory_operand" ""))
15225 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15226 (use (match_operand:SWI48 3 "const_int_operand" ""))
15227 (use (match_operand:SI 4 "const_int_operand" ""))
15228 (use (match_operand:SI 5 "const_int_operand" ""))]
15231 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15232 operands[4], operands[5]))
15238 ;; Most CPUs don't like single string operations
15239 ;; Handle this case here to simplify previous expander.
15241 (define_expand "strmov"
15242 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15243 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15244 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15245 (clobber (reg:CC FLAGS_REG))])
15246 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15247 (clobber (reg:CC FLAGS_REG))])]
15250 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15252 /* If .md ever supports :P for Pmode, these can be directly
15253 in the pattern above. */
15254 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15255 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15257 /* Can't use this if the user has appropriated esi or edi. */
15258 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15259 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15261 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15262 operands[2], operands[3],
15263 operands[5], operands[6]));
15267 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15270 (define_expand "strmov_singleop"
15271 [(parallel [(set (match_operand 1 "memory_operand" "")
15272 (match_operand 3 "memory_operand" ""))
15273 (set (match_operand 0 "register_operand" "")
15274 (match_operand 4 "" ""))
15275 (set (match_operand 2 "register_operand" "")
15276 (match_operand 5 "" ""))])]
15278 "ix86_current_function_needs_cld = 1;")
15280 (define_insn "*strmovdi_rex_1"
15281 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15282 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15283 (set (match_operand:DI 0 "register_operand" "=D")
15284 (plus:DI (match_dup 2)
15286 (set (match_operand:DI 1 "register_operand" "=S")
15287 (plus:DI (match_dup 3)
15291 [(set_attr "type" "str")
15292 (set_attr "memory" "both")
15293 (set_attr "mode" "DI")])
15295 (define_insn "*strmovsi_1"
15296 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15297 (mem:SI (match_operand:P 3 "register_operand" "1")))
15298 (set (match_operand:P 0 "register_operand" "=D")
15299 (plus:P (match_dup 2)
15301 (set (match_operand:P 1 "register_operand" "=S")
15302 (plus:P (match_dup 3)
15306 [(set_attr "type" "str")
15307 (set_attr "memory" "both")
15308 (set_attr "mode" "SI")])
15310 (define_insn "*strmovhi_1"
15311 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15312 (mem:HI (match_operand:P 3 "register_operand" "1")))
15313 (set (match_operand:P 0 "register_operand" "=D")
15314 (plus:P (match_dup 2)
15316 (set (match_operand:P 1 "register_operand" "=S")
15317 (plus:P (match_dup 3)
15321 [(set_attr "type" "str")
15322 (set_attr "memory" "both")
15323 (set_attr "mode" "HI")])
15325 (define_insn "*strmovqi_1"
15326 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15327 (mem:QI (match_operand:P 3 "register_operand" "1")))
15328 (set (match_operand:P 0 "register_operand" "=D")
15329 (plus:P (match_dup 2)
15331 (set (match_operand:P 1 "register_operand" "=S")
15332 (plus:P (match_dup 3)
15336 [(set_attr "type" "str")
15337 (set_attr "memory" "both")
15338 (set (attr "prefix_rex")
15340 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15342 (const_string "*")))
15343 (set_attr "mode" "QI")])
15345 (define_expand "rep_mov"
15346 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15347 (set (match_operand 0 "register_operand" "")
15348 (match_operand 5 "" ""))
15349 (set (match_operand 2 "register_operand" "")
15350 (match_operand 6 "" ""))
15351 (set (match_operand 1 "memory_operand" "")
15352 (match_operand 3 "memory_operand" ""))
15353 (use (match_dup 4))])]
15355 "ix86_current_function_needs_cld = 1;")
15357 (define_insn "*rep_movdi_rex64"
15358 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15359 (set (match_operand:DI 0 "register_operand" "=D")
15360 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15362 (match_operand:DI 3 "register_operand" "0")))
15363 (set (match_operand:DI 1 "register_operand" "=S")
15364 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15365 (match_operand:DI 4 "register_operand" "1")))
15366 (set (mem:BLK (match_dup 3))
15367 (mem:BLK (match_dup 4)))
15368 (use (match_dup 5))]
15371 [(set_attr "type" "str")
15372 (set_attr "prefix_rep" "1")
15373 (set_attr "memory" "both")
15374 (set_attr "mode" "DI")])
15376 (define_insn "*rep_movsi"
15377 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15378 (set (match_operand:P 0 "register_operand" "=D")
15379 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15381 (match_operand:P 3 "register_operand" "0")))
15382 (set (match_operand:P 1 "register_operand" "=S")
15383 (plus:P (ashift:P (match_dup 5) (const_int 2))
15384 (match_operand:P 4 "register_operand" "1")))
15385 (set (mem:BLK (match_dup 3))
15386 (mem:BLK (match_dup 4)))
15387 (use (match_dup 5))]
15389 "rep{%;} movs{l|d}"
15390 [(set_attr "type" "str")
15391 (set_attr "prefix_rep" "1")
15392 (set_attr "memory" "both")
15393 (set_attr "mode" "SI")])
15395 (define_insn "*rep_movqi"
15396 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15397 (set (match_operand:P 0 "register_operand" "=D")
15398 (plus:P (match_operand:P 3 "register_operand" "0")
15399 (match_operand:P 5 "register_operand" "2")))
15400 (set (match_operand:P 1 "register_operand" "=S")
15401 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15402 (set (mem:BLK (match_dup 3))
15403 (mem:BLK (match_dup 4)))
15404 (use (match_dup 5))]
15407 [(set_attr "type" "str")
15408 (set_attr "prefix_rep" "1")
15409 (set_attr "memory" "both")
15410 (set_attr "mode" "QI")])
15412 (define_expand "setmem<mode>"
15413 [(use (match_operand:BLK 0 "memory_operand" ""))
15414 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15415 (use (match_operand 2 "const_int_operand" ""))
15416 (use (match_operand 3 "const_int_operand" ""))
15417 (use (match_operand:SI 4 "const_int_operand" ""))
15418 (use (match_operand:SI 5 "const_int_operand" ""))]
15421 if (ix86_expand_setmem (operands[0], operands[1],
15422 operands[2], operands[3],
15423 operands[4], operands[5]))
15429 ;; Most CPUs don't like single string operations
15430 ;; Handle this case here to simplify previous expander.
15432 (define_expand "strset"
15433 [(set (match_operand 1 "memory_operand" "")
15434 (match_operand 2 "register_operand" ""))
15435 (parallel [(set (match_operand 0 "register_operand" "")
15437 (clobber (reg:CC FLAGS_REG))])]
15440 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15441 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15443 /* If .md ever supports :P for Pmode, this can be directly
15444 in the pattern above. */
15445 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15446 GEN_INT (GET_MODE_SIZE (GET_MODE
15448 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15450 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15456 (define_expand "strset_singleop"
15457 [(parallel [(set (match_operand 1 "memory_operand" "")
15458 (match_operand 2 "register_operand" ""))
15459 (set (match_operand 0 "register_operand" "")
15460 (match_operand 3 "" ""))])]
15462 "ix86_current_function_needs_cld = 1;")
15464 (define_insn "*strsetdi_rex_1"
15465 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15466 (match_operand:DI 2 "register_operand" "a"))
15467 (set (match_operand:DI 0 "register_operand" "=D")
15468 (plus:DI (match_dup 1)
15472 [(set_attr "type" "str")
15473 (set_attr "memory" "store")
15474 (set_attr "mode" "DI")])
15476 (define_insn "*strsetsi_1"
15477 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15478 (match_operand:SI 2 "register_operand" "a"))
15479 (set (match_operand:P 0 "register_operand" "=D")
15480 (plus:P (match_dup 1)
15484 [(set_attr "type" "str")
15485 (set_attr "memory" "store")
15486 (set_attr "mode" "SI")])
15488 (define_insn "*strsethi_1"
15489 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15490 (match_operand:HI 2 "register_operand" "a"))
15491 (set (match_operand:P 0 "register_operand" "=D")
15492 (plus:P (match_dup 1)
15496 [(set_attr "type" "str")
15497 (set_attr "memory" "store")
15498 (set_attr "mode" "HI")])
15500 (define_insn "*strsetqi_1"
15501 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15502 (match_operand:QI 2 "register_operand" "a"))
15503 (set (match_operand:P 0 "register_operand" "=D")
15504 (plus:P (match_dup 1)
15508 [(set_attr "type" "str")
15509 (set_attr "memory" "store")
15510 (set (attr "prefix_rex")
15512 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15514 (const_string "*")))
15515 (set_attr "mode" "QI")])
15517 (define_expand "rep_stos"
15518 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15519 (set (match_operand 0 "register_operand" "")
15520 (match_operand 4 "" ""))
15521 (set (match_operand 2 "memory_operand" "") (const_int 0))
15522 (use (match_operand 3 "register_operand" ""))
15523 (use (match_dup 1))])]
15525 "ix86_current_function_needs_cld = 1;")
15527 (define_insn "*rep_stosdi_rex64"
15528 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15529 (set (match_operand:DI 0 "register_operand" "=D")
15530 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15532 (match_operand:DI 3 "register_operand" "0")))
15533 (set (mem:BLK (match_dup 3))
15535 (use (match_operand:DI 2 "register_operand" "a"))
15536 (use (match_dup 4))]
15539 [(set_attr "type" "str")
15540 (set_attr "prefix_rep" "1")
15541 (set_attr "memory" "store")
15542 (set_attr "mode" "DI")])
15544 (define_insn "*rep_stossi"
15545 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15546 (set (match_operand:P 0 "register_operand" "=D")
15547 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15549 (match_operand:P 3 "register_operand" "0")))
15550 (set (mem:BLK (match_dup 3))
15552 (use (match_operand:SI 2 "register_operand" "a"))
15553 (use (match_dup 4))]
15555 "rep{%;} stos{l|d}"
15556 [(set_attr "type" "str")
15557 (set_attr "prefix_rep" "1")
15558 (set_attr "memory" "store")
15559 (set_attr "mode" "SI")])
15561 (define_insn "*rep_stosqi"
15562 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15563 (set (match_operand:P 0 "register_operand" "=D")
15564 (plus:P (match_operand:P 3 "register_operand" "0")
15565 (match_operand:P 4 "register_operand" "1")))
15566 (set (mem:BLK (match_dup 3))
15568 (use (match_operand:QI 2 "register_operand" "a"))
15569 (use (match_dup 4))]
15572 [(set_attr "type" "str")
15573 (set_attr "prefix_rep" "1")
15574 (set_attr "memory" "store")
15575 (set (attr "prefix_rex")
15577 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15579 (const_string "*")))
15580 (set_attr "mode" "QI")])
15582 (define_expand "cmpstrnsi"
15583 [(set (match_operand:SI 0 "register_operand" "")
15584 (compare:SI (match_operand:BLK 1 "general_operand" "")
15585 (match_operand:BLK 2 "general_operand" "")))
15586 (use (match_operand 3 "general_operand" ""))
15587 (use (match_operand 4 "immediate_operand" ""))]
15590 rtx addr1, addr2, out, outlow, count, countreg, align;
15592 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15595 /* Can't use this if the user has appropriated esi or edi. */
15596 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15601 out = gen_reg_rtx (SImode);
15603 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15604 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15605 if (addr1 != XEXP (operands[1], 0))
15606 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15607 if (addr2 != XEXP (operands[2], 0))
15608 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15610 count = operands[3];
15611 countreg = ix86_zero_extend_to_Pmode (count);
15613 /* %%% Iff we are testing strict equality, we can use known alignment
15614 to good advantage. This may be possible with combine, particularly
15615 once cc0 is dead. */
15616 align = operands[4];
15618 if (CONST_INT_P (count))
15620 if (INTVAL (count) == 0)
15622 emit_move_insn (operands[0], const0_rtx);
15625 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15626 operands[1], operands[2]));
15630 rtx (*gen_cmp) (rtx, rtx);
15632 gen_cmp = (TARGET_64BIT
15633 ? gen_cmpdi_1 : gen_cmpsi_1);
15635 emit_insn (gen_cmp (countreg, countreg));
15636 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15637 operands[1], operands[2]));
15640 outlow = gen_lowpart (QImode, out);
15641 emit_insn (gen_cmpintqi (outlow));
15642 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15644 if (operands[0] != out)
15645 emit_move_insn (operands[0], out);
15650 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15652 (define_expand "cmpintqi"
15653 [(set (match_dup 1)
15654 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15656 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15657 (parallel [(set (match_operand:QI 0 "register_operand" "")
15658 (minus:QI (match_dup 1)
15660 (clobber (reg:CC FLAGS_REG))])]
15663 operands[1] = gen_reg_rtx (QImode);
15664 operands[2] = gen_reg_rtx (QImode);
15667 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15668 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15670 (define_expand "cmpstrnqi_nz_1"
15671 [(parallel [(set (reg:CC FLAGS_REG)
15672 (compare:CC (match_operand 4 "memory_operand" "")
15673 (match_operand 5 "memory_operand" "")))
15674 (use (match_operand 2 "register_operand" ""))
15675 (use (match_operand:SI 3 "immediate_operand" ""))
15676 (clobber (match_operand 0 "register_operand" ""))
15677 (clobber (match_operand 1 "register_operand" ""))
15678 (clobber (match_dup 2))])]
15680 "ix86_current_function_needs_cld = 1;")
15682 (define_insn "*cmpstrnqi_nz_1"
15683 [(set (reg:CC FLAGS_REG)
15684 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15685 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15686 (use (match_operand:P 6 "register_operand" "2"))
15687 (use (match_operand:SI 3 "immediate_operand" "i"))
15688 (clobber (match_operand:P 0 "register_operand" "=S"))
15689 (clobber (match_operand:P 1 "register_operand" "=D"))
15690 (clobber (match_operand:P 2 "register_operand" "=c"))]
15693 [(set_attr "type" "str")
15694 (set_attr "mode" "QI")
15695 (set (attr "prefix_rex")
15697 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15699 (const_string "*")))
15700 (set_attr "prefix_rep" "1")])
15702 ;; The same, but the count is not known to not be zero.
15704 (define_expand "cmpstrnqi_1"
15705 [(parallel [(set (reg:CC FLAGS_REG)
15706 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15708 (compare:CC (match_operand 4 "memory_operand" "")
15709 (match_operand 5 "memory_operand" ""))
15711 (use (match_operand:SI 3 "immediate_operand" ""))
15712 (use (reg:CC FLAGS_REG))
15713 (clobber (match_operand 0 "register_operand" ""))
15714 (clobber (match_operand 1 "register_operand" ""))
15715 (clobber (match_dup 2))])]
15717 "ix86_current_function_needs_cld = 1;")
15719 (define_insn "*cmpstrnqi_1"
15720 [(set (reg:CC FLAGS_REG)
15721 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15723 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15724 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15726 (use (match_operand:SI 3 "immediate_operand" "i"))
15727 (use (reg:CC FLAGS_REG))
15728 (clobber (match_operand:P 0 "register_operand" "=S"))
15729 (clobber (match_operand:P 1 "register_operand" "=D"))
15730 (clobber (match_operand:P 2 "register_operand" "=c"))]
15733 [(set_attr "type" "str")
15734 (set_attr "mode" "QI")
15735 (set (attr "prefix_rex")
15737 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15739 (const_string "*")))
15740 (set_attr "prefix_rep" "1")])
15742 (define_expand "strlen<mode>"
15743 [(set (match_operand:SWI48x 0 "register_operand" "")
15744 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15745 (match_operand:QI 2 "immediate_operand" "")
15746 (match_operand 3 "immediate_operand" "")]
15750 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15756 (define_expand "strlenqi_1"
15757 [(parallel [(set (match_operand 0 "register_operand" "")
15758 (match_operand 2 "" ""))
15759 (clobber (match_operand 1 "register_operand" ""))
15760 (clobber (reg:CC FLAGS_REG))])]
15762 "ix86_current_function_needs_cld = 1;")
15764 (define_insn "*strlenqi_1"
15765 [(set (match_operand:P 0 "register_operand" "=&c")
15766 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15767 (match_operand:QI 2 "register_operand" "a")
15768 (match_operand:P 3 "immediate_operand" "i")
15769 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15770 (clobber (match_operand:P 1 "register_operand" "=D"))
15771 (clobber (reg:CC FLAGS_REG))]
15774 [(set_attr "type" "str")
15775 (set_attr "mode" "QI")
15776 (set (attr "prefix_rex")
15778 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15780 (const_string "*")))
15781 (set_attr "prefix_rep" "1")])
15783 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15784 ;; handled in combine, but it is not currently up to the task.
15785 ;; When used for their truth value, the cmpstrn* expanders generate
15794 ;; The intermediate three instructions are unnecessary.
15796 ;; This one handles cmpstrn*_nz_1...
15799 (set (reg:CC FLAGS_REG)
15800 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15801 (mem:BLK (match_operand 5 "register_operand" ""))))
15802 (use (match_operand 6 "register_operand" ""))
15803 (use (match_operand:SI 3 "immediate_operand" ""))
15804 (clobber (match_operand 0 "register_operand" ""))
15805 (clobber (match_operand 1 "register_operand" ""))
15806 (clobber (match_operand 2 "register_operand" ""))])
15807 (set (match_operand:QI 7 "register_operand" "")
15808 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15809 (set (match_operand:QI 8 "register_operand" "")
15810 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15811 (set (reg FLAGS_REG)
15812 (compare (match_dup 7) (match_dup 8)))
15814 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15816 (set (reg:CC FLAGS_REG)
15817 (compare:CC (mem:BLK (match_dup 4))
15818 (mem:BLK (match_dup 5))))
15819 (use (match_dup 6))
15820 (use (match_dup 3))
15821 (clobber (match_dup 0))
15822 (clobber (match_dup 1))
15823 (clobber (match_dup 2))])])
15825 ;; ...and this one handles cmpstrn*_1.
15828 (set (reg:CC FLAGS_REG)
15829 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15831 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15832 (mem:BLK (match_operand 5 "register_operand" "")))
15834 (use (match_operand:SI 3 "immediate_operand" ""))
15835 (use (reg:CC FLAGS_REG))
15836 (clobber (match_operand 0 "register_operand" ""))
15837 (clobber (match_operand 1 "register_operand" ""))
15838 (clobber (match_operand 2 "register_operand" ""))])
15839 (set (match_operand:QI 7 "register_operand" "")
15840 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15841 (set (match_operand:QI 8 "register_operand" "")
15842 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15843 (set (reg FLAGS_REG)
15844 (compare (match_dup 7) (match_dup 8)))
15846 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15848 (set (reg:CC FLAGS_REG)
15849 (if_then_else:CC (ne (match_dup 6)
15851 (compare:CC (mem:BLK (match_dup 4))
15852 (mem:BLK (match_dup 5)))
15854 (use (match_dup 3))
15855 (use (reg:CC FLAGS_REG))
15856 (clobber (match_dup 0))
15857 (clobber (match_dup 1))
15858 (clobber (match_dup 2))])])
15860 ;; Conditional move instructions.
15862 (define_expand "mov<mode>cc"
15863 [(set (match_operand:SWIM 0 "register_operand" "")
15864 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15865 (match_operand:SWIM 2 "general_operand" "")
15866 (match_operand:SWIM 3 "general_operand" "")))]
15868 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15870 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15871 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15872 ;; So just document what we're doing explicitly.
15874 (define_expand "x86_mov<mode>cc_0_m1"
15876 [(set (match_operand:SWI48 0 "register_operand" "")
15877 (if_then_else:SWI48
15878 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15879 [(match_operand 1 "flags_reg_operand" "")
15883 (clobber (reg:CC FLAGS_REG))])])
15885 (define_insn "*x86_mov<mode>cc_0_m1"
15886 [(set (match_operand:SWI48 0 "register_operand" "=r")
15887 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15888 [(reg FLAGS_REG) (const_int 0)])
15891 (clobber (reg:CC FLAGS_REG))]
15893 "sbb{<imodesuffix>}\t%0, %0"
15894 ; Since we don't have the proper number of operands for an alu insn,
15895 ; fill in all the blanks.
15896 [(set_attr "type" "alu")
15897 (set_attr "use_carry" "1")
15898 (set_attr "pent_pair" "pu")
15899 (set_attr "memory" "none")
15900 (set_attr "imm_disp" "false")
15901 (set_attr "mode" "<MODE>")
15902 (set_attr "length_immediate" "0")])
15904 (define_insn "*x86_mov<mode>cc_0_m1_se"
15905 [(set (match_operand:SWI48 0 "register_operand" "=r")
15906 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15907 [(reg FLAGS_REG) (const_int 0)])
15910 (clobber (reg:CC FLAGS_REG))]
15912 "sbb{<imodesuffix>}\t%0, %0"
15913 [(set_attr "type" "alu")
15914 (set_attr "use_carry" "1")
15915 (set_attr "pent_pair" "pu")
15916 (set_attr "memory" "none")
15917 (set_attr "imm_disp" "false")
15918 (set_attr "mode" "<MODE>")
15919 (set_attr "length_immediate" "0")])
15921 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15922 [(set (match_operand:SWI48 0 "register_operand" "=r")
15923 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15924 [(reg FLAGS_REG) (const_int 0)])))]
15926 "sbb{<imodesuffix>}\t%0, %0"
15927 [(set_attr "type" "alu")
15928 (set_attr "use_carry" "1")
15929 (set_attr "pent_pair" "pu")
15930 (set_attr "memory" "none")
15931 (set_attr "imm_disp" "false")
15932 (set_attr "mode" "<MODE>")
15933 (set_attr "length_immediate" "0")])
15935 (define_insn "*mov<mode>cc_noc"
15936 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
15937 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15938 [(reg FLAGS_REG) (const_int 0)])
15939 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
15940 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
15941 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15943 cmov%O2%C1\t{%2, %0|%0, %2}
15944 cmov%O2%c1\t{%3, %0|%0, %3}"
15945 [(set_attr "type" "icmov")
15946 (set_attr "mode" "<MODE>")])
15948 (define_insn_and_split "*movqicc_noc"
15949 [(set (match_operand:QI 0 "register_operand" "=r,r")
15950 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
15951 [(match_operand 4 "flags_reg_operand" "")
15953 (match_operand:QI 2 "register_operand" "r,0")
15954 (match_operand:QI 3 "register_operand" "0,r")))]
15955 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
15957 "&& reload_completed"
15958 [(set (match_dup 0)
15959 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15962 "operands[0] = gen_lowpart (SImode, operands[0]);
15963 operands[2] = gen_lowpart (SImode, operands[2]);
15964 operands[3] = gen_lowpart (SImode, operands[3]);"
15965 [(set_attr "type" "icmov")
15966 (set_attr "mode" "SI")])
15968 (define_expand "mov<mode>cc"
15969 [(set (match_operand:X87MODEF 0 "register_operand" "")
15970 (if_then_else:X87MODEF
15971 (match_operand 1 "ix86_fp_comparison_operator" "")
15972 (match_operand:X87MODEF 2 "register_operand" "")
15973 (match_operand:X87MODEF 3 "register_operand" "")))]
15974 "(TARGET_80387 && TARGET_CMOVE)
15975 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15976 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
15978 (define_insn "*movxfcc_1"
15979 [(set (match_operand:XF 0 "register_operand" "=f,f")
15980 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
15981 [(reg FLAGS_REG) (const_int 0)])
15982 (match_operand:XF 2 "register_operand" "f,0")
15983 (match_operand:XF 3 "register_operand" "0,f")))]
15984 "TARGET_80387 && TARGET_CMOVE"
15986 fcmov%F1\t{%2, %0|%0, %2}
15987 fcmov%f1\t{%3, %0|%0, %3}"
15988 [(set_attr "type" "fcmov")
15989 (set_attr "mode" "XF")])
15991 (define_insn "*movdfcc_1_rex64"
15992 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
15993 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15994 [(reg FLAGS_REG) (const_int 0)])
15995 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15996 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15997 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15998 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16000 fcmov%F1\t{%2, %0|%0, %2}
16001 fcmov%f1\t{%3, %0|%0, %3}
16002 cmov%O2%C1\t{%2, %0|%0, %2}
16003 cmov%O2%c1\t{%3, %0|%0, %3}"
16004 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16005 (set_attr "mode" "DF,DF,DI,DI")])
16007 (define_insn "*movdfcc_1"
16008 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16009 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16010 [(reg FLAGS_REG) (const_int 0)])
16011 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16012 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16013 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16014 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16016 fcmov%F1\t{%2, %0|%0, %2}
16017 fcmov%f1\t{%3, %0|%0, %3}
16020 [(set_attr "type" "fcmov,fcmov,multi,multi")
16021 (set_attr "mode" "DF,DF,DI,DI")])
16024 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16025 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16026 [(match_operand 4 "flags_reg_operand" "")
16028 (match_operand:DF 2 "nonimmediate_operand" "")
16029 (match_operand:DF 3 "nonimmediate_operand" "")))]
16030 "!TARGET_64BIT && reload_completed"
16031 [(set (match_dup 2)
16032 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16036 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16040 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16041 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16044 (define_insn "*movsfcc_1_387"
16045 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16046 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16047 [(reg FLAGS_REG) (const_int 0)])
16048 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16049 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16050 "TARGET_80387 && TARGET_CMOVE
16051 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16053 fcmov%F1\t{%2, %0|%0, %2}
16054 fcmov%f1\t{%3, %0|%0, %3}
16055 cmov%O2%C1\t{%2, %0|%0, %2}
16056 cmov%O2%c1\t{%3, %0|%0, %3}"
16057 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16058 (set_attr "mode" "SF,SF,SI,SI")])
16060 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16061 ;; the scalar versions to have only XMM registers as operands.
16063 ;; XOP conditional move
16064 (define_insn "*xop_pcmov_<mode>"
16065 [(set (match_operand:MODEF 0 "register_operand" "=x")
16066 (if_then_else:MODEF
16067 (match_operand:MODEF 1 "register_operand" "x")
16068 (match_operand:MODEF 2 "register_operand" "x")
16069 (match_operand:MODEF 3 "register_operand" "x")))]
16071 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16072 [(set_attr "type" "sse4arg")])
16074 ;; These versions of the min/max patterns are intentionally ignorant of
16075 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16076 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16077 ;; are undefined in this condition, we're certain this is correct.
16079 (define_insn "*avx_<code><mode>3"
16080 [(set (match_operand:MODEF 0 "register_operand" "=x")
16082 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16083 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16084 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16085 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16086 [(set_attr "type" "sseadd")
16087 (set_attr "prefix" "vex")
16088 (set_attr "mode" "<MODE>")])
16090 (define_insn "<code><mode>3"
16091 [(set (match_operand:MODEF 0 "register_operand" "=x")
16093 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16094 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16095 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16096 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16097 [(set_attr "type" "sseadd")
16098 (set_attr "mode" "<MODE>")])
16100 ;; These versions of the min/max patterns implement exactly the operations
16101 ;; min = (op1 < op2 ? op1 : op2)
16102 ;; max = (!(op1 < op2) ? op1 : op2)
16103 ;; Their operands are not commutative, and thus they may be used in the
16104 ;; presence of -0.0 and NaN.
16106 (define_insn "*avx_ieee_smin<mode>3"
16107 [(set (match_operand:MODEF 0 "register_operand" "=x")
16109 [(match_operand:MODEF 1 "register_operand" "x")
16110 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16112 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16113 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16114 [(set_attr "type" "sseadd")
16115 (set_attr "prefix" "vex")
16116 (set_attr "mode" "<MODE>")])
16118 (define_insn "*ieee_smin<mode>3"
16119 [(set (match_operand:MODEF 0 "register_operand" "=x")
16121 [(match_operand:MODEF 1 "register_operand" "0")
16122 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16124 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16125 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16126 [(set_attr "type" "sseadd")
16127 (set_attr "mode" "<MODE>")])
16129 (define_insn "*avx_ieee_smax<mode>3"
16130 [(set (match_operand:MODEF 0 "register_operand" "=x")
16132 [(match_operand:MODEF 1 "register_operand" "0")
16133 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16135 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16136 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16137 [(set_attr "type" "sseadd")
16138 (set_attr "prefix" "vex")
16139 (set_attr "mode" "<MODE>")])
16141 (define_insn "*ieee_smax<mode>3"
16142 [(set (match_operand:MODEF 0 "register_operand" "=x")
16144 [(match_operand:MODEF 1 "register_operand" "0")
16145 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16147 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16148 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16149 [(set_attr "type" "sseadd")
16150 (set_attr "mode" "<MODE>")])
16152 ;; Make two stack loads independent:
16154 ;; fld %st(0) -> fld bb
16155 ;; fmul bb fmul %st(1), %st
16157 ;; Actually we only match the last two instructions for simplicity.
16159 [(set (match_operand 0 "fp_register_operand" "")
16160 (match_operand 1 "fp_register_operand" ""))
16162 (match_operator 2 "binary_fp_operator"
16164 (match_operand 3 "memory_operand" "")]))]
16165 "REGNO (operands[0]) != REGNO (operands[1])"
16166 [(set (match_dup 0) (match_dup 3))
16167 (set (match_dup 0) (match_dup 4))]
16169 ;; The % modifier is not operational anymore in peephole2's, so we have to
16170 ;; swap the operands manually in the case of addition and multiplication.
16171 "if (COMMUTATIVE_ARITH_P (operands[2]))
16172 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16173 GET_MODE (operands[2]),
16174 operands[0], operands[1]);
16176 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16177 GET_MODE (operands[2]),
16178 operands[1], operands[0]);")
16180 ;; Conditional addition patterns
16181 (define_expand "add<mode>cc"
16182 [(match_operand:SWI 0 "register_operand" "")
16183 (match_operand 1 "ordered_comparison_operator" "")
16184 (match_operand:SWI 2 "register_operand" "")
16185 (match_operand:SWI 3 "const_int_operand" "")]
16187 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16189 ;; Misc patterns (?)
16191 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16192 ;; Otherwise there will be nothing to keep
16194 ;; [(set (reg ebp) (reg esp))]
16195 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16196 ;; (clobber (eflags)]
16197 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16199 ;; in proper program order.
16201 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16202 [(set (match_operand:P 0 "register_operand" "=r,r")
16203 (plus:P (match_operand:P 1 "register_operand" "0,r")
16204 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16205 (clobber (reg:CC FLAGS_REG))
16206 (clobber (mem:BLK (scratch)))]
16209 switch (get_attr_type (insn))
16212 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16215 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16216 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16217 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16219 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16222 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16223 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16226 [(set (attr "type")
16227 (cond [(and (eq_attr "alternative" "0")
16228 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16229 (const_string "alu")
16230 (match_operand:<MODE> 2 "const0_operand" "")
16231 (const_string "imov")
16233 (const_string "lea")))
16234 (set (attr "length_immediate")
16235 (cond [(eq_attr "type" "imov")
16237 (and (eq_attr "type" "alu")
16238 (match_operand 2 "const128_operand" ""))
16241 (const_string "*")))
16242 (set_attr "mode" "<MODE>")])
16244 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16245 [(set (match_operand:P 0 "register_operand" "=r")
16246 (minus:P (match_operand:P 1 "register_operand" "0")
16247 (match_operand:P 2 "register_operand" "r")))
16248 (clobber (reg:CC FLAGS_REG))
16249 (clobber (mem:BLK (scratch)))]
16251 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16252 [(set_attr "type" "alu")
16253 (set_attr "mode" "<MODE>")])
16255 (define_insn "allocate_stack_worker_probe_<mode>"
16256 [(set (match_operand:P 0 "register_operand" "=a")
16257 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16258 UNSPECV_STACK_PROBE))
16259 (clobber (reg:CC FLAGS_REG))]
16260 "ix86_target_stack_probe ()"
16261 "call\t___chkstk_ms"
16262 [(set_attr "type" "multi")
16263 (set_attr "length" "5")])
16265 (define_expand "allocate_stack"
16266 [(match_operand 0 "register_operand" "")
16267 (match_operand 1 "general_operand" "")]
16268 "ix86_target_stack_probe ()"
16272 #ifndef CHECK_STACK_LIMIT
16273 #define CHECK_STACK_LIMIT 0
16276 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16277 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16279 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16280 stack_pointer_rtx, 0, OPTAB_DIRECT);
16281 if (x != stack_pointer_rtx)
16282 emit_move_insn (stack_pointer_rtx, x);
16286 x = copy_to_mode_reg (Pmode, operands[1]);
16288 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16290 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16291 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16292 stack_pointer_rtx, 0, OPTAB_DIRECT);
16293 if (x != stack_pointer_rtx)
16294 emit_move_insn (stack_pointer_rtx, x);
16297 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16301 ;; Use IOR for stack probes, this is shorter.
16302 (define_expand "probe_stack"
16303 [(match_operand 0 "memory_operand" "")]
16306 rtx (*gen_ior3) (rtx, rtx, rtx);
16308 gen_ior3 = (GET_MODE (operands[0]) == DImode
16309 ? gen_iordi3 : gen_iorsi3);
16311 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16315 (define_insn "adjust_stack_and_probe<mode>"
16316 [(set (match_operand:P 0 "register_operand" "=r")
16317 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16318 UNSPECV_PROBE_STACK_RANGE))
16319 (set (reg:P SP_REG)
16320 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16321 (clobber (reg:CC FLAGS_REG))
16322 (clobber (mem:BLK (scratch)))]
16324 "* return output_adjust_stack_and_probe (operands[0]);"
16325 [(set_attr "type" "multi")])
16327 (define_insn "probe_stack_range<mode>"
16328 [(set (match_operand:P 0 "register_operand" "=r")
16329 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16330 (match_operand:P 2 "const_int_operand" "n")]
16331 UNSPECV_PROBE_STACK_RANGE))
16332 (clobber (reg:CC FLAGS_REG))]
16334 "* return output_probe_stack_range (operands[0], operands[2]);"
16335 [(set_attr "type" "multi")])
16337 (define_expand "builtin_setjmp_receiver"
16338 [(label_ref (match_operand 0 "" ""))]
16339 "!TARGET_64BIT && flag_pic"
16345 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16346 rtx label_rtx = gen_label_rtx ();
16347 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16348 xops[0] = xops[1] = picreg;
16349 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16350 ix86_expand_binary_operator (MINUS, SImode, xops);
16354 emit_insn (gen_set_got (pic_offset_table_rtx));
16358 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16361 [(set (match_operand 0 "register_operand" "")
16362 (match_operator 3 "promotable_binary_operator"
16363 [(match_operand 1 "register_operand" "")
16364 (match_operand 2 "aligned_operand" "")]))
16365 (clobber (reg:CC FLAGS_REG))]
16366 "! TARGET_PARTIAL_REG_STALL && reload_completed
16367 && ((GET_MODE (operands[0]) == HImode
16368 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16369 /* ??? next two lines just !satisfies_constraint_K (...) */
16370 || !CONST_INT_P (operands[2])
16371 || satisfies_constraint_K (operands[2])))
16372 || (GET_MODE (operands[0]) == QImode
16373 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16374 [(parallel [(set (match_dup 0)
16375 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16376 (clobber (reg:CC FLAGS_REG))])]
16377 "operands[0] = gen_lowpart (SImode, operands[0]);
16378 operands[1] = gen_lowpart (SImode, operands[1]);
16379 if (GET_CODE (operands[3]) != ASHIFT)
16380 operands[2] = gen_lowpart (SImode, operands[2]);
16381 PUT_MODE (operands[3], SImode);")
16383 ; Promote the QImode tests, as i386 has encoding of the AND
16384 ; instruction with 32-bit sign-extended immediate and thus the
16385 ; instruction size is unchanged, except in the %eax case for
16386 ; which it is increased by one byte, hence the ! optimize_size.
16388 [(set (match_operand 0 "flags_reg_operand" "")
16389 (match_operator 2 "compare_operator"
16390 [(and (match_operand 3 "aligned_operand" "")
16391 (match_operand 4 "const_int_operand" ""))
16393 (set (match_operand 1 "register_operand" "")
16394 (and (match_dup 3) (match_dup 4)))]
16395 "! TARGET_PARTIAL_REG_STALL && reload_completed
16396 && optimize_insn_for_speed_p ()
16397 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16398 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16399 /* Ensure that the operand will remain sign-extended immediate. */
16400 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16401 [(parallel [(set (match_dup 0)
16402 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16405 (and:SI (match_dup 3) (match_dup 4)))])]
16408 = gen_int_mode (INTVAL (operands[4])
16409 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16410 operands[1] = gen_lowpart (SImode, operands[1]);
16411 operands[3] = gen_lowpart (SImode, operands[3]);
16414 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16415 ; the TEST instruction with 32-bit sign-extended immediate and thus
16416 ; the instruction size would at least double, which is not what we
16417 ; want even with ! optimize_size.
16419 [(set (match_operand 0 "flags_reg_operand" "")
16420 (match_operator 1 "compare_operator"
16421 [(and (match_operand:HI 2 "aligned_operand" "")
16422 (match_operand:HI 3 "const_int_operand" ""))
16424 "! TARGET_PARTIAL_REG_STALL && reload_completed
16425 && ! TARGET_FAST_PREFIX
16426 && optimize_insn_for_speed_p ()
16427 /* Ensure that the operand will remain sign-extended immediate. */
16428 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16429 [(set (match_dup 0)
16430 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16434 = gen_int_mode (INTVAL (operands[3])
16435 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16436 operands[2] = gen_lowpart (SImode, operands[2]);
16440 [(set (match_operand 0 "register_operand" "")
16441 (neg (match_operand 1 "register_operand" "")))
16442 (clobber (reg:CC FLAGS_REG))]
16443 "! TARGET_PARTIAL_REG_STALL && reload_completed
16444 && (GET_MODE (operands[0]) == HImode
16445 || (GET_MODE (operands[0]) == QImode
16446 && (TARGET_PROMOTE_QImode
16447 || optimize_insn_for_size_p ())))"
16448 [(parallel [(set (match_dup 0)
16449 (neg:SI (match_dup 1)))
16450 (clobber (reg:CC FLAGS_REG))])]
16451 "operands[0] = gen_lowpart (SImode, operands[0]);
16452 operands[1] = gen_lowpart (SImode, operands[1]);")
16455 [(set (match_operand 0 "register_operand" "")
16456 (not (match_operand 1 "register_operand" "")))]
16457 "! TARGET_PARTIAL_REG_STALL && reload_completed
16458 && (GET_MODE (operands[0]) == HImode
16459 || (GET_MODE (operands[0]) == QImode
16460 && (TARGET_PROMOTE_QImode
16461 || optimize_insn_for_size_p ())))"
16462 [(set (match_dup 0)
16463 (not:SI (match_dup 1)))]
16464 "operands[0] = gen_lowpart (SImode, operands[0]);
16465 operands[1] = gen_lowpart (SImode, operands[1]);")
16468 [(set (match_operand 0 "register_operand" "")
16469 (if_then_else (match_operator 1 "ordered_comparison_operator"
16470 [(reg FLAGS_REG) (const_int 0)])
16471 (match_operand 2 "register_operand" "")
16472 (match_operand 3 "register_operand" "")))]
16473 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16474 && (GET_MODE (operands[0]) == HImode
16475 || (GET_MODE (operands[0]) == QImode
16476 && (TARGET_PROMOTE_QImode
16477 || optimize_insn_for_size_p ())))"
16478 [(set (match_dup 0)
16479 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16480 "operands[0] = gen_lowpart (SImode, operands[0]);
16481 operands[2] = gen_lowpart (SImode, operands[2]);
16482 operands[3] = gen_lowpart (SImode, operands[3]);")
16484 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16485 ;; transform a complex memory operation into two memory to register operations.
16487 ;; Don't push memory operands
16489 [(set (match_operand:SWI 0 "push_operand" "")
16490 (match_operand:SWI 1 "memory_operand" ""))
16491 (match_scratch:SWI 2 "<r>")]
16492 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16493 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16494 [(set (match_dup 2) (match_dup 1))
16495 (set (match_dup 0) (match_dup 2))])
16497 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16500 [(set (match_operand:SF 0 "push_operand" "")
16501 (match_operand:SF 1 "memory_operand" ""))
16502 (match_scratch:SF 2 "r")]
16503 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16504 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16505 [(set (match_dup 2) (match_dup 1))
16506 (set (match_dup 0) (match_dup 2))])
16508 ;; Don't move an immediate directly to memory when the instruction
16511 [(match_scratch:SWI124 1 "<r>")
16512 (set (match_operand:SWI124 0 "memory_operand" "")
16514 "optimize_insn_for_speed_p ()
16515 && !TARGET_USE_MOV0
16516 && TARGET_SPLIT_LONG_MOVES
16517 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16518 && peep2_regno_dead_p (0, FLAGS_REG)"
16519 [(parallel [(set (match_dup 2) (const_int 0))
16520 (clobber (reg:CC FLAGS_REG))])
16521 (set (match_dup 0) (match_dup 1))]
16522 "operands[2] = gen_lowpart (SImode, operands[1]);")
16525 [(match_scratch:SWI124 2 "<r>")
16526 (set (match_operand:SWI124 0 "memory_operand" "")
16527 (match_operand:SWI124 1 "immediate_operand" ""))]
16528 "optimize_insn_for_speed_p ()
16529 && TARGET_SPLIT_LONG_MOVES
16530 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16531 [(set (match_dup 2) (match_dup 1))
16532 (set (match_dup 0) (match_dup 2))])
16534 ;; Don't compare memory with zero, load and use a test instead.
16536 [(set (match_operand 0 "flags_reg_operand" "")
16537 (match_operator 1 "compare_operator"
16538 [(match_operand:SI 2 "memory_operand" "")
16540 (match_scratch:SI 3 "r")]
16541 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16542 [(set (match_dup 3) (match_dup 2))
16543 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16545 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16546 ;; Don't split NOTs with a displacement operand, because resulting XOR
16547 ;; will not be pairable anyway.
16549 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16550 ;; represented using a modRM byte. The XOR replacement is long decoded,
16551 ;; so this split helps here as well.
16553 ;; Note: Can't do this as a regular split because we can't get proper
16554 ;; lifetime information then.
16557 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16558 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16559 "optimize_insn_for_speed_p ()
16560 && ((TARGET_NOT_UNPAIRABLE
16561 && (!MEM_P (operands[0])
16562 || !memory_displacement_operand (operands[0], <MODE>mode)))
16563 || (TARGET_NOT_VECTORMODE
16564 && long_memory_operand (operands[0], <MODE>mode)))
16565 && peep2_regno_dead_p (0, FLAGS_REG)"
16566 [(parallel [(set (match_dup 0)
16567 (xor:SWI124 (match_dup 1) (const_int -1)))
16568 (clobber (reg:CC FLAGS_REG))])])
16570 ;; Non pairable "test imm, reg" instructions can be translated to
16571 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16572 ;; byte opcode instead of two, have a short form for byte operands),
16573 ;; so do it for other CPUs as well. Given that the value was dead,
16574 ;; this should not create any new dependencies. Pass on the sub-word
16575 ;; versions if we're concerned about partial register stalls.
16578 [(set (match_operand 0 "flags_reg_operand" "")
16579 (match_operator 1 "compare_operator"
16580 [(and:SI (match_operand:SI 2 "register_operand" "")
16581 (match_operand:SI 3 "immediate_operand" ""))
16583 "ix86_match_ccmode (insn, CCNOmode)
16584 && (true_regnum (operands[2]) != AX_REG
16585 || satisfies_constraint_K (operands[3]))
16586 && peep2_reg_dead_p (1, operands[2])"
16588 [(set (match_dup 0)
16589 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16592 (and:SI (match_dup 2) (match_dup 3)))])])
16594 ;; We don't need to handle HImode case, because it will be promoted to SImode
16595 ;; on ! TARGET_PARTIAL_REG_STALL
16598 [(set (match_operand 0 "flags_reg_operand" "")
16599 (match_operator 1 "compare_operator"
16600 [(and:QI (match_operand:QI 2 "register_operand" "")
16601 (match_operand:QI 3 "immediate_operand" ""))
16603 "! TARGET_PARTIAL_REG_STALL
16604 && ix86_match_ccmode (insn, CCNOmode)
16605 && true_regnum (operands[2]) != AX_REG
16606 && peep2_reg_dead_p (1, operands[2])"
16608 [(set (match_dup 0)
16609 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16612 (and:QI (match_dup 2) (match_dup 3)))])])
16615 [(set (match_operand 0 "flags_reg_operand" "")
16616 (match_operator 1 "compare_operator"
16619 (match_operand 2 "ext_register_operand" "")
16622 (match_operand 3 "const_int_operand" ""))
16624 "! TARGET_PARTIAL_REG_STALL
16625 && ix86_match_ccmode (insn, CCNOmode)
16626 && true_regnum (operands[2]) != AX_REG
16627 && peep2_reg_dead_p (1, operands[2])"
16628 [(parallel [(set (match_dup 0)
16637 (set (zero_extract:SI (match_dup 2)
16645 (match_dup 3)))])])
16647 ;; Don't do logical operations with memory inputs.
16649 [(match_scratch:SI 2 "r")
16650 (parallel [(set (match_operand:SI 0 "register_operand" "")
16651 (match_operator:SI 3 "arith_or_logical_operator"
16653 (match_operand:SI 1 "memory_operand" "")]))
16654 (clobber (reg:CC FLAGS_REG))])]
16655 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16656 [(set (match_dup 2) (match_dup 1))
16657 (parallel [(set (match_dup 0)
16658 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16659 (clobber (reg:CC FLAGS_REG))])])
16662 [(match_scratch:SI 2 "r")
16663 (parallel [(set (match_operand:SI 0 "register_operand" "")
16664 (match_operator:SI 3 "arith_or_logical_operator"
16665 [(match_operand:SI 1 "memory_operand" "")
16667 (clobber (reg:CC FLAGS_REG))])]
16668 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16669 [(set (match_dup 2) (match_dup 1))
16670 (parallel [(set (match_dup 0)
16671 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16672 (clobber (reg:CC FLAGS_REG))])])
16674 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16675 ;; refers to the destination of the load!
16678 [(set (match_operand:SI 0 "register_operand" "")
16679 (match_operand:SI 1 "register_operand" ""))
16680 (parallel [(set (match_dup 0)
16681 (match_operator:SI 3 "commutative_operator"
16683 (match_operand:SI 2 "memory_operand" "")]))
16684 (clobber (reg:CC FLAGS_REG))])]
16685 "REGNO (operands[0]) != REGNO (operands[1])
16686 && GENERAL_REGNO_P (REGNO (operands[0]))
16687 && GENERAL_REGNO_P (REGNO (operands[1]))"
16688 [(set (match_dup 0) (match_dup 4))
16689 (parallel [(set (match_dup 0)
16690 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16691 (clobber (reg:CC FLAGS_REG))])]
16692 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16695 [(set (match_operand 0 "register_operand" "")
16696 (match_operand 1 "register_operand" ""))
16698 (match_operator 3 "commutative_operator"
16700 (match_operand 2 "memory_operand" "")]))]
16701 "REGNO (operands[0]) != REGNO (operands[1])
16702 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16703 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16704 [(set (match_dup 0) (match_dup 2))
16706 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16708 ; Don't do logical operations with memory outputs
16710 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16711 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16712 ; the same decoder scheduling characteristics as the original.
16715 [(match_scratch:SI 2 "r")
16716 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16717 (match_operator:SI 3 "arith_or_logical_operator"
16719 (match_operand:SI 1 "nonmemory_operand" "")]))
16720 (clobber (reg:CC FLAGS_REG))])]
16721 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16722 /* Do not split stack checking probes. */
16723 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16724 [(set (match_dup 2) (match_dup 0))
16725 (parallel [(set (match_dup 2)
16726 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16727 (clobber (reg:CC FLAGS_REG))])
16728 (set (match_dup 0) (match_dup 2))])
16731 [(match_scratch:SI 2 "r")
16732 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16733 (match_operator:SI 3 "arith_or_logical_operator"
16734 [(match_operand:SI 1 "nonmemory_operand" "")
16736 (clobber (reg:CC FLAGS_REG))])]
16737 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16738 /* Do not split stack checking probes. */
16739 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16740 [(set (match_dup 2) (match_dup 0))
16741 (parallel [(set (match_dup 2)
16742 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16743 (clobber (reg:CC FLAGS_REG))])
16744 (set (match_dup 0) (match_dup 2))])
16746 ;; Attempt to always use XOR for zeroing registers.
16748 [(set (match_operand 0 "register_operand" "")
16749 (match_operand 1 "const0_operand" ""))]
16750 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16751 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16752 && GENERAL_REG_P (operands[0])
16753 && peep2_regno_dead_p (0, FLAGS_REG)"
16754 [(parallel [(set (match_dup 0) (const_int 0))
16755 (clobber (reg:CC FLAGS_REG))])]
16756 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16759 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16761 "(GET_MODE (operands[0]) == QImode
16762 || GET_MODE (operands[0]) == HImode)
16763 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16764 && peep2_regno_dead_p (0, FLAGS_REG)"
16765 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16766 (clobber (reg:CC FLAGS_REG))])])
16768 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16770 [(set (match_operand:SWI248 0 "register_operand" "")
16772 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16773 && peep2_regno_dead_p (0, FLAGS_REG)"
16774 [(parallel [(set (match_dup 0) (const_int -1))
16775 (clobber (reg:CC FLAGS_REG))])]
16777 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16778 operands[0] = gen_lowpart (SImode, operands[0]);
16781 ;; Attempt to convert simple lea to add/shift.
16782 ;; These can be created by move expanders.
16785 [(set (match_operand:SWI48 0 "register_operand" "")
16786 (plus:SWI48 (match_dup 0)
16787 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16788 "peep2_regno_dead_p (0, FLAGS_REG)"
16789 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16790 (clobber (reg:CC FLAGS_REG))])])
16793 [(set (match_operand:SI 0 "register_operand" "")
16794 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16795 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16797 && peep2_regno_dead_p (0, FLAGS_REG)
16798 && REGNO (operands[0]) == REGNO (operands[1])"
16799 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16800 (clobber (reg:CC FLAGS_REG))])]
16801 "operands[2] = gen_lowpart (SImode, operands[2]);")
16804 [(set (match_operand:SWI48 0 "register_operand" "")
16805 (mult:SWI48 (match_dup 0)
16806 (match_operand:SWI48 1 "const_int_operand" "")))]
16807 "exact_log2 (INTVAL (operands[1])) >= 0
16808 && peep2_regno_dead_p (0, FLAGS_REG)"
16809 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16810 (clobber (reg:CC FLAGS_REG))])]
16811 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16814 [(set (match_operand:SI 0 "register_operand" "")
16815 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16816 (match_operand:DI 2 "const_int_operand" "")) 0))]
16818 && exact_log2 (INTVAL (operands[2])) >= 0
16819 && REGNO (operands[0]) == REGNO (operands[1])
16820 && peep2_regno_dead_p (0, FLAGS_REG)"
16821 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16822 (clobber (reg:CC FLAGS_REG))])]
16823 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16825 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16826 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16827 ;; On many CPUs it is also faster, since special hardware to avoid esp
16828 ;; dependencies is present.
16830 ;; While some of these conversions may be done using splitters, we use
16831 ;; peepholes in order to allow combine_stack_adjustments pass to see
16832 ;; nonobfuscated RTL.
16834 ;; Convert prologue esp subtractions to push.
16835 ;; We need register to push. In order to keep verify_flow_info happy we have
16837 ;; - use scratch and clobber it in order to avoid dependencies
16838 ;; - use already live register
16839 ;; We can't use the second way right now, since there is no reliable way how to
16840 ;; verify that given register is live. First choice will also most likely in
16841 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16842 ;; call clobbered registers are dead. We may want to use base pointer as an
16843 ;; alternative when no register is available later.
16846 [(match_scratch:P 1 "r")
16847 (parallel [(set (reg:P SP_REG)
16848 (plus:P (reg:P SP_REG)
16849 (match_operand:P 0 "const_int_operand" "")))
16850 (clobber (reg:CC FLAGS_REG))
16851 (clobber (mem:BLK (scratch)))])]
16852 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16853 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16854 [(clobber (match_dup 1))
16855 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16856 (clobber (mem:BLK (scratch)))])])
16859 [(match_scratch:P 1 "r")
16860 (parallel [(set (reg:P SP_REG)
16861 (plus:P (reg:P SP_REG)
16862 (match_operand:P 0 "const_int_operand" "")))
16863 (clobber (reg:CC FLAGS_REG))
16864 (clobber (mem:BLK (scratch)))])]
16865 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16866 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16867 [(clobber (match_dup 1))
16868 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16869 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16870 (clobber (mem:BLK (scratch)))])])
16872 ;; Convert esp subtractions to push.
16874 [(match_scratch:P 1 "r")
16875 (parallel [(set (reg:P SP_REG)
16876 (plus:P (reg:P SP_REG)
16877 (match_operand:P 0 "const_int_operand" "")))
16878 (clobber (reg:CC FLAGS_REG))])]
16879 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16880 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16881 [(clobber (match_dup 1))
16882 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16885 [(match_scratch:P 1 "r")
16886 (parallel [(set (reg:P SP_REG)
16887 (plus:P (reg:P SP_REG)
16888 (match_operand:P 0 "const_int_operand" "")))
16889 (clobber (reg:CC FLAGS_REG))])]
16890 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16891 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16892 [(clobber (match_dup 1))
16893 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16894 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16896 ;; Convert epilogue deallocator to pop.
16898 [(match_scratch:P 1 "r")
16899 (parallel [(set (reg:P SP_REG)
16900 (plus:P (reg:P SP_REG)
16901 (match_operand:P 0 "const_int_operand" "")))
16902 (clobber (reg:CC FLAGS_REG))
16903 (clobber (mem:BLK (scratch)))])]
16904 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
16905 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16906 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16907 (clobber (mem:BLK (scratch)))])])
16909 ;; Two pops case is tricky, since pop causes dependency
16910 ;; on destination register. We use two registers if available.
16912 [(match_scratch:P 1 "r")
16913 (match_scratch:P 2 "r")
16914 (parallel [(set (reg:P SP_REG)
16915 (plus:P (reg:P SP_REG)
16916 (match_operand:P 0 "const_int_operand" "")))
16917 (clobber (reg:CC FLAGS_REG))
16918 (clobber (mem:BLK (scratch)))])]
16919 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
16920 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16921 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16922 (clobber (mem:BLK (scratch)))])
16923 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
16926 [(match_scratch:P 1 "r")
16927 (parallel [(set (reg:P SP_REG)
16928 (plus:P (reg:P SP_REG)
16929 (match_operand:P 0 "const_int_operand" "")))
16930 (clobber (reg:CC FLAGS_REG))
16931 (clobber (mem:BLK (scratch)))])]
16932 "optimize_insn_for_size_p ()
16933 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16934 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16935 (clobber (mem:BLK (scratch)))])
16936 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16938 ;; Convert esp additions to pop.
16940 [(match_scratch:P 1 "r")
16941 (parallel [(set (reg:P SP_REG)
16942 (plus:P (reg:P SP_REG)
16943 (match_operand:P 0 "const_int_operand" "")))
16944 (clobber (reg:CC FLAGS_REG))])]
16945 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16946 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16948 ;; Two pops case is tricky, since pop causes dependency
16949 ;; on destination register. We use two registers if available.
16951 [(match_scratch:P 1 "r")
16952 (match_scratch:P 2 "r")
16953 (parallel [(set (reg:P SP_REG)
16954 (plus:P (reg:P SP_REG)
16955 (match_operand:P 0 "const_int_operand" "")))
16956 (clobber (reg:CC FLAGS_REG))])]
16957 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16958 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16959 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
16962 [(match_scratch:P 1 "r")
16963 (parallel [(set (reg:P SP_REG)
16964 (plus:P (reg:P SP_REG)
16965 (match_operand:P 0 "const_int_operand" "")))
16966 (clobber (reg:CC FLAGS_REG))])]
16967 "optimize_insn_for_size_p ()
16968 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16969 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16970 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16972 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
16973 ;; required and register dies. Similarly for 128 to -128.
16975 [(set (match_operand 0 "flags_reg_operand" "")
16976 (match_operator 1 "compare_operator"
16977 [(match_operand 2 "register_operand" "")
16978 (match_operand 3 "const_int_operand" "")]))]
16979 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
16980 && incdec_operand (operands[3], GET_MODE (operands[3])))
16981 || (!TARGET_FUSE_CMP_AND_BRANCH
16982 && INTVAL (operands[3]) == 128))
16983 && ix86_match_ccmode (insn, CCGCmode)
16984 && peep2_reg_dead_p (1, operands[2])"
16985 [(parallel [(set (match_dup 0)
16986 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
16987 (clobber (match_dup 2))])])
16989 ;; Convert imul by three, five and nine into lea
16992 [(set (match_operand:SWI48 0 "register_operand" "")
16993 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
16994 (match_operand:SWI48 2 "const_int_operand" "")))
16995 (clobber (reg:CC FLAGS_REG))])]
16996 "INTVAL (operands[2]) == 3
16997 || INTVAL (operands[2]) == 5
16998 || INTVAL (operands[2]) == 9"
16999 [(set (match_dup 0)
17000 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17002 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17006 [(set (match_operand:SWI48 0 "register_operand" "")
17007 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17008 (match_operand:SWI48 2 "const_int_operand" "")))
17009 (clobber (reg:CC FLAGS_REG))])]
17010 "optimize_insn_for_speed_p ()
17011 && (INTVAL (operands[2]) == 3
17012 || INTVAL (operands[2]) == 5
17013 || INTVAL (operands[2]) == 9)"
17014 [(set (match_dup 0) (match_dup 1))
17016 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17018 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17020 ;; imul $32bit_imm, mem, reg is vector decoded, while
17021 ;; imul $32bit_imm, reg, reg is direct decoded.
17023 [(match_scratch:SWI48 3 "r")
17024 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17025 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17026 (match_operand:SWI48 2 "immediate_operand" "")))
17027 (clobber (reg:CC FLAGS_REG))])]
17028 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17029 && !satisfies_constraint_K (operands[2])"
17030 [(set (match_dup 3) (match_dup 1))
17031 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17032 (clobber (reg:CC FLAGS_REG))])])
17035 [(match_scratch:SI 3 "r")
17036 (parallel [(set (match_operand:DI 0 "register_operand" "")
17038 (mult:SI (match_operand:SI 1 "memory_operand" "")
17039 (match_operand:SI 2 "immediate_operand" ""))))
17040 (clobber (reg:CC FLAGS_REG))])]
17042 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17043 && !satisfies_constraint_K (operands[2])"
17044 [(set (match_dup 3) (match_dup 1))
17045 (parallel [(set (match_dup 0)
17046 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17047 (clobber (reg:CC FLAGS_REG))])])
17049 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17050 ;; Convert it into imul reg, reg
17051 ;; It would be better to force assembler to encode instruction using long
17052 ;; immediate, but there is apparently no way to do so.
17054 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17056 (match_operand:SWI248 1 "nonimmediate_operand" "")
17057 (match_operand:SWI248 2 "const_int_operand" "")))
17058 (clobber (reg:CC FLAGS_REG))])
17059 (match_scratch:SWI248 3 "r")]
17060 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17061 && satisfies_constraint_K (operands[2])"
17062 [(set (match_dup 3) (match_dup 2))
17063 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17064 (clobber (reg:CC FLAGS_REG))])]
17066 if (!rtx_equal_p (operands[0], operands[1]))
17067 emit_move_insn (operands[0], operands[1]);
17070 ;; After splitting up read-modify operations, array accesses with memory
17071 ;; operands might end up in form:
17073 ;; movl 4(%esp), %edx
17075 ;; instead of pre-splitting:
17077 ;; addl 4(%esp), %eax
17079 ;; movl 4(%esp), %edx
17080 ;; leal (%edx,%eax,4), %eax
17083 [(match_scratch:P 5 "r")
17084 (parallel [(set (match_operand 0 "register_operand" "")
17085 (ashift (match_operand 1 "register_operand" "")
17086 (match_operand 2 "const_int_operand" "")))
17087 (clobber (reg:CC FLAGS_REG))])
17088 (parallel [(set (match_operand 3 "register_operand" "")
17089 (plus (match_dup 0)
17090 (match_operand 4 "x86_64_general_operand" "")))
17091 (clobber (reg:CC FLAGS_REG))])]
17092 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17093 /* Validate MODE for lea. */
17094 && ((!TARGET_PARTIAL_REG_STALL
17095 && (GET_MODE (operands[0]) == QImode
17096 || GET_MODE (operands[0]) == HImode))
17097 || GET_MODE (operands[0]) == SImode
17098 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17099 && (rtx_equal_p (operands[0], operands[3])
17100 || peep2_reg_dead_p (2, operands[0]))
17101 /* We reorder load and the shift. */
17102 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17103 [(set (match_dup 5) (match_dup 4))
17104 (set (match_dup 0) (match_dup 1))]
17106 enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17107 int scale = 1 << INTVAL (operands[2]);
17108 rtx index = gen_lowpart (Pmode, operands[1]);
17109 rtx base = gen_lowpart (Pmode, operands[5]);
17110 rtx dest = gen_lowpart (mode, operands[3]);
17112 operands[1] = gen_rtx_PLUS (Pmode, base,
17113 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17114 operands[5] = base;
17117 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17118 operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17120 operands[0] = dest;
17123 ;; Call-value patterns last so that the wildcard operand does not
17124 ;; disrupt insn-recog's switch tables.
17126 (define_insn "*call_value_pop_0"
17127 [(set (match_operand 0 "" "")
17128 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17129 (match_operand:SI 2 "" "")))
17130 (set (reg:SI SP_REG)
17131 (plus:SI (reg:SI SP_REG)
17132 (match_operand:SI 3 "immediate_operand" "")))]
17134 { return ix86_output_call_insn (insn, operands[1], 1); }
17135 [(set_attr "type" "callv")])
17137 (define_insn "*call_value_pop_1"
17138 [(set (match_operand 0 "" "")
17139 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17140 (match_operand:SI 2 "" "")))
17141 (set (reg:SI SP_REG)
17142 (plus:SI (reg:SI SP_REG)
17143 (match_operand:SI 3 "immediate_operand" "i")))]
17144 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17145 { return ix86_output_call_insn (insn, operands[1], 1); }
17146 [(set_attr "type" "callv")])
17148 (define_insn "*sibcall_value_pop_1"
17149 [(set (match_operand 0 "" "")
17150 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17151 (match_operand:SI 2 "" "")))
17152 (set (reg:SI SP_REG)
17153 (plus:SI (reg:SI SP_REG)
17154 (match_operand:SI 3 "immediate_operand" "i,i")))]
17155 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17156 { return ix86_output_call_insn (insn, operands[1], 1); }
17157 [(set_attr "type" "callv")])
17159 (define_insn "*call_value_0"
17160 [(set (match_operand 0 "" "")
17161 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17162 (match_operand:SI 2 "" "")))]
17164 { return ix86_output_call_insn (insn, operands[1], 1); }
17165 [(set_attr "type" "callv")])
17167 (define_insn "*call_value_0_rex64"
17168 [(set (match_operand 0 "" "")
17169 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17170 (match_operand:DI 2 "const_int_operand" "")))]
17172 { return ix86_output_call_insn (insn, operands[1], 1); }
17173 [(set_attr "type" "callv")])
17175 (define_insn "*call_value_0_rex64_ms_sysv"
17176 [(set (match_operand 0 "" "")
17177 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17178 (match_operand:DI 2 "const_int_operand" "")))
17179 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17180 (clobber (reg:TI XMM6_REG))
17181 (clobber (reg:TI XMM7_REG))
17182 (clobber (reg:TI XMM8_REG))
17183 (clobber (reg:TI XMM9_REG))
17184 (clobber (reg:TI XMM10_REG))
17185 (clobber (reg:TI XMM11_REG))
17186 (clobber (reg:TI XMM12_REG))
17187 (clobber (reg:TI XMM13_REG))
17188 (clobber (reg:TI XMM14_REG))
17189 (clobber (reg:TI XMM15_REG))
17190 (clobber (reg:DI SI_REG))
17191 (clobber (reg:DI DI_REG))]
17192 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17193 { return ix86_output_call_insn (insn, operands[1], 1); }
17194 [(set_attr "type" "callv")])
17196 (define_insn "*call_value_1"
17197 [(set (match_operand 0 "" "")
17198 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17199 (match_operand:SI 2 "" "")))]
17200 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17201 { return ix86_output_call_insn (insn, operands[1], 1); }
17202 [(set_attr "type" "callv")])
17204 (define_insn "*sibcall_value_1"
17205 [(set (match_operand 0 "" "")
17206 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17207 (match_operand:SI 2 "" "")))]
17208 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17209 { return ix86_output_call_insn (insn, operands[1], 1); }
17210 [(set_attr "type" "callv")])
17212 (define_insn "*call_value_1_rex64"
17213 [(set (match_operand 0 "" "")
17214 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17215 (match_operand:DI 2 "" "")))]
17216 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17217 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17218 { return ix86_output_call_insn (insn, operands[1], 1); }
17219 [(set_attr "type" "callv")])
17221 (define_insn "*call_value_1_rex64_ms_sysv"
17222 [(set (match_operand 0 "" "")
17223 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17224 (match_operand:DI 2 "" "")))
17225 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17226 (clobber (reg:TI XMM6_REG))
17227 (clobber (reg:TI XMM7_REG))
17228 (clobber (reg:TI XMM8_REG))
17229 (clobber (reg:TI XMM9_REG))
17230 (clobber (reg:TI XMM10_REG))
17231 (clobber (reg:TI XMM11_REG))
17232 (clobber (reg:TI XMM12_REG))
17233 (clobber (reg:TI XMM13_REG))
17234 (clobber (reg:TI XMM14_REG))
17235 (clobber (reg:TI XMM15_REG))
17236 (clobber (reg:DI SI_REG))
17237 (clobber (reg:DI DI_REG))]
17238 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17239 { return ix86_output_call_insn (insn, operands[1], 1); }
17240 [(set_attr "type" "callv")])
17242 (define_insn "*call_value_1_rex64_large"
17243 [(set (match_operand 0 "" "")
17244 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17245 (match_operand:DI 2 "" "")))]
17246 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17247 { return ix86_output_call_insn (insn, operands[1], 1); }
17248 [(set_attr "type" "callv")])
17250 (define_insn "*sibcall_value_1_rex64"
17251 [(set (match_operand 0 "" "")
17252 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17253 (match_operand:DI 2 "" "")))]
17254 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17255 { return ix86_output_call_insn (insn, operands[1], 1); }
17256 [(set_attr "type" "callv")])
17258 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17259 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17260 ;; caught for use by garbage collectors and the like. Using an insn that
17261 ;; maps to SIGILL makes it more likely the program will rightfully die.
17262 ;; Keeping with tradition, "6" is in honor of #UD.
17263 (define_insn "trap"
17264 [(trap_if (const_int 1) (const_int 6))]
17266 { return ASM_SHORT "0x0b0f"; }
17267 [(set_attr "length" "2")])
17269 (define_expand "prefetch"
17270 [(prefetch (match_operand 0 "address_operand" "")
17271 (match_operand:SI 1 "const_int_operand" "")
17272 (match_operand:SI 2 "const_int_operand" ""))]
17273 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17275 int rw = INTVAL (operands[1]);
17276 int locality = INTVAL (operands[2]);
17278 gcc_assert (rw == 0 || rw == 1);
17279 gcc_assert (locality >= 0 && locality <= 3);
17280 gcc_assert (GET_MODE (operands[0]) == Pmode
17281 || GET_MODE (operands[0]) == VOIDmode);
17283 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17284 supported by SSE counterpart or the SSE prefetch is not available
17285 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17287 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17288 operands[2] = GEN_INT (3);
17290 operands[1] = const0_rtx;
17293 (define_insn "*prefetch_sse_<mode>"
17294 [(prefetch (match_operand:P 0 "address_operand" "p")
17296 (match_operand:SI 1 "const_int_operand" ""))]
17297 "TARGET_PREFETCH_SSE"
17299 static const char * const patterns[4] = {
17300 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17303 int locality = INTVAL (operands[1]);
17304 gcc_assert (locality >= 0 && locality <= 3);
17306 return patterns[locality];
17308 [(set_attr "type" "sse")
17309 (set_attr "atom_sse_attr" "prefetch")
17310 (set (attr "length_address")
17311 (symbol_ref "memory_address_length (operands[0])"))
17312 (set_attr "memory" "none")])
17314 (define_insn "*prefetch_3dnow_<mode>"
17315 [(prefetch (match_operand:P 0 "address_operand" "p")
17316 (match_operand:SI 1 "const_int_operand" "n")
17320 if (INTVAL (operands[1]) == 0)
17321 return "prefetch\t%a0";
17323 return "prefetchw\t%a0";
17325 [(set_attr "type" "mmx")
17326 (set (attr "length_address")
17327 (symbol_ref "memory_address_length (operands[0])"))
17328 (set_attr "memory" "none")])
17330 (define_expand "stack_protect_set"
17331 [(match_operand 0 "memory_operand" "")
17332 (match_operand 1 "memory_operand" "")]
17335 rtx (*insn)(rtx, rtx);
17337 #ifdef TARGET_THREAD_SSP_OFFSET
17338 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17339 insn = (TARGET_64BIT
17340 ? gen_stack_tls_protect_set_di
17341 : gen_stack_tls_protect_set_si);
17343 insn = (TARGET_64BIT
17344 ? gen_stack_protect_set_di
17345 : gen_stack_protect_set_si);
17348 emit_insn (insn (operands[0], operands[1]));
17352 (define_insn "stack_protect_set_<mode>"
17353 [(set (match_operand:P 0 "memory_operand" "=m")
17354 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17355 (set (match_scratch:P 2 "=&r") (const_int 0))
17356 (clobber (reg:CC FLAGS_REG))]
17358 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17359 [(set_attr "type" "multi")])
17361 (define_insn "stack_tls_protect_set_<mode>"
17362 [(set (match_operand:P 0 "memory_operand" "=m")
17363 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17364 UNSPEC_SP_TLS_SET))
17365 (set (match_scratch:P 2 "=&r") (const_int 0))
17366 (clobber (reg:CC FLAGS_REG))]
17368 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17369 [(set_attr "type" "multi")])
17371 (define_expand "stack_protect_test"
17372 [(match_operand 0 "memory_operand" "")
17373 (match_operand 1 "memory_operand" "")
17374 (match_operand 2 "" "")]
17377 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17379 rtx (*insn)(rtx, rtx, rtx);
17381 #ifdef TARGET_THREAD_SSP_OFFSET
17382 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17383 insn = (TARGET_64BIT
17384 ? gen_stack_tls_protect_test_di
17385 : gen_stack_tls_protect_test_si);
17387 insn = (TARGET_64BIT
17388 ? gen_stack_protect_test_di
17389 : gen_stack_protect_test_si);
17392 emit_insn (insn (flags, operands[0], operands[1]));
17394 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17395 flags, const0_rtx, operands[2]));
17399 (define_insn "stack_protect_test_<mode>"
17400 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17401 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17402 (match_operand:P 2 "memory_operand" "m")]
17404 (clobber (match_scratch:P 3 "=&r"))]
17406 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17407 [(set_attr "type" "multi")])
17409 (define_insn "stack_tls_protect_test_<mode>"
17410 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17411 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17412 (match_operand:P 2 "const_int_operand" "i")]
17413 UNSPEC_SP_TLS_TEST))
17414 (clobber (match_scratch:P 3 "=r"))]
17416 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17417 [(set_attr "type" "multi")])
17419 (define_insn "sse4_2_crc32<mode>"
17420 [(set (match_operand:SI 0 "register_operand" "=r")
17422 [(match_operand:SI 1 "register_operand" "0")
17423 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17425 "TARGET_SSE4_2 || TARGET_CRC32"
17426 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17427 [(set_attr "type" "sselog1")
17428 (set_attr "prefix_rep" "1")
17429 (set_attr "prefix_extra" "1")
17430 (set (attr "prefix_data16")
17431 (if_then_else (match_operand:HI 2 "" "")
17433 (const_string "*")))
17434 (set (attr "prefix_rex")
17435 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17437 (const_string "*")))
17438 (set_attr "mode" "SI")])
17440 (define_insn "sse4_2_crc32di"
17441 [(set (match_operand:DI 0 "register_operand" "=r")
17443 [(match_operand:DI 1 "register_operand" "0")
17444 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17446 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17447 "crc32{q}\t{%2, %0|%0, %2}"
17448 [(set_attr "type" "sselog1")
17449 (set_attr "prefix_rep" "1")
17450 (set_attr "prefix_extra" "1")
17451 (set_attr "mode" "DI")])
17453 (define_expand "rdpmc"
17454 [(match_operand:DI 0 "register_operand" "")
17455 (match_operand:SI 1 "register_operand" "")]
17458 rtx reg = gen_reg_rtx (DImode);
17461 /* Force operand 1 into ECX. */
17462 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17463 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17464 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17469 rtvec vec = rtvec_alloc (2);
17470 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17471 rtx upper = gen_reg_rtx (DImode);
17472 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17473 gen_rtvec (1, const0_rtx),
17475 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17476 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17478 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17479 NULL, 1, OPTAB_DIRECT);
17480 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17484 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17485 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17489 (define_insn "*rdpmc"
17490 [(set (match_operand:DI 0 "register_operand" "=A")
17491 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17495 [(set_attr "type" "other")
17496 (set_attr "length" "2")])
17498 (define_insn "*rdpmc_rex64"
17499 [(set (match_operand:DI 0 "register_operand" "=a")
17500 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17502 (set (match_operand:DI 1 "register_operand" "=d")
17503 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17506 [(set_attr "type" "other")
17507 (set_attr "length" "2")])
17509 (define_expand "rdtsc"
17510 [(set (match_operand:DI 0 "register_operand" "")
17511 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17516 rtvec vec = rtvec_alloc (2);
17517 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17518 rtx upper = gen_reg_rtx (DImode);
17519 rtx lower = gen_reg_rtx (DImode);
17520 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17521 gen_rtvec (1, const0_rtx),
17523 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17524 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17526 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17527 NULL, 1, OPTAB_DIRECT);
17528 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17530 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17535 (define_insn "*rdtsc"
17536 [(set (match_operand:DI 0 "register_operand" "=A")
17537 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17540 [(set_attr "type" "other")
17541 (set_attr "length" "2")])
17543 (define_insn "*rdtsc_rex64"
17544 [(set (match_operand:DI 0 "register_operand" "=a")
17545 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17546 (set (match_operand:DI 1 "register_operand" "=d")
17547 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17550 [(set_attr "type" "other")
17551 (set_attr "length" "2")])
17553 (define_expand "rdtscp"
17554 [(match_operand:DI 0 "register_operand" "")
17555 (match_operand:SI 1 "memory_operand" "")]
17558 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17559 gen_rtvec (1, const0_rtx),
17561 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17562 gen_rtvec (1, const0_rtx),
17564 rtx reg = gen_reg_rtx (DImode);
17565 rtx tmp = gen_reg_rtx (SImode);
17569 rtvec vec = rtvec_alloc (3);
17570 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17571 rtx upper = gen_reg_rtx (DImode);
17572 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17573 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17574 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17576 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17577 NULL, 1, OPTAB_DIRECT);
17578 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17583 rtvec vec = rtvec_alloc (2);
17584 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17585 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17586 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17589 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17590 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17594 (define_insn "*rdtscp"
17595 [(set (match_operand:DI 0 "register_operand" "=A")
17596 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17597 (set (match_operand:SI 1 "register_operand" "=c")
17598 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17601 [(set_attr "type" "other")
17602 (set_attr "length" "3")])
17604 (define_insn "*rdtscp_rex64"
17605 [(set (match_operand:DI 0 "register_operand" "=a")
17606 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17607 (set (match_operand:DI 1 "register_operand" "=d")
17608 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17609 (set (match_operand:SI 2 "register_operand" "=c")
17610 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17613 [(set_attr "type" "other")
17614 (set_attr "length" "3")])
17616 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17618 ;; LWP instructions
17620 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17622 (define_expand "lwp_llwpcb"
17623 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17624 UNSPECV_LLWP_INTRINSIC)]
17627 (define_insn "*lwp_llwpcb<mode>1"
17628 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17629 UNSPECV_LLWP_INTRINSIC)]
17632 [(set_attr "type" "lwp")
17633 (set_attr "mode" "<MODE>")
17634 (set_attr "length" "5")])
17636 (define_expand "lwp_slwpcb"
17637 [(set (match_operand 0 "register_operand" "=r")
17638 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17642 emit_insn (gen_lwp_slwpcbdi (operands[0]));
17644 emit_insn (gen_lwp_slwpcbsi (operands[0]));
17648 (define_insn "lwp_slwpcb<mode>"
17649 [(set (match_operand:P 0 "register_operand" "=r")
17650 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17653 [(set_attr "type" "lwp")
17654 (set_attr "mode" "<MODE>")
17655 (set_attr "length" "5")])
17657 (define_expand "lwp_lwpval<mode>3"
17658 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17659 (match_operand:SI 2 "nonimmediate_operand" "rm")
17660 (match_operand:SI 3 "const_int_operand" "i")]
17661 UNSPECV_LWPVAL_INTRINSIC)]
17663 "/* Avoid unused variable warning. */
17666 (define_insn "*lwp_lwpval<mode>3_1"
17667 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17668 (match_operand:SI 1 "nonimmediate_operand" "rm")
17669 (match_operand:SI 2 "const_int_operand" "i")]
17670 UNSPECV_LWPVAL_INTRINSIC)]
17672 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17673 [(set_attr "type" "lwp")
17674 (set_attr "mode" "<MODE>")
17675 (set (attr "length")
17676 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17678 (define_expand "lwp_lwpins<mode>3"
17679 [(set (reg:CCC FLAGS_REG)
17680 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17681 (match_operand:SI 2 "nonimmediate_operand" "rm")
17682 (match_operand:SI 3 "const_int_operand" "i")]
17683 UNSPECV_LWPINS_INTRINSIC))
17684 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17685 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17688 (define_insn "*lwp_lwpins<mode>3_1"
17689 [(set (reg:CCC FLAGS_REG)
17690 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17691 (match_operand:SI 1 "nonimmediate_operand" "rm")
17692 (match_operand:SI 2 "const_int_operand" "i")]
17693 UNSPECV_LWPINS_INTRINSIC))]
17695 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17696 [(set_attr "type" "lwp")
17697 (set_attr "mode" "<MODE>")
17698 (set (attr "length")
17699 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17701 (define_insn "rdfsbase<mode>"
17702 [(set (match_operand:SWI48 0 "register_operand" "=r")
17703 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17704 "TARGET_64BIT && TARGET_FSGSBASE"
17706 [(set_attr "type" "other")
17707 (set_attr "prefix_extra" "2")])
17709 (define_insn "rdgsbase<mode>"
17710 [(set (match_operand:SWI48 0 "register_operand" "=r")
17711 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17712 "TARGET_64BIT && TARGET_FSGSBASE"
17714 [(set_attr "type" "other")
17715 (set_attr "prefix_extra" "2")])
17717 (define_insn "wrfsbase<mode>"
17718 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17720 "TARGET_64BIT && TARGET_FSGSBASE"
17722 [(set_attr "type" "other")
17723 (set_attr "prefix_extra" "2")])
17725 (define_insn "wrgsbase<mode>"
17726 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17728 "TARGET_64BIT && TARGET_FSGSBASE"
17730 [(set_attr "type" "other")
17731 (set_attr "prefix_extra" "2")])
17733 (define_expand "rdrand<mode>"
17734 [(set (match_operand:SWI248 0 "register_operand" "=r")
17735 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17738 rtx retry_label, insn, ccc;
17740 retry_label = gen_label_rtx ();
17742 emit_label (retry_label);
17744 /* Generate rdrand. */
17745 emit_insn (gen_rdrand<mode>_1 (operands[0]));
17747 /* Retry if the carry flag isn't valid. */
17748 ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
17749 ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
17750 ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
17751 gen_rtx_LABEL_REF (VOIDmode, retry_label));
17752 insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
17753 JUMP_LABEL (insn) = retry_label;
17758 (define_insn "rdrand<mode>_1"
17759 [(set (match_operand:SWI248 0 "register_operand" "=r")
17760 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17763 [(set_attr "type" "other")
17764 (set_attr "prefix_extra" "1")])
17768 (include "sync.md")