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, 2011, 2012
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 ;; E -- print address with DImode register names if TARGET_64BIT.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;; %b0 would print %al if operands[0] is reg 0.
47 ;; w -- likewise, print the HImode name of the register.
48 ;; k -- likewise, print the SImode name of the register.
49 ;; q -- likewise, print the DImode name of the register.
50 ;; x -- likewise, print the V4SFmode name of the register.
51 ;; t -- likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; p -- print raw symbol name.
58 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
59 ;; & -- print some in-use local-dynamic symbol name.
60 ;; H -- print a memory address offset by 8; used for sse high-parts
61 ;; K -- print HLE lock prefix
62 ;; Y -- print condition for XOP pcom* instruction.
63 ;; + -- print a branch hint as 'cs' or 'ds' prefix
64 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
65 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
66 ;; @ -- print a segment register of thread base pointer load
67 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
69 (define_c_enum "unspec" [
70 ;; Relocation specifiers
81 UNSPEC_MACHOPIC_OFFSET
91 UNSPEC_MEMORY_BLOCKAGE
101 ;; Other random patterns
110 UNSPEC_LD_MPIC ; load_macho_picbase
112 UNSPEC_DIV_ALREADY_SPLIT
113 UNSPEC_MS_TO_SYSV_CALL
114 UNSPEC_CALL_NEEDS_VZEROUPPER
119 ;; For SSE/MMX support:
127 ;; Generic math support
129 UNSPEC_IEEE_MIN ; not commutative
130 UNSPEC_IEEE_MAX ; not commutative
132 ;; x87 Floating point
148 UNSPEC_FRNDINT_MASK_PM
152 ;; x87 Double output FP
187 (define_c_enum "unspecv" [
190 UNSPECV_PROBE_STACK_RANGE
193 UNSPECV_SPLIT_STACK_RETURN
199 UNSPECV_LLWP_INTRINSIC
200 UNSPECV_SLWP_INTRINSIC
201 UNSPECV_LWPVAL_INTRINSIC
202 UNSPECV_LWPINS_INTRINSIC
208 ;; For RDRAND support
218 ;; Constants to represent rounding modes in the ROUND instruction
227 ;; Constants to represent pcomtrue/pcomfalse variants
237 ;; Constants used in the XOP pperm instruction
239 [(PPERM_SRC 0x00) /* copy source */
240 (PPERM_INVERT 0x20) /* invert source */
241 (PPERM_REVERSE 0x40) /* bit reverse source */
242 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
243 (PPERM_ZERO 0x80) /* all 0's */
244 (PPERM_ONES 0xa0) /* all 1's */
245 (PPERM_SIGN 0xc0) /* propagate sign bit */
246 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
247 (PPERM_SRC1 0x00) /* use first source byte */
248 (PPERM_SRC2 0x10) /* use second source byte */
251 ;; Registers by name.
304 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
307 ;; In C guard expressions, put expressions which may be compile-time
308 ;; constants first. This allows for better optimization. For
309 ;; example, write "TARGET_64BIT && reload_completed", not
310 ;; "reload_completed && TARGET_64BIT".
314 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
315 atom,generic64,amdfam10,bdver1,bdver2,btver1"
316 (const (symbol_ref "ix86_schedule")))
318 ;; A basic instruction type. Refinements due to arguments to be
319 ;; provided in other attributes.
322 alu,alu1,negnot,imov,imovx,lea,
323 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
324 icmp,test,ibr,setcc,icmov,
325 push,pop,call,callv,leave,
327 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
328 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
329 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
330 ssemuladd,sse4arg,lwp,
331 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
332 (const_string "other"))
334 ;; Main data type used by the insn
336 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
337 (const_string "unknown"))
339 ;; The CPU unit operations uses.
340 (define_attr "unit" "integer,i387,sse,mmx,unknown"
341 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
342 (const_string "i387")
343 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
344 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
345 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
347 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
349 (eq_attr "type" "other")
350 (const_string "unknown")]
351 (const_string "integer")))
353 ;; The (bounding maximum) length of an instruction immediate.
354 (define_attr "length_immediate" ""
355 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
358 (eq_attr "unit" "i387,sse,mmx")
360 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
361 rotate,rotatex,rotate1,imul,icmp,push,pop")
362 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
363 (eq_attr "type" "imov,test")
364 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
365 (eq_attr "type" "call")
366 (if_then_else (match_operand 0 "constant_call_address_operand")
369 (eq_attr "type" "callv")
370 (if_then_else (match_operand 1 "constant_call_address_operand")
373 ;; We don't know the size before shorten_branches. Expect
374 ;; the instruction to fit for better scheduling.
375 (eq_attr "type" "ibr")
378 (symbol_ref "/* Update immediate_length and other attributes! */
379 gcc_unreachable (),1")))
381 ;; The (bounding maximum) length of an instruction address.
382 (define_attr "length_address" ""
383 (cond [(eq_attr "type" "str,other,multi,fxch")
385 (and (eq_attr "type" "call")
386 (match_operand 0 "constant_call_address_operand"))
388 (and (eq_attr "type" "callv")
389 (match_operand 1 "constant_call_address_operand"))
392 (symbol_ref "ix86_attr_length_address_default (insn)")))
394 ;; Set when length prefix is used.
395 (define_attr "prefix_data16" ""
396 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
398 (eq_attr "mode" "HI")
400 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
405 ;; Set when string REP prefix is used.
406 (define_attr "prefix_rep" ""
407 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
409 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
414 ;; Set when 0f opcode prefix is used.
415 (define_attr "prefix_0f" ""
417 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
418 (eq_attr "unit" "sse,mmx"))
422 ;; Set when REX opcode prefix is used.
423 (define_attr "prefix_rex" ""
424 (cond [(not (match_test "TARGET_64BIT"))
426 (and (eq_attr "mode" "DI")
427 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
428 (eq_attr "unit" "!mmx")))
430 (and (eq_attr "mode" "QI")
431 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
433 (match_test "x86_extended_reg_mentioned_p (insn)")
435 (and (eq_attr "type" "imovx")
436 (match_operand:QI 1 "ext_QIreg_operand"))
441 ;; There are also additional prefixes in 3DNOW, SSSE3.
442 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
443 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
444 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
445 (define_attr "prefix_extra" ""
446 (cond [(eq_attr "type" "ssemuladd,sse4arg")
448 (eq_attr "type" "sseiadd1,ssecvt1")
453 ;; Prefix used: original, VEX or maybe VEX.
454 (define_attr "prefix" "orig,vex,maybe_vex"
455 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
457 (const_string "orig")))
459 ;; VEX W bit is used.
460 (define_attr "prefix_vex_w" "" (const_int 0))
462 ;; The length of VEX prefix
463 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
464 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
465 ;; still prefix_0f 1, with prefix_extra 1.
466 (define_attr "length_vex" ""
467 (if_then_else (and (eq_attr "prefix_0f" "1")
468 (eq_attr "prefix_extra" "0"))
469 (if_then_else (eq_attr "prefix_vex_w" "1")
470 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
471 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
472 (if_then_else (eq_attr "prefix_vex_w" "1")
473 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
474 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
476 ;; Set when modrm byte is used.
477 (define_attr "modrm" ""
478 (cond [(eq_attr "type" "str,leave")
480 (eq_attr "unit" "i387")
482 (and (eq_attr "type" "incdec")
483 (and (not (match_test "TARGET_64BIT"))
484 (ior (match_operand:SI 1 "register_operand")
485 (match_operand:HI 1 "register_operand"))))
487 (and (eq_attr "type" "push")
488 (not (match_operand 1 "memory_operand")))
490 (and (eq_attr "type" "pop")
491 (not (match_operand 0 "memory_operand")))
493 (and (eq_attr "type" "imov")
494 (and (not (eq_attr "mode" "DI"))
495 (ior (and (match_operand 0 "register_operand")
496 (match_operand 1 "immediate_operand"))
497 (ior (and (match_operand 0 "ax_reg_operand")
498 (match_operand 1 "memory_displacement_only_operand"))
499 (and (match_operand 0 "memory_displacement_only_operand")
500 (match_operand 1 "ax_reg_operand"))))))
502 (and (eq_attr "type" "call")
503 (match_operand 0 "constant_call_address_operand"))
505 (and (eq_attr "type" "callv")
506 (match_operand 1 "constant_call_address_operand"))
508 (and (eq_attr "type" "alu,alu1,icmp,test")
509 (match_operand 0 "ax_reg_operand"))
510 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
514 ;; The (bounding maximum) length of an instruction in bytes.
515 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
516 ;; Later we may want to split them and compute proper length as for
518 (define_attr "length" ""
519 (cond [(eq_attr "type" "other,multi,fistp,frndint")
521 (eq_attr "type" "fcmp")
523 (eq_attr "unit" "i387")
525 (plus (attr "prefix_data16")
526 (attr "length_address")))
527 (ior (eq_attr "prefix" "vex")
528 (and (eq_attr "prefix" "maybe_vex")
529 (match_test "TARGET_AVX")))
530 (plus (attr "length_vex")
531 (plus (attr "length_immediate")
533 (attr "length_address"))))]
534 (plus (plus (attr "modrm")
535 (plus (attr "prefix_0f")
536 (plus (attr "prefix_rex")
537 (plus (attr "prefix_extra")
539 (plus (attr "prefix_rep")
540 (plus (attr "prefix_data16")
541 (plus (attr "length_immediate")
542 (attr "length_address")))))))
544 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
545 ;; `store' if there is a simple memory reference therein, or `unknown'
546 ;; if the instruction is complex.
548 (define_attr "memory" "none,load,store,both,unknown"
549 (cond [(eq_attr "type" "other,multi,str,lwp")
550 (const_string "unknown")
551 (eq_attr "type" "lea,fcmov,fpspc")
552 (const_string "none")
553 (eq_attr "type" "fistp,leave")
554 (const_string "both")
555 (eq_attr "type" "frndint")
556 (const_string "load")
557 (eq_attr "type" "push")
558 (if_then_else (match_operand 1 "memory_operand")
559 (const_string "both")
560 (const_string "store"))
561 (eq_attr "type" "pop")
562 (if_then_else (match_operand 0 "memory_operand")
563 (const_string "both")
564 (const_string "load"))
565 (eq_attr "type" "setcc")
566 (if_then_else (match_operand 0 "memory_operand")
567 (const_string "store")
568 (const_string "none"))
569 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
570 (if_then_else (ior (match_operand 0 "memory_operand")
571 (match_operand 1 "memory_operand"))
572 (const_string "load")
573 (const_string "none"))
574 (eq_attr "type" "ibr")
575 (if_then_else (match_operand 0 "memory_operand")
576 (const_string "load")
577 (const_string "none"))
578 (eq_attr "type" "call")
579 (if_then_else (match_operand 0 "constant_call_address_operand")
580 (const_string "none")
581 (const_string "load"))
582 (eq_attr "type" "callv")
583 (if_then_else (match_operand 1 "constant_call_address_operand")
584 (const_string "none")
585 (const_string "load"))
586 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
587 (match_operand 1 "memory_operand"))
588 (const_string "both")
589 (and (match_operand 0 "memory_operand")
590 (match_operand 1 "memory_operand"))
591 (const_string "both")
592 (match_operand 0 "memory_operand")
593 (const_string "store")
594 (match_operand 1 "memory_operand")
595 (const_string "load")
597 "!alu1,negnot,ishift1,
598 imov,imovx,icmp,test,bitmanip,
600 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
601 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
602 (match_operand 2 "memory_operand"))
603 (const_string "load")
604 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
605 (match_operand 3 "memory_operand"))
606 (const_string "load")
608 (const_string "none")))
610 ;; Indicates if an instruction has both an immediate and a displacement.
612 (define_attr "imm_disp" "false,true,unknown"
613 (cond [(eq_attr "type" "other,multi")
614 (const_string "unknown")
615 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
616 (and (match_operand 0 "memory_displacement_operand")
617 (match_operand 1 "immediate_operand")))
618 (const_string "true")
619 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
620 (and (match_operand 0 "memory_displacement_operand")
621 (match_operand 2 "immediate_operand")))
622 (const_string "true")
624 (const_string "false")))
626 ;; Indicates if an FP operation has an integer source.
628 (define_attr "fp_int_src" "false,true"
629 (const_string "false"))
631 ;; Defines rounding mode of an FP operation.
633 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
634 (const_string "any"))
636 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
637 (define_attr "use_carry" "0,1" (const_string "0"))
639 ;; Define attribute to indicate unaligned ssemov insns
640 (define_attr "movu" "0,1" (const_string "0"))
642 ;; Used to control the "enabled" attribute on a per-instruction basis.
643 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,avx2,noavx2,bmi2"
644 (const_string "base"))
646 (define_attr "enabled" ""
647 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
648 (eq_attr "isa" "sse2_noavx")
649 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
650 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
651 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
652 (eq_attr "isa" "sse4_noavx")
653 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
654 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
655 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
656 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
657 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
658 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
662 ;; Describe a user's asm statement.
663 (define_asm_attributes
664 [(set_attr "length" "128")
665 (set_attr "type" "multi")])
667 (define_code_iterator plusminus [plus minus])
669 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
671 ;; Base name for define_insn
672 (define_code_attr plusminus_insn
673 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
674 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
676 ;; Base name for insn mnemonic.
677 (define_code_attr plusminus_mnemonic
678 [(plus "add") (ss_plus "adds") (us_plus "addus")
679 (minus "sub") (ss_minus "subs") (us_minus "subus")])
680 (define_code_attr plusminus_carry_mnemonic
681 [(plus "adc") (minus "sbb")])
683 ;; Mark commutative operators as such in constraints.
684 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
685 (minus "") (ss_minus "") (us_minus "")])
687 ;; Mapping of max and min
688 (define_code_iterator maxmin [smax smin umax umin])
690 ;; Mapping of signed max and min
691 (define_code_iterator smaxmin [smax smin])
693 ;; Mapping of unsigned max and min
694 (define_code_iterator umaxmin [umax umin])
696 ;; Base name for integer and FP insn mnemonic
697 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
698 (umax "maxu") (umin "minu")])
699 (define_code_attr maxmin_float [(smax "max") (smin "min")])
701 ;; Mapping of logic operators
702 (define_code_iterator any_logic [and ior xor])
703 (define_code_iterator any_or [ior xor])
705 ;; Base name for insn mnemonic.
706 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
708 ;; Mapping of logic-shift operators
709 (define_code_iterator any_lshift [ashift lshiftrt])
711 ;; Mapping of shift-right operators
712 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
714 ;; Mapping of all shift operators
715 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
717 ;; Base name for define_insn
718 (define_code_attr shift_insn
719 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
721 ;; Base name for insn mnemonic.
722 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
723 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
725 ;; Mapping of rotate operators
726 (define_code_iterator any_rotate [rotate rotatert])
728 ;; Base name for define_insn
729 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
731 ;; Base name for insn mnemonic.
732 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
734 ;; Mapping of abs neg operators
735 (define_code_iterator absneg [abs neg])
737 ;; Base name for x87 insn mnemonic.
738 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
740 ;; Used in signed and unsigned widening multiplications.
741 (define_code_iterator any_extend [sign_extend zero_extend])
743 ;; Prefix for insn menmonic.
744 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
746 ;; Prefix for define_insn
747 (define_code_attr u [(sign_extend "") (zero_extend "u")])
748 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
750 ;; All integer modes.
751 (define_mode_iterator SWI1248x [QI HI SI DI])
753 ;; All integer modes without QImode.
754 (define_mode_iterator SWI248x [HI SI DI])
756 ;; All integer modes without QImode and HImode.
757 (define_mode_iterator SWI48x [SI DI])
759 ;; All integer modes without SImode and DImode.
760 (define_mode_iterator SWI12 [QI HI])
762 ;; All integer modes without DImode.
763 (define_mode_iterator SWI124 [QI HI SI])
765 ;; All integer modes without QImode and DImode.
766 (define_mode_iterator SWI24 [HI SI])
768 ;; Single word integer modes.
769 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
771 ;; Single word integer modes without QImode.
772 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
774 ;; Single word integer modes without QImode and HImode.
775 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
777 ;; All math-dependant single and double word integer modes.
778 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
779 (HI "TARGET_HIMODE_MATH")
780 SI DI (TI "TARGET_64BIT")])
782 ;; Math-dependant single word integer modes.
783 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
784 (HI "TARGET_HIMODE_MATH")
785 SI (DI "TARGET_64BIT")])
787 ;; Math-dependant integer modes without DImode.
788 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
789 (HI "TARGET_HIMODE_MATH")
792 ;; Math-dependant single word integer modes without QImode.
793 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
794 SI (DI "TARGET_64BIT")])
796 ;; Double word integer modes.
797 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
798 (TI "TARGET_64BIT")])
800 ;; Double word integer modes as mode attribute.
801 (define_mode_attr DWI [(SI "DI") (DI "TI")])
802 (define_mode_attr dwi [(SI "di") (DI "ti")])
804 ;; Half mode for double word integer modes.
805 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
806 (DI "TARGET_64BIT")])
808 ;; Instruction suffix for integer modes.
809 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
811 ;; Pointer size prefix for integer modes (Intel asm dialect)
812 (define_mode_attr iptrsize [(QI "BYTE")
817 ;; Register class for integer modes.
818 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
820 ;; Immediate operand constraint for integer modes.
821 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
823 ;; General operand constraint for word modes.
824 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
826 ;; Immediate operand constraint for double integer modes.
827 (define_mode_attr di [(SI "nF") (DI "e")])
829 ;; Immediate operand constraint for shifts.
830 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
832 ;; General operand predicate for integer modes.
833 (define_mode_attr general_operand
834 [(QI "general_operand")
835 (HI "general_operand")
836 (SI "x86_64_general_operand")
837 (DI "x86_64_general_operand")
838 (TI "x86_64_general_operand")])
840 ;; General sign/zero extend operand predicate for integer modes.
841 (define_mode_attr general_szext_operand
842 [(QI "general_operand")
843 (HI "general_operand")
844 (SI "x86_64_szext_general_operand")
845 (DI "x86_64_szext_general_operand")])
847 ;; Immediate operand predicate for integer modes.
848 (define_mode_attr immediate_operand
849 [(QI "immediate_operand")
850 (HI "immediate_operand")
851 (SI "x86_64_immediate_operand")
852 (DI "x86_64_immediate_operand")])
854 ;; Nonmemory operand predicate for integer modes.
855 (define_mode_attr nonmemory_operand
856 [(QI "nonmemory_operand")
857 (HI "nonmemory_operand")
858 (SI "x86_64_nonmemory_operand")
859 (DI "x86_64_nonmemory_operand")])
861 ;; Operand predicate for shifts.
862 (define_mode_attr shift_operand
863 [(QI "nonimmediate_operand")
864 (HI "nonimmediate_operand")
865 (SI "nonimmediate_operand")
866 (DI "shiftdi_operand")
867 (TI "register_operand")])
869 ;; Operand predicate for shift argument.
870 (define_mode_attr shift_immediate_operand
871 [(QI "const_1_to_31_operand")
872 (HI "const_1_to_31_operand")
873 (SI "const_1_to_31_operand")
874 (DI "const_1_to_63_operand")])
876 ;; Input operand predicate for arithmetic left shifts.
877 (define_mode_attr ashl_input_operand
878 [(QI "nonimmediate_operand")
879 (HI "nonimmediate_operand")
880 (SI "nonimmediate_operand")
881 (DI "ashldi_input_operand")
882 (TI "reg_or_pm1_operand")])
884 ;; SSE and x87 SFmode and DFmode floating point modes
885 (define_mode_iterator MODEF [SF DF])
887 ;; All x87 floating point modes
888 (define_mode_iterator X87MODEF [SF DF XF])
890 ;; SSE instruction suffix for various modes
891 (define_mode_attr ssemodesuffix
893 (V8SF "ps") (V4DF "pd")
894 (V4SF "ps") (V2DF "pd")
895 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
896 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
898 ;; SSE vector suffix for floating point modes
899 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
901 ;; SSE vector mode corresponding to a scalar mode
902 (define_mode_attr ssevecmode
903 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
905 ;; Instruction suffix for REX 64bit operators.
906 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
908 ;; This mode iterator allows :P to be used for patterns that operate on
909 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
910 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
912 ;; This mode iterator allows :W to be used for patterns that operate on
913 ;; word_mode sized quantities.
914 (define_mode_iterator W
915 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
917 ;; This mode iterator allows :PTR to be used for patterns that operate on
918 ;; ptr_mode sized quantities.
919 (define_mode_iterator PTR
920 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
922 ;; Scheduling descriptions
924 (include "pentium.md")
927 (include "athlon.md")
928 (include "bdver1.md")
934 ;; Operand and operator predicates and constraints
936 (include "predicates.md")
937 (include "constraints.md")
940 ;; Compare and branch/compare and store instructions.
942 (define_expand "cbranch<mode>4"
943 [(set (reg:CC FLAGS_REG)
944 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
945 (match_operand:SDWIM 2 "<general_operand>")))
946 (set (pc) (if_then_else
947 (match_operator 0 "ordered_comparison_operator"
948 [(reg:CC FLAGS_REG) (const_int 0)])
949 (label_ref (match_operand 3))
953 if (MEM_P (operands[1]) && MEM_P (operands[2]))
954 operands[1] = force_reg (<MODE>mode, operands[1]);
955 ix86_expand_branch (GET_CODE (operands[0]),
956 operands[1], operands[2], operands[3]);
960 (define_expand "cstore<mode>4"
961 [(set (reg:CC FLAGS_REG)
962 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
963 (match_operand:SWIM 3 "<general_operand>")))
964 (set (match_operand:QI 0 "register_operand")
965 (match_operator 1 "ordered_comparison_operator"
966 [(reg:CC FLAGS_REG) (const_int 0)]))]
969 if (MEM_P (operands[2]) && MEM_P (operands[3]))
970 operands[2] = force_reg (<MODE>mode, operands[2]);
971 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
972 operands[2], operands[3]);
976 (define_expand "cmp<mode>_1"
977 [(set (reg:CC FLAGS_REG)
978 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
979 (match_operand:SWI48 1 "<general_operand>")))])
981 (define_insn "*cmp<mode>_ccno_1"
982 [(set (reg FLAGS_REG)
983 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
984 (match_operand:SWI 1 "const0_operand")))]
985 "ix86_match_ccmode (insn, CCNOmode)"
987 test{<imodesuffix>}\t%0, %0
988 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
989 [(set_attr "type" "test,icmp")
990 (set_attr "length_immediate" "0,1")
991 (set_attr "mode" "<MODE>")])
993 (define_insn "*cmp<mode>_1"
994 [(set (reg FLAGS_REG)
995 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
996 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
997 "ix86_match_ccmode (insn, CCmode)"
998 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
999 [(set_attr "type" "icmp")
1000 (set_attr "mode" "<MODE>")])
1002 (define_insn "*cmp<mode>_minus_1"
1003 [(set (reg FLAGS_REG)
1005 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1006 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1008 "ix86_match_ccmode (insn, CCGOCmode)"
1009 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1010 [(set_attr "type" "icmp")
1011 (set_attr "mode" "<MODE>")])
1013 (define_insn "*cmpqi_ext_1"
1014 [(set (reg FLAGS_REG)
1016 (match_operand:QI 0 "general_operand" "Qm")
1019 (match_operand 1 "ext_register_operand" "Q")
1021 (const_int 8)) 0)))]
1022 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1023 "cmp{b}\t{%h1, %0|%0, %h1}"
1024 [(set_attr "type" "icmp")
1025 (set_attr "mode" "QI")])
1027 (define_insn "*cmpqi_ext_1_rex64"
1028 [(set (reg FLAGS_REG)
1030 (match_operand:QI 0 "register_operand" "Q")
1033 (match_operand 1 "ext_register_operand" "Q")
1035 (const_int 8)) 0)))]
1036 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1037 "cmp{b}\t{%h1, %0|%0, %h1}"
1038 [(set_attr "type" "icmp")
1039 (set_attr "mode" "QI")])
1041 (define_insn "*cmpqi_ext_2"
1042 [(set (reg FLAGS_REG)
1046 (match_operand 0 "ext_register_operand" "Q")
1049 (match_operand:QI 1 "const0_operand")))]
1050 "ix86_match_ccmode (insn, CCNOmode)"
1052 [(set_attr "type" "test")
1053 (set_attr "length_immediate" "0")
1054 (set_attr "mode" "QI")])
1056 (define_expand "cmpqi_ext_3"
1057 [(set (reg:CC FLAGS_REG)
1061 (match_operand 0 "ext_register_operand")
1064 (match_operand:QI 1 "immediate_operand")))])
1066 (define_insn "*cmpqi_ext_3_insn"
1067 [(set (reg FLAGS_REG)
1071 (match_operand 0 "ext_register_operand" "Q")
1074 (match_operand:QI 1 "general_operand" "Qmn")))]
1075 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1076 "cmp{b}\t{%1, %h0|%h0, %1}"
1077 [(set_attr "type" "icmp")
1078 (set_attr "modrm" "1")
1079 (set_attr "mode" "QI")])
1081 (define_insn "*cmpqi_ext_3_insn_rex64"
1082 [(set (reg FLAGS_REG)
1086 (match_operand 0 "ext_register_operand" "Q")
1089 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1090 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1091 "cmp{b}\t{%1, %h0|%h0, %1}"
1092 [(set_attr "type" "icmp")
1093 (set_attr "modrm" "1")
1094 (set_attr "mode" "QI")])
1096 (define_insn "*cmpqi_ext_4"
1097 [(set (reg FLAGS_REG)
1101 (match_operand 0 "ext_register_operand" "Q")
1106 (match_operand 1 "ext_register_operand" "Q")
1108 (const_int 8)) 0)))]
1109 "ix86_match_ccmode (insn, CCmode)"
1110 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1111 [(set_attr "type" "icmp")
1112 (set_attr "mode" "QI")])
1114 ;; These implement float point compares.
1115 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1116 ;; which would allow mix and match FP modes on the compares. Which is what
1117 ;; the old patterns did, but with many more of them.
1119 (define_expand "cbranchxf4"
1120 [(set (reg:CC FLAGS_REG)
1121 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1122 (match_operand:XF 2 "nonmemory_operand")))
1123 (set (pc) (if_then_else
1124 (match_operator 0 "ix86_fp_comparison_operator"
1127 (label_ref (match_operand 3))
1131 ix86_expand_branch (GET_CODE (operands[0]),
1132 operands[1], operands[2], operands[3]);
1136 (define_expand "cstorexf4"
1137 [(set (reg:CC FLAGS_REG)
1138 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1139 (match_operand:XF 3 "nonmemory_operand")))
1140 (set (match_operand:QI 0 "register_operand")
1141 (match_operator 1 "ix86_fp_comparison_operator"
1146 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1147 operands[2], operands[3]);
1151 (define_expand "cbranch<mode>4"
1152 [(set (reg:CC FLAGS_REG)
1153 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1154 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1155 (set (pc) (if_then_else
1156 (match_operator 0 "ix86_fp_comparison_operator"
1159 (label_ref (match_operand 3))
1161 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1163 ix86_expand_branch (GET_CODE (operands[0]),
1164 operands[1], operands[2], operands[3]);
1168 (define_expand "cstore<mode>4"
1169 [(set (reg:CC FLAGS_REG)
1170 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1171 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1172 (set (match_operand:QI 0 "register_operand")
1173 (match_operator 1 "ix86_fp_comparison_operator"
1176 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1178 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1179 operands[2], operands[3]);
1183 (define_expand "cbranchcc4"
1184 [(set (pc) (if_then_else
1185 (match_operator 0 "comparison_operator"
1186 [(match_operand 1 "flags_reg_operand")
1187 (match_operand 2 "const0_operand")])
1188 (label_ref (match_operand 3))
1192 ix86_expand_branch (GET_CODE (operands[0]),
1193 operands[1], operands[2], operands[3]);
1197 (define_expand "cstorecc4"
1198 [(set (match_operand:QI 0 "register_operand")
1199 (match_operator 1 "comparison_operator"
1200 [(match_operand 2 "flags_reg_operand")
1201 (match_operand 3 "const0_operand")]))]
1204 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1205 operands[2], operands[3]);
1210 ;; FP compares, step 1:
1211 ;; Set the FP condition codes.
1213 ;; CCFPmode compare with exceptions
1214 ;; CCFPUmode compare with no exceptions
1216 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1217 ;; used to manage the reg stack popping would not be preserved.
1219 (define_insn "*cmpfp_0"
1220 [(set (match_operand:HI 0 "register_operand" "=a")
1223 (match_operand 1 "register_operand" "f")
1224 (match_operand 2 "const0_operand"))]
1226 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1227 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1228 "* return output_fp_compare (insn, operands, false, false);"
1229 [(set_attr "type" "multi")
1230 (set_attr "unit" "i387")
1232 (cond [(match_operand:SF 1)
1234 (match_operand:DF 1)
1237 (const_string "XF")))])
1239 (define_insn_and_split "*cmpfp_0_cc"
1240 [(set (reg:CCFP FLAGS_REG)
1242 (match_operand 1 "register_operand" "f")
1243 (match_operand 2 "const0_operand")))
1244 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1245 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1246 && TARGET_SAHF && !TARGET_CMOVE
1247 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1249 "&& reload_completed"
1252 [(compare:CCFP (match_dup 1)(match_dup 2))]
1254 (set (reg:CC FLAGS_REG)
1255 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1257 [(set_attr "type" "multi")
1258 (set_attr "unit" "i387")
1260 (cond [(match_operand:SF 1)
1262 (match_operand:DF 1)
1265 (const_string "XF")))])
1267 (define_insn "*cmpfp_xf"
1268 [(set (match_operand:HI 0 "register_operand" "=a")
1271 (match_operand:XF 1 "register_operand" "f")
1272 (match_operand:XF 2 "register_operand" "f"))]
1275 "* return output_fp_compare (insn, operands, false, false);"
1276 [(set_attr "type" "multi")
1277 (set_attr "unit" "i387")
1278 (set_attr "mode" "XF")])
1280 (define_insn_and_split "*cmpfp_xf_cc"
1281 [(set (reg:CCFP FLAGS_REG)
1283 (match_operand:XF 1 "register_operand" "f")
1284 (match_operand:XF 2 "register_operand" "f")))
1285 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1287 && TARGET_SAHF && !TARGET_CMOVE"
1289 "&& reload_completed"
1292 [(compare:CCFP (match_dup 1)(match_dup 2))]
1294 (set (reg:CC FLAGS_REG)
1295 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1297 [(set_attr "type" "multi")
1298 (set_attr "unit" "i387")
1299 (set_attr "mode" "XF")])
1301 (define_insn "*cmpfp_<mode>"
1302 [(set (match_operand:HI 0 "register_operand" "=a")
1305 (match_operand:MODEF 1 "register_operand" "f")
1306 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1309 "* return output_fp_compare (insn, operands, false, false);"
1310 [(set_attr "type" "multi")
1311 (set_attr "unit" "i387")
1312 (set_attr "mode" "<MODE>")])
1314 (define_insn_and_split "*cmpfp_<mode>_cc"
1315 [(set (reg:CCFP FLAGS_REG)
1317 (match_operand:MODEF 1 "register_operand" "f")
1318 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1319 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1321 && TARGET_SAHF && !TARGET_CMOVE"
1323 "&& reload_completed"
1326 [(compare:CCFP (match_dup 1)(match_dup 2))]
1328 (set (reg:CC FLAGS_REG)
1329 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1331 [(set_attr "type" "multi")
1332 (set_attr "unit" "i387")
1333 (set_attr "mode" "<MODE>")])
1335 (define_insn "*cmpfp_u"
1336 [(set (match_operand:HI 0 "register_operand" "=a")
1339 (match_operand 1 "register_operand" "f")
1340 (match_operand 2 "register_operand" "f"))]
1342 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1343 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1344 "* return output_fp_compare (insn, operands, false, true);"
1345 [(set_attr "type" "multi")
1346 (set_attr "unit" "i387")
1348 (cond [(match_operand:SF 1)
1350 (match_operand:DF 1)
1353 (const_string "XF")))])
1355 (define_insn_and_split "*cmpfp_u_cc"
1356 [(set (reg:CCFPU FLAGS_REG)
1358 (match_operand 1 "register_operand" "f")
1359 (match_operand 2 "register_operand" "f")))
1360 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1361 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1362 && TARGET_SAHF && !TARGET_CMOVE
1363 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1365 "&& reload_completed"
1368 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1370 (set (reg:CC FLAGS_REG)
1371 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1373 [(set_attr "type" "multi")
1374 (set_attr "unit" "i387")
1376 (cond [(match_operand:SF 1)
1378 (match_operand:DF 1)
1381 (const_string "XF")))])
1383 (define_insn "*cmpfp_<mode>"
1384 [(set (match_operand:HI 0 "register_operand" "=a")
1387 (match_operand 1 "register_operand" "f")
1388 (match_operator 3 "float_operator"
1389 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1391 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1392 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1393 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1394 "* return output_fp_compare (insn, operands, false, false);"
1395 [(set_attr "type" "multi")
1396 (set_attr "unit" "i387")
1397 (set_attr "fp_int_src" "true")
1398 (set_attr "mode" "<MODE>")])
1400 (define_insn_and_split "*cmpfp_<mode>_cc"
1401 [(set (reg:CCFP FLAGS_REG)
1403 (match_operand 1 "register_operand" "f")
1404 (match_operator 3 "float_operator"
1405 [(match_operand:SWI24 2 "memory_operand" "m")])))
1406 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1407 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1408 && TARGET_SAHF && !TARGET_CMOVE
1409 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1410 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1412 "&& reload_completed"
1417 (match_op_dup 3 [(match_dup 2)]))]
1419 (set (reg:CC FLAGS_REG)
1420 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1422 [(set_attr "type" "multi")
1423 (set_attr "unit" "i387")
1424 (set_attr "fp_int_src" "true")
1425 (set_attr "mode" "<MODE>")])
1427 ;; FP compares, step 2
1428 ;; Move the fpsw to ax.
1430 (define_insn "x86_fnstsw_1"
1431 [(set (match_operand:HI 0 "register_operand" "=a")
1432 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1435 [(set (attr "length")
1436 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1437 (set_attr "mode" "SI")
1438 (set_attr "unit" "i387")])
1440 ;; FP compares, step 3
1441 ;; Get ax into flags, general case.
1443 (define_insn "x86_sahf_1"
1444 [(set (reg:CC FLAGS_REG)
1445 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1449 #ifndef HAVE_AS_IX86_SAHF
1451 return ASM_BYTE "0x9e";
1456 [(set_attr "length" "1")
1457 (set_attr "athlon_decode" "vector")
1458 (set_attr "amdfam10_decode" "direct")
1459 (set_attr "bdver1_decode" "direct")
1460 (set_attr "mode" "SI")])
1462 ;; Pentium Pro can do steps 1 through 3 in one go.
1463 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1464 ;; (these i387 instructions set flags directly)
1465 (define_insn "*cmpfp_i_mixed"
1466 [(set (reg:CCFP FLAGS_REG)
1467 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1468 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1469 "TARGET_MIX_SSE_I387
1470 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1471 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1472 "* return output_fp_compare (insn, operands, true, false);"
1473 [(set_attr "type" "fcmp,ssecomi")
1474 (set_attr "prefix" "orig,maybe_vex")
1476 (if_then_else (match_operand:SF 1)
1478 (const_string "DF")))
1479 (set (attr "prefix_rep")
1480 (if_then_else (eq_attr "type" "ssecomi")
1482 (const_string "*")))
1483 (set (attr "prefix_data16")
1484 (cond [(eq_attr "type" "fcmp")
1486 (eq_attr "mode" "DF")
1489 (const_string "0")))
1490 (set_attr "athlon_decode" "vector")
1491 (set_attr "amdfam10_decode" "direct")
1492 (set_attr "bdver1_decode" "double")])
1494 (define_insn "*cmpfp_i_sse"
1495 [(set (reg:CCFP FLAGS_REG)
1496 (compare:CCFP (match_operand 0 "register_operand" "x")
1497 (match_operand 1 "nonimmediate_operand" "xm")))]
1499 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1500 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1501 "* return output_fp_compare (insn, operands, true, false);"
1502 [(set_attr "type" "ssecomi")
1503 (set_attr "prefix" "maybe_vex")
1505 (if_then_else (match_operand:SF 1)
1507 (const_string "DF")))
1508 (set_attr "prefix_rep" "0")
1509 (set (attr "prefix_data16")
1510 (if_then_else (eq_attr "mode" "DF")
1512 (const_string "0")))
1513 (set_attr "athlon_decode" "vector")
1514 (set_attr "amdfam10_decode" "direct")
1515 (set_attr "bdver1_decode" "double")])
1517 (define_insn "*cmpfp_i_i387"
1518 [(set (reg:CCFP FLAGS_REG)
1519 (compare:CCFP (match_operand 0 "register_operand" "f")
1520 (match_operand 1 "register_operand" "f")))]
1521 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1523 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1524 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1525 "* return output_fp_compare (insn, operands, true, false);"
1526 [(set_attr "type" "fcmp")
1528 (cond [(match_operand:SF 1)
1530 (match_operand:DF 1)
1533 (const_string "XF")))
1534 (set_attr "athlon_decode" "vector")
1535 (set_attr "amdfam10_decode" "direct")
1536 (set_attr "bdver1_decode" "double")])
1538 (define_insn "*cmpfp_iu_mixed"
1539 [(set (reg:CCFPU FLAGS_REG)
1540 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1541 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1542 "TARGET_MIX_SSE_I387
1543 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1544 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1545 "* return output_fp_compare (insn, operands, true, true);"
1546 [(set_attr "type" "fcmp,ssecomi")
1547 (set_attr "prefix" "orig,maybe_vex")
1549 (if_then_else (match_operand:SF 1)
1551 (const_string "DF")))
1552 (set (attr "prefix_rep")
1553 (if_then_else (eq_attr "type" "ssecomi")
1555 (const_string "*")))
1556 (set (attr "prefix_data16")
1557 (cond [(eq_attr "type" "fcmp")
1559 (eq_attr "mode" "DF")
1562 (const_string "0")))
1563 (set_attr "athlon_decode" "vector")
1564 (set_attr "amdfam10_decode" "direct")
1565 (set_attr "bdver1_decode" "double")])
1567 (define_insn "*cmpfp_iu_sse"
1568 [(set (reg:CCFPU FLAGS_REG)
1569 (compare:CCFPU (match_operand 0 "register_operand" "x")
1570 (match_operand 1 "nonimmediate_operand" "xm")))]
1572 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1573 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1574 "* return output_fp_compare (insn, operands, true, true);"
1575 [(set_attr "type" "ssecomi")
1576 (set_attr "prefix" "maybe_vex")
1578 (if_then_else (match_operand:SF 1)
1580 (const_string "DF")))
1581 (set_attr "prefix_rep" "0")
1582 (set (attr "prefix_data16")
1583 (if_then_else (eq_attr "mode" "DF")
1585 (const_string "0")))
1586 (set_attr "athlon_decode" "vector")
1587 (set_attr "amdfam10_decode" "direct")
1588 (set_attr "bdver1_decode" "double")])
1590 (define_insn "*cmpfp_iu_387"
1591 [(set (reg:CCFPU FLAGS_REG)
1592 (compare:CCFPU (match_operand 0 "register_operand" "f")
1593 (match_operand 1 "register_operand" "f")))]
1594 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1596 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1597 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1598 "* return output_fp_compare (insn, operands, true, true);"
1599 [(set_attr "type" "fcmp")
1601 (cond [(match_operand:SF 1)
1603 (match_operand:DF 1)
1606 (const_string "XF")))
1607 (set_attr "athlon_decode" "vector")
1608 (set_attr "amdfam10_decode" "direct")
1609 (set_attr "bdver1_decode" "direct")])
1611 ;; Push/pop instructions.
1613 (define_insn "*push<mode>2"
1614 [(set (match_operand:DWI 0 "push_operand" "=<")
1615 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1618 [(set_attr "type" "multi")
1619 (set_attr "mode" "<MODE>")])
1622 [(set (match_operand:TI 0 "push_operand")
1623 (match_operand:TI 1 "general_operand"))]
1624 "TARGET_64BIT && reload_completed
1625 && !SSE_REG_P (operands[1])"
1627 "ix86_split_long_move (operands); DONE;")
1629 (define_insn "*pushdi2_rex64"
1630 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1631 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1636 [(set_attr "type" "push,multi")
1637 (set_attr "mode" "DI")])
1639 ;; Convert impossible pushes of immediate to existing instructions.
1640 ;; First try to get scratch register and go through it. In case this
1641 ;; fails, push sign extended lower part first and then overwrite
1642 ;; upper part by 32bit move.
1644 [(match_scratch:DI 2 "r")
1645 (set (match_operand:DI 0 "push_operand")
1646 (match_operand:DI 1 "immediate_operand"))]
1647 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1648 && !x86_64_immediate_operand (operands[1], DImode)"
1649 [(set (match_dup 2) (match_dup 1))
1650 (set (match_dup 0) (match_dup 2))])
1652 ;; We need to define this as both peepholer and splitter for case
1653 ;; peephole2 pass is not run.
1654 ;; "&& 1" is needed to keep it from matching the previous pattern.
1656 [(set (match_operand:DI 0 "push_operand")
1657 (match_operand:DI 1 "immediate_operand"))]
1658 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1659 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1660 [(set (match_dup 0) (match_dup 1))
1661 (set (match_dup 2) (match_dup 3))]
1663 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1665 operands[1] = gen_lowpart (DImode, operands[2]);
1666 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1671 [(set (match_operand:DI 0 "push_operand")
1672 (match_operand:DI 1 "immediate_operand"))]
1673 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1674 ? epilogue_completed : reload_completed)
1675 && !symbolic_operand (operands[1], DImode)
1676 && !x86_64_immediate_operand (operands[1], DImode)"
1677 [(set (match_dup 0) (match_dup 1))
1678 (set (match_dup 2) (match_dup 3))]
1680 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1682 operands[1] = gen_lowpart (DImode, operands[2]);
1683 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1688 [(set (match_operand:DI 0 "push_operand")
1689 (match_operand:DI 1 "general_operand"))]
1690 "!TARGET_64BIT && reload_completed
1691 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1693 "ix86_split_long_move (operands); DONE;")
1695 (define_insn "*pushsi2"
1696 [(set (match_operand:SI 0 "push_operand" "=<")
1697 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1700 [(set_attr "type" "push")
1701 (set_attr "mode" "SI")])
1703 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1704 ;; "push a byte/word". But actually we use pushl, which has the effect
1705 ;; of rounding the amount pushed up to a word.
1707 ;; For TARGET_64BIT we always round up to 8 bytes.
1708 (define_insn "*push<mode>2_rex64"
1709 [(set (match_operand:SWI124 0 "push_operand" "=X")
1710 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1713 [(set_attr "type" "push")
1714 (set_attr "mode" "DI")])
1716 (define_insn "*push<mode>2"
1717 [(set (match_operand:SWI12 0 "push_operand" "=X")
1718 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1721 [(set_attr "type" "push")
1722 (set_attr "mode" "SI")])
1724 (define_insn "*push<mode>2_prologue"
1725 [(set (match_operand:W 0 "push_operand" "=<")
1726 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1727 (clobber (mem:BLK (scratch)))]
1729 "push{<imodesuffix>}\t%1"
1730 [(set_attr "type" "push")
1731 (set_attr "mode" "<MODE>")])
1733 (define_insn "*pop<mode>1"
1734 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1735 (match_operand:W 1 "pop_operand" ">"))]
1737 "pop{<imodesuffix>}\t%0"
1738 [(set_attr "type" "pop")
1739 (set_attr "mode" "<MODE>")])
1741 (define_insn "*pop<mode>1_epilogue"
1742 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1743 (match_operand:W 1 "pop_operand" ">"))
1744 (clobber (mem:BLK (scratch)))]
1746 "pop{<imodesuffix>}\t%0"
1747 [(set_attr "type" "pop")
1748 (set_attr "mode" "<MODE>")])
1750 ;; Move instructions.
1752 (define_expand "movoi"
1753 [(set (match_operand:OI 0 "nonimmediate_operand")
1754 (match_operand:OI 1 "general_operand"))]
1756 "ix86_expand_move (OImode, operands); DONE;")
1758 (define_expand "movti"
1759 [(set (match_operand:TI 0 "nonimmediate_operand")
1760 (match_operand:TI 1 "nonimmediate_operand"))]
1761 "TARGET_64BIT || TARGET_SSE"
1764 ix86_expand_move (TImode, operands);
1765 else if (push_operand (operands[0], TImode))
1766 ix86_expand_push (TImode, operands[1]);
1768 ix86_expand_vector_move (TImode, operands);
1772 ;; This expands to what emit_move_complex would generate if we didn't
1773 ;; have a movti pattern. Having this avoids problems with reload on
1774 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1775 ;; to have around all the time.
1776 (define_expand "movcdi"
1777 [(set (match_operand:CDI 0 "nonimmediate_operand")
1778 (match_operand:CDI 1 "general_operand"))]
1781 if (push_operand (operands[0], CDImode))
1782 emit_move_complex_push (CDImode, operands[0], operands[1]);
1784 emit_move_complex_parts (operands[0], operands[1]);
1788 (define_expand "mov<mode>"
1789 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1790 (match_operand:SWI1248x 1 "general_operand"))]
1792 "ix86_expand_move (<MODE>mode, operands); DONE;")
1794 (define_insn "*mov<mode>_xor"
1795 [(set (match_operand:SWI48 0 "register_operand" "=r")
1796 (match_operand:SWI48 1 "const0_operand"))
1797 (clobber (reg:CC FLAGS_REG))]
1800 [(set_attr "type" "alu1")
1801 (set_attr "mode" "SI")
1802 (set_attr "length_immediate" "0")])
1804 (define_insn "*mov<mode>_or"
1805 [(set (match_operand:SWI48 0 "register_operand" "=r")
1806 (match_operand:SWI48 1 "const_int_operand"))
1807 (clobber (reg:CC FLAGS_REG))]
1809 && operands[1] == constm1_rtx"
1810 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1811 [(set_attr "type" "alu1")
1812 (set_attr "mode" "<MODE>")
1813 (set_attr "length_immediate" "1")])
1815 (define_insn "*movoi_internal_avx"
1816 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1817 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1818 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1820 switch (which_alternative)
1823 return standard_sse_constant_opcode (insn, operands[1]);
1826 if (misaligned_operand (operands[0], OImode)
1827 || misaligned_operand (operands[1], OImode))
1829 if (get_attr_mode (insn) == MODE_V8SF)
1830 return "vmovups\t{%1, %0|%0, %1}";
1832 return "vmovdqu\t{%1, %0|%0, %1}";
1836 if (get_attr_mode (insn) == MODE_V8SF)
1837 return "vmovaps\t{%1, %0|%0, %1}";
1839 return "vmovdqa\t{%1, %0|%0, %1}";
1845 [(set_attr "type" "sselog1,ssemov,ssemov")
1846 (set_attr "prefix" "vex")
1848 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1849 (const_string "V8SF")
1850 (and (eq_attr "alternative" "2")
1851 (match_test "TARGET_SSE_TYPELESS_STORES"))
1852 (const_string "V8SF")
1854 (const_string "OI")))])
1856 (define_insn "*movti_internal_rex64"
1857 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1858 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1859 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1861 switch (which_alternative)
1867 return standard_sse_constant_opcode (insn, operands[1]);
1870 /* TDmode values are passed as TImode on the stack. Moving them
1871 to stack may result in unaligned memory access. */
1872 if (misaligned_operand (operands[0], TImode)
1873 || misaligned_operand (operands[1], TImode))
1875 if (get_attr_mode (insn) == MODE_V4SF)
1876 return "%vmovups\t{%1, %0|%0, %1}";
1878 return "%vmovdqu\t{%1, %0|%0, %1}";
1882 if (get_attr_mode (insn) == MODE_V4SF)
1883 return "%vmovaps\t{%1, %0|%0, %1}";
1885 return "%vmovdqa\t{%1, %0|%0, %1}";
1891 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1892 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1894 (cond [(eq_attr "alternative" "0,1")
1896 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1897 (const_string "V4SF")
1898 (and (eq_attr "alternative" "4")
1899 (match_test "TARGET_SSE_TYPELESS_STORES"))
1900 (const_string "V4SF")
1901 (match_test "TARGET_AVX")
1903 (match_test "optimize_function_for_size_p (cfun)")
1904 (const_string "V4SF")
1906 (const_string "TI")))])
1909 [(set (match_operand:TI 0 "nonimmediate_operand")
1910 (match_operand:TI 1 "general_operand"))]
1912 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1914 "ix86_split_long_move (operands); DONE;")
1916 (define_insn "*movti_internal_sse"
1917 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x ,m")
1918 (match_operand:TI 1 "vector_move_operand" "C ,xm,x"))]
1919 "TARGET_SSE && !TARGET_64BIT
1920 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1922 switch (which_alternative)
1925 return standard_sse_constant_opcode (insn, operands[1]);
1928 /* TDmode values are passed as TImode on the stack. Moving them
1929 to stack may result in unaligned memory access. */
1930 if (misaligned_operand (operands[0], TImode)
1931 || misaligned_operand (operands[1], TImode))
1933 if (get_attr_mode (insn) == MODE_V4SF)
1934 return "%vmovups\t{%1, %0|%0, %1}";
1936 return "%vmovdqu\t{%1, %0|%0, %1}";
1940 if (get_attr_mode (insn) == MODE_V4SF)
1941 return "%vmovaps\t{%1, %0|%0, %1}";
1943 return "%vmovdqa\t{%1, %0|%0, %1}";
1949 [(set_attr "type" "sselog1,ssemov,ssemov")
1950 (set_attr "prefix" "maybe_vex")
1952 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1953 (const_string "V4SF")
1954 (and (eq_attr "alternative" "2")
1955 (match_test "TARGET_SSE_TYPELESS_STORES"))
1956 (const_string "V4SF")
1957 (match_test "TARGET_AVX")
1959 (ior (not (match_test "TARGET_SSE2"))
1960 (match_test "optimize_function_for_size_p (cfun)"))
1961 (const_string "V4SF")
1963 (const_string "TI")))])
1965 (define_insn "*movdi_internal_rex64"
1966 [(set (match_operand:DI 0 "nonimmediate_operand"
1967 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1968 (match_operand:DI 1 "general_operand"
1969 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1970 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1972 switch (get_attr_type (insn))
1975 if (SSE_REG_P (operands[0]))
1976 return "movq2dq\t{%1, %0|%0, %1}";
1978 return "movdq2q\t{%1, %0|%0, %1}";
1981 if (get_attr_mode (insn) == MODE_V4SF)
1982 return "%vmovaps\t{%1, %0|%0, %1}";
1983 else if (get_attr_mode (insn) == MODE_TI)
1984 return "%vmovdqa\t{%1, %0|%0, %1}";
1986 /* Handle broken assemblers that require movd instead of movq. */
1987 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1988 return "%vmovd\t{%1, %0|%0, %1}";
1990 return "%vmovq\t{%1, %0|%0, %1}";
1993 /* Handle broken assemblers that require movd instead of movq. */
1994 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1995 return "movd\t{%1, %0|%0, %1}";
1997 return "movq\t{%1, %0|%0, %1}";
2000 return standard_sse_constant_opcode (insn, operands[1]);
2003 return "pxor\t%0, %0";
2009 return "lea{q}\t{%E1, %0|%0, %E1}";
2012 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2013 if (get_attr_mode (insn) == MODE_SI)
2014 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2015 else if (which_alternative == 2)
2016 return "movabs{q}\t{%1, %0|%0, %1}";
2017 else if (ix86_use_lea_for_mov (insn, operands))
2018 return "lea{q}\t{%E1, %0|%0, %E1}";
2020 return "mov{q}\t{%1, %0|%0, %1}";
2024 (cond [(eq_attr "alternative" "4")
2025 (const_string "multi")
2026 (eq_attr "alternative" "5")
2027 (const_string "mmx")
2028 (eq_attr "alternative" "6,7,8,9")
2029 (const_string "mmxmov")
2030 (eq_attr "alternative" "10")
2031 (const_string "sselog1")
2032 (eq_attr "alternative" "11,12,13,14,15")
2033 (const_string "ssemov")
2034 (eq_attr "alternative" "16,17")
2035 (const_string "ssecvt")
2036 (match_operand 1 "pic_32bit_operand")
2037 (const_string "lea")
2039 (const_string "imov")))
2042 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2044 (const_string "*")))
2045 (set (attr "length_immediate")
2047 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2049 (const_string "*")))
2050 (set (attr "prefix_rex")
2051 (if_then_else (eq_attr "alternative" "8,9")
2053 (const_string "*")))
2054 (set (attr "prefix_data16")
2055 (if_then_else (eq_attr "alternative" "11")
2057 (const_string "*")))
2058 (set (attr "prefix")
2059 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2060 (const_string "maybe_vex")
2061 (const_string "orig")))
2063 (cond [(eq_attr "alternative" "0,4")
2065 (eq_attr "alternative" "10,12")
2066 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2067 (const_string "V4SF")
2068 (match_test "TARGET_AVX")
2070 (match_test "optimize_function_for_size_p (cfun)")
2071 (const_string "V4SF")
2073 (const_string "TI"))
2075 (const_string "DI")))])
2077 ;; Reload patterns to support multi-word load/store
2078 ;; with non-offsetable address.
2079 (define_expand "reload_noff_store"
2080 [(parallel [(match_operand 0 "memory_operand" "=m")
2081 (match_operand 1 "register_operand" "r")
2082 (match_operand:DI 2 "register_operand" "=&r")])]
2085 rtx mem = operands[0];
2086 rtx addr = XEXP (mem, 0);
2088 emit_move_insn (operands[2], addr);
2089 mem = replace_equiv_address_nv (mem, operands[2]);
2091 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2095 (define_expand "reload_noff_load"
2096 [(parallel [(match_operand 0 "register_operand" "=r")
2097 (match_operand 1 "memory_operand" "m")
2098 (match_operand:DI 2 "register_operand" "=r")])]
2101 rtx mem = operands[1];
2102 rtx addr = XEXP (mem, 0);
2104 emit_move_insn (operands[2], addr);
2105 mem = replace_equiv_address_nv (mem, operands[2]);
2107 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2111 ;; Convert impossible stores of immediate to existing instructions.
2112 ;; First try to get scratch register and go through it. In case this
2113 ;; fails, move by 32bit parts.
2115 [(match_scratch:DI 2 "r")
2116 (set (match_operand:DI 0 "memory_operand")
2117 (match_operand:DI 1 "immediate_operand"))]
2118 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2119 && !x86_64_immediate_operand (operands[1], DImode)"
2120 [(set (match_dup 2) (match_dup 1))
2121 (set (match_dup 0) (match_dup 2))])
2123 ;; We need to define this as both peepholer and splitter for case
2124 ;; peephole2 pass is not run.
2125 ;; "&& 1" is needed to keep it from matching the previous pattern.
2127 [(set (match_operand:DI 0 "memory_operand")
2128 (match_operand:DI 1 "immediate_operand"))]
2129 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2130 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2131 [(set (match_dup 2) (match_dup 3))
2132 (set (match_dup 4) (match_dup 5))]
2133 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2136 [(set (match_operand:DI 0 "memory_operand")
2137 (match_operand:DI 1 "immediate_operand"))]
2138 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2139 ? epilogue_completed : reload_completed)
2140 && !symbolic_operand (operands[1], DImode)
2141 && !x86_64_immediate_operand (operands[1], DImode)"
2142 [(set (match_dup 2) (match_dup 3))
2143 (set (match_dup 4) (match_dup 5))]
2144 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2146 (define_insn "*movdi_internal"
2147 [(set (match_operand:DI 0 "nonimmediate_operand"
2148 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2149 (match_operand:DI 1 "general_operand"
2150 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2151 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2153 switch (get_attr_type (insn))
2156 if (SSE_REG_P (operands[0]))
2157 return "movq2dq\t{%1, %0|%0, %1}";
2159 return "movdq2q\t{%1, %0|%0, %1}";
2162 switch (get_attr_mode (insn))
2165 return "%vmovdqa\t{%1, %0|%0, %1}";
2167 return "%vmovq\t{%1, %0|%0, %1}";
2169 return "%vmovaps\t{%1, %0|%0, %1}";
2171 return "movlps\t{%1, %0|%0, %1}";
2177 return "movq\t{%1, %0|%0, %1}";
2180 return standard_sse_constant_opcode (insn, operands[1]);
2183 return "pxor\t%0, %0";
2193 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2194 (const_string "sse2")
2195 (eq_attr "alternative" "9,10,11,12")
2196 (const_string "noavx")
2198 (const_string "*")))
2200 (cond [(eq_attr "alternative" "0,1")
2201 (const_string "multi")
2202 (eq_attr "alternative" "2")
2203 (const_string "mmx")
2204 (eq_attr "alternative" "3,4")
2205 (const_string "mmxmov")
2206 (eq_attr "alternative" "5,9")
2207 (const_string "sselog1")
2208 (eq_attr "alternative" "13,14")
2209 (const_string "ssecvt")
2211 (const_string "ssemov")))
2212 (set (attr "prefix")
2213 (if_then_else (eq_attr "alternative" "5,6,7,8")
2214 (const_string "maybe_vex")
2215 (const_string "orig")))
2217 (cond [(eq_attr "alternative" "9,11")
2218 (const_string "V4SF")
2219 (eq_attr "alternative" "10,12")
2220 (const_string "V2SF")
2221 (eq_attr "alternative" "5,7")
2222 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2223 (const_string "V4SF")
2224 (match_test "TARGET_AVX")
2226 (match_test "optimize_function_for_size_p (cfun)")
2227 (const_string "V4SF")
2229 (const_string "TI"))
2231 (const_string "DI")))])
2234 [(set (match_operand:DI 0 "nonimmediate_operand")
2235 (match_operand:DI 1 "general_operand"))]
2236 "!TARGET_64BIT && reload_completed
2237 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2238 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2240 "ix86_split_long_move (operands); DONE;")
2242 (define_insn "*movsi_internal"
2243 [(set (match_operand:SI 0 "nonimmediate_operand"
2244 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2245 (match_operand:SI 1 "general_operand"
2246 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2247 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2249 switch (get_attr_type (insn))
2252 return standard_sse_constant_opcode (insn, operands[1]);
2255 switch (get_attr_mode (insn))
2258 return "%vmovdqa\t{%1, %0|%0, %1}";
2260 return "%vmovaps\t{%1, %0|%0, %1}";
2262 return "%vmovd\t{%1, %0|%0, %1}";
2264 return "%vmovss\t{%1, %0|%0, %1}";
2270 return "pxor\t%0, %0";
2273 if (get_attr_mode (insn) == MODE_DI)
2274 return "movq\t{%1, %0|%0, %1}";
2275 return "movd\t{%1, %0|%0, %1}";
2278 return "lea{l}\t{%E1, %0|%0, %E1}";
2281 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2282 if (ix86_use_lea_for_mov (insn, operands))
2283 return "lea{l}\t{%E1, %0|%0, %E1}";
2285 return "mov{l}\t{%1, %0|%0, %1}";
2289 (cond [(eq_attr "alternative" "2")
2290 (const_string "mmx")
2291 (eq_attr "alternative" "3,4,5")
2292 (const_string "mmxmov")
2293 (eq_attr "alternative" "6")
2294 (const_string "sselog1")
2295 (eq_attr "alternative" "7,8,9,10,11")
2296 (const_string "ssemov")
2297 (match_operand 1 "pic_32bit_operand")
2298 (const_string "lea")
2300 (const_string "imov")))
2301 (set (attr "prefix")
2302 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2303 (const_string "orig")
2304 (const_string "maybe_vex")))
2305 (set (attr "prefix_data16")
2306 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2308 (const_string "*")))
2310 (cond [(eq_attr "alternative" "2,3")
2312 (eq_attr "alternative" "6,7")
2313 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2314 (const_string "V4SF")
2315 (match_test "TARGET_AVX")
2317 (ior (not (match_test "TARGET_SSE2"))
2318 (match_test "optimize_function_for_size_p (cfun)"))
2319 (const_string "V4SF")
2321 (const_string "TI"))
2322 (and (eq_attr "alternative" "8,9,10,11")
2323 (not (match_test "TARGET_SSE2")))
2326 (const_string "SI")))])
2328 (define_insn "*movhi_internal"
2329 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2330 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2331 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2333 switch (get_attr_type (insn))
2336 /* movzwl is faster than movw on p2 due to partial word stalls,
2337 though not as fast as an aligned movl. */
2338 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2340 if (get_attr_mode (insn) == MODE_SI)
2341 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2343 return "mov{w}\t{%1, %0|%0, %1}";
2347 (cond [(match_test "optimize_function_for_size_p (cfun)")
2348 (const_string "imov")
2349 (and (eq_attr "alternative" "0")
2350 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2351 (not (match_test "TARGET_HIMODE_MATH"))))
2352 (const_string "imov")
2353 (and (eq_attr "alternative" "1,2")
2354 (match_operand:HI 1 "aligned_operand"))
2355 (const_string "imov")
2356 (and (match_test "TARGET_MOVX")
2357 (eq_attr "alternative" "0,2"))
2358 (const_string "imovx")
2360 (const_string "imov")))
2362 (cond [(eq_attr "type" "imovx")
2364 (and (eq_attr "alternative" "1,2")
2365 (match_operand:HI 1 "aligned_operand"))
2367 (and (eq_attr "alternative" "0")
2368 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2369 (not (match_test "TARGET_HIMODE_MATH"))))
2372 (const_string "HI")))])
2374 ;; Situation is quite tricky about when to choose full sized (SImode) move
2375 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2376 ;; partial register dependency machines (such as AMD Athlon), where QImode
2377 ;; moves issue extra dependency and for partial register stalls machines
2378 ;; that don't use QImode patterns (and QImode move cause stall on the next
2381 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2382 ;; register stall machines with, where we use QImode instructions, since
2383 ;; partial register stall can be caused there. Then we use movzx.
2384 (define_insn "*movqi_internal"
2385 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2386 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2387 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2389 switch (get_attr_type (insn))
2392 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2393 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2395 if (get_attr_mode (insn) == MODE_SI)
2396 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2398 return "mov{b}\t{%1, %0|%0, %1}";
2402 (cond [(and (eq_attr "alternative" "5")
2403 (not (match_operand:QI 1 "aligned_operand")))
2404 (const_string "imovx")
2405 (match_test "optimize_function_for_size_p (cfun)")
2406 (const_string "imov")
2407 (and (eq_attr "alternative" "3")
2408 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2409 (not (match_test "TARGET_QIMODE_MATH"))))
2410 (const_string "imov")
2411 (eq_attr "alternative" "3,5")
2412 (const_string "imovx")
2413 (and (match_test "TARGET_MOVX")
2414 (eq_attr "alternative" "2"))
2415 (const_string "imovx")
2417 (const_string "imov")))
2419 (cond [(eq_attr "alternative" "3,4,5")
2421 (eq_attr "alternative" "6")
2423 (eq_attr "type" "imovx")
2425 (and (eq_attr "type" "imov")
2426 (and (eq_attr "alternative" "0,1")
2427 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2428 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2429 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2431 ;; Avoid partial register stalls when not using QImode arithmetic
2432 (and (eq_attr "type" "imov")
2433 (and (eq_attr "alternative" "0,1")
2434 (and (match_test "TARGET_PARTIAL_REG_STALL")
2435 (not (match_test "TARGET_QIMODE_MATH")))))
2438 (const_string "QI")))])
2440 ;; Stores and loads of ax to arbitrary constant address.
2441 ;; We fake an second form of instruction to force reload to load address
2442 ;; into register when rax is not available
2443 (define_insn "*movabs<mode>_1"
2444 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2445 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2446 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2448 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2449 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2450 [(set_attr "type" "imov")
2451 (set_attr "modrm" "0,*")
2452 (set_attr "length_address" "8,0")
2453 (set_attr "length_immediate" "0,*")
2454 (set_attr "memory" "store")
2455 (set_attr "mode" "<MODE>")])
2457 (define_insn "*movabs<mode>_2"
2458 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2459 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2460 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2462 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2463 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2464 [(set_attr "type" "imov")
2465 (set_attr "modrm" "0,*")
2466 (set_attr "length_address" "8,0")
2467 (set_attr "length_immediate" "0")
2468 (set_attr "memory" "load")
2469 (set_attr "mode" "<MODE>")])
2471 (define_insn "swap<mode>"
2472 [(set (match_operand:SWI48 0 "register_operand" "+r")
2473 (match_operand:SWI48 1 "register_operand" "+r"))
2477 "xchg{<imodesuffix>}\t%1, %0"
2478 [(set_attr "type" "imov")
2479 (set_attr "mode" "<MODE>")
2480 (set_attr "pent_pair" "np")
2481 (set_attr "athlon_decode" "vector")
2482 (set_attr "amdfam10_decode" "double")
2483 (set_attr "bdver1_decode" "double")])
2485 (define_insn "*swap<mode>_1"
2486 [(set (match_operand:SWI12 0 "register_operand" "+r")
2487 (match_operand:SWI12 1 "register_operand" "+r"))
2490 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2492 [(set_attr "type" "imov")
2493 (set_attr "mode" "SI")
2494 (set_attr "pent_pair" "np")
2495 (set_attr "athlon_decode" "vector")
2496 (set_attr "amdfam10_decode" "double")
2497 (set_attr "bdver1_decode" "double")])
2499 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2500 ;; is disabled for AMDFAM10
2501 (define_insn "*swap<mode>_2"
2502 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2503 (match_operand:SWI12 1 "register_operand" "+<r>"))
2506 "TARGET_PARTIAL_REG_STALL"
2507 "xchg{<imodesuffix>}\t%1, %0"
2508 [(set_attr "type" "imov")
2509 (set_attr "mode" "<MODE>")
2510 (set_attr "pent_pair" "np")
2511 (set_attr "athlon_decode" "vector")])
2513 (define_expand "movstrict<mode>"
2514 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2515 (match_operand:SWI12 1 "general_operand"))]
2518 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2520 if (GET_CODE (operands[0]) == SUBREG
2521 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2523 /* Don't generate memory->memory moves, go through a register */
2524 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2525 operands[1] = force_reg (<MODE>mode, operands[1]);
2528 (define_insn "*movstrict<mode>_1"
2529 [(set (strict_low_part
2530 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2531 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2532 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2533 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2534 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2535 [(set_attr "type" "imov")
2536 (set_attr "mode" "<MODE>")])
2538 (define_insn "*movstrict<mode>_xor"
2539 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2540 (match_operand:SWI12 1 "const0_operand"))
2541 (clobber (reg:CC FLAGS_REG))]
2543 "xor{<imodesuffix>}\t%0, %0"
2544 [(set_attr "type" "alu1")
2545 (set_attr "mode" "<MODE>")
2546 (set_attr "length_immediate" "0")])
2548 (define_insn "*mov<mode>_extv_1"
2549 [(set (match_operand:SWI24 0 "register_operand" "=R")
2550 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2554 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2555 [(set_attr "type" "imovx")
2556 (set_attr "mode" "SI")])
2558 (define_insn "*movqi_extv_1_rex64"
2559 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2560 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2565 switch (get_attr_type (insn))
2568 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2570 return "mov{b}\t{%h1, %0|%0, %h1}";
2574 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2575 (match_test "TARGET_MOVX"))
2576 (const_string "imovx")
2577 (const_string "imov")))
2579 (if_then_else (eq_attr "type" "imovx")
2581 (const_string "QI")))])
2583 (define_insn "*movqi_extv_1"
2584 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2585 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2590 switch (get_attr_type (insn))
2593 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2595 return "mov{b}\t{%h1, %0|%0, %h1}";
2599 (if_then_else (and (match_operand:QI 0 "register_operand")
2600 (ior (not (match_operand:QI 0 "QIreg_operand"))
2601 (match_test "TARGET_MOVX")))
2602 (const_string "imovx")
2603 (const_string "imov")))
2605 (if_then_else (eq_attr "type" "imovx")
2607 (const_string "QI")))])
2609 (define_insn "*mov<mode>_extzv_1"
2610 [(set (match_operand:SWI48 0 "register_operand" "=R")
2611 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2615 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2616 [(set_attr "type" "imovx")
2617 (set_attr "mode" "SI")])
2619 (define_insn "*movqi_extzv_2_rex64"
2620 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2622 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2627 switch (get_attr_type (insn))
2630 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2632 return "mov{b}\t{%h1, %0|%0, %h1}";
2636 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2637 (match_test "TARGET_MOVX"))
2638 (const_string "imovx")
2639 (const_string "imov")))
2641 (if_then_else (eq_attr "type" "imovx")
2643 (const_string "QI")))])
2645 (define_insn "*movqi_extzv_2"
2646 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2648 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2653 switch (get_attr_type (insn))
2656 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2658 return "mov{b}\t{%h1, %0|%0, %h1}";
2662 (if_then_else (and (match_operand:QI 0 "register_operand")
2663 (ior (not (match_operand:QI 0 "QIreg_operand"))
2664 (match_test "TARGET_MOVX")))
2665 (const_string "imovx")
2666 (const_string "imov")))
2668 (if_then_else (eq_attr "type" "imovx")
2670 (const_string "QI")))])
2672 (define_expand "mov<mode>_insv_1"
2673 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2676 (match_operand:SWI48 1 "nonmemory_operand"))])
2678 (define_insn "*mov<mode>_insv_1_rex64"
2679 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2682 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2684 "mov{b}\t{%b1, %h0|%h0, %b1}"
2685 [(set_attr "type" "imov")
2686 (set_attr "mode" "QI")])
2688 (define_insn "*movsi_insv_1"
2689 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2692 (match_operand:SI 1 "general_operand" "Qmn"))]
2694 "mov{b}\t{%b1, %h0|%h0, %b1}"
2695 [(set_attr "type" "imov")
2696 (set_attr "mode" "QI")])
2698 (define_insn "*movqi_insv_2"
2699 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2702 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2705 "mov{b}\t{%h1, %h0|%h0, %h1}"
2706 [(set_attr "type" "imov")
2707 (set_attr "mode" "QI")])
2709 ;; Floating point push instructions.
2711 (define_insn "*pushtf"
2712 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2713 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2716 /* This insn should be already split before reg-stack. */
2719 [(set_attr "type" "multi")
2720 (set_attr "unit" "sse,*,*")
2721 (set_attr "mode" "TF,SI,SI")])
2723 ;; %%% Kill this when call knows how to work this out.
2725 [(set (match_operand:TF 0 "push_operand")
2726 (match_operand:TF 1 "sse_reg_operand"))]
2727 "TARGET_SSE && reload_completed"
2728 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2729 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2731 (define_insn "*pushxf"
2732 [(set (match_operand:XF 0 "push_operand" "=<,<")
2733 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2734 "optimize_function_for_speed_p (cfun)"
2736 /* This insn should be already split before reg-stack. */
2739 [(set_attr "type" "multi")
2740 (set_attr "unit" "i387,*")
2741 (set_attr "mode" "XF,SI")])
2743 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2744 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2745 ;; Pushing using integer instructions is longer except for constants
2746 ;; and direct memory references (assuming that any given constant is pushed
2747 ;; only once, but this ought to be handled elsewhere).
2749 (define_insn "*pushxf_nointeger"
2750 [(set (match_operand:XF 0 "push_operand" "=<,<")
2751 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2752 "optimize_function_for_size_p (cfun)"
2754 /* This insn should be already split before reg-stack. */
2757 [(set_attr "type" "multi")
2758 (set_attr "unit" "i387,*")
2759 (set_attr "mode" "XF,SI")])
2761 ;; %%% Kill this when call knows how to work this out.
2763 [(set (match_operand:XF 0 "push_operand")
2764 (match_operand:XF 1 "fp_register_operand"))]
2766 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2767 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2768 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2770 (define_insn "*pushdf_rex64"
2771 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2772 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2775 /* This insn should be already split before reg-stack. */
2778 [(set_attr "type" "multi")
2779 (set_attr "unit" "i387,*,*")
2780 (set_attr "mode" "DF,DI,DF")])
2782 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2783 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2784 ;; On the average, pushdf using integers can be still shorter.
2786 (define_insn "*pushdf"
2787 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2788 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2791 /* This insn should be already split before reg-stack. */
2794 [(set_attr "isa" "*,*,sse2")
2795 (set_attr "type" "multi")
2796 (set_attr "unit" "i387,*,*")
2797 (set_attr "mode" "DF,DI,DF")])
2799 ;; %%% Kill this when call knows how to work this out.
2801 [(set (match_operand:DF 0 "push_operand")
2802 (match_operand:DF 1 "any_fp_register_operand"))]
2804 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2805 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2807 (define_insn "*pushsf_rex64"
2808 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2809 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2812 /* Anything else should be already split before reg-stack. */
2813 gcc_assert (which_alternative == 1);
2814 return "push{q}\t%q1";
2816 [(set_attr "type" "multi,push,multi")
2817 (set_attr "unit" "i387,*,*")
2818 (set_attr "mode" "SF,DI,SF")])
2820 (define_insn "*pushsf"
2821 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2822 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2825 /* Anything else should be already split before reg-stack. */
2826 gcc_assert (which_alternative == 1);
2827 return "push{l}\t%1";
2829 [(set_attr "type" "multi,push,multi")
2830 (set_attr "unit" "i387,*,*")
2831 (set_attr "mode" "SF,SI,SF")])
2833 ;; %%% Kill this when call knows how to work this out.
2835 [(set (match_operand:SF 0 "push_operand")
2836 (match_operand:SF 1 "any_fp_register_operand"))]
2838 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2839 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2840 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2843 [(set (match_operand:SF 0 "push_operand")
2844 (match_operand:SF 1 "memory_operand"))]
2846 && (operands[2] = find_constant_src (insn))"
2847 [(set (match_dup 0) (match_dup 2))])
2850 [(set (match_operand 0 "push_operand")
2851 (match_operand 1 "general_operand"))]
2853 && (GET_MODE (operands[0]) == TFmode
2854 || GET_MODE (operands[0]) == XFmode
2855 || GET_MODE (operands[0]) == DFmode)
2856 && !ANY_FP_REG_P (operands[1])"
2858 "ix86_split_long_move (operands); DONE;")
2860 ;; Floating point move instructions.
2862 (define_expand "movtf"
2863 [(set (match_operand:TF 0 "nonimmediate_operand")
2864 (match_operand:TF 1 "nonimmediate_operand"))]
2867 ix86_expand_move (TFmode, operands);
2871 (define_expand "mov<mode>"
2872 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2873 (match_operand:X87MODEF 1 "general_operand"))]
2875 "ix86_expand_move (<MODE>mode, operands); DONE;")
2877 (define_insn "*movtf_internal"
2878 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2879 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,F*r"))]
2881 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2882 && (!can_create_pseudo_p ()
2883 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2884 || GET_CODE (operands[1]) != CONST_DOUBLE
2885 || (optimize_function_for_size_p (cfun)
2886 && standard_sse_constant_p (operands[1])
2887 && !memory_operand (operands[0], TFmode))
2888 || (!TARGET_MEMORY_MISMATCH_STALL
2889 && memory_operand (operands[0], TFmode)))"
2891 switch (which_alternative)
2894 return standard_sse_constant_opcode (insn, operands[1]);
2897 /* Handle misaligned load/store since we
2898 don't have movmisaligntf pattern. */
2899 if (misaligned_operand (operands[0], TFmode)
2900 || misaligned_operand (operands[1], TFmode))
2902 if (get_attr_mode (insn) == MODE_V4SF)
2903 return "%vmovups\t{%1, %0|%0, %1}";
2905 return "%vmovdqu\t{%1, %0|%0, %1}";
2909 if (get_attr_mode (insn) == MODE_V4SF)
2910 return "%vmovaps\t{%1, %0|%0, %1}";
2912 return "%vmovdqa\t{%1, %0|%0, %1}";
2923 [(set_attr "type" "sselog1,ssemov,ssemov,*,*")
2924 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2926 (cond [(eq_attr "alternative" "3,4")
2928 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2929 (const_string "V4SF")
2930 (and (eq_attr "alternative" "2")
2931 (match_test "TARGET_SSE_TYPELESS_STORES"))
2932 (const_string "V4SF")
2933 (match_test "TARGET_AVX")
2935 (ior (not (match_test "TARGET_SSE2"))
2936 (match_test "optimize_function_for_size_p (cfun)"))
2937 (const_string "V4SF")
2939 (const_string "TI")))])
2941 ;; Possible store forwarding (partial memory) stall in alternative 4.
2942 (define_insn "*movxf_internal"
2943 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2944 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2945 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2946 && (!can_create_pseudo_p ()
2947 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2948 || GET_CODE (operands[1]) != CONST_DOUBLE
2949 || (optimize_function_for_size_p (cfun)
2950 && standard_80387_constant_p (operands[1]) > 0
2951 && !memory_operand (operands[0], XFmode))
2952 || (!TARGET_MEMORY_MISMATCH_STALL
2953 && memory_operand (operands[0], XFmode)))"
2955 switch (which_alternative)
2959 return output_387_reg_move (insn, operands);
2962 return standard_80387_constant_opcode (operands[1]);
2972 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2973 (set_attr "mode" "XF,XF,XF,SI,SI")])
2975 (define_insn "*movdf_internal_rex64"
2976 [(set (match_operand:DF 0 "nonimmediate_operand"
2977 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2978 (match_operand:DF 1 "general_operand"
2979 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2980 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2981 && (!can_create_pseudo_p ()
2982 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2983 || GET_CODE (operands[1]) != CONST_DOUBLE
2984 || (optimize_function_for_size_p (cfun)
2985 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2986 && standard_80387_constant_p (operands[1]) > 0)
2987 || (TARGET_SSE2 && TARGET_SSE_MATH
2988 && standard_sse_constant_p (operands[1]))))
2989 || memory_operand (operands[0], DFmode))"
2991 switch (which_alternative)
2995 return output_387_reg_move (insn, operands);
2998 return standard_80387_constant_opcode (operands[1]);
3002 return "mov{q}\t{%1, %0|%0, %1}";
3005 return "movabs{q}\t{%1, %0|%0, %1}";
3011 return standard_sse_constant_opcode (insn, operands[1]);
3016 switch (get_attr_mode (insn))
3019 return "%vmovapd\t{%1, %0|%0, %1}";
3021 return "%vmovaps\t{%1, %0|%0, %1}";
3024 return "%vmovq\t{%1, %0|%0, %1}";
3026 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3027 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3028 return "%vmovsd\t{%1, %0|%0, %1}";
3030 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3032 return "%vmovlps\t{%1, %d0|%d0, %1}";
3039 /* Handle broken assemblers that require movd instead of movq. */
3040 return "%vmovd\t{%1, %0|%0, %1}";
3047 (cond [(eq_attr "alternative" "0,1,2")
3048 (const_string "fmov")
3049 (eq_attr "alternative" "3,4,5")
3050 (const_string "imov")
3051 (eq_attr "alternative" "6")
3052 (const_string "multi")
3053 (eq_attr "alternative" "7")
3054 (const_string "sselog1")
3056 (const_string "ssemov")))
3059 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3061 (const_string "*")))
3062 (set (attr "length_immediate")
3064 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3066 (const_string "*")))
3067 (set (attr "prefix")
3068 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3069 (const_string "orig")
3070 (const_string "maybe_vex")))
3071 (set (attr "prefix_data16")
3072 (if_then_else (eq_attr "mode" "V1DF")
3074 (const_string "*")))
3076 (cond [(eq_attr "alternative" "0,1,2")
3078 (eq_attr "alternative" "3,4,5,6,11,12")
3081 /* xorps is one byte shorter for !TARGET_AVX. */
3082 (eq_attr "alternative" "7")
3083 (cond [(match_test "TARGET_AVX")
3084 (const_string "V2DF")
3085 (match_test "optimize_function_for_size_p (cfun)")
3086 (const_string "V4SF")
3087 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3090 (const_string "V2DF"))
3092 /* For architectures resolving dependencies on
3093 whole SSE registers use APD move to break dependency
3094 chains, otherwise use short move to avoid extra work.
3096 movaps encodes one byte shorter for !TARGET_AVX. */
3097 (eq_attr "alternative" "8")
3098 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3099 (const_string "V4SF")
3100 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3101 (const_string "V2DF")
3102 (match_test "TARGET_AVX")
3104 (match_test "optimize_function_for_size_p (cfun)")
3105 (const_string "V4SF")
3107 (const_string "DF"))
3108 /* For architectures resolving dependencies on register
3109 parts we may avoid extra work to zero out upper part
3111 (eq_attr "alternative" "9")
3113 (match_test "TARGET_SSE_SPLIT_REGS")
3114 (const_string "V1DF")
3115 (const_string "DF"))
3117 (const_string "DF")))])
3119 ;; Possible store forwarding (partial memory) stall in alternative 4.
3120 (define_insn "*movdf_internal"
3121 [(set (match_operand:DF 0 "nonimmediate_operand"
3122 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3123 (match_operand:DF 1 "general_operand"
3124 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3125 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3126 && (!can_create_pseudo_p ()
3127 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3128 || GET_CODE (operands[1]) != CONST_DOUBLE
3129 || (optimize_function_for_size_p (cfun)
3130 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3131 && standard_80387_constant_p (operands[1]) > 0)
3132 || (TARGET_SSE2 && TARGET_SSE_MATH
3133 && standard_sse_constant_p (operands[1])))
3134 && !memory_operand (operands[0], DFmode))
3135 || (!TARGET_MEMORY_MISMATCH_STALL
3136 && memory_operand (operands[0], DFmode)))"
3138 switch (which_alternative)
3142 return output_387_reg_move (insn, operands);
3145 return standard_80387_constant_opcode (operands[1]);
3153 return standard_sse_constant_opcode (insn, operands[1]);
3161 switch (get_attr_mode (insn))
3164 return "%vmovapd\t{%1, %0|%0, %1}";
3166 return "%vmovaps\t{%1, %0|%0, %1}";
3169 return "%vmovq\t{%1, %0|%0, %1}";
3171 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3172 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3173 return "%vmovsd\t{%1, %0|%0, %1}";
3175 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3177 return "%vmovlps\t{%1, %d0|%d0, %1}";
3187 (if_then_else (eq_attr "alternative" "5,6,7,8")
3188 (const_string "sse2")
3189 (const_string "*")))
3191 (cond [(eq_attr "alternative" "0,1,2")
3192 (const_string "fmov")
3193 (eq_attr "alternative" "3,4")
3194 (const_string "multi")
3195 (eq_attr "alternative" "5,9")
3196 (const_string "sselog1")
3198 (const_string "ssemov")))
3199 (set (attr "prefix")
3200 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3201 (const_string "orig")
3202 (const_string "maybe_vex")))
3203 (set (attr "prefix_data16")
3204 (if_then_else (eq_attr "mode" "V1DF")
3206 (const_string "*")))
3208 (cond [(eq_attr "alternative" "0,1,2")
3210 (eq_attr "alternative" "3,4")
3213 /* For SSE1, we have many fewer alternatives. */
3214 (not (match_test "TARGET_SSE2"))
3216 (eq_attr "alternative" "5,6,9,10")
3217 (const_string "V4SF")
3218 (const_string "V2SF"))
3220 /* xorps is one byte shorter for !TARGET_AVX. */
3221 (eq_attr "alternative" "5,9")
3222 (cond [(match_test "TARGET_AVX")
3223 (const_string "V2DF")
3224 (match_test "optimize_function_for_size_p (cfun)")
3225 (const_string "V4SF")
3226 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3229 (const_string "V2DF"))
3231 /* For architectures resolving dependencies on
3232 whole SSE registers use APD move to break dependency
3233 chains, otherwise use short move to avoid extra work.
3235 movaps encodes one byte shorter for !TARGET_AVX. */
3236 (eq_attr "alternative" "6,10")
3237 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3238 (const_string "V4SF")
3239 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3240 (const_string "V2DF")
3241 (match_test "TARGET_AVX")
3243 (match_test "optimize_function_for_size_p (cfun)")
3244 (const_string "V4SF")
3246 (const_string "DF"))
3248 /* For architectures resolving dependencies on register
3249 parts we may avoid extra work to zero out upper part
3251 (eq_attr "alternative" "7,11")
3253 (match_test "TARGET_SSE_SPLIT_REGS")
3254 (const_string "V1DF")
3255 (const_string "DF"))
3257 (const_string "DF")))])
3259 (define_insn "*movsf_internal"
3260 [(set (match_operand:SF 0 "nonimmediate_operand"
3261 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3262 (match_operand:SF 1 "general_operand"
3263 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3264 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3265 && (!can_create_pseudo_p ()
3266 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3267 || GET_CODE (operands[1]) != CONST_DOUBLE
3268 || (optimize_function_for_size_p (cfun)
3269 && ((!TARGET_SSE_MATH
3270 && standard_80387_constant_p (operands[1]) > 0)
3272 && standard_sse_constant_p (operands[1]))))
3273 || memory_operand (operands[0], SFmode))"
3275 switch (which_alternative)
3279 return output_387_reg_move (insn, operands);
3282 return standard_80387_constant_opcode (operands[1]);
3286 return "mov{l}\t{%1, %0|%0, %1}";
3289 return standard_sse_constant_opcode (insn, operands[1]);
3292 if (get_attr_mode (insn) == MODE_V4SF)
3293 return "%vmovaps\t{%1, %0|%0, %1}";
3295 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3299 return "%vmovss\t{%1, %0|%0, %1}";
3305 return "movd\t{%1, %0|%0, %1}";
3308 return "movq\t{%1, %0|%0, %1}";
3312 return "%vmovd\t{%1, %0|%0, %1}";
3319 (cond [(eq_attr "alternative" "0,1,2")
3320 (const_string "fmov")
3321 (eq_attr "alternative" "3,4")
3322 (const_string "multi")
3323 (eq_attr "alternative" "5")
3324 (const_string "sselog1")
3325 (eq_attr "alternative" "9,10,11,14,15")
3326 (const_string "mmxmov")
3328 (const_string "ssemov")))
3329 (set (attr "prefix")
3330 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3331 (const_string "maybe_vex")
3332 (const_string "orig")))
3334 (cond [(eq_attr "alternative" "3,4,9,10")
3336 (eq_attr "alternative" "5")
3337 (cond [(match_test "TARGET_AVX")
3338 (const_string "V4SF")
3339 (ior (not (match_test "TARGET_SSE2"))
3340 (match_test "optimize_function_for_size_p (cfun)"))
3341 (const_string "V4SF")
3342 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3345 (const_string "V4SF"))
3347 /* For architectures resolving dependencies on
3348 whole SSE registers use APS move to break dependency
3349 chains, otherwise use short move to avoid extra work.
3351 Do the same for architectures resolving dependencies on
3352 the parts. While in DF mode it is better to always handle
3353 just register parts, the SF mode is different due to lack
3354 of instructions to load just part of the register. It is
3355 better to maintain the whole registers in single format
3356 to avoid problems on using packed logical operations. */
3357 (eq_attr "alternative" "6")
3359 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3360 (match_test "TARGET_SSE_SPLIT_REGS"))
3361 (const_string "V4SF")
3362 (const_string "SF"))
3363 (eq_attr "alternative" "11")
3364 (const_string "DI")]
3365 (const_string "SF")))])
3368 [(set (match_operand 0 "any_fp_register_operand")
3369 (match_operand 1 "memory_operand"))]
3371 && (GET_MODE (operands[0]) == TFmode
3372 || GET_MODE (operands[0]) == XFmode
3373 || GET_MODE (operands[0]) == DFmode
3374 || GET_MODE (operands[0]) == SFmode)
3375 && (operands[2] = find_constant_src (insn))"
3376 [(set (match_dup 0) (match_dup 2))]
3378 rtx c = operands[2];
3379 int r = REGNO (operands[0]);
3381 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3382 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3387 [(set (match_operand 0 "any_fp_register_operand")
3388 (float_extend (match_operand 1 "memory_operand")))]
3390 && (GET_MODE (operands[0]) == TFmode
3391 || GET_MODE (operands[0]) == XFmode
3392 || GET_MODE (operands[0]) == DFmode)
3393 && (operands[2] = find_constant_src (insn))"
3394 [(set (match_dup 0) (match_dup 2))]
3396 rtx c = operands[2];
3397 int r = REGNO (operands[0]);
3399 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3400 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3404 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3406 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3407 (match_operand:X87MODEF 1 "immediate_operand"))]
3409 && (standard_80387_constant_p (operands[1]) == 8
3410 || standard_80387_constant_p (operands[1]) == 9)"
3411 [(set (match_dup 0)(match_dup 1))
3413 (neg:X87MODEF (match_dup 0)))]
3417 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3418 if (real_isnegzero (&r))
3419 operands[1] = CONST0_RTX (<MODE>mode);
3421 operands[1] = CONST1_RTX (<MODE>mode);
3425 [(set (match_operand 0 "nonimmediate_operand")
3426 (match_operand 1 "general_operand"))]
3428 && (GET_MODE (operands[0]) == TFmode
3429 || GET_MODE (operands[0]) == XFmode
3430 || GET_MODE (operands[0]) == DFmode)
3431 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3433 "ix86_split_long_move (operands); DONE;")
3435 (define_insn "swapxf"
3436 [(set (match_operand:XF 0 "register_operand" "+f")
3437 (match_operand:XF 1 "register_operand" "+f"))
3442 if (STACK_TOP_P (operands[0]))
3447 [(set_attr "type" "fxch")
3448 (set_attr "mode" "XF")])
3450 (define_insn "*swap<mode>"
3451 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3452 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3455 "TARGET_80387 || reload_completed"
3457 if (STACK_TOP_P (operands[0]))
3462 [(set_attr "type" "fxch")
3463 (set_attr "mode" "<MODE>")])
3465 ;; Zero extension instructions
3467 (define_expand "zero_extendsidi2"
3468 [(set (match_operand:DI 0 "nonimmediate_operand")
3469 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3471 (define_insn "*zero_extendsidi2_rex64"
3472 [(set (match_operand:DI 0 "nonimmediate_operand"
3473 "=r ,o,?*Ym,?*y,?*Yi,?*x")
3475 (match_operand:SI 1 "x86_64_zext_general_operand"
3476 "rmWz,0,r ,m ,r ,m")))]
3479 mov{l}\t{%1, %k0|%k0, %1}
3481 movd\t{%1, %0|%0, %1}
3482 movd\t{%1, %0|%0, %1}
3483 %vmovd\t{%1, %0|%0, %1}
3484 %vmovd\t{%1, %0|%0, %1}"
3485 [(set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3486 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3487 (set_attr "prefix_0f" "0,*,*,*,*,*")
3488 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3490 (define_insn "*zero_extendsidi2"
3491 [(set (match_operand:DI 0 "nonimmediate_operand"
3492 "=ro,?r,?o,?*Ym,?*y,?*Yi,?*x")
3493 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3494 "0 ,rm,r ,r ,m ,r ,m")))]
3500 movd\t{%1, %0|%0, %1}
3501 movd\t{%1, %0|%0, %1}
3502 %vmovd\t{%1, %0|%0, %1}
3503 %vmovd\t{%1, %0|%0, %1}"
3504 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3505 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3506 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3507 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3510 [(set (match_operand:DI 0 "memory_operand")
3511 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3513 [(set (match_dup 4) (const_int 0))]
3514 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3517 [(set (match_operand:DI 0 "register_operand")
3518 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3519 "!TARGET_64BIT && reload_completed
3520 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3521 && true_regnum (operands[0]) == true_regnum (operands[1])"
3522 [(set (match_dup 4) (const_int 0))]
3523 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3526 [(set (match_operand:DI 0 "nonimmediate_operand")
3527 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3528 "!TARGET_64BIT && reload_completed
3529 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3530 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3531 [(set (match_dup 3) (match_dup 1))
3532 (set (match_dup 4) (const_int 0))]
3533 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3535 (define_insn "zero_extend<mode>di2"
3536 [(set (match_operand:DI 0 "register_operand" "=r")
3538 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3540 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3541 [(set_attr "type" "imovx")
3542 (set_attr "mode" "SI")])
3544 (define_expand "zero_extend<mode>si2"
3545 [(set (match_operand:SI 0 "register_operand")
3546 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3549 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3551 operands[1] = force_reg (<MODE>mode, operands[1]);
3552 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3557 (define_insn_and_split "zero_extend<mode>si2_and"
3558 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3560 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3561 (clobber (reg:CC FLAGS_REG))]
3562 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3564 "&& reload_completed"
3565 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3566 (clobber (reg:CC FLAGS_REG))])]
3568 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3570 ix86_expand_clear (operands[0]);
3572 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3573 emit_insn (gen_movstrict<mode>
3574 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3578 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3580 [(set_attr "type" "alu1")
3581 (set_attr "mode" "SI")])
3583 (define_insn "*zero_extend<mode>si2"
3584 [(set (match_operand:SI 0 "register_operand" "=r")
3586 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3587 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3588 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3589 [(set_attr "type" "imovx")
3590 (set_attr "mode" "SI")])
3592 (define_expand "zero_extendqihi2"
3593 [(set (match_operand:HI 0 "register_operand")
3594 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3597 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3599 operands[1] = force_reg (QImode, operands[1]);
3600 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3605 (define_insn_and_split "zero_extendqihi2_and"
3606 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3607 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3608 (clobber (reg:CC FLAGS_REG))]
3609 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3611 "&& reload_completed"
3612 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3613 (clobber (reg:CC FLAGS_REG))])]
3615 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3617 ix86_expand_clear (operands[0]);
3619 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3620 emit_insn (gen_movstrictqi
3621 (gen_lowpart (QImode, operands[0]), operands[1]));
3625 operands[0] = gen_lowpart (SImode, operands[0]);
3627 [(set_attr "type" "alu1")
3628 (set_attr "mode" "SI")])
3630 ; zero extend to SImode to avoid partial register stalls
3631 (define_insn "*zero_extendqihi2"
3632 [(set (match_operand:HI 0 "register_operand" "=r")
3633 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3634 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3635 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3636 [(set_attr "type" "imovx")
3637 (set_attr "mode" "SI")])
3639 ;; Sign extension instructions
3641 (define_expand "extendsidi2"
3642 [(set (match_operand:DI 0 "register_operand")
3643 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3648 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3653 (define_insn "*extendsidi2_rex64"
3654 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3655 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3659 movs{lq|x}\t{%1, %0|%0, %1}"
3660 [(set_attr "type" "imovx")
3661 (set_attr "mode" "DI")
3662 (set_attr "prefix_0f" "0")
3663 (set_attr "modrm" "0,1")])
3665 (define_insn "extendsidi2_1"
3666 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3667 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3668 (clobber (reg:CC FLAGS_REG))
3669 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3673 ;; Extend to memory case when source register does die.
3675 [(set (match_operand:DI 0 "memory_operand")
3676 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3677 (clobber (reg:CC FLAGS_REG))
3678 (clobber (match_operand:SI 2 "register_operand"))]
3680 && dead_or_set_p (insn, operands[1])
3681 && !reg_mentioned_p (operands[1], operands[0]))"
3682 [(set (match_dup 3) (match_dup 1))
3683 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3684 (clobber (reg:CC FLAGS_REG))])
3685 (set (match_dup 4) (match_dup 1))]
3686 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3688 ;; Extend to memory case when source register does not die.
3690 [(set (match_operand:DI 0 "memory_operand")
3691 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3692 (clobber (reg:CC FLAGS_REG))
3693 (clobber (match_operand:SI 2 "register_operand"))]
3697 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3699 emit_move_insn (operands[3], operands[1]);
3701 /* Generate a cltd if possible and doing so it profitable. */
3702 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3703 && true_regnum (operands[1]) == AX_REG
3704 && true_regnum (operands[2]) == DX_REG)
3706 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3710 emit_move_insn (operands[2], operands[1]);
3711 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3713 emit_move_insn (operands[4], operands[2]);
3717 ;; Extend to register case. Optimize case where source and destination
3718 ;; registers match and cases where we can use cltd.
3720 [(set (match_operand:DI 0 "register_operand")
3721 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3722 (clobber (reg:CC FLAGS_REG))
3723 (clobber (match_scratch:SI 2))]
3727 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3729 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3730 emit_move_insn (operands[3], operands[1]);
3732 /* Generate a cltd if possible and doing so it profitable. */
3733 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3734 && true_regnum (operands[3]) == AX_REG
3735 && true_regnum (operands[4]) == DX_REG)
3737 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3741 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3742 emit_move_insn (operands[4], operands[1]);
3744 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3748 (define_insn "extend<mode>di2"
3749 [(set (match_operand:DI 0 "register_operand" "=r")
3751 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3753 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3754 [(set_attr "type" "imovx")
3755 (set_attr "mode" "DI")])
3757 (define_insn "extendhisi2"
3758 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3759 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3762 switch (get_attr_prefix_0f (insn))
3765 return "{cwtl|cwde}";
3767 return "movs{wl|x}\t{%1, %0|%0, %1}";
3770 [(set_attr "type" "imovx")
3771 (set_attr "mode" "SI")
3772 (set (attr "prefix_0f")
3773 ;; movsx is short decodable while cwtl is vector decoded.
3774 (if_then_else (and (eq_attr "cpu" "!k6")
3775 (eq_attr "alternative" "0"))
3777 (const_string "1")))
3779 (if_then_else (eq_attr "prefix_0f" "0")
3781 (const_string "1")))])
3783 (define_insn "*extendhisi2_zext"
3784 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3787 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3790 switch (get_attr_prefix_0f (insn))
3793 return "{cwtl|cwde}";
3795 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3798 [(set_attr "type" "imovx")
3799 (set_attr "mode" "SI")
3800 (set (attr "prefix_0f")
3801 ;; movsx is short decodable while cwtl is vector decoded.
3802 (if_then_else (and (eq_attr "cpu" "!k6")
3803 (eq_attr "alternative" "0"))
3805 (const_string "1")))
3807 (if_then_else (eq_attr "prefix_0f" "0")
3809 (const_string "1")))])
3811 (define_insn "extendqisi2"
3812 [(set (match_operand:SI 0 "register_operand" "=r")
3813 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3815 "movs{bl|x}\t{%1, %0|%0, %1}"
3816 [(set_attr "type" "imovx")
3817 (set_attr "mode" "SI")])
3819 (define_insn "*extendqisi2_zext"
3820 [(set (match_operand:DI 0 "register_operand" "=r")
3822 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3824 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3825 [(set_attr "type" "imovx")
3826 (set_attr "mode" "SI")])
3828 (define_insn "extendqihi2"
3829 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3830 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3833 switch (get_attr_prefix_0f (insn))
3836 return "{cbtw|cbw}";
3838 return "movs{bw|x}\t{%1, %0|%0, %1}";
3841 [(set_attr "type" "imovx")
3842 (set_attr "mode" "HI")
3843 (set (attr "prefix_0f")
3844 ;; movsx is short decodable while cwtl is vector decoded.
3845 (if_then_else (and (eq_attr "cpu" "!k6")
3846 (eq_attr "alternative" "0"))
3848 (const_string "1")))
3850 (if_then_else (eq_attr "prefix_0f" "0")
3852 (const_string "1")))])
3854 ;; Conversions between float and double.
3856 ;; These are all no-ops in the model used for the 80387.
3857 ;; So just emit moves.
3859 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3861 [(set (match_operand:DF 0 "push_operand")
3862 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3864 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3865 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3868 [(set (match_operand:XF 0 "push_operand")
3869 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3871 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3872 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3873 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3875 (define_expand "extendsfdf2"
3876 [(set (match_operand:DF 0 "nonimmediate_operand")
3877 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3878 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3880 /* ??? Needed for compress_float_constant since all fp constants
3881 are TARGET_LEGITIMATE_CONSTANT_P. */
3882 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3884 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3885 && standard_80387_constant_p (operands[1]) > 0)
3887 operands[1] = simplify_const_unary_operation
3888 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3889 emit_move_insn_1 (operands[0], operands[1]);
3892 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3896 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3898 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3900 We do the conversion post reload to avoid producing of 128bit spills
3901 that might lead to ICE on 32bit target. The sequence unlikely combine
3904 [(set (match_operand:DF 0 "register_operand")
3906 (match_operand:SF 1 "nonimmediate_operand")))]
3907 "TARGET_USE_VECTOR_FP_CONVERTS
3908 && optimize_insn_for_speed_p ()
3909 && reload_completed && SSE_REG_P (operands[0])"
3914 (parallel [(const_int 0) (const_int 1)]))))]
3916 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3917 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3918 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3919 Try to avoid move when unpacking can be done in source. */
3920 if (REG_P (operands[1]))
3922 /* If it is unsafe to overwrite upper half of source, we need
3923 to move to destination and unpack there. */
3924 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3925 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3926 && true_regnum (operands[0]) != true_regnum (operands[1]))
3928 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3929 emit_move_insn (tmp, operands[1]);
3932 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3933 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3937 emit_insn (gen_vec_setv4sf_0 (operands[3],
3938 CONST0_RTX (V4SFmode), operands[1]));
3941 (define_insn "*extendsfdf2_mixed"
3942 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3944 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3945 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3947 switch (which_alternative)
3951 return output_387_reg_move (insn, operands);
3954 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3960 [(set_attr "type" "fmov,fmov,ssecvt")
3961 (set_attr "prefix" "orig,orig,maybe_vex")
3962 (set_attr "mode" "SF,XF,DF")])
3964 (define_insn "*extendsfdf2_sse"
3965 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3966 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3967 "TARGET_SSE2 && TARGET_SSE_MATH"
3968 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3969 [(set_attr "type" "ssecvt")
3970 (set_attr "prefix" "maybe_vex")
3971 (set_attr "mode" "DF")])
3973 (define_insn "*extendsfdf2_i387"
3974 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3975 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3977 "* return output_387_reg_move (insn, operands);"
3978 [(set_attr "type" "fmov")
3979 (set_attr "mode" "SF,XF")])
3981 (define_expand "extend<mode>xf2"
3982 [(set (match_operand:XF 0 "nonimmediate_operand")
3983 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3986 /* ??? Needed for compress_float_constant since all fp constants
3987 are TARGET_LEGITIMATE_CONSTANT_P. */
3988 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3990 if (standard_80387_constant_p (operands[1]) > 0)
3992 operands[1] = simplify_const_unary_operation
3993 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3994 emit_move_insn_1 (operands[0], operands[1]);
3997 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4001 (define_insn "*extend<mode>xf2_i387"
4002 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4004 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4006 "* return output_387_reg_move (insn, operands);"
4007 [(set_attr "type" "fmov")
4008 (set_attr "mode" "<MODE>,XF")])
4010 ;; %%% This seems bad bad news.
4011 ;; This cannot output into an f-reg because there is no way to be sure
4012 ;; of truncating in that case. Otherwise this is just like a simple move
4013 ;; insn. So we pretend we can output to a reg in order to get better
4014 ;; register preferencing, but we really use a stack slot.
4016 ;; Conversion from DFmode to SFmode.
4018 (define_expand "truncdfsf2"
4019 [(set (match_operand:SF 0 "nonimmediate_operand")
4021 (match_operand:DF 1 "nonimmediate_operand")))]
4022 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4024 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4026 else if (flag_unsafe_math_optimizations)
4030 enum ix86_stack_slot slot = (virtuals_instantiated
4033 rtx temp = assign_386_stack_local (SFmode, slot);
4034 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4039 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4041 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4043 We do the conversion post reload to avoid producing of 128bit spills
4044 that might lead to ICE on 32bit target. The sequence unlikely combine
4047 [(set (match_operand:SF 0 "register_operand")
4049 (match_operand:DF 1 "nonimmediate_operand")))]
4050 "TARGET_USE_VECTOR_FP_CONVERTS
4051 && optimize_insn_for_speed_p ()
4052 && reload_completed && SSE_REG_P (operands[0])"
4055 (float_truncate:V2SF
4059 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4060 operands[3] = CONST0_RTX (V2SFmode);
4061 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4062 /* Use movsd for loading from memory, unpcklpd for registers.
4063 Try to avoid move when unpacking can be done in source, or SSE3
4064 movddup is available. */
4065 if (REG_P (operands[1]))
4068 && true_regnum (operands[0]) != true_regnum (operands[1])
4069 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4070 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4072 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4073 emit_move_insn (tmp, operands[1]);
4076 else if (!TARGET_SSE3)
4077 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4078 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4081 emit_insn (gen_sse2_loadlpd (operands[4],
4082 CONST0_RTX (V2DFmode), operands[1]));
4085 (define_expand "truncdfsf2_with_temp"
4086 [(parallel [(set (match_operand:SF 0)
4087 (float_truncate:SF (match_operand:DF 1)))
4088 (clobber (match_operand:SF 2))])])
4090 (define_insn "*truncdfsf_fast_mixed"
4091 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4093 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4094 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4096 switch (which_alternative)
4099 return output_387_reg_move (insn, operands);
4101 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4106 [(set_attr "type" "fmov,ssecvt")
4107 (set_attr "prefix" "orig,maybe_vex")
4108 (set_attr "mode" "SF")])
4110 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4111 ;; because nothing we do here is unsafe.
4112 (define_insn "*truncdfsf_fast_sse"
4113 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4115 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4116 "TARGET_SSE2 && TARGET_SSE_MATH"
4117 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4118 [(set_attr "type" "ssecvt")
4119 (set_attr "prefix" "maybe_vex")
4120 (set_attr "mode" "SF")])
4122 (define_insn "*truncdfsf_fast_i387"
4123 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4125 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4126 "TARGET_80387 && flag_unsafe_math_optimizations"
4127 "* return output_387_reg_move (insn, operands);"
4128 [(set_attr "type" "fmov")
4129 (set_attr "mode" "SF")])
4131 (define_insn "*truncdfsf_mixed"
4132 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4134 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4135 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4136 "TARGET_MIX_SSE_I387"
4138 switch (which_alternative)
4141 return output_387_reg_move (insn, operands);
4143 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4149 [(set_attr "isa" "*,sse2,*,*,*")
4150 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4151 (set_attr "unit" "*,*,i387,i387,i387")
4152 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4153 (set_attr "mode" "SF")])
4155 (define_insn "*truncdfsf_i387"
4156 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4158 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4159 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4162 switch (which_alternative)
4165 return output_387_reg_move (insn, operands);
4171 [(set_attr "type" "fmov,multi,multi,multi")
4172 (set_attr "unit" "*,i387,i387,i387")
4173 (set_attr "mode" "SF")])
4175 (define_insn "*truncdfsf2_i387_1"
4176 [(set (match_operand:SF 0 "memory_operand" "=m")
4178 (match_operand:DF 1 "register_operand" "f")))]
4180 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4181 && !TARGET_MIX_SSE_I387"
4182 "* return output_387_reg_move (insn, operands);"
4183 [(set_attr "type" "fmov")
4184 (set_attr "mode" "SF")])
4187 [(set (match_operand:SF 0 "register_operand")
4189 (match_operand:DF 1 "fp_register_operand")))
4190 (clobber (match_operand 2))]
4192 [(set (match_dup 2) (match_dup 1))
4193 (set (match_dup 0) (match_dup 2))]
4194 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4196 ;; Conversion from XFmode to {SF,DF}mode
4198 (define_expand "truncxf<mode>2"
4199 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4200 (float_truncate:MODEF
4201 (match_operand:XF 1 "register_operand")))
4202 (clobber (match_dup 2))])]
4205 if (flag_unsafe_math_optimizations)
4207 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4208 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4209 if (reg != operands[0])
4210 emit_move_insn (operands[0], reg);
4215 enum ix86_stack_slot slot = (virtuals_instantiated
4218 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4222 (define_insn "*truncxfsf2_mixed"
4223 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4225 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4226 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4229 gcc_assert (!which_alternative);
4230 return output_387_reg_move (insn, operands);
4232 [(set_attr "type" "fmov,multi,multi,multi")
4233 (set_attr "unit" "*,i387,i387,i387")
4234 (set_attr "mode" "SF")])
4236 (define_insn "*truncxfdf2_mixed"
4237 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4239 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4240 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4243 gcc_assert (!which_alternative);
4244 return output_387_reg_move (insn, operands);
4246 [(set_attr "isa" "*,*,sse2,*")
4247 (set_attr "type" "fmov,multi,multi,multi")
4248 (set_attr "unit" "*,i387,i387,i387")
4249 (set_attr "mode" "DF")])
4251 (define_insn "truncxf<mode>2_i387_noop"
4252 [(set (match_operand:MODEF 0 "register_operand" "=f")
4253 (float_truncate:MODEF
4254 (match_operand:XF 1 "register_operand" "f")))]
4255 "TARGET_80387 && flag_unsafe_math_optimizations"
4256 "* return output_387_reg_move (insn, operands);"
4257 [(set_attr "type" "fmov")
4258 (set_attr "mode" "<MODE>")])
4260 (define_insn "*truncxf<mode>2_i387"
4261 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4262 (float_truncate:MODEF
4263 (match_operand:XF 1 "register_operand" "f")))]
4265 "* return output_387_reg_move (insn, operands);"
4266 [(set_attr "type" "fmov")
4267 (set_attr "mode" "<MODE>")])
4270 [(set (match_operand:MODEF 0 "register_operand")
4271 (float_truncate:MODEF
4272 (match_operand:XF 1 "register_operand")))
4273 (clobber (match_operand:MODEF 2 "memory_operand"))]
4274 "TARGET_80387 && reload_completed"
4275 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4276 (set (match_dup 0) (match_dup 2))])
4279 [(set (match_operand:MODEF 0 "memory_operand")
4280 (float_truncate:MODEF
4281 (match_operand:XF 1 "register_operand")))
4282 (clobber (match_operand:MODEF 2 "memory_operand"))]
4284 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4286 ;; Signed conversion to DImode.
4288 (define_expand "fix_truncxfdi2"
4289 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4290 (fix:DI (match_operand:XF 1 "register_operand")))
4291 (clobber (reg:CC FLAGS_REG))])]
4296 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4301 (define_expand "fix_trunc<mode>di2"
4302 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4303 (fix:DI (match_operand:MODEF 1 "register_operand")))
4304 (clobber (reg:CC FLAGS_REG))])]
4305 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4308 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4310 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4313 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4315 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4316 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4317 if (out != operands[0])
4318 emit_move_insn (operands[0], out);
4323 ;; Signed conversion to SImode.
4325 (define_expand "fix_truncxfsi2"
4326 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4327 (fix:SI (match_operand:XF 1 "register_operand")))
4328 (clobber (reg:CC FLAGS_REG))])]
4333 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4338 (define_expand "fix_trunc<mode>si2"
4339 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4340 (fix:SI (match_operand:MODEF 1 "register_operand")))
4341 (clobber (reg:CC FLAGS_REG))])]
4342 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4345 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4347 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4350 if (SSE_FLOAT_MODE_P (<MODE>mode))
4352 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4353 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4354 if (out != operands[0])
4355 emit_move_insn (operands[0], out);
4360 ;; Signed conversion to HImode.
4362 (define_expand "fix_trunc<mode>hi2"
4363 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4364 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4365 (clobber (reg:CC FLAGS_REG))])]
4367 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4371 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4376 ;; Unsigned conversion to SImode.
4378 (define_expand "fixuns_trunc<mode>si2"
4380 [(set (match_operand:SI 0 "register_operand")
4382 (match_operand:MODEF 1 "nonimmediate_operand")))
4384 (clobber (match_scratch:<ssevecmode> 3))
4385 (clobber (match_scratch:<ssevecmode> 4))])]
4386 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4388 enum machine_mode mode = <MODE>mode;
4389 enum machine_mode vecmode = <ssevecmode>mode;
4390 REAL_VALUE_TYPE TWO31r;
4393 if (optimize_insn_for_size_p ())
4396 real_ldexp (&TWO31r, &dconst1, 31);
4397 two31 = const_double_from_real_value (TWO31r, mode);
4398 two31 = ix86_build_const_vector (vecmode, true, two31);
4399 operands[2] = force_reg (vecmode, two31);
4402 (define_insn_and_split "*fixuns_trunc<mode>_1"
4403 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4405 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4406 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4407 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4408 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4409 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4410 && optimize_function_for_speed_p (cfun)"
4412 "&& reload_completed"
4415 ix86_split_convert_uns_si_sse (operands);
4419 ;; Unsigned conversion to HImode.
4420 ;; Without these patterns, we'll try the unsigned SI conversion which
4421 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4423 (define_expand "fixuns_trunc<mode>hi2"
4425 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4426 (set (match_operand:HI 0 "nonimmediate_operand")
4427 (subreg:HI (match_dup 2) 0))]
4428 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4429 "operands[2] = gen_reg_rtx (SImode);")
4431 ;; When SSE is available, it is always faster to use it!
4432 (define_insn "fix_trunc<mode>di_sse"
4433 [(set (match_operand:DI 0 "register_operand" "=r,r")
4434 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4435 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4436 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4437 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4438 [(set_attr "type" "sseicvt")
4439 (set_attr "prefix" "maybe_vex")
4440 (set_attr "prefix_rex" "1")
4441 (set_attr "mode" "<MODE>")
4442 (set_attr "athlon_decode" "double,vector")
4443 (set_attr "amdfam10_decode" "double,double")
4444 (set_attr "bdver1_decode" "double,double")])
4446 (define_insn "fix_trunc<mode>si_sse"
4447 [(set (match_operand:SI 0 "register_operand" "=r,r")
4448 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4449 "SSE_FLOAT_MODE_P (<MODE>mode)
4450 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4451 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4452 [(set_attr "type" "sseicvt")
4453 (set_attr "prefix" "maybe_vex")
4454 (set_attr "mode" "<MODE>")
4455 (set_attr "athlon_decode" "double,vector")
4456 (set_attr "amdfam10_decode" "double,double")
4457 (set_attr "bdver1_decode" "double,double")])
4459 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4461 [(set (match_operand:MODEF 0 "register_operand")
4462 (match_operand:MODEF 1 "memory_operand"))
4463 (set (match_operand:SWI48x 2 "register_operand")
4464 (fix:SWI48x (match_dup 0)))]
4465 "TARGET_SHORTEN_X87_SSE
4466 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4467 && peep2_reg_dead_p (2, operands[0])"
4468 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4470 ;; Avoid vector decoded forms of the instruction.
4472 [(match_scratch:DF 2 "x")
4473 (set (match_operand:SWI48x 0 "register_operand")
4474 (fix:SWI48x (match_operand:DF 1 "memory_operand")))]
4475 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4476 [(set (match_dup 2) (match_dup 1))
4477 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4480 [(match_scratch:SF 2 "x")
4481 (set (match_operand:SWI48x 0 "register_operand")
4482 (fix:SWI48x (match_operand:SF 1 "memory_operand")))]
4483 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4484 [(set (match_dup 2) (match_dup 1))
4485 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4487 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4488 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4489 (fix:SWI248x (match_operand 1 "register_operand")))]
4490 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4492 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4493 && (TARGET_64BIT || <MODE>mode != DImode))
4495 && can_create_pseudo_p ()"
4500 if (memory_operand (operands[0], VOIDmode))
4501 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4504 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4505 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4511 [(set_attr "type" "fisttp")
4512 (set_attr "mode" "<MODE>")])
4514 (define_insn "fix_trunc<mode>_i387_fisttp"
4515 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4516 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4517 (clobber (match_scratch:XF 2 "=&1f"))]
4518 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4520 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4521 && (TARGET_64BIT || <MODE>mode != DImode))
4522 && TARGET_SSE_MATH)"
4523 "* return output_fix_trunc (insn, operands, true);"
4524 [(set_attr "type" "fisttp")
4525 (set_attr "mode" "<MODE>")])
4527 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4528 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4529 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4530 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4531 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4532 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4534 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4535 && (TARGET_64BIT || <MODE>mode != DImode))
4536 && TARGET_SSE_MATH)"
4538 [(set_attr "type" "fisttp")
4539 (set_attr "mode" "<MODE>")])
4542 [(set (match_operand:SWI248x 0 "register_operand")
4543 (fix:SWI248x (match_operand 1 "register_operand")))
4544 (clobber (match_operand:SWI248x 2 "memory_operand"))
4545 (clobber (match_scratch 3))]
4547 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4548 (clobber (match_dup 3))])
4549 (set (match_dup 0) (match_dup 2))])
4552 [(set (match_operand:SWI248x 0 "memory_operand")
4553 (fix:SWI248x (match_operand 1 "register_operand")))
4554 (clobber (match_operand:SWI248x 2 "memory_operand"))
4555 (clobber (match_scratch 3))]
4557 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4558 (clobber (match_dup 3))])])
4560 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4561 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4562 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4563 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4564 ;; function in i386.c.
4565 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4566 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4567 (fix:SWI248x (match_operand 1 "register_operand")))
4568 (clobber (reg:CC FLAGS_REG))]
4569 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4571 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4572 && (TARGET_64BIT || <MODE>mode != DImode))
4573 && can_create_pseudo_p ()"
4578 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4580 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4581 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4582 if (memory_operand (operands[0], VOIDmode))
4583 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4584 operands[2], operands[3]));
4587 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4588 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4589 operands[2], operands[3],
4594 [(set_attr "type" "fistp")
4595 (set_attr "i387_cw" "trunc")
4596 (set_attr "mode" "<MODE>")])
4598 (define_insn "fix_truncdi_i387"
4599 [(set (match_operand:DI 0 "memory_operand" "=m")
4600 (fix:DI (match_operand 1 "register_operand" "f")))
4601 (use (match_operand:HI 2 "memory_operand" "m"))
4602 (use (match_operand:HI 3 "memory_operand" "m"))
4603 (clobber (match_scratch:XF 4 "=&1f"))]
4604 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4606 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4607 "* return output_fix_trunc (insn, operands, false);"
4608 [(set_attr "type" "fistp")
4609 (set_attr "i387_cw" "trunc")
4610 (set_attr "mode" "DI")])
4612 (define_insn "fix_truncdi_i387_with_temp"
4613 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4614 (fix:DI (match_operand 1 "register_operand" "f,f")))
4615 (use (match_operand:HI 2 "memory_operand" "m,m"))
4616 (use (match_operand:HI 3 "memory_operand" "m,m"))
4617 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4618 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4619 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4621 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4623 [(set_attr "type" "fistp")
4624 (set_attr "i387_cw" "trunc")
4625 (set_attr "mode" "DI")])
4628 [(set (match_operand:DI 0 "register_operand")
4629 (fix:DI (match_operand 1 "register_operand")))
4630 (use (match_operand:HI 2 "memory_operand"))
4631 (use (match_operand:HI 3 "memory_operand"))
4632 (clobber (match_operand:DI 4 "memory_operand"))
4633 (clobber (match_scratch 5))]
4635 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4638 (clobber (match_dup 5))])
4639 (set (match_dup 0) (match_dup 4))])
4642 [(set (match_operand:DI 0 "memory_operand")
4643 (fix:DI (match_operand 1 "register_operand")))
4644 (use (match_operand:HI 2 "memory_operand"))
4645 (use (match_operand:HI 3 "memory_operand"))
4646 (clobber (match_operand:DI 4 "memory_operand"))
4647 (clobber (match_scratch 5))]
4649 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4652 (clobber (match_dup 5))])])
4654 (define_insn "fix_trunc<mode>_i387"
4655 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4656 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4657 (use (match_operand:HI 2 "memory_operand" "m"))
4658 (use (match_operand:HI 3 "memory_operand" "m"))]
4659 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4661 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4662 "* return output_fix_trunc (insn, operands, false);"
4663 [(set_attr "type" "fistp")
4664 (set_attr "i387_cw" "trunc")
4665 (set_attr "mode" "<MODE>")])
4667 (define_insn "fix_trunc<mode>_i387_with_temp"
4668 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4669 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4670 (use (match_operand:HI 2 "memory_operand" "m,m"))
4671 (use (match_operand:HI 3 "memory_operand" "m,m"))
4672 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4673 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4675 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4677 [(set_attr "type" "fistp")
4678 (set_attr "i387_cw" "trunc")
4679 (set_attr "mode" "<MODE>")])
4682 [(set (match_operand:SWI24 0 "register_operand")
4683 (fix:SWI24 (match_operand 1 "register_operand")))
4684 (use (match_operand:HI 2 "memory_operand"))
4685 (use (match_operand:HI 3 "memory_operand"))
4686 (clobber (match_operand:SWI24 4 "memory_operand"))]
4688 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4690 (use (match_dup 3))])
4691 (set (match_dup 0) (match_dup 4))])
4694 [(set (match_operand:SWI24 0 "memory_operand")
4695 (fix:SWI24 (match_operand 1 "register_operand")))
4696 (use (match_operand:HI 2 "memory_operand"))
4697 (use (match_operand:HI 3 "memory_operand"))
4698 (clobber (match_operand:SWI24 4 "memory_operand"))]
4700 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4702 (use (match_dup 3))])])
4704 (define_insn "x86_fnstcw_1"
4705 [(set (match_operand:HI 0 "memory_operand" "=m")
4706 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4709 [(set (attr "length")
4710 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4711 (set_attr "mode" "HI")
4712 (set_attr "unit" "i387")
4713 (set_attr "bdver1_decode" "vector")])
4715 (define_insn "x86_fldcw_1"
4716 [(set (reg:HI FPCR_REG)
4717 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4720 [(set (attr "length")
4721 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4722 (set_attr "mode" "HI")
4723 (set_attr "unit" "i387")
4724 (set_attr "athlon_decode" "vector")
4725 (set_attr "amdfam10_decode" "vector")
4726 (set_attr "bdver1_decode" "vector")])
4728 ;; Conversion between fixed point and floating point.
4730 ;; Even though we only accept memory inputs, the backend _really_
4731 ;; wants to be able to do this between registers.
4733 (define_expand "floathi<mode>2"
4734 [(set (match_operand:X87MODEF 0 "register_operand")
4735 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4737 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4738 || TARGET_MIX_SSE_I387)")
4740 ;; Pre-reload splitter to add memory clobber to the pattern.
4741 (define_insn_and_split "*floathi<mode>2_1"
4742 [(set (match_operand:X87MODEF 0 "register_operand")
4743 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4745 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4746 || TARGET_MIX_SSE_I387)
4747 && can_create_pseudo_p ()"
4750 [(parallel [(set (match_dup 0)
4751 (float:X87MODEF (match_dup 1)))
4752 (clobber (match_dup 2))])]
4753 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4755 (define_insn "*floathi<mode>2_i387_with_temp"
4756 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4757 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4758 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4760 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4761 || TARGET_MIX_SSE_I387)"
4763 [(set_attr "type" "fmov,multi")
4764 (set_attr "mode" "<MODE>")
4765 (set_attr "unit" "*,i387")
4766 (set_attr "fp_int_src" "true")])
4768 (define_insn "*floathi<mode>2_i387"
4769 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4770 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4772 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4773 || TARGET_MIX_SSE_I387)"
4775 [(set_attr "type" "fmov")
4776 (set_attr "mode" "<MODE>")
4777 (set_attr "fp_int_src" "true")])
4780 [(set (match_operand:X87MODEF 0 "register_operand")
4781 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4782 (clobber (match_operand:HI 2 "memory_operand"))]
4784 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4785 || TARGET_MIX_SSE_I387)
4786 && reload_completed"
4787 [(set (match_dup 2) (match_dup 1))
4788 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4791 [(set (match_operand:X87MODEF 0 "register_operand")
4792 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4793 (clobber (match_operand:HI 2 "memory_operand"))]
4795 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4796 || TARGET_MIX_SSE_I387)
4797 && reload_completed"
4798 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4800 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4801 [(set (match_operand:X87MODEF 0 "register_operand")
4803 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4805 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4806 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4808 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4809 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4810 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4812 rtx reg = gen_reg_rtx (XFmode);
4813 rtx (*insn)(rtx, rtx);
4815 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4817 if (<X87MODEF:MODE>mode == SFmode)
4818 insn = gen_truncxfsf2;
4819 else if (<X87MODEF:MODE>mode == DFmode)
4820 insn = gen_truncxfdf2;
4824 emit_insn (insn (operands[0], reg));
4829 ;; Pre-reload splitter to add memory clobber to the pattern.
4830 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4831 [(set (match_operand:X87MODEF 0 "register_operand")
4832 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4834 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4835 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4836 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4837 || TARGET_MIX_SSE_I387))
4838 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4839 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4840 && ((<SWI48x:MODE>mode == SImode
4841 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4842 && optimize_function_for_speed_p (cfun)
4843 && flag_trapping_math)
4844 || !(TARGET_INTER_UNIT_CONVERSIONS
4845 || optimize_function_for_size_p (cfun)))))
4846 && can_create_pseudo_p ()"
4849 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4850 (clobber (match_dup 2))])]
4852 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4854 /* Avoid store forwarding (partial memory) stall penalty
4855 by passing DImode value through XMM registers. */
4856 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4857 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4858 && optimize_function_for_speed_p (cfun))
4860 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4867 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4868 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4870 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4871 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4872 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4873 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4875 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4876 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4877 (set_attr "unit" "*,i387,*,*,*")
4878 (set_attr "athlon_decode" "*,*,double,direct,double")
4879 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4880 (set_attr "bdver1_decode" "*,*,double,direct,double")
4881 (set_attr "fp_int_src" "true")])
4883 (define_insn "*floatsi<mode>2_vector_mixed"
4884 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4885 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4886 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4887 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4891 [(set_attr "type" "fmov,sseicvt")
4892 (set_attr "mode" "<MODE>,<ssevecmode>")
4893 (set_attr "unit" "i387,*")
4894 (set_attr "athlon_decode" "*,direct")
4895 (set_attr "amdfam10_decode" "*,double")
4896 (set_attr "bdver1_decode" "*,direct")
4897 (set_attr "fp_int_src" "true")])
4899 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4900 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4902 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4903 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4904 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4905 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4907 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4908 (set_attr "mode" "<MODEF:MODE>")
4909 (set_attr "unit" "*,i387,*,*")
4910 (set_attr "athlon_decode" "*,*,double,direct")
4911 (set_attr "amdfam10_decode" "*,*,vector,double")
4912 (set_attr "bdver1_decode" "*,*,double,direct")
4913 (set_attr "fp_int_src" "true")])
4916 [(set (match_operand:MODEF 0 "register_operand")
4917 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4918 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4919 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4920 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4921 && TARGET_INTER_UNIT_CONVERSIONS
4923 && (SSE_REG_P (operands[0])
4924 || (GET_CODE (operands[0]) == SUBREG
4925 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4926 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4929 [(set (match_operand:MODEF 0 "register_operand")
4930 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4931 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4932 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4933 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4934 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4936 && (SSE_REG_P (operands[0])
4937 || (GET_CODE (operands[0]) == SUBREG
4938 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4939 [(set (match_dup 2) (match_dup 1))
4940 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4942 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4943 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4945 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4946 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4947 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4948 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4951 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4952 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4953 [(set_attr "type" "fmov,sseicvt,sseicvt")
4954 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4955 (set_attr "mode" "<MODEF:MODE>")
4956 (set (attr "prefix_rex")
4958 (and (eq_attr "prefix" "maybe_vex")
4959 (match_test "<SWI48x:MODE>mode == DImode"))
4961 (const_string "*")))
4962 (set_attr "unit" "i387,*,*")
4963 (set_attr "athlon_decode" "*,double,direct")
4964 (set_attr "amdfam10_decode" "*,vector,double")
4965 (set_attr "bdver1_decode" "*,double,direct")
4966 (set_attr "fp_int_src" "true")])
4968 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4969 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4971 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4972 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4973 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4974 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4977 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4978 [(set_attr "type" "fmov,sseicvt")
4979 (set_attr "prefix" "orig,maybe_vex")
4980 (set_attr "mode" "<MODEF:MODE>")
4981 (set (attr "prefix_rex")
4983 (and (eq_attr "prefix" "maybe_vex")
4984 (match_test "<SWI48x:MODE>mode == DImode"))
4986 (const_string "*")))
4987 (set_attr "athlon_decode" "*,direct")
4988 (set_attr "amdfam10_decode" "*,double")
4989 (set_attr "bdver1_decode" "*,direct")
4990 (set_attr "fp_int_src" "true")])
4992 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4993 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4995 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4996 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4997 "TARGET_SSE2 && TARGET_SSE_MATH
4998 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5000 [(set_attr "type" "sseicvt")
5001 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5002 (set_attr "athlon_decode" "double,direct,double")
5003 (set_attr "amdfam10_decode" "vector,double,double")
5004 (set_attr "bdver1_decode" "double,direct,double")
5005 (set_attr "fp_int_src" "true")])
5007 (define_insn "*floatsi<mode>2_vector_sse"
5008 [(set (match_operand:MODEF 0 "register_operand" "=x")
5009 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5010 "TARGET_SSE2 && TARGET_SSE_MATH
5011 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5013 [(set_attr "type" "sseicvt")
5014 (set_attr "mode" "<MODE>")
5015 (set_attr "athlon_decode" "direct")
5016 (set_attr "amdfam10_decode" "double")
5017 (set_attr "bdver1_decode" "direct")
5018 (set_attr "fp_int_src" "true")])
5021 [(set (match_operand:MODEF 0 "register_operand")
5022 (float:MODEF (match_operand:SI 1 "register_operand")))
5023 (clobber (match_operand:SI 2 "memory_operand"))]
5024 "TARGET_SSE2 && TARGET_SSE_MATH
5025 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5027 && (SSE_REG_P (operands[0])
5028 || (GET_CODE (operands[0]) == SUBREG
5029 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5032 rtx op1 = operands[1];
5034 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5036 if (GET_CODE (op1) == SUBREG)
5037 op1 = SUBREG_REG (op1);
5039 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5041 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5042 emit_insn (gen_sse2_loadld (operands[4],
5043 CONST0_RTX (V4SImode), operands[1]));
5045 /* We can ignore possible trapping value in the
5046 high part of SSE register for non-trapping math. */
5047 else if (SSE_REG_P (op1) && !flag_trapping_math)
5048 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5051 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5052 emit_move_insn (operands[2], operands[1]);
5053 emit_insn (gen_sse2_loadld (operands[4],
5054 CONST0_RTX (V4SImode), operands[2]));
5056 if (<ssevecmode>mode == V4SFmode)
5057 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5059 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5064 [(set (match_operand:MODEF 0 "register_operand")
5065 (float:MODEF (match_operand:SI 1 "memory_operand")))
5066 (clobber (match_operand:SI 2 "memory_operand"))]
5067 "TARGET_SSE2 && TARGET_SSE_MATH
5068 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5070 && (SSE_REG_P (operands[0])
5071 || (GET_CODE (operands[0]) == SUBREG
5072 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5075 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5077 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5079 emit_insn (gen_sse2_loadld (operands[4],
5080 CONST0_RTX (V4SImode), operands[1]));
5081 if (<ssevecmode>mode == V4SFmode)
5082 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5084 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5089 [(set (match_operand:MODEF 0 "register_operand")
5090 (float:MODEF (match_operand:SI 1 "register_operand")))]
5091 "TARGET_SSE2 && TARGET_SSE_MATH
5092 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5094 && (SSE_REG_P (operands[0])
5095 || (GET_CODE (operands[0]) == SUBREG
5096 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5099 rtx op1 = operands[1];
5101 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5103 if (GET_CODE (op1) == SUBREG)
5104 op1 = SUBREG_REG (op1);
5106 if (GENERAL_REG_P (op1))
5108 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5109 if (TARGET_INTER_UNIT_MOVES)
5110 emit_insn (gen_sse2_loadld (operands[4],
5111 CONST0_RTX (V4SImode), operands[1]));
5114 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5116 emit_insn (gen_sse2_loadld (operands[4],
5117 CONST0_RTX (V4SImode), operands[5]));
5118 ix86_free_from_memory (GET_MODE (operands[1]));
5121 /* We can ignore possible trapping value in the
5122 high part of SSE register for non-trapping math. */
5123 else if (SSE_REG_P (op1) && !flag_trapping_math)
5124 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5127 if (<ssevecmode>mode == V4SFmode)
5128 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5130 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5135 [(set (match_operand:MODEF 0 "register_operand")
5136 (float:MODEF (match_operand:SI 1 "memory_operand")))]
5137 "TARGET_SSE2 && TARGET_SSE_MATH
5138 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5140 && (SSE_REG_P (operands[0])
5141 || (GET_CODE (operands[0]) == SUBREG
5142 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5145 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5147 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5149 emit_insn (gen_sse2_loadld (operands[4],
5150 CONST0_RTX (V4SImode), operands[1]));
5151 if (<ssevecmode>mode == V4SFmode)
5152 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5154 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5158 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5159 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5161 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5162 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5163 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5164 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5166 [(set_attr "type" "sseicvt")
5167 (set_attr "mode" "<MODEF:MODE>")
5168 (set_attr "athlon_decode" "double,direct")
5169 (set_attr "amdfam10_decode" "vector,double")
5170 (set_attr "bdver1_decode" "double,direct")
5171 (set_attr "fp_int_src" "true")])
5173 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5174 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5176 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5177 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5178 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5179 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5180 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5181 [(set_attr "type" "sseicvt")
5182 (set_attr "prefix" "maybe_vex")
5183 (set_attr "mode" "<MODEF:MODE>")
5184 (set (attr "prefix_rex")
5186 (and (eq_attr "prefix" "maybe_vex")
5187 (match_test "<SWI48x:MODE>mode == DImode"))
5189 (const_string "*")))
5190 (set_attr "athlon_decode" "double,direct")
5191 (set_attr "amdfam10_decode" "vector,double")
5192 (set_attr "bdver1_decode" "double,direct")
5193 (set_attr "fp_int_src" "true")])
5196 [(set (match_operand:MODEF 0 "register_operand")
5197 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))
5198 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5199 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5200 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5201 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5203 && (SSE_REG_P (operands[0])
5204 || (GET_CODE (operands[0]) == SUBREG
5205 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5206 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5208 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5209 [(set (match_operand:MODEF 0 "register_operand" "=x")
5211 (match_operand:SWI48x 1 "memory_operand" "m")))]
5212 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5213 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5214 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5215 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5216 [(set_attr "type" "sseicvt")
5217 (set_attr "prefix" "maybe_vex")
5218 (set_attr "mode" "<MODEF:MODE>")
5219 (set (attr "prefix_rex")
5221 (and (eq_attr "prefix" "maybe_vex")
5222 (match_test "<SWI48x:MODE>mode == DImode"))
5224 (const_string "*")))
5225 (set_attr "athlon_decode" "direct")
5226 (set_attr "amdfam10_decode" "double")
5227 (set_attr "bdver1_decode" "direct")
5228 (set_attr "fp_int_src" "true")])
5231 [(set (match_operand:MODEF 0 "register_operand")
5232 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
5233 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5234 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5235 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5236 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5238 && (SSE_REG_P (operands[0])
5239 || (GET_CODE (operands[0]) == SUBREG
5240 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5241 [(set (match_dup 2) (match_dup 1))
5242 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5245 [(set (match_operand:MODEF 0 "register_operand")
5246 (float:MODEF (match_operand:SWI48x 1 "memory_operand")))
5247 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5248 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5249 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5251 && (SSE_REG_P (operands[0])
5252 || (GET_CODE (operands[0]) == SUBREG
5253 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5254 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5256 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5257 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5259 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5260 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5262 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5266 [(set_attr "type" "fmov,multi")
5267 (set_attr "mode" "<X87MODEF:MODE>")
5268 (set_attr "unit" "*,i387")
5269 (set_attr "fp_int_src" "true")])
5271 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5272 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5274 (match_operand:SWI48x 1 "memory_operand" "m")))]
5276 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5278 [(set_attr "type" "fmov")
5279 (set_attr "mode" "<X87MODEF:MODE>")
5280 (set_attr "fp_int_src" "true")])
5283 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5284 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5285 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5287 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5288 && reload_completed"
5289 [(set (match_dup 2) (match_dup 1))
5290 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5293 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5294 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5295 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5297 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5298 && reload_completed"
5299 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5301 ;; Avoid store forwarding (partial memory) stall penalty
5302 ;; by passing DImode value through XMM registers. */
5304 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5305 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5307 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5308 (clobber (match_scratch:V4SI 3 "=X,x"))
5309 (clobber (match_scratch:V4SI 4 "=X,x"))
5310 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5311 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5312 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5313 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5315 [(set_attr "type" "multi")
5316 (set_attr "mode" "<X87MODEF:MODE>")
5317 (set_attr "unit" "i387")
5318 (set_attr "fp_int_src" "true")])
5321 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5322 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5323 (clobber (match_scratch:V4SI 3))
5324 (clobber (match_scratch:V4SI 4))
5325 (clobber (match_operand:DI 2 "memory_operand"))]
5326 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5327 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5328 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5329 && reload_completed"
5330 [(set (match_dup 2) (match_dup 3))
5331 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5333 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5334 Assemble the 64-bit DImode value in an xmm register. */
5335 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5336 gen_rtx_SUBREG (SImode, operands[1], 0)));
5337 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5338 gen_rtx_SUBREG (SImode, operands[1], 4)));
5339 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5342 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5346 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5347 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5348 (clobber (match_scratch:V4SI 3))
5349 (clobber (match_scratch:V4SI 4))
5350 (clobber (match_operand:DI 2 "memory_operand"))]
5351 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5352 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5353 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5354 && reload_completed"
5355 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5357 ;; Avoid store forwarding (partial memory) stall penalty by extending
5358 ;; SImode value to DImode through XMM register instead of pushing two
5359 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5360 ;; targets benefit from this optimization. Also note that fild
5361 ;; loads from memory only.
5363 (define_insn "*floatunssi<mode>2_1"
5364 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5365 (unsigned_float:X87MODEF
5366 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5367 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5368 (clobber (match_scratch:SI 3 "=X,x"))]
5370 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5373 [(set_attr "type" "multi")
5374 (set_attr "mode" "<MODE>")])
5377 [(set (match_operand:X87MODEF 0 "register_operand")
5378 (unsigned_float:X87MODEF
5379 (match_operand:SI 1 "register_operand")))
5380 (clobber (match_operand:DI 2 "memory_operand"))
5381 (clobber (match_scratch:SI 3))]
5383 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5385 && reload_completed"
5386 [(set (match_dup 2) (match_dup 1))
5388 (float:X87MODEF (match_dup 2)))]
5389 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5392 [(set (match_operand:X87MODEF 0 "register_operand")
5393 (unsigned_float:X87MODEF
5394 (match_operand:SI 1 "memory_operand")))
5395 (clobber (match_operand:DI 2 "memory_operand"))
5396 (clobber (match_scratch:SI 3))]
5398 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5400 && reload_completed"
5401 [(set (match_dup 2) (match_dup 3))
5403 (float:X87MODEF (match_dup 2)))]
5405 emit_move_insn (operands[3], operands[1]);
5406 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5409 (define_expand "floatunssi<mode>2"
5411 [(set (match_operand:X87MODEF 0 "register_operand")
5412 (unsigned_float:X87MODEF
5413 (match_operand:SI 1 "nonimmediate_operand")))
5414 (clobber (match_dup 2))
5415 (clobber (match_scratch:SI 3))])]
5417 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5419 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5421 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5423 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5428 enum ix86_stack_slot slot = (virtuals_instantiated
5431 operands[2] = assign_386_stack_local (DImode, slot);
5435 (define_expand "floatunsdisf2"
5436 [(use (match_operand:SF 0 "register_operand"))
5437 (use (match_operand:DI 1 "nonimmediate_operand"))]
5438 "TARGET_64BIT && TARGET_SSE_MATH"
5439 "x86_emit_floatuns (operands); DONE;")
5441 (define_expand "floatunsdidf2"
5442 [(use (match_operand:DF 0 "register_operand"))
5443 (use (match_operand:DI 1 "nonimmediate_operand"))]
5444 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5445 && TARGET_SSE2 && TARGET_SSE_MATH"
5448 x86_emit_floatuns (operands);
5450 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5456 (define_expand "add<mode>3"
5457 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5458 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5459 (match_operand:SDWIM 2 "<general_operand>")))]
5461 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5463 (define_insn_and_split "*add<dwi>3_doubleword"
5464 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5466 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5467 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5468 (clobber (reg:CC FLAGS_REG))]
5469 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5472 [(parallel [(set (reg:CC FLAGS_REG)
5473 (unspec:CC [(match_dup 1) (match_dup 2)]
5476 (plus:DWIH (match_dup 1) (match_dup 2)))])
5477 (parallel [(set (match_dup 3)
5481 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5483 (clobber (reg:CC FLAGS_REG))])]
5484 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5486 (define_insn "*add<mode>3_cc"
5487 [(set (reg:CC FLAGS_REG)
5489 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5490 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5492 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5493 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5494 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5495 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5496 [(set_attr "type" "alu")
5497 (set_attr "mode" "<MODE>")])
5499 (define_insn "addqi3_cc"
5500 [(set (reg:CC FLAGS_REG)
5502 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5503 (match_operand:QI 2 "general_operand" "qn,qm")]
5505 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5506 (plus:QI (match_dup 1) (match_dup 2)))]
5507 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5508 "add{b}\t{%2, %0|%0, %2}"
5509 [(set_attr "type" "alu")
5510 (set_attr "mode" "QI")])
5512 (define_insn_and_split "*lea_1"
5513 [(set (match_operand:SI 0 "register_operand" "=r")
5514 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5516 "lea{l}\t{%E1, %0|%0, %E1}"
5517 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5520 ix86_split_lea_for_addr (operands, SImode);
5523 [(set_attr "type" "lea")
5524 (set_attr "mode" "SI")])
5526 (define_insn_and_split "*lea<mode>_2"
5527 [(set (match_operand:SWI48 0 "register_operand" "=r")
5528 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5530 "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"
5531 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5534 ix86_split_lea_for_addr (operands, <MODE>mode);
5537 [(set_attr "type" "lea")
5538 (set_attr "mode" "<MODE>")])
5540 (define_insn "*lea_3_zext"
5541 [(set (match_operand:DI 0 "register_operand" "=r")
5543 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5545 "lea{l}\t{%E1, %k0|%k0, %E1}"
5546 [(set_attr "type" "lea")
5547 (set_attr "mode" "SI")])
5549 (define_insn "*lea_4_zext"
5550 [(set (match_operand:DI 0 "register_operand" "=r")
5552 (match_operand:SI 1 "lea_address_operand" "j")))]
5554 "lea{l}\t{%E1, %k0|%k0, %E1}"
5555 [(set_attr "type" "lea")
5556 (set_attr "mode" "SI")])
5558 (define_insn "*lea_5_zext"
5559 [(set (match_operand:DI 0 "register_operand" "=r")
5561 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5562 (match_operand:DI 2 "const_32bit_mask" "n")))]
5564 "lea{l}\t{%E1, %k0|%k0, %E1}"
5565 [(set_attr "type" "lea")
5566 (set_attr "mode" "SI")])
5568 (define_insn "*lea_6_zext"
5569 [(set (match_operand:DI 0 "register_operand" "=r")
5571 (match_operand:DI 1 "lea_address_operand" "p")
5572 (match_operand:DI 2 "const_32bit_mask" "n")))]
5574 "lea{l}\t{%E1, %k0|%k0, %E1}"
5575 [(set_attr "type" "lea")
5576 (set_attr "mode" "SI")])
5578 (define_insn "*add<mode>_1"
5579 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5581 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5582 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5583 (clobber (reg:CC FLAGS_REG))]
5584 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5586 switch (get_attr_type (insn))
5592 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5593 if (operands[2] == const1_rtx)
5594 return "inc{<imodesuffix>}\t%0";
5597 gcc_assert (operands[2] == constm1_rtx);
5598 return "dec{<imodesuffix>}\t%0";
5602 /* For most processors, ADD is faster than LEA. This alternative
5603 was added to use ADD as much as possible. */
5604 if (which_alternative == 2)
5607 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5610 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5611 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5612 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5614 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5618 (cond [(eq_attr "alternative" "3")
5619 (const_string "lea")
5620 (match_operand:SWI48 2 "incdec_operand")
5621 (const_string "incdec")
5623 (const_string "alu")))
5624 (set (attr "length_immediate")
5626 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5628 (const_string "*")))
5629 (set_attr "mode" "<MODE>")])
5631 ;; It may seem that nonimmediate operand is proper one for operand 1.
5632 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5633 ;; we take care in ix86_binary_operator_ok to not allow two memory
5634 ;; operands so proper swapping will be done in reload. This allow
5635 ;; patterns constructed from addsi_1 to match.
5637 (define_insn "addsi_1_zext"
5638 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5640 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5641 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5642 (clobber (reg:CC FLAGS_REG))]
5643 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5645 switch (get_attr_type (insn))
5651 if (operands[2] == const1_rtx)
5652 return "inc{l}\t%k0";
5655 gcc_assert (operands[2] == constm1_rtx);
5656 return "dec{l}\t%k0";
5660 /* For most processors, ADD is faster than LEA. This alternative
5661 was added to use ADD as much as possible. */
5662 if (which_alternative == 1)
5665 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5668 if (x86_maybe_negate_const_int (&operands[2], SImode))
5669 return "sub{l}\t{%2, %k0|%k0, %2}";
5671 return "add{l}\t{%2, %k0|%k0, %2}";
5675 (cond [(eq_attr "alternative" "2")
5676 (const_string "lea")
5677 (match_operand:SI 2 "incdec_operand")
5678 (const_string "incdec")
5680 (const_string "alu")))
5681 (set (attr "length_immediate")
5683 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5685 (const_string "*")))
5686 (set_attr "mode" "SI")])
5688 (define_insn "*addhi_1"
5689 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5690 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5691 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5692 (clobber (reg:CC FLAGS_REG))]
5693 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5695 switch (get_attr_type (insn))
5701 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5702 if (operands[2] == const1_rtx)
5703 return "inc{w}\t%0";
5706 gcc_assert (operands[2] == constm1_rtx);
5707 return "dec{w}\t%0";
5711 /* For most processors, ADD is faster than LEA. This alternative
5712 was added to use ADD as much as possible. */
5713 if (which_alternative == 2)
5716 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5719 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5720 if (x86_maybe_negate_const_int (&operands[2], HImode))
5721 return "sub{w}\t{%2, %0|%0, %2}";
5723 return "add{w}\t{%2, %0|%0, %2}";
5727 (cond [(eq_attr "alternative" "3")
5728 (const_string "lea")
5729 (match_operand:HI 2 "incdec_operand")
5730 (const_string "incdec")
5732 (const_string "alu")))
5733 (set (attr "length_immediate")
5735 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5737 (const_string "*")))
5738 (set_attr "mode" "HI,HI,HI,SI")])
5740 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5741 (define_insn "*addqi_1"
5742 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5743 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5744 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5745 (clobber (reg:CC FLAGS_REG))]
5746 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5748 bool widen = (which_alternative == 3 || which_alternative == 4);
5750 switch (get_attr_type (insn))
5756 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5757 if (operands[2] == const1_rtx)
5758 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5761 gcc_assert (operands[2] == constm1_rtx);
5762 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5766 /* For most processors, ADD is faster than LEA. These alternatives
5767 were added to use ADD as much as possible. */
5768 if (which_alternative == 2 || which_alternative == 4)
5771 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5774 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5775 if (x86_maybe_negate_const_int (&operands[2], QImode))
5778 return "sub{l}\t{%2, %k0|%k0, %2}";
5780 return "sub{b}\t{%2, %0|%0, %2}";
5783 return "add{l}\t{%k2, %k0|%k0, %k2}";
5785 return "add{b}\t{%2, %0|%0, %2}";
5789 (cond [(eq_attr "alternative" "5")
5790 (const_string "lea")
5791 (match_operand:QI 2 "incdec_operand")
5792 (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" "QI,QI,QI,SI,SI,SI")])
5802 (define_insn "*addqi_1_slp"
5803 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5804 (plus:QI (match_dup 0)
5805 (match_operand:QI 1 "general_operand" "qn,qm")))
5806 (clobber (reg:CC FLAGS_REG))]
5807 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5808 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5810 switch (get_attr_type (insn))
5813 if (operands[1] == const1_rtx)
5814 return "inc{b}\t%0";
5817 gcc_assert (operands[1] == constm1_rtx);
5818 return "dec{b}\t%0";
5822 if (x86_maybe_negate_const_int (&operands[1], QImode))
5823 return "sub{b}\t{%1, %0|%0, %1}";
5825 return "add{b}\t{%1, %0|%0, %1}";
5829 (if_then_else (match_operand:QI 1 "incdec_operand")
5830 (const_string "incdec")
5831 (const_string "alu1")))
5832 (set (attr "memory")
5833 (if_then_else (match_operand 1 "memory_operand")
5834 (const_string "load")
5835 (const_string "none")))
5836 (set_attr "mode" "QI")])
5838 ;; Split non destructive adds if we cannot use lea.
5840 [(set (match_operand:SWI48 0 "register_operand")
5841 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5842 (match_operand:SWI48 2 "nonmemory_operand")))
5843 (clobber (reg:CC FLAGS_REG))]
5844 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5845 [(set (match_dup 0) (match_dup 1))
5846 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5847 (clobber (reg:CC FLAGS_REG))])])
5849 ;; Convert add to the lea pattern to avoid flags dependency.
5851 [(set (match_operand:SWI 0 "register_operand")
5852 (plus:SWI (match_operand:SWI 1 "register_operand")
5853 (match_operand:SWI 2 "<nonmemory_operand>")))
5854 (clobber (reg:CC FLAGS_REG))]
5855 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5858 enum machine_mode mode = <MODE>mode;
5861 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5864 operands[0] = gen_lowpart (mode, operands[0]);
5865 operands[1] = gen_lowpart (mode, operands[1]);
5866 operands[2] = gen_lowpart (mode, operands[2]);
5869 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5871 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5875 ;; Convert add to the lea pattern to avoid flags dependency.
5877 [(set (match_operand:DI 0 "register_operand")
5879 (plus:SI (match_operand:SI 1 "register_operand")
5880 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5881 (clobber (reg:CC FLAGS_REG))]
5882 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5884 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5886 (define_insn "*add<mode>_2"
5887 [(set (reg FLAGS_REG)
5890 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5891 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5893 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5894 (plus:SWI (match_dup 1) (match_dup 2)))]
5895 "ix86_match_ccmode (insn, CCGOCmode)
5896 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5898 switch (get_attr_type (insn))
5901 if (operands[2] == const1_rtx)
5902 return "inc{<imodesuffix>}\t%0";
5905 gcc_assert (operands[2] == constm1_rtx);
5906 return "dec{<imodesuffix>}\t%0";
5910 if (which_alternative == 2)
5913 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5916 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5917 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5918 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5920 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5924 (if_then_else (match_operand:SWI 2 "incdec_operand")
5925 (const_string "incdec")
5926 (const_string "alu")))
5927 (set (attr "length_immediate")
5929 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5931 (const_string "*")))
5932 (set_attr "mode" "<MODE>")])
5934 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5935 (define_insn "*addsi_2_zext"
5936 [(set (reg FLAGS_REG)
5938 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5939 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5941 (set (match_operand:DI 0 "register_operand" "=r,r")
5942 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5943 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5944 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5946 switch (get_attr_type (insn))
5949 if (operands[2] == const1_rtx)
5950 return "inc{l}\t%k0";
5953 gcc_assert (operands[2] == constm1_rtx);
5954 return "dec{l}\t%k0";
5958 if (which_alternative == 1)
5961 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5964 if (x86_maybe_negate_const_int (&operands[2], SImode))
5965 return "sub{l}\t{%2, %k0|%k0, %2}";
5967 return "add{l}\t{%2, %k0|%k0, %2}";
5971 (if_then_else (match_operand:SI 2 "incdec_operand")
5972 (const_string "incdec")
5973 (const_string "alu")))
5974 (set (attr "length_immediate")
5976 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5978 (const_string "*")))
5979 (set_attr "mode" "SI")])
5981 (define_insn "*add<mode>_3"
5982 [(set (reg FLAGS_REG)
5984 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5985 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5986 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5987 "ix86_match_ccmode (insn, CCZmode)
5988 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5990 switch (get_attr_type (insn))
5993 if (operands[2] == const1_rtx)
5994 return "inc{<imodesuffix>}\t%0";
5997 gcc_assert (operands[2] == constm1_rtx);
5998 return "dec{<imodesuffix>}\t%0";
6002 if (which_alternative == 1)
6005 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6008 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6009 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6010 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6012 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6016 (if_then_else (match_operand:SWI 2 "incdec_operand")
6017 (const_string "incdec")
6018 (const_string "alu")))
6019 (set (attr "length_immediate")
6021 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6023 (const_string "*")))
6024 (set_attr "mode" "<MODE>")])
6026 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6027 (define_insn "*addsi_3_zext"
6028 [(set (reg FLAGS_REG)
6030 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6031 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6032 (set (match_operand:DI 0 "register_operand" "=r,r")
6033 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6034 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6035 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6037 switch (get_attr_type (insn))
6040 if (operands[2] == const1_rtx)
6041 return "inc{l}\t%k0";
6044 gcc_assert (operands[2] == constm1_rtx);
6045 return "dec{l}\t%k0";
6049 if (which_alternative == 1)
6052 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6055 if (x86_maybe_negate_const_int (&operands[2], SImode))
6056 return "sub{l}\t{%2, %k0|%k0, %2}";
6058 return "add{l}\t{%2, %k0|%k0, %2}";
6062 (if_then_else (match_operand:SI 2 "incdec_operand")
6063 (const_string "incdec")
6064 (const_string "alu")))
6065 (set (attr "length_immediate")
6067 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6069 (const_string "*")))
6070 (set_attr "mode" "SI")])
6072 ; For comparisons against 1, -1 and 128, we may generate better code
6073 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6074 ; is matched then. We can't accept general immediate, because for
6075 ; case of overflows, the result is messed up.
6076 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6077 ; only for comparisons not depending on it.
6079 (define_insn "*adddi_4"
6080 [(set (reg FLAGS_REG)
6082 (match_operand:DI 1 "nonimmediate_operand" "0")
6083 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6084 (clobber (match_scratch:DI 0 "=rm"))]
6086 && ix86_match_ccmode (insn, CCGCmode)"
6088 switch (get_attr_type (insn))
6091 if (operands[2] == constm1_rtx)
6092 return "inc{q}\t%0";
6095 gcc_assert (operands[2] == const1_rtx);
6096 return "dec{q}\t%0";
6100 if (x86_maybe_negate_const_int (&operands[2], DImode))
6101 return "add{q}\t{%2, %0|%0, %2}";
6103 return "sub{q}\t{%2, %0|%0, %2}";
6107 (if_then_else (match_operand:DI 2 "incdec_operand")
6108 (const_string "incdec")
6109 (const_string "alu")))
6110 (set (attr "length_immediate")
6112 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6114 (const_string "*")))
6115 (set_attr "mode" "DI")])
6117 ; For comparisons against 1, -1 and 128, we may generate better code
6118 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6119 ; is matched then. We can't accept general immediate, because for
6120 ; case of overflows, the result is messed up.
6121 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6122 ; only for comparisons not depending on it.
6124 (define_insn "*add<mode>_4"
6125 [(set (reg FLAGS_REG)
6127 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6128 (match_operand:SWI124 2 "const_int_operand" "n")))
6129 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6130 "ix86_match_ccmode (insn, CCGCmode)"
6132 switch (get_attr_type (insn))
6135 if (operands[2] == constm1_rtx)
6136 return "inc{<imodesuffix>}\t%0";
6139 gcc_assert (operands[2] == const1_rtx);
6140 return "dec{<imodesuffix>}\t%0";
6144 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6145 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6147 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6151 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6152 (const_string "incdec")
6153 (const_string "alu")))
6154 (set (attr "length_immediate")
6156 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6158 (const_string "*")))
6159 (set_attr "mode" "<MODE>")])
6161 (define_insn "*add<mode>_5"
6162 [(set (reg FLAGS_REG)
6165 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6166 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6168 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6169 "ix86_match_ccmode (insn, CCGOCmode)
6170 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6172 switch (get_attr_type (insn))
6175 if (operands[2] == const1_rtx)
6176 return "inc{<imodesuffix>}\t%0";
6179 gcc_assert (operands[2] == constm1_rtx);
6180 return "dec{<imodesuffix>}\t%0";
6184 if (which_alternative == 1)
6187 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6190 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6191 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6192 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6194 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6198 (if_then_else (match_operand:SWI 2 "incdec_operand")
6199 (const_string "incdec")
6200 (const_string "alu")))
6201 (set (attr "length_immediate")
6203 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6205 (const_string "*")))
6206 (set_attr "mode" "<MODE>")])
6208 (define_insn "*addqi_ext_1_rex64"
6209 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6214 (match_operand 1 "ext_register_operand" "0")
6217 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6218 (clobber (reg:CC FLAGS_REG))]
6221 switch (get_attr_type (insn))
6224 if (operands[2] == const1_rtx)
6225 return "inc{b}\t%h0";
6228 gcc_assert (operands[2] == constm1_rtx);
6229 return "dec{b}\t%h0";
6233 return "add{b}\t{%2, %h0|%h0, %2}";
6237 (if_then_else (match_operand:QI 2 "incdec_operand")
6238 (const_string "incdec")
6239 (const_string "alu")))
6240 (set_attr "modrm" "1")
6241 (set_attr "mode" "QI")])
6243 (define_insn "addqi_ext_1"
6244 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6249 (match_operand 1 "ext_register_operand" "0")
6252 (match_operand:QI 2 "general_operand" "Qmn")))
6253 (clobber (reg:CC FLAGS_REG))]
6256 switch (get_attr_type (insn))
6259 if (operands[2] == const1_rtx)
6260 return "inc{b}\t%h0";
6263 gcc_assert (operands[2] == constm1_rtx);
6264 return "dec{b}\t%h0";
6268 return "add{b}\t{%2, %h0|%h0, %2}";
6272 (if_then_else (match_operand:QI 2 "incdec_operand")
6273 (const_string "incdec")
6274 (const_string "alu")))
6275 (set_attr "modrm" "1")
6276 (set_attr "mode" "QI")])
6278 (define_insn "*addqi_ext_2"
6279 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6284 (match_operand 1 "ext_register_operand" "%0")
6288 (match_operand 2 "ext_register_operand" "Q")
6291 (clobber (reg:CC FLAGS_REG))]
6293 "add{b}\t{%h2, %h0|%h0, %h2}"
6294 [(set_attr "type" "alu")
6295 (set_attr "mode" "QI")])
6297 ;; The lea patterns for modes less than 32 bits need to be matched by
6298 ;; several insns converted to real lea by splitters.
6300 (define_insn_and_split "*lea_general_1"
6301 [(set (match_operand 0 "register_operand" "=r")
6302 (plus (plus (match_operand 1 "index_register_operand" "l")
6303 (match_operand 2 "register_operand" "r"))
6304 (match_operand 3 "immediate_operand" "i")))]
6305 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6306 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6307 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6308 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6309 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6310 || GET_MODE (operands[3]) == VOIDmode)"
6312 "&& reload_completed"
6315 enum machine_mode mode = SImode;
6318 operands[0] = gen_lowpart (mode, operands[0]);
6319 operands[1] = gen_lowpart (mode, operands[1]);
6320 operands[2] = gen_lowpart (mode, operands[2]);
6321 operands[3] = gen_lowpart (mode, operands[3]);
6323 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6326 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6329 [(set_attr "type" "lea")
6330 (set_attr "mode" "SI")])
6332 (define_insn_and_split "*lea_general_2"
6333 [(set (match_operand 0 "register_operand" "=r")
6334 (plus (mult (match_operand 1 "index_register_operand" "l")
6335 (match_operand 2 "const248_operand" "n"))
6336 (match_operand 3 "nonmemory_operand" "ri")))]
6337 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6338 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6339 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6340 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6341 || GET_MODE (operands[3]) == VOIDmode)"
6343 "&& reload_completed"
6346 enum machine_mode mode = SImode;
6349 operands[0] = gen_lowpart (mode, operands[0]);
6350 operands[1] = gen_lowpart (mode, operands[1]);
6351 operands[3] = gen_lowpart (mode, operands[3]);
6353 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6356 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6359 [(set_attr "type" "lea")
6360 (set_attr "mode" "SI")])
6362 (define_insn_and_split "*lea_general_3"
6363 [(set (match_operand 0 "register_operand" "=r")
6364 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6365 (match_operand 2 "const248_operand" "n"))
6366 (match_operand 3 "register_operand" "r"))
6367 (match_operand 4 "immediate_operand" "i")))]
6368 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6369 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6370 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6371 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6373 "&& reload_completed"
6376 enum machine_mode mode = SImode;
6379 operands[0] = gen_lowpart (mode, operands[0]);
6380 operands[1] = gen_lowpart (mode, operands[1]);
6381 operands[3] = gen_lowpart (mode, operands[3]);
6382 operands[4] = gen_lowpart (mode, operands[4]);
6384 pat = gen_rtx_PLUS (mode,
6386 gen_rtx_MULT (mode, operands[1],
6391 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6394 [(set_attr "type" "lea")
6395 (set_attr "mode" "SI")])
6397 (define_insn_and_split "*lea_general_4"
6398 [(set (match_operand 0 "register_operand" "=r")
6400 (match_operand 1 "index_register_operand" "l")
6401 (match_operand 2 "const_int_operand" "n"))
6402 (match_operand 3 "const_int_operand" "n")))]
6403 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6404 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6405 || GET_MODE (operands[0]) == SImode
6406 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6407 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6408 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6409 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6410 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6412 "&& reload_completed"
6415 enum machine_mode mode = GET_MODE (operands[0]);
6418 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6421 operands[0] = gen_lowpart (mode, operands[0]);
6422 operands[1] = gen_lowpart (mode, operands[1]);
6425 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6427 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6428 INTVAL (operands[3]));
6430 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6433 [(set_attr "type" "lea")
6435 (if_then_else (match_operand:DI 0)
6437 (const_string "SI")))])
6439 ;; Subtract instructions
6441 (define_expand "sub<mode>3"
6442 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6443 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6444 (match_operand:SDWIM 2 "<general_operand>")))]
6446 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6448 (define_insn_and_split "*sub<dwi>3_doubleword"
6449 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6451 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6452 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6453 (clobber (reg:CC FLAGS_REG))]
6454 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6457 [(parallel [(set (reg:CC FLAGS_REG)
6458 (compare:CC (match_dup 1) (match_dup 2)))
6460 (minus:DWIH (match_dup 1) (match_dup 2)))])
6461 (parallel [(set (match_dup 3)
6465 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6467 (clobber (reg:CC FLAGS_REG))])]
6468 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6470 (define_insn "*sub<mode>_1"
6471 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6473 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6474 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6475 (clobber (reg:CC FLAGS_REG))]
6476 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6477 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6478 [(set_attr "type" "alu")
6479 (set_attr "mode" "<MODE>")])
6481 (define_insn "*subsi_1_zext"
6482 [(set (match_operand:DI 0 "register_operand" "=r")
6484 (minus:SI (match_operand:SI 1 "register_operand" "0")
6485 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6486 (clobber (reg:CC FLAGS_REG))]
6487 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6488 "sub{l}\t{%2, %k0|%k0, %2}"
6489 [(set_attr "type" "alu")
6490 (set_attr "mode" "SI")])
6492 (define_insn "*subqi_1_slp"
6493 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6494 (minus:QI (match_dup 0)
6495 (match_operand:QI 1 "general_operand" "qn,qm")))
6496 (clobber (reg:CC FLAGS_REG))]
6497 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6498 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6499 "sub{b}\t{%1, %0|%0, %1}"
6500 [(set_attr "type" "alu1")
6501 (set_attr "mode" "QI")])
6503 (define_insn "*sub<mode>_2"
6504 [(set (reg FLAGS_REG)
6507 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6508 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6510 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6511 (minus:SWI (match_dup 1) (match_dup 2)))]
6512 "ix86_match_ccmode (insn, CCGOCmode)
6513 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6514 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6515 [(set_attr "type" "alu")
6516 (set_attr "mode" "<MODE>")])
6518 (define_insn "*subsi_2_zext"
6519 [(set (reg FLAGS_REG)
6521 (minus:SI (match_operand:SI 1 "register_operand" "0")
6522 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6524 (set (match_operand:DI 0 "register_operand" "=r")
6526 (minus:SI (match_dup 1)
6528 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6529 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6530 "sub{l}\t{%2, %k0|%k0, %2}"
6531 [(set_attr "type" "alu")
6532 (set_attr "mode" "SI")])
6534 (define_insn "*sub<mode>_3"
6535 [(set (reg FLAGS_REG)
6536 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6537 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6538 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6539 (minus:SWI (match_dup 1) (match_dup 2)))]
6540 "ix86_match_ccmode (insn, CCmode)
6541 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6542 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6543 [(set_attr "type" "alu")
6544 (set_attr "mode" "<MODE>")])
6546 (define_insn "*subsi_3_zext"
6547 [(set (reg FLAGS_REG)
6548 (compare (match_operand:SI 1 "register_operand" "0")
6549 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6550 (set (match_operand:DI 0 "register_operand" "=r")
6552 (minus:SI (match_dup 1)
6554 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6555 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6556 "sub{l}\t{%2, %1|%1, %2}"
6557 [(set_attr "type" "alu")
6558 (set_attr "mode" "SI")])
6560 ;; Add with carry and subtract with borrow
6562 (define_expand "<plusminus_insn><mode>3_carry"
6564 [(set (match_operand:SWI 0 "nonimmediate_operand")
6566 (match_operand:SWI 1 "nonimmediate_operand")
6567 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6568 [(match_operand 3 "flags_reg_operand")
6570 (match_operand:SWI 2 "<general_operand>"))))
6571 (clobber (reg:CC FLAGS_REG))])]
6572 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6574 (define_insn "*<plusminus_insn><mode>3_carry"
6575 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6577 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6579 (match_operator 3 "ix86_carry_flag_operator"
6580 [(reg FLAGS_REG) (const_int 0)])
6581 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6582 (clobber (reg:CC FLAGS_REG))]
6583 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6584 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6585 [(set_attr "type" "alu")
6586 (set_attr "use_carry" "1")
6587 (set_attr "pent_pair" "pu")
6588 (set_attr "mode" "<MODE>")])
6590 (define_insn "*addsi3_carry_zext"
6591 [(set (match_operand:DI 0 "register_operand" "=r")
6593 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6594 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6595 [(reg FLAGS_REG) (const_int 0)])
6596 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6597 (clobber (reg:CC FLAGS_REG))]
6598 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6599 "adc{l}\t{%2, %k0|%k0, %2}"
6600 [(set_attr "type" "alu")
6601 (set_attr "use_carry" "1")
6602 (set_attr "pent_pair" "pu")
6603 (set_attr "mode" "SI")])
6605 (define_insn "*subsi3_carry_zext"
6606 [(set (match_operand:DI 0 "register_operand" "=r")
6608 (minus:SI (match_operand:SI 1 "register_operand" "0")
6609 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6610 [(reg FLAGS_REG) (const_int 0)])
6611 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6612 (clobber (reg:CC FLAGS_REG))]
6613 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6614 "sbb{l}\t{%2, %k0|%k0, %2}"
6615 [(set_attr "type" "alu")
6616 (set_attr "pent_pair" "pu")
6617 (set_attr "mode" "SI")])
6619 ;; Overflow setting add and subtract instructions
6621 (define_insn "*add<mode>3_cconly_overflow"
6622 [(set (reg:CCC FLAGS_REG)
6625 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6626 (match_operand:SWI 2 "<general_operand>" "<g>"))
6628 (clobber (match_scratch:SWI 0 "=<r>"))]
6629 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6630 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6631 [(set_attr "type" "alu")
6632 (set_attr "mode" "<MODE>")])
6634 (define_insn "*sub<mode>3_cconly_overflow"
6635 [(set (reg:CCC FLAGS_REG)
6638 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6639 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6642 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6643 [(set_attr "type" "icmp")
6644 (set_attr "mode" "<MODE>")])
6646 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6647 [(set (reg:CCC FLAGS_REG)
6650 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6651 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6653 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6654 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6655 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6656 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6657 [(set_attr "type" "alu")
6658 (set_attr "mode" "<MODE>")])
6660 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6661 [(set (reg:CCC FLAGS_REG)
6664 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6665 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6667 (set (match_operand:DI 0 "register_operand" "=r")
6668 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6669 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6670 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6671 [(set_attr "type" "alu")
6672 (set_attr "mode" "SI")])
6674 ;; The patterns that match these are at the end of this file.
6676 (define_expand "<plusminus_insn>xf3"
6677 [(set (match_operand:XF 0 "register_operand")
6679 (match_operand:XF 1 "register_operand")
6680 (match_operand:XF 2 "register_operand")))]
6683 (define_expand "<plusminus_insn><mode>3"
6684 [(set (match_operand:MODEF 0 "register_operand")
6686 (match_operand:MODEF 1 "register_operand")
6687 (match_operand:MODEF 2 "nonimmediate_operand")))]
6688 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6689 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6691 ;; Multiply instructions
6693 (define_expand "mul<mode>3"
6694 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6696 (match_operand:SWIM248 1 "register_operand")
6697 (match_operand:SWIM248 2 "<general_operand>")))
6698 (clobber (reg:CC FLAGS_REG))])])
6700 (define_expand "mulqi3"
6701 [(parallel [(set (match_operand:QI 0 "register_operand")
6703 (match_operand:QI 1 "register_operand")
6704 (match_operand:QI 2 "nonimmediate_operand")))
6705 (clobber (reg:CC FLAGS_REG))])]
6706 "TARGET_QIMODE_MATH")
6709 ;; IMUL reg32/64, reg32/64, imm8 Direct
6710 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6711 ;; IMUL reg32/64, reg32/64, imm32 Direct
6712 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6713 ;; IMUL reg32/64, reg32/64 Direct
6714 ;; IMUL reg32/64, mem32/64 Direct
6716 ;; On BDVER1, all above IMULs use DirectPath
6718 (define_insn "*mul<mode>3_1"
6719 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6721 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6722 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6723 (clobber (reg:CC FLAGS_REG))]
6724 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6726 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6727 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6728 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6729 [(set_attr "type" "imul")
6730 (set_attr "prefix_0f" "0,0,1")
6731 (set (attr "athlon_decode")
6732 (cond [(eq_attr "cpu" "athlon")
6733 (const_string "vector")
6734 (eq_attr "alternative" "1")
6735 (const_string "vector")
6736 (and (eq_attr "alternative" "2")
6737 (match_operand 1 "memory_operand"))
6738 (const_string "vector")]
6739 (const_string "direct")))
6740 (set (attr "amdfam10_decode")
6741 (cond [(and (eq_attr "alternative" "0,1")
6742 (match_operand 1 "memory_operand"))
6743 (const_string "vector")]
6744 (const_string "direct")))
6745 (set_attr "bdver1_decode" "direct")
6746 (set_attr "mode" "<MODE>")])
6748 (define_insn "*mulsi3_1_zext"
6749 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6751 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6752 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6753 (clobber (reg:CC FLAGS_REG))]
6755 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6757 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6758 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6759 imul{l}\t{%2, %k0|%k0, %2}"
6760 [(set_attr "type" "imul")
6761 (set_attr "prefix_0f" "0,0,1")
6762 (set (attr "athlon_decode")
6763 (cond [(eq_attr "cpu" "athlon")
6764 (const_string "vector")
6765 (eq_attr "alternative" "1")
6766 (const_string "vector")
6767 (and (eq_attr "alternative" "2")
6768 (match_operand 1 "memory_operand"))
6769 (const_string "vector")]
6770 (const_string "direct")))
6771 (set (attr "amdfam10_decode")
6772 (cond [(and (eq_attr "alternative" "0,1")
6773 (match_operand 1 "memory_operand"))
6774 (const_string "vector")]
6775 (const_string "direct")))
6776 (set_attr "bdver1_decode" "direct")
6777 (set_attr "mode" "SI")])
6780 ;; IMUL reg16, reg16, imm8 VectorPath
6781 ;; IMUL reg16, mem16, imm8 VectorPath
6782 ;; IMUL reg16, reg16, imm16 VectorPath
6783 ;; IMUL reg16, mem16, imm16 VectorPath
6784 ;; IMUL reg16, reg16 Direct
6785 ;; IMUL reg16, mem16 Direct
6787 ;; On BDVER1, all HI MULs use DoublePath
6789 (define_insn "*mulhi3_1"
6790 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6791 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6792 (match_operand:HI 2 "general_operand" "K,n,mr")))
6793 (clobber (reg:CC FLAGS_REG))]
6795 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6797 imul{w}\t{%2, %1, %0|%0, %1, %2}
6798 imul{w}\t{%2, %1, %0|%0, %1, %2}
6799 imul{w}\t{%2, %0|%0, %2}"
6800 [(set_attr "type" "imul")
6801 (set_attr "prefix_0f" "0,0,1")
6802 (set (attr "athlon_decode")
6803 (cond [(eq_attr "cpu" "athlon")
6804 (const_string "vector")
6805 (eq_attr "alternative" "1,2")
6806 (const_string "vector")]
6807 (const_string "direct")))
6808 (set (attr "amdfam10_decode")
6809 (cond [(eq_attr "alternative" "0,1")
6810 (const_string "vector")]
6811 (const_string "direct")))
6812 (set_attr "bdver1_decode" "double")
6813 (set_attr "mode" "HI")])
6815 ;;On AMDFAM10 and BDVER1
6819 (define_insn "*mulqi3_1"
6820 [(set (match_operand:QI 0 "register_operand" "=a")
6821 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6822 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6823 (clobber (reg:CC FLAGS_REG))]
6825 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6827 [(set_attr "type" "imul")
6828 (set_attr "length_immediate" "0")
6829 (set (attr "athlon_decode")
6830 (if_then_else (eq_attr "cpu" "athlon")
6831 (const_string "vector")
6832 (const_string "direct")))
6833 (set_attr "amdfam10_decode" "direct")
6834 (set_attr "bdver1_decode" "direct")
6835 (set_attr "mode" "QI")])
6837 (define_expand "<u>mul<mode><dwi>3"
6838 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6841 (match_operand:DWIH 1 "nonimmediate_operand"))
6843 (match_operand:DWIH 2 "register_operand"))))
6844 (clobber (reg:CC FLAGS_REG))])])
6846 (define_expand "<u>mulqihi3"
6847 [(parallel [(set (match_operand:HI 0 "register_operand")
6850 (match_operand:QI 1 "nonimmediate_operand"))
6852 (match_operand:QI 2 "register_operand"))))
6853 (clobber (reg:CC FLAGS_REG))])]
6854 "TARGET_QIMODE_MATH")
6856 (define_insn "*bmi2_umulditi3_1"
6857 [(set (match_operand:DI 0 "register_operand" "=r")
6859 (match_operand:DI 2 "nonimmediate_operand" "%d")
6860 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6861 (set (match_operand:DI 1 "register_operand" "=r")
6864 (mult:TI (zero_extend:TI (match_dup 2))
6865 (zero_extend:TI (match_dup 3)))
6867 "TARGET_64BIT && TARGET_BMI2
6868 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6869 "mulx\t{%3, %0, %1|%1, %0, %3}"
6870 [(set_attr "type" "imulx")
6871 (set_attr "prefix" "vex")
6872 (set_attr "mode" "DI")])
6874 (define_insn "*bmi2_umulsidi3_1"
6875 [(set (match_operand:SI 0 "register_operand" "=r")
6877 (match_operand:SI 2 "nonimmediate_operand" "%d")
6878 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6879 (set (match_operand:SI 1 "register_operand" "=r")
6882 (mult:DI (zero_extend:DI (match_dup 2))
6883 (zero_extend:DI (match_dup 3)))
6885 "!TARGET_64BIT && TARGET_BMI2
6886 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6887 "mulx\t{%3, %0, %1|%1, %0, %3}"
6888 [(set_attr "type" "imulx")
6889 (set_attr "prefix" "vex")
6890 (set_attr "mode" "SI")])
6892 (define_insn "*umul<mode><dwi>3_1"
6893 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6896 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6898 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6899 (clobber (reg:CC FLAGS_REG))]
6900 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6903 mul{<imodesuffix>}\t%2"
6904 [(set_attr "isa" "bmi2,*")
6905 (set_attr "type" "imulx,imul")
6906 (set_attr "length_immediate" "*,0")
6907 (set (attr "athlon_decode")
6908 (cond [(eq_attr "alternative" "1")
6909 (if_then_else (eq_attr "cpu" "athlon")
6910 (const_string "vector")
6911 (const_string "double"))]
6912 (const_string "*")))
6913 (set_attr "amdfam10_decode" "*,double")
6914 (set_attr "bdver1_decode" "*,direct")
6915 (set_attr "prefix" "vex,orig")
6916 (set_attr "mode" "<MODE>")])
6918 ;; Convert mul to the mulx pattern to avoid flags dependency.
6920 [(set (match_operand:<DWI> 0 "register_operand")
6923 (match_operand:DWIH 1 "register_operand"))
6925 (match_operand:DWIH 2 "nonimmediate_operand"))))
6926 (clobber (reg:CC FLAGS_REG))]
6927 "TARGET_BMI2 && reload_completed
6928 && true_regnum (operands[1]) == DX_REG"
6929 [(parallel [(set (match_dup 3)
6930 (mult:DWIH (match_dup 1) (match_dup 2)))
6934 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6935 (zero_extend:<DWI> (match_dup 2)))
6938 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6940 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6943 (define_insn "*mul<mode><dwi>3_1"
6944 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6947 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6949 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6950 (clobber (reg:CC FLAGS_REG))]
6951 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6952 "imul{<imodesuffix>}\t%2"
6953 [(set_attr "type" "imul")
6954 (set_attr "length_immediate" "0")
6955 (set (attr "athlon_decode")
6956 (if_then_else (eq_attr "cpu" "athlon")
6957 (const_string "vector")
6958 (const_string "double")))
6959 (set_attr "amdfam10_decode" "double")
6960 (set_attr "bdver1_decode" "direct")
6961 (set_attr "mode" "<MODE>")])
6963 (define_insn "*<u>mulqihi3_1"
6964 [(set (match_operand:HI 0 "register_operand" "=a")
6967 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6969 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6970 (clobber (reg:CC FLAGS_REG))]
6972 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6973 "<sgnprefix>mul{b}\t%2"
6974 [(set_attr "type" "imul")
6975 (set_attr "length_immediate" "0")
6976 (set (attr "athlon_decode")
6977 (if_then_else (eq_attr "cpu" "athlon")
6978 (const_string "vector")
6979 (const_string "direct")))
6980 (set_attr "amdfam10_decode" "direct")
6981 (set_attr "bdver1_decode" "direct")
6982 (set_attr "mode" "QI")])
6984 (define_expand "<s>mul<mode>3_highpart"
6985 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6990 (match_operand:SWI48 1 "nonimmediate_operand"))
6992 (match_operand:SWI48 2 "register_operand")))
6994 (clobber (match_scratch:SWI48 3))
6995 (clobber (reg:CC FLAGS_REG))])]
6997 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6999 (define_insn "*<s>muldi3_highpart_1"
7000 [(set (match_operand:DI 0 "register_operand" "=d")
7005 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7007 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7009 (clobber (match_scratch:DI 3 "=1"))
7010 (clobber (reg:CC FLAGS_REG))]
7012 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7013 "<sgnprefix>mul{q}\t%2"
7014 [(set_attr "type" "imul")
7015 (set_attr "length_immediate" "0")
7016 (set (attr "athlon_decode")
7017 (if_then_else (eq_attr "cpu" "athlon")
7018 (const_string "vector")
7019 (const_string "double")))
7020 (set_attr "amdfam10_decode" "double")
7021 (set_attr "bdver1_decode" "direct")
7022 (set_attr "mode" "DI")])
7024 (define_insn "*<s>mulsi3_highpart_1"
7025 [(set (match_operand:SI 0 "register_operand" "=d")
7030 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7032 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7034 (clobber (match_scratch:SI 3 "=1"))
7035 (clobber (reg:CC FLAGS_REG))]
7036 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7037 "<sgnprefix>mul{l}\t%2"
7038 [(set_attr "type" "imul")
7039 (set_attr "length_immediate" "0")
7040 (set (attr "athlon_decode")
7041 (if_then_else (eq_attr "cpu" "athlon")
7042 (const_string "vector")
7043 (const_string "double")))
7044 (set_attr "amdfam10_decode" "double")
7045 (set_attr "bdver1_decode" "direct")
7046 (set_attr "mode" "SI")])
7048 (define_insn "*<s>mulsi3_highpart_zext"
7049 [(set (match_operand:DI 0 "register_operand" "=d")
7050 (zero_extend:DI (truncate:SI
7052 (mult:DI (any_extend:DI
7053 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7055 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7057 (clobber (match_scratch:SI 3 "=1"))
7058 (clobber (reg:CC FLAGS_REG))]
7060 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7061 "<sgnprefix>mul{l}\t%2"
7062 [(set_attr "type" "imul")
7063 (set_attr "length_immediate" "0")
7064 (set (attr "athlon_decode")
7065 (if_then_else (eq_attr "cpu" "athlon")
7066 (const_string "vector")
7067 (const_string "double")))
7068 (set_attr "amdfam10_decode" "double")
7069 (set_attr "bdver1_decode" "direct")
7070 (set_attr "mode" "SI")])
7072 ;; The patterns that match these are at the end of this file.
7074 (define_expand "mulxf3"
7075 [(set (match_operand:XF 0 "register_operand")
7076 (mult:XF (match_operand:XF 1 "register_operand")
7077 (match_operand:XF 2 "register_operand")))]
7080 (define_expand "mul<mode>3"
7081 [(set (match_operand:MODEF 0 "register_operand")
7082 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7083 (match_operand:MODEF 2 "nonimmediate_operand")))]
7084 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7085 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7087 ;; Divide instructions
7089 ;; The patterns that match these are at the end of this file.
7091 (define_expand "divxf3"
7092 [(set (match_operand:XF 0 "register_operand")
7093 (div:XF (match_operand:XF 1 "register_operand")
7094 (match_operand:XF 2 "register_operand")))]
7097 (define_expand "divdf3"
7098 [(set (match_operand:DF 0 "register_operand")
7099 (div:DF (match_operand:DF 1 "register_operand")
7100 (match_operand:DF 2 "nonimmediate_operand")))]
7101 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7102 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7104 (define_expand "divsf3"
7105 [(set (match_operand:SF 0 "register_operand")
7106 (div:SF (match_operand:SF 1 "register_operand")
7107 (match_operand:SF 2 "nonimmediate_operand")))]
7108 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7113 && optimize_insn_for_speed_p ()
7114 && flag_finite_math_only && !flag_trapping_math
7115 && flag_unsafe_math_optimizations)
7117 ix86_emit_swdivsf (operands[0], operands[1],
7118 operands[2], SFmode);
7123 ;; Divmod instructions.
7125 (define_expand "divmod<mode>4"
7126 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7128 (match_operand:SWIM248 1 "register_operand")
7129 (match_operand:SWIM248 2 "nonimmediate_operand")))
7130 (set (match_operand:SWIM248 3 "register_operand")
7131 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7132 (clobber (reg:CC FLAGS_REG))])])
7134 ;; Split with 8bit unsigned divide:
7135 ;; if (dividend an divisor are in [0-255])
7136 ;; use 8bit unsigned integer divide
7138 ;; use original integer divide
7140 [(set (match_operand:SWI48 0 "register_operand")
7141 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7142 (match_operand:SWI48 3 "nonimmediate_operand")))
7143 (set (match_operand:SWI48 1 "register_operand")
7144 (mod:SWI48 (match_dup 2) (match_dup 3)))
7145 (clobber (reg:CC FLAGS_REG))]
7146 "TARGET_USE_8BIT_IDIV
7147 && TARGET_QIMODE_MATH
7148 && can_create_pseudo_p ()
7149 && !optimize_insn_for_size_p ()"
7151 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7153 (define_insn_and_split "divmod<mode>4_1"
7154 [(set (match_operand:SWI48 0 "register_operand" "=a")
7155 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7156 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7157 (set (match_operand:SWI48 1 "register_operand" "=&d")
7158 (mod:SWI48 (match_dup 2) (match_dup 3)))
7159 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7160 (clobber (reg:CC FLAGS_REG))]
7164 [(parallel [(set (match_dup 1)
7165 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7166 (clobber (reg:CC FLAGS_REG))])
7167 (parallel [(set (match_dup 0)
7168 (div:SWI48 (match_dup 2) (match_dup 3)))
7170 (mod:SWI48 (match_dup 2) (match_dup 3)))
7172 (clobber (reg:CC FLAGS_REG))])]
7174 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7176 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7177 operands[4] = operands[2];
7180 /* Avoid use of cltd in favor of a mov+shift. */
7181 emit_move_insn (operands[1], operands[2]);
7182 operands[4] = operands[1];
7185 [(set_attr "type" "multi")
7186 (set_attr "mode" "<MODE>")])
7188 (define_insn_and_split "*divmod<mode>4"
7189 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7190 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7191 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7192 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7193 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7194 (clobber (reg:CC FLAGS_REG))]
7198 [(parallel [(set (match_dup 1)
7199 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7200 (clobber (reg:CC FLAGS_REG))])
7201 (parallel [(set (match_dup 0)
7202 (div:SWIM248 (match_dup 2) (match_dup 3)))
7204 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7206 (clobber (reg:CC FLAGS_REG))])]
7208 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7210 if (<MODE>mode != HImode
7211 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7212 operands[4] = operands[2];
7215 /* Avoid use of cltd in favor of a mov+shift. */
7216 emit_move_insn (operands[1], operands[2]);
7217 operands[4] = operands[1];
7220 [(set_attr "type" "multi")
7221 (set_attr "mode" "<MODE>")])
7223 (define_insn "*divmod<mode>4_noext"
7224 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7225 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7226 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7227 (set (match_operand:SWIM248 1 "register_operand" "=d")
7228 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7229 (use (match_operand:SWIM248 4 "register_operand" "1"))
7230 (clobber (reg:CC FLAGS_REG))]
7232 "idiv{<imodesuffix>}\t%3"
7233 [(set_attr "type" "idiv")
7234 (set_attr "mode" "<MODE>")])
7236 (define_expand "divmodqi4"
7237 [(parallel [(set (match_operand:QI 0 "register_operand")
7239 (match_operand:QI 1 "register_operand")
7240 (match_operand:QI 2 "nonimmediate_operand")))
7241 (set (match_operand:QI 3 "register_operand")
7242 (mod:QI (match_dup 1) (match_dup 2)))
7243 (clobber (reg:CC FLAGS_REG))])]
7244 "TARGET_QIMODE_MATH"
7249 tmp0 = gen_reg_rtx (HImode);
7250 tmp1 = gen_reg_rtx (HImode);
7252 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7254 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7255 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7257 /* Extract remainder from AH. */
7258 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7259 insn = emit_move_insn (operands[3], tmp1);
7261 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7262 set_unique_reg_note (insn, REG_EQUAL, mod);
7264 /* Extract quotient from AL. */
7265 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7267 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7268 set_unique_reg_note (insn, REG_EQUAL, div);
7273 ;; Divide AX by r/m8, with result stored in
7276 ;; Change div/mod to HImode and extend the second argument to HImode
7277 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7278 ;; combine may fail.
7279 (define_insn "divmodhiqi3"
7280 [(set (match_operand:HI 0 "register_operand" "=a")
7285 (mod:HI (match_operand:HI 1 "register_operand" "0")
7287 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7291 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7292 (clobber (reg:CC FLAGS_REG))]
7293 "TARGET_QIMODE_MATH"
7295 [(set_attr "type" "idiv")
7296 (set_attr "mode" "QI")])
7298 (define_expand "udivmod<mode>4"
7299 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7301 (match_operand:SWIM248 1 "register_operand")
7302 (match_operand:SWIM248 2 "nonimmediate_operand")))
7303 (set (match_operand:SWIM248 3 "register_operand")
7304 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7305 (clobber (reg:CC FLAGS_REG))])])
7307 ;; Split with 8bit unsigned divide:
7308 ;; if (dividend an divisor are in [0-255])
7309 ;; use 8bit unsigned integer divide
7311 ;; use original integer divide
7313 [(set (match_operand:SWI48 0 "register_operand")
7314 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7315 (match_operand:SWI48 3 "nonimmediate_operand")))
7316 (set (match_operand:SWI48 1 "register_operand")
7317 (umod:SWI48 (match_dup 2) (match_dup 3)))
7318 (clobber (reg:CC FLAGS_REG))]
7319 "TARGET_USE_8BIT_IDIV
7320 && TARGET_QIMODE_MATH
7321 && can_create_pseudo_p ()
7322 && !optimize_insn_for_size_p ()"
7324 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7326 (define_insn_and_split "udivmod<mode>4_1"
7327 [(set (match_operand:SWI48 0 "register_operand" "=a")
7328 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7329 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7330 (set (match_operand:SWI48 1 "register_operand" "=&d")
7331 (umod:SWI48 (match_dup 2) (match_dup 3)))
7332 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7333 (clobber (reg:CC FLAGS_REG))]
7337 [(set (match_dup 1) (const_int 0))
7338 (parallel [(set (match_dup 0)
7339 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7341 (umod:SWI48 (match_dup 2) (match_dup 3)))
7343 (clobber (reg:CC FLAGS_REG))])]
7345 [(set_attr "type" "multi")
7346 (set_attr "mode" "<MODE>")])
7348 (define_insn_and_split "*udivmod<mode>4"
7349 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7350 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7351 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7352 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7353 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7354 (clobber (reg:CC FLAGS_REG))]
7358 [(set (match_dup 1) (const_int 0))
7359 (parallel [(set (match_dup 0)
7360 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7362 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7364 (clobber (reg:CC FLAGS_REG))])]
7366 [(set_attr "type" "multi")
7367 (set_attr "mode" "<MODE>")])
7369 (define_insn "*udivmod<mode>4_noext"
7370 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7371 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7372 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7373 (set (match_operand:SWIM248 1 "register_operand" "=d")
7374 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7375 (use (match_operand:SWIM248 4 "register_operand" "1"))
7376 (clobber (reg:CC FLAGS_REG))]
7378 "div{<imodesuffix>}\t%3"
7379 [(set_attr "type" "idiv")
7380 (set_attr "mode" "<MODE>")])
7382 (define_expand "udivmodqi4"
7383 [(parallel [(set (match_operand:QI 0 "register_operand")
7385 (match_operand:QI 1 "register_operand")
7386 (match_operand:QI 2 "nonimmediate_operand")))
7387 (set (match_operand:QI 3 "register_operand")
7388 (umod:QI (match_dup 1) (match_dup 2)))
7389 (clobber (reg:CC FLAGS_REG))])]
7390 "TARGET_QIMODE_MATH"
7395 tmp0 = gen_reg_rtx (HImode);
7396 tmp1 = gen_reg_rtx (HImode);
7398 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7400 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7401 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7403 /* Extract remainder from AH. */
7404 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7405 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7406 insn = emit_move_insn (operands[3], tmp1);
7408 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7409 set_unique_reg_note (insn, REG_EQUAL, mod);
7411 /* Extract quotient from AL. */
7412 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7414 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7415 set_unique_reg_note (insn, REG_EQUAL, div);
7420 (define_insn "udivmodhiqi3"
7421 [(set (match_operand:HI 0 "register_operand" "=a")
7426 (mod:HI (match_operand:HI 1 "register_operand" "0")
7428 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7432 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7433 (clobber (reg:CC FLAGS_REG))]
7434 "TARGET_QIMODE_MATH"
7436 [(set_attr "type" "idiv")
7437 (set_attr "mode" "QI")])
7439 ;; We cannot use div/idiv for double division, because it causes
7440 ;; "division by zero" on the overflow and that's not what we expect
7441 ;; from truncate. Because true (non truncating) double division is
7442 ;; never generated, we can't create this insn anyway.
7445 ; [(set (match_operand:SI 0 "register_operand" "=a")
7447 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7449 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7450 ; (set (match_operand:SI 3 "register_operand" "=d")
7452 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7453 ; (clobber (reg:CC FLAGS_REG))]
7455 ; "div{l}\t{%2, %0|%0, %2}"
7456 ; [(set_attr "type" "idiv")])
7458 ;;- Logical AND instructions
7460 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7461 ;; Note that this excludes ah.
7463 (define_expand "testsi_ccno_1"
7464 [(set (reg:CCNO FLAGS_REG)
7466 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7467 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7470 (define_expand "testqi_ccz_1"
7471 [(set (reg:CCZ FLAGS_REG)
7472 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7473 (match_operand:QI 1 "nonmemory_operand"))
7476 (define_expand "testdi_ccno_1"
7477 [(set (reg:CCNO FLAGS_REG)
7479 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7480 (match_operand:DI 1 "x86_64_szext_general_operand"))
7482 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7484 (define_insn "*testdi_1"
7485 [(set (reg FLAGS_REG)
7488 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7489 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7491 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7492 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7494 test{l}\t{%k1, %k0|%k0, %k1}
7495 test{l}\t{%k1, %k0|%k0, %k1}
7496 test{q}\t{%1, %0|%0, %1}
7497 test{q}\t{%1, %0|%0, %1}
7498 test{q}\t{%1, %0|%0, %1}"
7499 [(set_attr "type" "test")
7500 (set_attr "modrm" "0,1,0,1,1")
7501 (set_attr "mode" "SI,SI,DI,DI,DI")])
7503 (define_insn "*testqi_1_maybe_si"
7504 [(set (reg FLAGS_REG)
7507 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7508 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7510 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7511 && ix86_match_ccmode (insn,
7512 CONST_INT_P (operands[1])
7513 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7515 if (which_alternative == 3)
7517 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7518 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7519 return "test{l}\t{%1, %k0|%k0, %1}";
7521 return "test{b}\t{%1, %0|%0, %1}";
7523 [(set_attr "type" "test")
7524 (set_attr "modrm" "0,1,1,1")
7525 (set_attr "mode" "QI,QI,QI,SI")
7526 (set_attr "pent_pair" "uv,np,uv,np")])
7528 (define_insn "*test<mode>_1"
7529 [(set (reg FLAGS_REG)
7532 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7533 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7535 "ix86_match_ccmode (insn, CCNOmode)
7536 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7537 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7538 [(set_attr "type" "test")
7539 (set_attr "modrm" "0,1,1")
7540 (set_attr "mode" "<MODE>")
7541 (set_attr "pent_pair" "uv,np,uv")])
7543 (define_expand "testqi_ext_ccno_0"
7544 [(set (reg:CCNO FLAGS_REG)
7548 (match_operand 0 "ext_register_operand")
7551 (match_operand 1 "const_int_operand"))
7554 (define_insn "*testqi_ext_0"
7555 [(set (reg FLAGS_REG)
7559 (match_operand 0 "ext_register_operand" "Q")
7562 (match_operand 1 "const_int_operand" "n"))
7564 "ix86_match_ccmode (insn, CCNOmode)"
7565 "test{b}\t{%1, %h0|%h0, %1}"
7566 [(set_attr "type" "test")
7567 (set_attr "mode" "QI")
7568 (set_attr "length_immediate" "1")
7569 (set_attr "modrm" "1")
7570 (set_attr "pent_pair" "np")])
7572 (define_insn "*testqi_ext_1_rex64"
7573 [(set (reg FLAGS_REG)
7577 (match_operand 0 "ext_register_operand" "Q")
7581 (match_operand:QI 1 "register_operand" "Q")))
7583 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7584 "test{b}\t{%1, %h0|%h0, %1}"
7585 [(set_attr "type" "test")
7586 (set_attr "mode" "QI")])
7588 (define_insn "*testqi_ext_1"
7589 [(set (reg FLAGS_REG)
7593 (match_operand 0 "ext_register_operand" "Q")
7597 (match_operand:QI 1 "general_operand" "Qm")))
7599 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7600 "test{b}\t{%1, %h0|%h0, %1}"
7601 [(set_attr "type" "test")
7602 (set_attr "mode" "QI")])
7604 (define_insn "*testqi_ext_2"
7605 [(set (reg FLAGS_REG)
7609 (match_operand 0 "ext_register_operand" "Q")
7613 (match_operand 1 "ext_register_operand" "Q")
7617 "ix86_match_ccmode (insn, CCNOmode)"
7618 "test{b}\t{%h1, %h0|%h0, %h1}"
7619 [(set_attr "type" "test")
7620 (set_attr "mode" "QI")])
7622 (define_insn "*testqi_ext_3_rex64"
7623 [(set (reg FLAGS_REG)
7624 (compare (zero_extract:DI
7625 (match_operand 0 "nonimmediate_operand" "rm")
7626 (match_operand:DI 1 "const_int_operand")
7627 (match_operand:DI 2 "const_int_operand"))
7630 && ix86_match_ccmode (insn, CCNOmode)
7631 && INTVAL (operands[1]) > 0
7632 && INTVAL (operands[2]) >= 0
7633 /* Ensure that resulting mask is zero or sign extended operand. */
7634 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7635 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7636 && INTVAL (operands[1]) > 32))
7637 && (GET_MODE (operands[0]) == SImode
7638 || GET_MODE (operands[0]) == DImode
7639 || GET_MODE (operands[0]) == HImode
7640 || GET_MODE (operands[0]) == QImode)"
7643 ;; Combine likes to form bit extractions for some tests. Humor it.
7644 (define_insn "*testqi_ext_3"
7645 [(set (reg FLAGS_REG)
7646 (compare (zero_extract:SI
7647 (match_operand 0 "nonimmediate_operand" "rm")
7648 (match_operand:SI 1 "const_int_operand")
7649 (match_operand:SI 2 "const_int_operand"))
7651 "ix86_match_ccmode (insn, CCNOmode)
7652 && INTVAL (operands[1]) > 0
7653 && INTVAL (operands[2]) >= 0
7654 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7655 && (GET_MODE (operands[0]) == SImode
7656 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7657 || GET_MODE (operands[0]) == HImode
7658 || GET_MODE (operands[0]) == QImode)"
7662 [(set (match_operand 0 "flags_reg_operand")
7663 (match_operator 1 "compare_operator"
7665 (match_operand 2 "nonimmediate_operand")
7666 (match_operand 3 "const_int_operand")
7667 (match_operand 4 "const_int_operand"))
7669 "ix86_match_ccmode (insn, CCNOmode)"
7670 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7672 rtx val = operands[2];
7673 HOST_WIDE_INT len = INTVAL (operands[3]);
7674 HOST_WIDE_INT pos = INTVAL (operands[4]);
7676 enum machine_mode mode, submode;
7678 mode = GET_MODE (val);
7681 /* ??? Combine likes to put non-volatile mem extractions in QImode
7682 no matter the size of the test. So find a mode that works. */
7683 if (! MEM_VOLATILE_P (val))
7685 mode = smallest_mode_for_size (pos + len, MODE_INT);
7686 val = adjust_address (val, mode, 0);
7689 else if (GET_CODE (val) == SUBREG
7690 && (submode = GET_MODE (SUBREG_REG (val)),
7691 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7692 && pos + len <= GET_MODE_BITSIZE (submode)
7693 && GET_MODE_CLASS (submode) == MODE_INT)
7695 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7697 val = SUBREG_REG (val);
7699 else if (mode == HImode && pos + len <= 8)
7701 /* Small HImode tests can be converted to QImode. */
7703 val = gen_lowpart (QImode, val);
7706 if (len == HOST_BITS_PER_WIDE_INT)
7709 mask = ((HOST_WIDE_INT)1 << len) - 1;
7712 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7715 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7716 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7717 ;; this is relatively important trick.
7718 ;; Do the conversion only post-reload to avoid limiting of the register class
7721 [(set (match_operand 0 "flags_reg_operand")
7722 (match_operator 1 "compare_operator"
7723 [(and (match_operand 2 "register_operand")
7724 (match_operand 3 "const_int_operand"))
7727 && QI_REG_P (operands[2])
7728 && GET_MODE (operands[2]) != QImode
7729 && ((ix86_match_ccmode (insn, CCZmode)
7730 && !(INTVAL (operands[3]) & ~(255 << 8)))
7731 || (ix86_match_ccmode (insn, CCNOmode)
7732 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7735 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7739 operands[2] = gen_lowpart (SImode, operands[2]);
7740 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7744 [(set (match_operand 0 "flags_reg_operand")
7745 (match_operator 1 "compare_operator"
7746 [(and (match_operand 2 "nonimmediate_operand")
7747 (match_operand 3 "const_int_operand"))
7750 && GET_MODE (operands[2]) != QImode
7751 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7752 && ((ix86_match_ccmode (insn, CCZmode)
7753 && !(INTVAL (operands[3]) & ~255))
7754 || (ix86_match_ccmode (insn, CCNOmode)
7755 && !(INTVAL (operands[3]) & ~127)))"
7757 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7760 operands[2] = gen_lowpart (QImode, operands[2]);
7761 operands[3] = gen_lowpart (QImode, operands[3]);
7764 ;; %%% This used to optimize known byte-wide and operations to memory,
7765 ;; and sometimes to QImode registers. If this is considered useful,
7766 ;; it should be done with splitters.
7768 (define_expand "and<mode>3"
7769 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7770 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7771 (match_operand:SWIM 2 "<general_szext_operand>")))]
7774 enum machine_mode mode = <MODE>mode;
7775 rtx (*insn) (rtx, rtx);
7777 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7779 HOST_WIDE_INT ival = INTVAL (operands[2]);
7781 if (ival == (HOST_WIDE_INT) 0xffffffff)
7783 else if (ival == 0xffff)
7785 else if (ival == 0xff)
7789 if (mode == <MODE>mode)
7791 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7795 if (<MODE>mode == DImode)
7796 insn = (mode == SImode)
7797 ? gen_zero_extendsidi2
7799 ? gen_zero_extendhidi2
7800 : gen_zero_extendqidi2;
7801 else if (<MODE>mode == SImode)
7802 insn = (mode == HImode)
7803 ? gen_zero_extendhisi2
7804 : gen_zero_extendqisi2;
7805 else if (<MODE>mode == HImode)
7806 insn = gen_zero_extendqihi2;
7810 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7814 (define_insn "*anddi_1"
7815 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7817 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7818 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7819 (clobber (reg:CC FLAGS_REG))]
7820 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7822 switch (get_attr_type (insn))
7828 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7829 if (get_attr_mode (insn) == MODE_SI)
7830 return "and{l}\t{%k2, %k0|%k0, %k2}";
7832 return "and{q}\t{%2, %0|%0, %2}";
7835 [(set_attr "type" "alu,alu,alu,imovx")
7836 (set_attr "length_immediate" "*,*,*,0")
7837 (set (attr "prefix_rex")
7839 (and (eq_attr "type" "imovx")
7840 (and (match_test "INTVAL (operands[2]) == 0xff")
7841 (match_operand 1 "ext_QIreg_operand")))
7843 (const_string "*")))
7844 (set_attr "mode" "SI,DI,DI,SI")])
7846 (define_insn "*andsi_1"
7847 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7848 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7849 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7850 (clobber (reg:CC FLAGS_REG))]
7851 "ix86_binary_operator_ok (AND, SImode, operands)"
7853 switch (get_attr_type (insn))
7859 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7860 return "and{l}\t{%2, %0|%0, %2}";
7863 [(set_attr "type" "alu,alu,imovx")
7864 (set (attr "prefix_rex")
7866 (and (eq_attr "type" "imovx")
7867 (and (match_test "INTVAL (operands[2]) == 0xff")
7868 (match_operand 1 "ext_QIreg_operand")))
7870 (const_string "*")))
7871 (set_attr "length_immediate" "*,*,0")
7872 (set_attr "mode" "SI")])
7874 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7875 (define_insn "*andsi_1_zext"
7876 [(set (match_operand:DI 0 "register_operand" "=r")
7878 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7879 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7880 (clobber (reg:CC FLAGS_REG))]
7881 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7882 "and{l}\t{%2, %k0|%k0, %2}"
7883 [(set_attr "type" "alu")
7884 (set_attr "mode" "SI")])
7886 (define_insn "*andhi_1"
7887 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7888 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7889 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7890 (clobber (reg:CC FLAGS_REG))]
7891 "ix86_binary_operator_ok (AND, HImode, operands)"
7893 switch (get_attr_type (insn))
7899 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7900 return "and{w}\t{%2, %0|%0, %2}";
7903 [(set_attr "type" "alu,alu,imovx")
7904 (set_attr "length_immediate" "*,*,0")
7905 (set (attr "prefix_rex")
7907 (and (eq_attr "type" "imovx")
7908 (match_operand 1 "ext_QIreg_operand"))
7910 (const_string "*")))
7911 (set_attr "mode" "HI,HI,SI")])
7913 ;; %%% Potential partial reg stall on alternative 2. What to do?
7914 (define_insn "*andqi_1"
7915 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7916 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7917 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7918 (clobber (reg:CC FLAGS_REG))]
7919 "ix86_binary_operator_ok (AND, QImode, operands)"
7921 and{b}\t{%2, %0|%0, %2}
7922 and{b}\t{%2, %0|%0, %2}
7923 and{l}\t{%k2, %k0|%k0, %k2}"
7924 [(set_attr "type" "alu")
7925 (set_attr "mode" "QI,QI,SI")])
7927 (define_insn "*andqi_1_slp"
7928 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7929 (and:QI (match_dup 0)
7930 (match_operand:QI 1 "general_operand" "qn,qmn")))
7931 (clobber (reg:CC FLAGS_REG))]
7932 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7933 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7934 "and{b}\t{%1, %0|%0, %1}"
7935 [(set_attr "type" "alu1")
7936 (set_attr "mode" "QI")])
7938 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7940 [(set (match_operand:DI 0 "register_operand")
7941 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7942 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7943 (clobber (reg:CC FLAGS_REG))]
7945 [(parallel [(set (match_dup 0)
7946 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7947 (clobber (reg:CC FLAGS_REG))])]
7948 "operands[2] = gen_lowpart (SImode, operands[2]);")
7951 [(set (match_operand:SWI248 0 "register_operand")
7952 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7953 (match_operand:SWI248 2 "const_int_operand")))
7954 (clobber (reg:CC FLAGS_REG))]
7956 && true_regnum (operands[0]) != true_regnum (operands[1])"
7959 HOST_WIDE_INT ival = INTVAL (operands[2]);
7960 enum machine_mode mode;
7961 rtx (*insn) (rtx, rtx);
7963 if (ival == (HOST_WIDE_INT) 0xffffffff)
7965 else if (ival == 0xffff)
7969 gcc_assert (ival == 0xff);
7973 if (<MODE>mode == DImode)
7974 insn = (mode == SImode)
7975 ? gen_zero_extendsidi2
7977 ? gen_zero_extendhidi2
7978 : gen_zero_extendqidi2;
7981 if (<MODE>mode != SImode)
7982 /* Zero extend to SImode to avoid partial register stalls. */
7983 operands[0] = gen_lowpart (SImode, operands[0]);
7985 insn = (mode == HImode)
7986 ? gen_zero_extendhisi2
7987 : gen_zero_extendqisi2;
7989 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7994 [(set (match_operand 0 "register_operand")
7996 (const_int -65536)))
7997 (clobber (reg:CC FLAGS_REG))]
7998 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7999 || optimize_function_for_size_p (cfun)"
8000 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8001 "operands[1] = gen_lowpart (HImode, operands[0]);")
8004 [(set (match_operand 0 "ext_register_operand")
8007 (clobber (reg:CC FLAGS_REG))]
8008 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8009 && reload_completed"
8010 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8011 "operands[1] = gen_lowpart (QImode, operands[0]);")
8014 [(set (match_operand 0 "ext_register_operand")
8016 (const_int -65281)))
8017 (clobber (reg:CC FLAGS_REG))]
8018 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8019 && reload_completed"
8020 [(parallel [(set (zero_extract:SI (match_dup 0)
8024 (zero_extract:SI (match_dup 0)
8027 (zero_extract:SI (match_dup 0)
8030 (clobber (reg:CC FLAGS_REG))])]
8031 "operands[0] = gen_lowpart (SImode, operands[0]);")
8033 (define_insn "*anddi_2"
8034 [(set (reg FLAGS_REG)
8037 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8038 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8040 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8041 (and:DI (match_dup 1) (match_dup 2)))]
8042 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8043 && ix86_binary_operator_ok (AND, DImode, operands)"
8045 and{l}\t{%k2, %k0|%k0, %k2}
8046 and{q}\t{%2, %0|%0, %2}
8047 and{q}\t{%2, %0|%0, %2}"
8048 [(set_attr "type" "alu")
8049 (set_attr "mode" "SI,DI,DI")])
8051 (define_insn "*andqi_2_maybe_si"
8052 [(set (reg FLAGS_REG)
8054 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8055 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8057 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8058 (and:QI (match_dup 1) (match_dup 2)))]
8059 "ix86_binary_operator_ok (AND, QImode, operands)
8060 && ix86_match_ccmode (insn,
8061 CONST_INT_P (operands[2])
8062 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8064 if (which_alternative == 2)
8066 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8067 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8068 return "and{l}\t{%2, %k0|%k0, %2}";
8070 return "and{b}\t{%2, %0|%0, %2}";
8072 [(set_attr "type" "alu")
8073 (set_attr "mode" "QI,QI,SI")])
8075 (define_insn "*and<mode>_2"
8076 [(set (reg FLAGS_REG)
8077 (compare (and:SWI124
8078 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8079 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8081 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8082 (and:SWI124 (match_dup 1) (match_dup 2)))]
8083 "ix86_match_ccmode (insn, CCNOmode)
8084 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8085 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8086 [(set_attr "type" "alu")
8087 (set_attr "mode" "<MODE>")])
8089 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8090 (define_insn "*andsi_2_zext"
8091 [(set (reg FLAGS_REG)
8093 (match_operand:SI 1 "nonimmediate_operand" "%0")
8094 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8096 (set (match_operand:DI 0 "register_operand" "=r")
8097 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8098 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8099 && ix86_binary_operator_ok (AND, SImode, operands)"
8100 "and{l}\t{%2, %k0|%k0, %2}"
8101 [(set_attr "type" "alu")
8102 (set_attr "mode" "SI")])
8104 (define_insn "*andqi_2_slp"
8105 [(set (reg FLAGS_REG)
8107 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8108 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8110 (set (strict_low_part (match_dup 0))
8111 (and:QI (match_dup 0) (match_dup 1)))]
8112 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8113 && ix86_match_ccmode (insn, CCNOmode)
8114 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8115 "and{b}\t{%1, %0|%0, %1}"
8116 [(set_attr "type" "alu1")
8117 (set_attr "mode" "QI")])
8119 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8120 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8121 ;; for a QImode operand, which of course failed.
8122 (define_insn "andqi_ext_0"
8123 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8128 (match_operand 1 "ext_register_operand" "0")
8131 (match_operand 2 "const_int_operand" "n")))
8132 (clobber (reg:CC FLAGS_REG))]
8134 "and{b}\t{%2, %h0|%h0, %2}"
8135 [(set_attr "type" "alu")
8136 (set_attr "length_immediate" "1")
8137 (set_attr "modrm" "1")
8138 (set_attr "mode" "QI")])
8140 ;; Generated by peephole translating test to and. This shows up
8141 ;; often in fp comparisons.
8142 (define_insn "*andqi_ext_0_cc"
8143 [(set (reg FLAGS_REG)
8147 (match_operand 1 "ext_register_operand" "0")
8150 (match_operand 2 "const_int_operand" "n"))
8152 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8161 "ix86_match_ccmode (insn, CCNOmode)"
8162 "and{b}\t{%2, %h0|%h0, %2}"
8163 [(set_attr "type" "alu")
8164 (set_attr "length_immediate" "1")
8165 (set_attr "modrm" "1")
8166 (set_attr "mode" "QI")])
8168 (define_insn "*andqi_ext_1_rex64"
8169 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8174 (match_operand 1 "ext_register_operand" "0")
8178 (match_operand 2 "ext_register_operand" "Q"))))
8179 (clobber (reg:CC FLAGS_REG))]
8181 "and{b}\t{%2, %h0|%h0, %2}"
8182 [(set_attr "type" "alu")
8183 (set_attr "length_immediate" "0")
8184 (set_attr "mode" "QI")])
8186 (define_insn "*andqi_ext_1"
8187 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8192 (match_operand 1 "ext_register_operand" "0")
8196 (match_operand:QI 2 "general_operand" "Qm"))))
8197 (clobber (reg:CC FLAGS_REG))]
8199 "and{b}\t{%2, %h0|%h0, %2}"
8200 [(set_attr "type" "alu")
8201 (set_attr "length_immediate" "0")
8202 (set_attr "mode" "QI")])
8204 (define_insn "*andqi_ext_2"
8205 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8210 (match_operand 1 "ext_register_operand" "%0")
8214 (match_operand 2 "ext_register_operand" "Q")
8217 (clobber (reg:CC FLAGS_REG))]
8219 "and{b}\t{%h2, %h0|%h0, %h2}"
8220 [(set_attr "type" "alu")
8221 (set_attr "length_immediate" "0")
8222 (set_attr "mode" "QI")])
8224 ;; Convert wide AND instructions with immediate operand to shorter QImode
8225 ;; equivalents when possible.
8226 ;; Don't do the splitting with memory operands, since it introduces risk
8227 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8228 ;; for size, but that can (should?) be handled by generic code instead.
8230 [(set (match_operand 0 "register_operand")
8231 (and (match_operand 1 "register_operand")
8232 (match_operand 2 "const_int_operand")))
8233 (clobber (reg:CC FLAGS_REG))]
8235 && QI_REG_P (operands[0])
8236 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8237 && !(~INTVAL (operands[2]) & ~(255 << 8))
8238 && GET_MODE (operands[0]) != QImode"
8239 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8240 (and:SI (zero_extract:SI (match_dup 1)
8241 (const_int 8) (const_int 8))
8243 (clobber (reg:CC FLAGS_REG))])]
8245 operands[0] = gen_lowpart (SImode, operands[0]);
8246 operands[1] = gen_lowpart (SImode, operands[1]);
8247 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8250 ;; Since AND can be encoded with sign extended immediate, this is only
8251 ;; profitable when 7th bit is not set.
8253 [(set (match_operand 0 "register_operand")
8254 (and (match_operand 1 "general_operand")
8255 (match_operand 2 "const_int_operand")))
8256 (clobber (reg:CC FLAGS_REG))]
8258 && ANY_QI_REG_P (operands[0])
8259 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8260 && !(~INTVAL (operands[2]) & ~255)
8261 && !(INTVAL (operands[2]) & 128)
8262 && GET_MODE (operands[0]) != QImode"
8263 [(parallel [(set (strict_low_part (match_dup 0))
8264 (and:QI (match_dup 1)
8266 (clobber (reg:CC FLAGS_REG))])]
8268 operands[0] = gen_lowpart (QImode, operands[0]);
8269 operands[1] = gen_lowpart (QImode, operands[1]);
8270 operands[2] = gen_lowpart (QImode, operands[2]);
8273 ;; Logical inclusive and exclusive OR instructions
8275 ;; %%% This used to optimize known byte-wide and operations to memory.
8276 ;; If this is considered useful, it should be done with splitters.
8278 (define_expand "<code><mode>3"
8279 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8280 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8281 (match_operand:SWIM 2 "<general_operand>")))]
8283 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8285 (define_insn "*<code><mode>_1"
8286 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8288 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8289 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8290 (clobber (reg:CC FLAGS_REG))]
8291 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8292 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8293 [(set_attr "type" "alu")
8294 (set_attr "mode" "<MODE>")])
8296 ;; %%% Potential partial reg stall on alternative 2. What to do?
8297 (define_insn "*<code>qi_1"
8298 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8299 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8300 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8301 (clobber (reg:CC FLAGS_REG))]
8302 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8304 <logic>{b}\t{%2, %0|%0, %2}
8305 <logic>{b}\t{%2, %0|%0, %2}
8306 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8307 [(set_attr "type" "alu")
8308 (set_attr "mode" "QI,QI,SI")])
8310 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8311 (define_insn "*<code>si_1_zext"
8312 [(set (match_operand:DI 0 "register_operand" "=r")
8314 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8315 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8316 (clobber (reg:CC FLAGS_REG))]
8317 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8318 "<logic>{l}\t{%2, %k0|%k0, %2}"
8319 [(set_attr "type" "alu")
8320 (set_attr "mode" "SI")])
8322 (define_insn "*<code>si_1_zext_imm"
8323 [(set (match_operand:DI 0 "register_operand" "=r")
8325 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8326 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8327 (clobber (reg:CC FLAGS_REG))]
8328 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8329 "<logic>{l}\t{%2, %k0|%k0, %2}"
8330 [(set_attr "type" "alu")
8331 (set_attr "mode" "SI")])
8333 (define_insn "*<code>qi_1_slp"
8334 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8335 (any_or:QI (match_dup 0)
8336 (match_operand:QI 1 "general_operand" "qmn,qn")))
8337 (clobber (reg:CC FLAGS_REG))]
8338 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8339 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8340 "<logic>{b}\t{%1, %0|%0, %1}"
8341 [(set_attr "type" "alu1")
8342 (set_attr "mode" "QI")])
8344 (define_insn "*<code><mode>_2"
8345 [(set (reg FLAGS_REG)
8346 (compare (any_or:SWI
8347 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8348 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8350 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8351 (any_or:SWI (match_dup 1) (match_dup 2)))]
8352 "ix86_match_ccmode (insn, CCNOmode)
8353 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8354 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8355 [(set_attr "type" "alu")
8356 (set_attr "mode" "<MODE>")])
8358 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8359 ;; ??? Special case for immediate operand is missing - it is tricky.
8360 (define_insn "*<code>si_2_zext"
8361 [(set (reg FLAGS_REG)
8362 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8363 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8365 (set (match_operand:DI 0 "register_operand" "=r")
8366 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8367 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8368 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8369 "<logic>{l}\t{%2, %k0|%k0, %2}"
8370 [(set_attr "type" "alu")
8371 (set_attr "mode" "SI")])
8373 (define_insn "*<code>si_2_zext_imm"
8374 [(set (reg FLAGS_REG)
8376 (match_operand:SI 1 "nonimmediate_operand" "%0")
8377 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8379 (set (match_operand:DI 0 "register_operand" "=r")
8380 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8381 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8382 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8383 "<logic>{l}\t{%2, %k0|%k0, %2}"
8384 [(set_attr "type" "alu")
8385 (set_attr "mode" "SI")])
8387 (define_insn "*<code>qi_2_slp"
8388 [(set (reg FLAGS_REG)
8389 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8390 (match_operand:QI 1 "general_operand" "qmn,qn"))
8392 (set (strict_low_part (match_dup 0))
8393 (any_or:QI (match_dup 0) (match_dup 1)))]
8394 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8395 && ix86_match_ccmode (insn, CCNOmode)
8396 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8397 "<logic>{b}\t{%1, %0|%0, %1}"
8398 [(set_attr "type" "alu1")
8399 (set_attr "mode" "QI")])
8401 (define_insn "*<code><mode>_3"
8402 [(set (reg FLAGS_REG)
8403 (compare (any_or:SWI
8404 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8405 (match_operand:SWI 2 "<general_operand>" "<g>"))
8407 (clobber (match_scratch:SWI 0 "=<r>"))]
8408 "ix86_match_ccmode (insn, CCNOmode)
8409 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8410 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8411 [(set_attr "type" "alu")
8412 (set_attr "mode" "<MODE>")])
8414 (define_insn "*<code>qi_ext_0"
8415 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8420 (match_operand 1 "ext_register_operand" "0")
8423 (match_operand 2 "const_int_operand" "n")))
8424 (clobber (reg:CC FLAGS_REG))]
8425 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8426 "<logic>{b}\t{%2, %h0|%h0, %2}"
8427 [(set_attr "type" "alu")
8428 (set_attr "length_immediate" "1")
8429 (set_attr "modrm" "1")
8430 (set_attr "mode" "QI")])
8432 (define_insn "*<code>qi_ext_1_rex64"
8433 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8438 (match_operand 1 "ext_register_operand" "0")
8442 (match_operand 2 "ext_register_operand" "Q"))))
8443 (clobber (reg:CC FLAGS_REG))]
8445 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8446 "<logic>{b}\t{%2, %h0|%h0, %2}"
8447 [(set_attr "type" "alu")
8448 (set_attr "length_immediate" "0")
8449 (set_attr "mode" "QI")])
8451 (define_insn "*<code>qi_ext_1"
8452 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8457 (match_operand 1 "ext_register_operand" "0")
8461 (match_operand:QI 2 "general_operand" "Qm"))))
8462 (clobber (reg:CC FLAGS_REG))]
8464 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8465 "<logic>{b}\t{%2, %h0|%h0, %2}"
8466 [(set_attr "type" "alu")
8467 (set_attr "length_immediate" "0")
8468 (set_attr "mode" "QI")])
8470 (define_insn "*<code>qi_ext_2"
8471 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8475 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8478 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8481 (clobber (reg:CC FLAGS_REG))]
8482 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8483 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8484 [(set_attr "type" "alu")
8485 (set_attr "length_immediate" "0")
8486 (set_attr "mode" "QI")])
8489 [(set (match_operand 0 "register_operand")
8490 (any_or (match_operand 1 "register_operand")
8491 (match_operand 2 "const_int_operand")))
8492 (clobber (reg:CC FLAGS_REG))]
8494 && QI_REG_P (operands[0])
8495 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8496 && !(INTVAL (operands[2]) & ~(255 << 8))
8497 && GET_MODE (operands[0]) != QImode"
8498 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8499 (any_or:SI (zero_extract:SI (match_dup 1)
8500 (const_int 8) (const_int 8))
8502 (clobber (reg:CC FLAGS_REG))])]
8504 operands[0] = gen_lowpart (SImode, operands[0]);
8505 operands[1] = gen_lowpart (SImode, operands[1]);
8506 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8509 ;; Since OR can be encoded with sign extended immediate, this is only
8510 ;; profitable when 7th bit is set.
8512 [(set (match_operand 0 "register_operand")
8513 (any_or (match_operand 1 "general_operand")
8514 (match_operand 2 "const_int_operand")))
8515 (clobber (reg:CC FLAGS_REG))]
8517 && ANY_QI_REG_P (operands[0])
8518 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8519 && !(INTVAL (operands[2]) & ~255)
8520 && (INTVAL (operands[2]) & 128)
8521 && GET_MODE (operands[0]) != QImode"
8522 [(parallel [(set (strict_low_part (match_dup 0))
8523 (any_or:QI (match_dup 1)
8525 (clobber (reg:CC FLAGS_REG))])]
8527 operands[0] = gen_lowpart (QImode, operands[0]);
8528 operands[1] = gen_lowpart (QImode, operands[1]);
8529 operands[2] = gen_lowpart (QImode, operands[2]);
8532 (define_expand "xorqi_cc_ext_1"
8534 (set (reg:CCNO FLAGS_REG)
8538 (match_operand 1 "ext_register_operand")
8541 (match_operand:QI 2 "general_operand"))
8543 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8553 (define_insn "*xorqi_cc_ext_1_rex64"
8554 [(set (reg FLAGS_REG)
8558 (match_operand 1 "ext_register_operand" "0")
8561 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8563 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8572 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8573 "xor{b}\t{%2, %h0|%h0, %2}"
8574 [(set_attr "type" "alu")
8575 (set_attr "modrm" "1")
8576 (set_attr "mode" "QI")])
8578 (define_insn "*xorqi_cc_ext_1"
8579 [(set (reg FLAGS_REG)
8583 (match_operand 1 "ext_register_operand" "0")
8586 (match_operand:QI 2 "general_operand" "qmn"))
8588 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8597 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8598 "xor{b}\t{%2, %h0|%h0, %2}"
8599 [(set_attr "type" "alu")
8600 (set_attr "modrm" "1")
8601 (set_attr "mode" "QI")])
8603 ;; Negation instructions
8605 (define_expand "neg<mode>2"
8606 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8607 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8609 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8611 (define_insn_and_split "*neg<dwi>2_doubleword"
8612 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8613 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8614 (clobber (reg:CC FLAGS_REG))]
8615 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8619 [(set (reg:CCZ FLAGS_REG)
8620 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8621 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8624 (plus:DWIH (match_dup 3)
8625 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8627 (clobber (reg:CC FLAGS_REG))])
8630 (neg:DWIH (match_dup 2)))
8631 (clobber (reg:CC FLAGS_REG))])]
8632 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8634 (define_insn "*neg<mode>2_1"
8635 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8636 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8637 (clobber (reg:CC FLAGS_REG))]
8638 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8639 "neg{<imodesuffix>}\t%0"
8640 [(set_attr "type" "negnot")
8641 (set_attr "mode" "<MODE>")])
8643 ;; Combine is quite creative about this pattern.
8644 (define_insn "*negsi2_1_zext"
8645 [(set (match_operand:DI 0 "register_operand" "=r")
8647 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8650 (clobber (reg:CC FLAGS_REG))]
8651 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8653 [(set_attr "type" "negnot")
8654 (set_attr "mode" "SI")])
8656 ;; The problem with neg is that it does not perform (compare x 0),
8657 ;; it really performs (compare 0 x), which leaves us with the zero
8658 ;; flag being the only useful item.
8660 (define_insn "*neg<mode>2_cmpz"
8661 [(set (reg:CCZ FLAGS_REG)
8663 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8665 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8666 (neg:SWI (match_dup 1)))]
8667 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8668 "neg{<imodesuffix>}\t%0"
8669 [(set_attr "type" "negnot")
8670 (set_attr "mode" "<MODE>")])
8672 (define_insn "*negsi2_cmpz_zext"
8673 [(set (reg:CCZ FLAGS_REG)
8677 (match_operand:DI 1 "register_operand" "0")
8681 (set (match_operand:DI 0 "register_operand" "=r")
8682 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8685 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8687 [(set_attr "type" "negnot")
8688 (set_attr "mode" "SI")])
8690 ;; Changing of sign for FP values is doable using integer unit too.
8692 (define_expand "<code><mode>2"
8693 [(set (match_operand:X87MODEF 0 "register_operand")
8694 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8695 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8696 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8698 (define_insn "*absneg<mode>2_mixed"
8699 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8700 (match_operator:MODEF 3 "absneg_operator"
8701 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8702 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8703 (clobber (reg:CC FLAGS_REG))]
8704 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8707 (define_insn "*absneg<mode>2_sse"
8708 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8709 (match_operator:MODEF 3 "absneg_operator"
8710 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8711 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8712 (clobber (reg:CC FLAGS_REG))]
8713 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8716 (define_insn "*absneg<mode>2_i387"
8717 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8718 (match_operator:X87MODEF 3 "absneg_operator"
8719 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8720 (use (match_operand 2))
8721 (clobber (reg:CC FLAGS_REG))]
8722 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8725 (define_expand "<code>tf2"
8726 [(set (match_operand:TF 0 "register_operand")
8727 (absneg:TF (match_operand:TF 1 "register_operand")))]
8729 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8731 (define_insn "*absnegtf2_sse"
8732 [(set (match_operand:TF 0 "register_operand" "=x,x")
8733 (match_operator:TF 3 "absneg_operator"
8734 [(match_operand:TF 1 "register_operand" "0,x")]))
8735 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8736 (clobber (reg:CC FLAGS_REG))]
8740 ;; Splitters for fp abs and neg.
8743 [(set (match_operand 0 "fp_register_operand")
8744 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8745 (use (match_operand 2))
8746 (clobber (reg:CC FLAGS_REG))]
8748 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8751 [(set (match_operand 0 "register_operand")
8752 (match_operator 3 "absneg_operator"
8753 [(match_operand 1 "register_operand")]))
8754 (use (match_operand 2 "nonimmediate_operand"))
8755 (clobber (reg:CC FLAGS_REG))]
8756 "reload_completed && SSE_REG_P (operands[0])"
8757 [(set (match_dup 0) (match_dup 3))]
8759 enum machine_mode mode = GET_MODE (operands[0]);
8760 enum machine_mode vmode = GET_MODE (operands[2]);
8763 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8764 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8765 if (operands_match_p (operands[0], operands[2]))
8768 operands[1] = operands[2];
8771 if (GET_CODE (operands[3]) == ABS)
8772 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8774 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8779 [(set (match_operand:SF 0 "register_operand")
8780 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8781 (use (match_operand:V4SF 2))
8782 (clobber (reg:CC FLAGS_REG))]
8784 [(parallel [(set (match_dup 0) (match_dup 1))
8785 (clobber (reg:CC FLAGS_REG))])]
8788 operands[0] = gen_lowpart (SImode, operands[0]);
8789 if (GET_CODE (operands[1]) == ABS)
8791 tmp = gen_int_mode (0x7fffffff, SImode);
8792 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8796 tmp = gen_int_mode (0x80000000, SImode);
8797 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8803 [(set (match_operand:DF 0 "register_operand")
8804 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8805 (use (match_operand 2))
8806 (clobber (reg:CC FLAGS_REG))]
8808 [(parallel [(set (match_dup 0) (match_dup 1))
8809 (clobber (reg:CC FLAGS_REG))])]
8814 tmp = gen_lowpart (DImode, operands[0]);
8815 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8818 if (GET_CODE (operands[1]) == ABS)
8821 tmp = gen_rtx_NOT (DImode, tmp);
8825 operands[0] = gen_highpart (SImode, operands[0]);
8826 if (GET_CODE (operands[1]) == ABS)
8828 tmp = gen_int_mode (0x7fffffff, SImode);
8829 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8833 tmp = gen_int_mode (0x80000000, SImode);
8834 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8841 [(set (match_operand:XF 0 "register_operand")
8842 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8843 (use (match_operand 2))
8844 (clobber (reg:CC FLAGS_REG))]
8846 [(parallel [(set (match_dup 0) (match_dup 1))
8847 (clobber (reg:CC FLAGS_REG))])]
8850 operands[0] = gen_rtx_REG (SImode,
8851 true_regnum (operands[0])
8852 + (TARGET_64BIT ? 1 : 2));
8853 if (GET_CODE (operands[1]) == ABS)
8855 tmp = GEN_INT (0x7fff);
8856 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8860 tmp = GEN_INT (0x8000);
8861 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8866 ;; Conditionalize these after reload. If they match before reload, we
8867 ;; lose the clobber and ability to use integer instructions.
8869 (define_insn "*<code><mode>2_1"
8870 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8871 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8873 && (reload_completed
8874 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8875 "f<absneg_mnemonic>"
8876 [(set_attr "type" "fsgn")
8877 (set_attr "mode" "<MODE>")])
8879 (define_insn "*<code>extendsfdf2"
8880 [(set (match_operand:DF 0 "register_operand" "=f")
8881 (absneg:DF (float_extend:DF
8882 (match_operand:SF 1 "register_operand" "0"))))]
8883 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8884 "f<absneg_mnemonic>"
8885 [(set_attr "type" "fsgn")
8886 (set_attr "mode" "DF")])
8888 (define_insn "*<code>extendsfxf2"
8889 [(set (match_operand:XF 0 "register_operand" "=f")
8890 (absneg:XF (float_extend:XF
8891 (match_operand:SF 1 "register_operand" "0"))))]
8893 "f<absneg_mnemonic>"
8894 [(set_attr "type" "fsgn")
8895 (set_attr "mode" "XF")])
8897 (define_insn "*<code>extenddfxf2"
8898 [(set (match_operand:XF 0 "register_operand" "=f")
8899 (absneg:XF (float_extend:XF
8900 (match_operand:DF 1 "register_operand" "0"))))]
8902 "f<absneg_mnemonic>"
8903 [(set_attr "type" "fsgn")
8904 (set_attr "mode" "XF")])
8906 ;; Copysign instructions
8908 (define_mode_iterator CSGNMODE [SF DF TF])
8909 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8911 (define_expand "copysign<mode>3"
8912 [(match_operand:CSGNMODE 0 "register_operand")
8913 (match_operand:CSGNMODE 1 "nonmemory_operand")
8914 (match_operand:CSGNMODE 2 "register_operand")]
8915 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8916 || (TARGET_SSE && (<MODE>mode == TFmode))"
8917 "ix86_expand_copysign (operands); DONE;")
8919 (define_insn_and_split "copysign<mode>3_const"
8920 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8922 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8923 (match_operand:CSGNMODE 2 "register_operand" "0")
8924 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8926 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8927 || (TARGET_SSE && (<MODE>mode == TFmode))"
8929 "&& reload_completed"
8931 "ix86_split_copysign_const (operands); DONE;")
8933 (define_insn "copysign<mode>3_var"
8934 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8936 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8937 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8938 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8939 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8941 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8942 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8943 || (TARGET_SSE && (<MODE>mode == TFmode))"
8947 [(set (match_operand:CSGNMODE 0 "register_operand")
8949 [(match_operand:CSGNMODE 2 "register_operand")
8950 (match_operand:CSGNMODE 3 "register_operand")
8951 (match_operand:<CSGNVMODE> 4)
8952 (match_operand:<CSGNVMODE> 5)]
8954 (clobber (match_scratch:<CSGNVMODE> 1))]
8955 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8956 || (TARGET_SSE && (<MODE>mode == TFmode)))
8957 && reload_completed"
8959 "ix86_split_copysign_var (operands); DONE;")
8961 ;; One complement instructions
8963 (define_expand "one_cmpl<mode>2"
8964 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8965 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8967 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8969 (define_insn "*one_cmpl<mode>2_1"
8970 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8971 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8972 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8973 "not{<imodesuffix>}\t%0"
8974 [(set_attr "type" "negnot")
8975 (set_attr "mode" "<MODE>")])
8977 ;; %%% Potential partial reg stall on alternative 1. What to do?
8978 (define_insn "*one_cmplqi2_1"
8979 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8980 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8981 "ix86_unary_operator_ok (NOT, QImode, operands)"
8985 [(set_attr "type" "negnot")
8986 (set_attr "mode" "QI,SI")])
8988 ;; ??? Currently never generated - xor is used instead.
8989 (define_insn "*one_cmplsi2_1_zext"
8990 [(set (match_operand:DI 0 "register_operand" "=r")
8992 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8993 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8995 [(set_attr "type" "negnot")
8996 (set_attr "mode" "SI")])
8998 (define_insn "*one_cmpl<mode>2_2"
8999 [(set (reg FLAGS_REG)
9000 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9002 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9003 (not:SWI (match_dup 1)))]
9004 "ix86_match_ccmode (insn, CCNOmode)
9005 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9007 [(set_attr "type" "alu1")
9008 (set_attr "mode" "<MODE>")])
9011 [(set (match_operand 0 "flags_reg_operand")
9012 (match_operator 2 "compare_operator"
9013 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9015 (set (match_operand:SWI 1 "nonimmediate_operand")
9016 (not:SWI (match_dup 3)))]
9017 "ix86_match_ccmode (insn, CCNOmode)"
9018 [(parallel [(set (match_dup 0)
9019 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9022 (xor:SWI (match_dup 3) (const_int -1)))])])
9024 ;; ??? Currently never generated - xor is used instead.
9025 (define_insn "*one_cmplsi2_2_zext"
9026 [(set (reg FLAGS_REG)
9027 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9029 (set (match_operand:DI 0 "register_operand" "=r")
9030 (zero_extend:DI (not:SI (match_dup 1))))]
9031 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9032 && ix86_unary_operator_ok (NOT, SImode, operands)"
9034 [(set_attr "type" "alu1")
9035 (set_attr "mode" "SI")])
9038 [(set (match_operand 0 "flags_reg_operand")
9039 (match_operator 2 "compare_operator"
9040 [(not:SI (match_operand:SI 3 "register_operand"))
9042 (set (match_operand:DI 1 "register_operand")
9043 (zero_extend:DI (not:SI (match_dup 3))))]
9044 "ix86_match_ccmode (insn, CCNOmode)"
9045 [(parallel [(set (match_dup 0)
9046 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9049 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9051 ;; Shift instructions
9053 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9054 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9055 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9056 ;; from the assembler input.
9058 ;; This instruction shifts the target reg/mem as usual, but instead of
9059 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9060 ;; is a left shift double, bits are taken from the high order bits of
9061 ;; reg, else if the insn is a shift right double, bits are taken from the
9062 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9063 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9065 ;; Since sh[lr]d does not change the `reg' operand, that is done
9066 ;; separately, making all shifts emit pairs of shift double and normal
9067 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9068 ;; support a 63 bit shift, each shift where the count is in a reg expands
9069 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9071 ;; If the shift count is a constant, we need never emit more than one
9072 ;; shift pair, instead using moves and sign extension for counts greater
9075 (define_expand "ashl<mode>3"
9076 [(set (match_operand:SDWIM 0 "<shift_operand>")
9077 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9078 (match_operand:QI 2 "nonmemory_operand")))]
9080 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9082 (define_insn "*ashl<mode>3_doubleword"
9083 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9084 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9085 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9086 (clobber (reg:CC FLAGS_REG))]
9089 [(set_attr "type" "multi")])
9092 [(set (match_operand:DWI 0 "register_operand")
9093 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9094 (match_operand:QI 2 "nonmemory_operand")))
9095 (clobber (reg:CC FLAGS_REG))]
9096 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9098 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9100 ;; By default we don't ask for a scratch register, because when DWImode
9101 ;; values are manipulated, registers are already at a premium. But if
9102 ;; we have one handy, we won't turn it away.
9105 [(match_scratch:DWIH 3 "r")
9106 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9108 (match_operand:<DWI> 1 "nonmemory_operand")
9109 (match_operand:QI 2 "nonmemory_operand")))
9110 (clobber (reg:CC FLAGS_REG))])
9114 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9116 (define_insn "x86_64_shld"
9117 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9118 (ior:DI (ashift:DI (match_dup 0)
9119 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9120 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9121 (minus:QI (const_int 64) (match_dup 2)))))
9122 (clobber (reg:CC FLAGS_REG))]
9124 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9125 [(set_attr "type" "ishift")
9126 (set_attr "prefix_0f" "1")
9127 (set_attr "mode" "DI")
9128 (set_attr "athlon_decode" "vector")
9129 (set_attr "amdfam10_decode" "vector")
9130 (set_attr "bdver1_decode" "vector")])
9132 (define_insn "x86_shld"
9133 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9134 (ior:SI (ashift:SI (match_dup 0)
9135 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9136 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9137 (minus:QI (const_int 32) (match_dup 2)))))
9138 (clobber (reg:CC FLAGS_REG))]
9140 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9141 [(set_attr "type" "ishift")
9142 (set_attr "prefix_0f" "1")
9143 (set_attr "mode" "SI")
9144 (set_attr "pent_pair" "np")
9145 (set_attr "athlon_decode" "vector")
9146 (set_attr "amdfam10_decode" "vector")
9147 (set_attr "bdver1_decode" "vector")])
9149 (define_expand "x86_shift<mode>_adj_1"
9150 [(set (reg:CCZ FLAGS_REG)
9151 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9154 (set (match_operand:SWI48 0 "register_operand")
9155 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9156 (match_operand:SWI48 1 "register_operand")
9159 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9160 (match_operand:SWI48 3 "register_operand")
9163 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9165 (define_expand "x86_shift<mode>_adj_2"
9166 [(use (match_operand:SWI48 0 "register_operand"))
9167 (use (match_operand:SWI48 1 "register_operand"))
9168 (use (match_operand:QI 2 "register_operand"))]
9171 rtx label = gen_label_rtx ();
9174 emit_insn (gen_testqi_ccz_1 (operands[2],
9175 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9177 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9178 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9179 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9180 gen_rtx_LABEL_REF (VOIDmode, label),
9182 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9183 JUMP_LABEL (tmp) = label;
9185 emit_move_insn (operands[0], operands[1]);
9186 ix86_expand_clear (operands[1]);
9189 LABEL_NUSES (label) = 1;
9194 ;; Avoid useless masking of count operand.
9195 (define_insn_and_split "*ashl<mode>3_mask"
9196 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9198 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9201 (match_operand:SI 2 "nonimmediate_operand" "c")
9202 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9203 (clobber (reg:CC FLAGS_REG))]
9204 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9205 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9206 == GET_MODE_BITSIZE (<MODE>mode)-1"
9209 [(parallel [(set (match_dup 0)
9210 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9211 (clobber (reg:CC FLAGS_REG))])]
9213 if (can_create_pseudo_p ())
9214 operands [2] = force_reg (SImode, operands[2]);
9216 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9218 [(set_attr "type" "ishift")
9219 (set_attr "mode" "<MODE>")])
9221 (define_insn "*bmi2_ashl<mode>3_1"
9222 [(set (match_operand:SWI48 0 "register_operand" "=r")
9223 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9224 (match_operand:SWI48 2 "register_operand" "r")))]
9226 "shlx\t{%2, %1, %0|%0, %1, %2}"
9227 [(set_attr "type" "ishiftx")
9228 (set_attr "mode" "<MODE>")])
9230 (define_insn "*ashl<mode>3_1"
9231 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9232 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9233 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9234 (clobber (reg:CC FLAGS_REG))]
9235 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9237 switch (get_attr_type (insn))
9244 gcc_assert (operands[2] == const1_rtx);
9245 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9246 return "add{<imodesuffix>}\t%0, %0";
9249 if (operands[2] == const1_rtx
9250 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9251 return "sal{<imodesuffix>}\t%0";
9253 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9256 [(set_attr "isa" "*,*,bmi2")
9258 (cond [(eq_attr "alternative" "1")
9259 (const_string "lea")
9260 (eq_attr "alternative" "2")
9261 (const_string "ishiftx")
9262 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9263 (match_operand 0 "register_operand"))
9264 (match_operand 2 "const1_operand"))
9265 (const_string "alu")
9267 (const_string "ishift")))
9268 (set (attr "length_immediate")
9270 (ior (eq_attr "type" "alu")
9271 (and (eq_attr "type" "ishift")
9272 (and (match_operand 2 "const1_operand")
9273 (ior (match_test "TARGET_SHIFT1")
9274 (match_test "optimize_function_for_size_p (cfun)")))))
9276 (const_string "*")))
9277 (set_attr "mode" "<MODE>")])
9279 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9281 [(set (match_operand:SWI48 0 "register_operand")
9282 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9283 (match_operand:QI 2 "register_operand")))
9284 (clobber (reg:CC FLAGS_REG))]
9285 "TARGET_BMI2 && reload_completed"
9287 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9288 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9290 (define_insn "*bmi2_ashlsi3_1_zext"
9291 [(set (match_operand:DI 0 "register_operand" "=r")
9293 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9294 (match_operand:SI 2 "register_operand" "r"))))]
9295 "TARGET_64BIT && TARGET_BMI2"
9296 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9297 [(set_attr "type" "ishiftx")
9298 (set_attr "mode" "SI")])
9300 (define_insn "*ashlsi3_1_zext"
9301 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9303 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9304 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9305 (clobber (reg:CC FLAGS_REG))]
9306 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9308 switch (get_attr_type (insn))
9315 gcc_assert (operands[2] == const1_rtx);
9316 return "add{l}\t%k0, %k0";
9319 if (operands[2] == const1_rtx
9320 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9321 return "sal{l}\t%k0";
9323 return "sal{l}\t{%2, %k0|%k0, %2}";
9326 [(set_attr "isa" "*,*,bmi2")
9328 (cond [(eq_attr "alternative" "1")
9329 (const_string "lea")
9330 (eq_attr "alternative" "2")
9331 (const_string "ishiftx")
9332 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9333 (match_operand 2 "const1_operand"))
9334 (const_string "alu")
9336 (const_string "ishift")))
9337 (set (attr "length_immediate")
9339 (ior (eq_attr "type" "alu")
9340 (and (eq_attr "type" "ishift")
9341 (and (match_operand 2 "const1_operand")
9342 (ior (match_test "TARGET_SHIFT1")
9343 (match_test "optimize_function_for_size_p (cfun)")))))
9345 (const_string "*")))
9346 (set_attr "mode" "SI")])
9348 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9350 [(set (match_operand:DI 0 "register_operand")
9352 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9353 (match_operand:QI 2 "register_operand"))))
9354 (clobber (reg:CC FLAGS_REG))]
9355 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9357 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9358 "operands[2] = gen_lowpart (SImode, operands[2]);")
9360 (define_insn "*ashlhi3_1"
9361 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9362 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9363 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9364 (clobber (reg:CC FLAGS_REG))]
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 (match_test "TARGET_DOUBLE_WITH_ADD")
9388 (match_operand 0 "register_operand"))
9389 (match_operand 2 "const1_operand"))
9390 (const_string "alu")
9392 (const_string "ishift")))
9393 (set (attr "length_immediate")
9395 (ior (eq_attr "type" "alu")
9396 (and (eq_attr "type" "ishift")
9397 (and (match_operand 2 "const1_operand")
9398 (ior (match_test "TARGET_SHIFT1")
9399 (match_test "optimize_function_for_size_p (cfun)")))))
9401 (const_string "*")))
9402 (set_attr "mode" "HI,SI")])
9404 ;; %%% Potential partial reg stall on alternative 1. What to do?
9405 (define_insn "*ashlqi3_1"
9406 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9407 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9408 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9409 (clobber (reg:CC FLAGS_REG))]
9410 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9412 switch (get_attr_type (insn))
9418 gcc_assert (operands[2] == const1_rtx);
9419 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9420 return "add{l}\t%k0, %k0";
9422 return "add{b}\t%0, %0";
9425 if (operands[2] == const1_rtx
9426 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9428 if (get_attr_mode (insn) == MODE_SI)
9429 return "sal{l}\t%k0";
9431 return "sal{b}\t%0";
9435 if (get_attr_mode (insn) == MODE_SI)
9436 return "sal{l}\t{%2, %k0|%k0, %2}";
9438 return "sal{b}\t{%2, %0|%0, %2}";
9443 (cond [(eq_attr "alternative" "2")
9444 (const_string "lea")
9445 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9446 (match_operand 0 "register_operand"))
9447 (match_operand 2 "const1_operand"))
9448 (const_string "alu")
9450 (const_string "ishift")))
9451 (set (attr "length_immediate")
9453 (ior (eq_attr "type" "alu")
9454 (and (eq_attr "type" "ishift")
9455 (and (match_operand 2 "const1_operand")
9456 (ior (match_test "TARGET_SHIFT1")
9457 (match_test "optimize_function_for_size_p (cfun)")))))
9459 (const_string "*")))
9460 (set_attr "mode" "QI,SI,SI")])
9462 (define_insn "*ashlqi3_1_slp"
9463 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9464 (ashift:QI (match_dup 0)
9465 (match_operand:QI 1 "nonmemory_operand" "cI")))
9466 (clobber (reg:CC FLAGS_REG))]
9467 "(optimize_function_for_size_p (cfun)
9468 || !TARGET_PARTIAL_FLAG_REG_STALL
9469 || (operands[1] == const1_rtx
9471 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9473 switch (get_attr_type (insn))
9476 gcc_assert (operands[1] == const1_rtx);
9477 return "add{b}\t%0, %0";
9480 if (operands[1] == const1_rtx
9481 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9482 return "sal{b}\t%0";
9484 return "sal{b}\t{%1, %0|%0, %1}";
9488 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9489 (match_operand 0 "register_operand"))
9490 (match_operand 1 "const1_operand"))
9491 (const_string "alu")
9493 (const_string "ishift1")))
9494 (set (attr "length_immediate")
9496 (ior (eq_attr "type" "alu")
9497 (and (eq_attr "type" "ishift1")
9498 (and (match_operand 1 "const1_operand")
9499 (ior (match_test "TARGET_SHIFT1")
9500 (match_test "optimize_function_for_size_p (cfun)")))))
9502 (const_string "*")))
9503 (set_attr "mode" "QI")])
9505 ;; Convert ashift to the lea pattern to avoid flags dependency.
9507 [(set (match_operand 0 "register_operand")
9508 (ashift (match_operand 1 "index_register_operand")
9509 (match_operand:QI 2 "const_int_operand")))
9510 (clobber (reg:CC FLAGS_REG))]
9511 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9513 && true_regnum (operands[0]) != true_regnum (operands[1])"
9516 enum machine_mode mode = GET_MODE (operands[0]);
9519 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9522 operands[0] = gen_lowpart (mode, operands[0]);
9523 operands[1] = gen_lowpart (mode, operands[1]);
9526 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9528 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9530 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9534 ;; Convert ashift to the lea pattern to avoid flags dependency.
9536 [(set (match_operand:DI 0 "register_operand")
9538 (ashift:SI (match_operand:SI 1 "index_register_operand")
9539 (match_operand:QI 2 "const_int_operand"))))
9540 (clobber (reg:CC FLAGS_REG))]
9541 "TARGET_64BIT && reload_completed
9542 && true_regnum (operands[0]) != true_regnum (operands[1])"
9544 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9546 operands[1] = gen_lowpart (DImode, operands[1]);
9547 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9550 ;; This pattern can't accept a variable shift count, since shifts by
9551 ;; zero don't affect the flags. We assume that shifts by constant
9552 ;; zero are optimized away.
9553 (define_insn "*ashl<mode>3_cmp"
9554 [(set (reg FLAGS_REG)
9556 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9557 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9559 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9560 (ashift:SWI (match_dup 1) (match_dup 2)))]
9561 "(optimize_function_for_size_p (cfun)
9562 || !TARGET_PARTIAL_FLAG_REG_STALL
9563 || (operands[2] == const1_rtx
9565 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9566 && ix86_match_ccmode (insn, CCGOCmode)
9567 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9569 switch (get_attr_type (insn))
9572 gcc_assert (operands[2] == const1_rtx);
9573 return "add{<imodesuffix>}\t%0, %0";
9576 if (operands[2] == const1_rtx
9577 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9578 return "sal{<imodesuffix>}\t%0";
9580 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9584 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9585 (match_operand 0 "register_operand"))
9586 (match_operand 2 "const1_operand"))
9587 (const_string "alu")
9589 (const_string "ishift")))
9590 (set (attr "length_immediate")
9592 (ior (eq_attr "type" "alu")
9593 (and (eq_attr "type" "ishift")
9594 (and (match_operand 2 "const1_operand")
9595 (ior (match_test "TARGET_SHIFT1")
9596 (match_test "optimize_function_for_size_p (cfun)")))))
9598 (const_string "*")))
9599 (set_attr "mode" "<MODE>")])
9601 (define_insn "*ashlsi3_cmp_zext"
9602 [(set (reg FLAGS_REG)
9604 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9605 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9607 (set (match_operand:DI 0 "register_operand" "=r")
9608 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9610 && (optimize_function_for_size_p (cfun)
9611 || !TARGET_PARTIAL_FLAG_REG_STALL
9612 || (operands[2] == const1_rtx
9614 || TARGET_DOUBLE_WITH_ADD)))
9615 && ix86_match_ccmode (insn, CCGOCmode)
9616 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9618 switch (get_attr_type (insn))
9621 gcc_assert (operands[2] == const1_rtx);
9622 return "add{l}\t%k0, %k0";
9625 if (operands[2] == const1_rtx
9626 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9627 return "sal{l}\t%k0";
9629 return "sal{l}\t{%2, %k0|%k0, %2}";
9633 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9634 (match_operand 2 "const1_operand"))
9635 (const_string "alu")
9637 (const_string "ishift")))
9638 (set (attr "length_immediate")
9640 (ior (eq_attr "type" "alu")
9641 (and (eq_attr "type" "ishift")
9642 (and (match_operand 2 "const1_operand")
9643 (ior (match_test "TARGET_SHIFT1")
9644 (match_test "optimize_function_for_size_p (cfun)")))))
9646 (const_string "*")))
9647 (set_attr "mode" "SI")])
9649 (define_insn "*ashl<mode>3_cconly"
9650 [(set (reg FLAGS_REG)
9652 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9653 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9655 (clobber (match_scratch:SWI 0 "=<r>"))]
9656 "(optimize_function_for_size_p (cfun)
9657 || !TARGET_PARTIAL_FLAG_REG_STALL
9658 || (operands[2] == const1_rtx
9660 || TARGET_DOUBLE_WITH_ADD)))
9661 && ix86_match_ccmode (insn, CCGOCmode)"
9663 switch (get_attr_type (insn))
9666 gcc_assert (operands[2] == const1_rtx);
9667 return "add{<imodesuffix>}\t%0, %0";
9670 if (operands[2] == const1_rtx
9671 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9672 return "sal{<imodesuffix>}\t%0";
9674 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9678 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9679 (match_operand 0 "register_operand"))
9680 (match_operand 2 "const1_operand"))
9681 (const_string "alu")
9683 (const_string "ishift")))
9684 (set (attr "length_immediate")
9686 (ior (eq_attr "type" "alu")
9687 (and (eq_attr "type" "ishift")
9688 (and (match_operand 2 "const1_operand")
9689 (ior (match_test "TARGET_SHIFT1")
9690 (match_test "optimize_function_for_size_p (cfun)")))))
9692 (const_string "*")))
9693 (set_attr "mode" "<MODE>")])
9695 ;; See comment above `ashl<mode>3' about how this works.
9697 (define_expand "<shift_insn><mode>3"
9698 [(set (match_operand:SDWIM 0 "<shift_operand>")
9699 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9700 (match_operand:QI 2 "nonmemory_operand")))]
9702 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9704 ;; Avoid useless masking of count operand.
9705 (define_insn_and_split "*<shift_insn><mode>3_mask"
9706 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9708 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9711 (match_operand:SI 2 "nonimmediate_operand" "c")
9712 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9713 (clobber (reg:CC FLAGS_REG))]
9714 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9715 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9716 == GET_MODE_BITSIZE (<MODE>mode)-1"
9719 [(parallel [(set (match_dup 0)
9720 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9721 (clobber (reg:CC FLAGS_REG))])]
9723 if (can_create_pseudo_p ())
9724 operands [2] = force_reg (SImode, operands[2]);
9726 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9728 [(set_attr "type" "ishift")
9729 (set_attr "mode" "<MODE>")])
9731 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9732 [(set (match_operand:DWI 0 "register_operand" "=r")
9733 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9734 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9735 (clobber (reg:CC FLAGS_REG))]
9738 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9740 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9741 [(set_attr "type" "multi")])
9743 ;; By default we don't ask for a scratch register, because when DWImode
9744 ;; values are manipulated, registers are already at a premium. But if
9745 ;; we have one handy, we won't turn it away.
9748 [(match_scratch:DWIH 3 "r")
9749 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9751 (match_operand:<DWI> 1 "register_operand")
9752 (match_operand:QI 2 "nonmemory_operand")))
9753 (clobber (reg:CC FLAGS_REG))])
9757 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9759 (define_insn "x86_64_shrd"
9760 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9761 (ior:DI (ashiftrt:DI (match_dup 0)
9762 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9763 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9764 (minus:QI (const_int 64) (match_dup 2)))))
9765 (clobber (reg:CC FLAGS_REG))]
9767 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9768 [(set_attr "type" "ishift")
9769 (set_attr "prefix_0f" "1")
9770 (set_attr "mode" "DI")
9771 (set_attr "athlon_decode" "vector")
9772 (set_attr "amdfam10_decode" "vector")
9773 (set_attr "bdver1_decode" "vector")])
9775 (define_insn "x86_shrd"
9776 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9777 (ior:SI (ashiftrt:SI (match_dup 0)
9778 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9779 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9780 (minus:QI (const_int 32) (match_dup 2)))))
9781 (clobber (reg:CC FLAGS_REG))]
9783 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9784 [(set_attr "type" "ishift")
9785 (set_attr "prefix_0f" "1")
9786 (set_attr "mode" "SI")
9787 (set_attr "pent_pair" "np")
9788 (set_attr "athlon_decode" "vector")
9789 (set_attr "amdfam10_decode" "vector")
9790 (set_attr "bdver1_decode" "vector")])
9792 (define_insn "ashrdi3_cvt"
9793 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9794 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9795 (match_operand:QI 2 "const_int_operand")))
9796 (clobber (reg:CC FLAGS_REG))]
9797 "TARGET_64BIT && INTVAL (operands[2]) == 63
9798 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9799 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9802 sar{q}\t{%2, %0|%0, %2}"
9803 [(set_attr "type" "imovx,ishift")
9804 (set_attr "prefix_0f" "0,*")
9805 (set_attr "length_immediate" "0,*")
9806 (set_attr "modrm" "0,1")
9807 (set_attr "mode" "DI")])
9809 (define_insn "ashrsi3_cvt"
9810 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9811 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9812 (match_operand:QI 2 "const_int_operand")))
9813 (clobber (reg:CC FLAGS_REG))]
9814 "INTVAL (operands[2]) == 31
9815 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9816 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9819 sar{l}\t{%2, %0|%0, %2}"
9820 [(set_attr "type" "imovx,ishift")
9821 (set_attr "prefix_0f" "0,*")
9822 (set_attr "length_immediate" "0,*")
9823 (set_attr "modrm" "0,1")
9824 (set_attr "mode" "SI")])
9826 (define_insn "*ashrsi3_cvt_zext"
9827 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9829 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9830 (match_operand:QI 2 "const_int_operand"))))
9831 (clobber (reg:CC FLAGS_REG))]
9832 "TARGET_64BIT && INTVAL (operands[2]) == 31
9833 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9834 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9837 sar{l}\t{%2, %k0|%k0, %2}"
9838 [(set_attr "type" "imovx,ishift")
9839 (set_attr "prefix_0f" "0,*")
9840 (set_attr "length_immediate" "0,*")
9841 (set_attr "modrm" "0,1")
9842 (set_attr "mode" "SI")])
9844 (define_expand "x86_shift<mode>_adj_3"
9845 [(use (match_operand:SWI48 0 "register_operand"))
9846 (use (match_operand:SWI48 1 "register_operand"))
9847 (use (match_operand:QI 2 "register_operand"))]
9850 rtx label = gen_label_rtx ();
9853 emit_insn (gen_testqi_ccz_1 (operands[2],
9854 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9856 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9857 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9858 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9859 gen_rtx_LABEL_REF (VOIDmode, label),
9861 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9862 JUMP_LABEL (tmp) = label;
9864 emit_move_insn (operands[0], operands[1]);
9865 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9866 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9868 LABEL_NUSES (label) = 1;
9873 (define_insn "*bmi2_<shift_insn><mode>3_1"
9874 [(set (match_operand:SWI48 0 "register_operand" "=r")
9875 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9876 (match_operand:SWI48 2 "register_operand" "r")))]
9878 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9879 [(set_attr "type" "ishiftx")
9880 (set_attr "mode" "<MODE>")])
9882 (define_insn "*<shift_insn><mode>3_1"
9883 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9885 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9886 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9887 (clobber (reg:CC FLAGS_REG))]
9888 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9890 switch (get_attr_type (insn))
9896 if (operands[2] == const1_rtx
9897 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9898 return "<shift>{<imodesuffix>}\t%0";
9900 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9903 [(set_attr "isa" "*,bmi2")
9904 (set_attr "type" "ishift,ishiftx")
9905 (set (attr "length_immediate")
9907 (and (match_operand 2 "const1_operand")
9908 (ior (match_test "TARGET_SHIFT1")
9909 (match_test "optimize_function_for_size_p (cfun)")))
9911 (const_string "*")))
9912 (set_attr "mode" "<MODE>")])
9914 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9916 [(set (match_operand:SWI48 0 "register_operand")
9917 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9918 (match_operand:QI 2 "register_operand")))
9919 (clobber (reg:CC FLAGS_REG))]
9920 "TARGET_BMI2 && reload_completed"
9922 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9923 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9925 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9926 [(set (match_operand:DI 0 "register_operand" "=r")
9928 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9929 (match_operand:SI 2 "register_operand" "r"))))]
9930 "TARGET_64BIT && TARGET_BMI2"
9931 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9932 [(set_attr "type" "ishiftx")
9933 (set_attr "mode" "SI")])
9935 (define_insn "*<shift_insn>si3_1_zext"
9936 [(set (match_operand:DI 0 "register_operand" "=r,r")
9938 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9939 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9940 (clobber (reg:CC FLAGS_REG))]
9941 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9943 switch (get_attr_type (insn))
9949 if (operands[2] == const1_rtx
9950 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9951 return "<shift>{l}\t%k0";
9953 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9956 [(set_attr "isa" "*,bmi2")
9957 (set_attr "type" "ishift,ishiftx")
9958 (set (attr "length_immediate")
9960 (and (match_operand 2 "const1_operand")
9961 (ior (match_test "TARGET_SHIFT1")
9962 (match_test "optimize_function_for_size_p (cfun)")))
9964 (const_string "*")))
9965 (set_attr "mode" "SI")])
9967 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9969 [(set (match_operand:DI 0 "register_operand")
9971 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9972 (match_operand:QI 2 "register_operand"))))
9973 (clobber (reg:CC FLAGS_REG))]
9974 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9976 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9977 "operands[2] = gen_lowpart (SImode, operands[2]);")
9979 (define_insn "*<shift_insn><mode>3_1"
9980 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9982 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9983 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9984 (clobber (reg:CC FLAGS_REG))]
9985 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9987 if (operands[2] == const1_rtx
9988 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9989 return "<shift>{<imodesuffix>}\t%0";
9991 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9993 [(set_attr "type" "ishift")
9994 (set (attr "length_immediate")
9996 (and (match_operand 2 "const1_operand")
9997 (ior (match_test "TARGET_SHIFT1")
9998 (match_test "optimize_function_for_size_p (cfun)")))
10000 (const_string "*")))
10001 (set_attr "mode" "<MODE>")])
10003 (define_insn "*<shift_insn>qi3_1_slp"
10004 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10005 (any_shiftrt:QI (match_dup 0)
10006 (match_operand:QI 1 "nonmemory_operand" "cI")))
10007 (clobber (reg:CC FLAGS_REG))]
10008 "(optimize_function_for_size_p (cfun)
10009 || !TARGET_PARTIAL_REG_STALL
10010 || (operands[1] == const1_rtx
10011 && TARGET_SHIFT1))"
10013 if (operands[1] == const1_rtx
10014 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10015 return "<shift>{b}\t%0";
10017 return "<shift>{b}\t{%1, %0|%0, %1}";
10019 [(set_attr "type" "ishift1")
10020 (set (attr "length_immediate")
10022 (and (match_operand 1 "const1_operand")
10023 (ior (match_test "TARGET_SHIFT1")
10024 (match_test "optimize_function_for_size_p (cfun)")))
10026 (const_string "*")))
10027 (set_attr "mode" "QI")])
10029 ;; This pattern can't accept a variable shift count, since shifts by
10030 ;; zero don't affect the flags. We assume that shifts by constant
10031 ;; zero are optimized away.
10032 (define_insn "*<shift_insn><mode>3_cmp"
10033 [(set (reg FLAGS_REG)
10036 (match_operand:SWI 1 "nonimmediate_operand" "0")
10037 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10039 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10040 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10041 "(optimize_function_for_size_p (cfun)
10042 || !TARGET_PARTIAL_FLAG_REG_STALL
10043 || (operands[2] == const1_rtx
10045 && ix86_match_ccmode (insn, CCGOCmode)
10046 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10048 if (operands[2] == const1_rtx
10049 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10050 return "<shift>{<imodesuffix>}\t%0";
10052 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10054 [(set_attr "type" "ishift")
10055 (set (attr "length_immediate")
10057 (and (match_operand 2 "const1_operand")
10058 (ior (match_test "TARGET_SHIFT1")
10059 (match_test "optimize_function_for_size_p (cfun)")))
10061 (const_string "*")))
10062 (set_attr "mode" "<MODE>")])
10064 (define_insn "*<shift_insn>si3_cmp_zext"
10065 [(set (reg FLAGS_REG)
10067 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10068 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10070 (set (match_operand:DI 0 "register_operand" "=r")
10071 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10073 && (optimize_function_for_size_p (cfun)
10074 || !TARGET_PARTIAL_FLAG_REG_STALL
10075 || (operands[2] == const1_rtx
10077 && ix86_match_ccmode (insn, CCGOCmode)
10078 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10080 if (operands[2] == const1_rtx
10081 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10082 return "<shift>{l}\t%k0";
10084 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10086 [(set_attr "type" "ishift")
10087 (set (attr "length_immediate")
10089 (and (match_operand 2 "const1_operand")
10090 (ior (match_test "TARGET_SHIFT1")
10091 (match_test "optimize_function_for_size_p (cfun)")))
10093 (const_string "*")))
10094 (set_attr "mode" "SI")])
10096 (define_insn "*<shift_insn><mode>3_cconly"
10097 [(set (reg FLAGS_REG)
10100 (match_operand:SWI 1 "register_operand" "0")
10101 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10103 (clobber (match_scratch:SWI 0 "=<r>"))]
10104 "(optimize_function_for_size_p (cfun)
10105 || !TARGET_PARTIAL_FLAG_REG_STALL
10106 || (operands[2] == const1_rtx
10108 && ix86_match_ccmode (insn, CCGOCmode)"
10110 if (operands[2] == const1_rtx
10111 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10112 return "<shift>{<imodesuffix>}\t%0";
10114 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10116 [(set_attr "type" "ishift")
10117 (set (attr "length_immediate")
10119 (and (match_operand 2 "const1_operand")
10120 (ior (match_test "TARGET_SHIFT1")
10121 (match_test "optimize_function_for_size_p (cfun)")))
10123 (const_string "*")))
10124 (set_attr "mode" "<MODE>")])
10126 ;; Rotate instructions
10128 (define_expand "<rotate_insn>ti3"
10129 [(set (match_operand:TI 0 "register_operand")
10130 (any_rotate:TI (match_operand:TI 1 "register_operand")
10131 (match_operand:QI 2 "nonmemory_operand")))]
10134 if (const_1_to_63_operand (operands[2], VOIDmode))
10135 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10136 (operands[0], operands[1], operands[2]));
10143 (define_expand "<rotate_insn>di3"
10144 [(set (match_operand:DI 0 "shiftdi_operand")
10145 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10146 (match_operand:QI 2 "nonmemory_operand")))]
10150 ix86_expand_binary_operator (<CODE>, DImode, operands);
10151 else if (const_1_to_31_operand (operands[2], VOIDmode))
10152 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10153 (operands[0], operands[1], operands[2]));
10160 (define_expand "<rotate_insn><mode>3"
10161 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10162 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10163 (match_operand:QI 2 "nonmemory_operand")))]
10165 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10167 ;; Avoid useless masking of count operand.
10168 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10169 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10171 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10174 (match_operand:SI 2 "nonimmediate_operand" "c")
10175 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10176 (clobber (reg:CC FLAGS_REG))]
10177 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10178 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10179 == GET_MODE_BITSIZE (<MODE>mode)-1"
10182 [(parallel [(set (match_dup 0)
10183 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10184 (clobber (reg:CC FLAGS_REG))])]
10186 if (can_create_pseudo_p ())
10187 operands [2] = force_reg (SImode, operands[2]);
10189 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10191 [(set_attr "type" "rotate")
10192 (set_attr "mode" "<MODE>")])
10194 ;; Implement rotation using two double-precision
10195 ;; shift instructions and a scratch register.
10197 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10198 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10199 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10200 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10201 (clobber (reg:CC FLAGS_REG))
10202 (clobber (match_scratch:DWIH 3 "=&r"))]
10206 [(set (match_dup 3) (match_dup 4))
10208 [(set (match_dup 4)
10209 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10210 (lshiftrt:DWIH (match_dup 5)
10211 (minus:QI (match_dup 6) (match_dup 2)))))
10212 (clobber (reg:CC FLAGS_REG))])
10214 [(set (match_dup 5)
10215 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10216 (lshiftrt:DWIH (match_dup 3)
10217 (minus:QI (match_dup 6) (match_dup 2)))))
10218 (clobber (reg:CC FLAGS_REG))])]
10220 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10222 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10225 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10226 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10227 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10228 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10229 (clobber (reg:CC FLAGS_REG))
10230 (clobber (match_scratch:DWIH 3 "=&r"))]
10234 [(set (match_dup 3) (match_dup 4))
10236 [(set (match_dup 4)
10237 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10238 (ashift:DWIH (match_dup 5)
10239 (minus:QI (match_dup 6) (match_dup 2)))))
10240 (clobber (reg:CC FLAGS_REG))])
10242 [(set (match_dup 5)
10243 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10244 (ashift:DWIH (match_dup 3)
10245 (minus:QI (match_dup 6) (match_dup 2)))))
10246 (clobber (reg:CC FLAGS_REG))])]
10248 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10250 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10253 (define_insn "*bmi2_rorx<mode>3_1"
10254 [(set (match_operand:SWI48 0 "register_operand" "=r")
10255 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10256 (match_operand:QI 2 "immediate_operand" "<S>")))]
10258 "rorx\t{%2, %1, %0|%0, %1, %2}"
10259 [(set_attr "type" "rotatex")
10260 (set_attr "mode" "<MODE>")])
10262 (define_insn "*<rotate_insn><mode>3_1"
10263 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10265 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10266 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10267 (clobber (reg:CC FLAGS_REG))]
10268 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10270 switch (get_attr_type (insn))
10276 if (operands[2] == const1_rtx
10277 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10278 return "<rotate>{<imodesuffix>}\t%0";
10280 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10283 [(set_attr "isa" "*,bmi2")
10284 (set_attr "type" "rotate,rotatex")
10285 (set (attr "length_immediate")
10287 (and (eq_attr "type" "rotate")
10288 (and (match_operand 2 "const1_operand")
10289 (ior (match_test "TARGET_SHIFT1")
10290 (match_test "optimize_function_for_size_p (cfun)"))))
10292 (const_string "*")))
10293 (set_attr "mode" "<MODE>")])
10295 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10297 [(set (match_operand:SWI48 0 "register_operand")
10298 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10299 (match_operand:QI 2 "immediate_operand")))
10300 (clobber (reg:CC FLAGS_REG))]
10301 "TARGET_BMI2 && reload_completed"
10302 [(set (match_dup 0)
10303 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10306 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10310 [(set (match_operand:SWI48 0 "register_operand")
10311 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10312 (match_operand:QI 2 "immediate_operand")))
10313 (clobber (reg:CC FLAGS_REG))]
10314 "TARGET_BMI2 && reload_completed"
10315 [(set (match_dup 0)
10316 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10318 (define_insn "*bmi2_rorxsi3_1_zext"
10319 [(set (match_operand:DI 0 "register_operand" "=r")
10321 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10322 (match_operand:QI 2 "immediate_operand" "I"))))]
10323 "TARGET_64BIT && TARGET_BMI2"
10324 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10325 [(set_attr "type" "rotatex")
10326 (set_attr "mode" "SI")])
10328 (define_insn "*<rotate_insn>si3_1_zext"
10329 [(set (match_operand:DI 0 "register_operand" "=r,r")
10331 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10332 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10333 (clobber (reg:CC FLAGS_REG))]
10334 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10336 switch (get_attr_type (insn))
10342 if (operands[2] == const1_rtx
10343 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10344 return "<rotate>{l}\t%k0";
10346 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10349 [(set_attr "isa" "*,bmi2")
10350 (set_attr "type" "rotate,rotatex")
10351 (set (attr "length_immediate")
10353 (and (eq_attr "type" "rotate")
10354 (and (match_operand 2 "const1_operand")
10355 (ior (match_test "TARGET_SHIFT1")
10356 (match_test "optimize_function_for_size_p (cfun)"))))
10358 (const_string "*")))
10359 (set_attr "mode" "SI")])
10361 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10363 [(set (match_operand:DI 0 "register_operand")
10365 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10366 (match_operand:QI 2 "immediate_operand"))))
10367 (clobber (reg:CC FLAGS_REG))]
10368 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10369 [(set (match_dup 0)
10370 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10373 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10377 [(set (match_operand:DI 0 "register_operand")
10379 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10380 (match_operand:QI 2 "immediate_operand"))))
10381 (clobber (reg:CC FLAGS_REG))]
10382 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10383 [(set (match_dup 0)
10384 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10386 (define_insn "*<rotate_insn><mode>3_1"
10387 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10388 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10389 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10390 (clobber (reg:CC FLAGS_REG))]
10391 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10393 if (operands[2] == const1_rtx
10394 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10395 return "<rotate>{<imodesuffix>}\t%0";
10397 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10399 [(set_attr "type" "rotate")
10400 (set (attr "length_immediate")
10402 (and (match_operand 2 "const1_operand")
10403 (ior (match_test "TARGET_SHIFT1")
10404 (match_test "optimize_function_for_size_p (cfun)")))
10406 (const_string "*")))
10407 (set_attr "mode" "<MODE>")])
10409 (define_insn "*<rotate_insn>qi3_1_slp"
10410 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10411 (any_rotate:QI (match_dup 0)
10412 (match_operand:QI 1 "nonmemory_operand" "cI")))
10413 (clobber (reg:CC FLAGS_REG))]
10414 "(optimize_function_for_size_p (cfun)
10415 || !TARGET_PARTIAL_REG_STALL
10416 || (operands[1] == const1_rtx
10417 && TARGET_SHIFT1))"
10419 if (operands[1] == const1_rtx
10420 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10421 return "<rotate>{b}\t%0";
10423 return "<rotate>{b}\t{%1, %0|%0, %1}";
10425 [(set_attr "type" "rotate1")
10426 (set (attr "length_immediate")
10428 (and (match_operand 1 "const1_operand")
10429 (ior (match_test "TARGET_SHIFT1")
10430 (match_test "optimize_function_for_size_p (cfun)")))
10432 (const_string "*")))
10433 (set_attr "mode" "QI")])
10436 [(set (match_operand:HI 0 "register_operand")
10437 (any_rotate:HI (match_dup 0) (const_int 8)))
10438 (clobber (reg:CC FLAGS_REG))]
10440 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10441 [(parallel [(set (strict_low_part (match_dup 0))
10442 (bswap:HI (match_dup 0)))
10443 (clobber (reg:CC FLAGS_REG))])])
10445 ;; Bit set / bit test instructions
10447 (define_expand "extv"
10448 [(set (match_operand:SI 0 "register_operand")
10449 (sign_extract:SI (match_operand:SI 1 "register_operand")
10450 (match_operand:SI 2 "const8_operand")
10451 (match_operand:SI 3 "const8_operand")))]
10454 /* Handle extractions from %ah et al. */
10455 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10458 /* From mips.md: extract_bit_field doesn't verify that our source
10459 matches the predicate, so check it again here. */
10460 if (! ext_register_operand (operands[1], VOIDmode))
10464 (define_expand "extzv"
10465 [(set (match_operand:SI 0 "register_operand")
10466 (zero_extract:SI (match_operand 1 "ext_register_operand")
10467 (match_operand:SI 2 "const8_operand")
10468 (match_operand:SI 3 "const8_operand")))]
10471 /* Handle extractions from %ah et al. */
10472 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10475 /* From mips.md: extract_bit_field doesn't verify that our source
10476 matches the predicate, so check it again here. */
10477 if (! ext_register_operand (operands[1], VOIDmode))
10481 (define_expand "insv"
10482 [(set (zero_extract (match_operand 0 "register_operand")
10483 (match_operand 1 "const_int_operand")
10484 (match_operand 2 "const_int_operand"))
10485 (match_operand 3 "register_operand"))]
10488 rtx (*gen_mov_insv_1) (rtx, rtx);
10490 if (ix86_expand_pinsr (operands))
10493 /* Handle insertions to %ah et al. */
10494 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10497 /* From mips.md: insert_bit_field doesn't verify that our source
10498 matches the predicate, so check it again here. */
10499 if (! ext_register_operand (operands[0], VOIDmode))
10502 gen_mov_insv_1 = (TARGET_64BIT
10503 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10505 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10509 ;; %%% bts, btr, btc, bt.
10510 ;; In general these instructions are *slow* when applied to memory,
10511 ;; since they enforce atomic operation. When applied to registers,
10512 ;; it depends on the cpu implementation. They're never faster than
10513 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10514 ;; no point. But in 64-bit, we can't hold the relevant immediates
10515 ;; within the instruction itself, so operating on bits in the high
10516 ;; 32-bits of a register becomes easier.
10518 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10519 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10520 ;; negdf respectively, so they can never be disabled entirely.
10522 (define_insn "*btsq"
10523 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10525 (match_operand:DI 1 "const_0_to_63_operand"))
10527 (clobber (reg:CC FLAGS_REG))]
10528 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10529 "bts{q}\t{%1, %0|%0, %1}"
10530 [(set_attr "type" "alu1")
10531 (set_attr "prefix_0f" "1")
10532 (set_attr "mode" "DI")])
10534 (define_insn "*btrq"
10535 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10537 (match_operand:DI 1 "const_0_to_63_operand"))
10539 (clobber (reg:CC FLAGS_REG))]
10540 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10541 "btr{q}\t{%1, %0|%0, %1}"
10542 [(set_attr "type" "alu1")
10543 (set_attr "prefix_0f" "1")
10544 (set_attr "mode" "DI")])
10546 (define_insn "*btcq"
10547 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10549 (match_operand:DI 1 "const_0_to_63_operand"))
10550 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10551 (clobber (reg:CC FLAGS_REG))]
10552 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10553 "btc{q}\t{%1, %0|%0, %1}"
10554 [(set_attr "type" "alu1")
10555 (set_attr "prefix_0f" "1")
10556 (set_attr "mode" "DI")])
10558 ;; Allow Nocona to avoid these instructions if a register is available.
10561 [(match_scratch:DI 2 "r")
10562 (parallel [(set (zero_extract:DI
10563 (match_operand:DI 0 "register_operand")
10565 (match_operand:DI 1 "const_0_to_63_operand"))
10567 (clobber (reg:CC FLAGS_REG))])]
10568 "TARGET_64BIT && !TARGET_USE_BT"
10571 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10574 if (HOST_BITS_PER_WIDE_INT >= 64)
10575 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10576 else if (i < HOST_BITS_PER_WIDE_INT)
10577 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10579 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10581 op1 = immed_double_const (lo, hi, DImode);
10584 emit_move_insn (operands[2], op1);
10588 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10593 [(match_scratch:DI 2 "r")
10594 (parallel [(set (zero_extract:DI
10595 (match_operand:DI 0 "register_operand")
10597 (match_operand:DI 1 "const_0_to_63_operand"))
10599 (clobber (reg:CC FLAGS_REG))])]
10600 "TARGET_64BIT && !TARGET_USE_BT"
10603 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10606 if (HOST_BITS_PER_WIDE_INT >= 64)
10607 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10608 else if (i < HOST_BITS_PER_WIDE_INT)
10609 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10611 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10613 op1 = immed_double_const (~lo, ~hi, DImode);
10616 emit_move_insn (operands[2], op1);
10620 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10625 [(match_scratch:DI 2 "r")
10626 (parallel [(set (zero_extract:DI
10627 (match_operand:DI 0 "register_operand")
10629 (match_operand:DI 1 "const_0_to_63_operand"))
10630 (not:DI (zero_extract:DI
10631 (match_dup 0) (const_int 1) (match_dup 1))))
10632 (clobber (reg:CC FLAGS_REG))])]
10633 "TARGET_64BIT && !TARGET_USE_BT"
10636 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10639 if (HOST_BITS_PER_WIDE_INT >= 64)
10640 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10641 else if (i < HOST_BITS_PER_WIDE_INT)
10642 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10644 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10646 op1 = immed_double_const (lo, hi, DImode);
10649 emit_move_insn (operands[2], op1);
10653 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10657 (define_insn "*bt<mode>"
10658 [(set (reg:CCC FLAGS_REG)
10660 (zero_extract:SWI48
10661 (match_operand:SWI48 0 "register_operand" "r")
10663 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10665 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10666 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10667 [(set_attr "type" "alu1")
10668 (set_attr "prefix_0f" "1")
10669 (set_attr "mode" "<MODE>")])
10671 ;; Store-flag instructions.
10673 ;; For all sCOND expanders, also expand the compare or test insn that
10674 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10676 (define_insn_and_split "*setcc_di_1"
10677 [(set (match_operand:DI 0 "register_operand" "=q")
10678 (match_operator:DI 1 "ix86_comparison_operator"
10679 [(reg FLAGS_REG) (const_int 0)]))]
10680 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10682 "&& reload_completed"
10683 [(set (match_dup 2) (match_dup 1))
10684 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10686 PUT_MODE (operands[1], QImode);
10687 operands[2] = gen_lowpart (QImode, operands[0]);
10690 (define_insn_and_split "*setcc_si_1_and"
10691 [(set (match_operand:SI 0 "register_operand" "=q")
10692 (match_operator:SI 1 "ix86_comparison_operator"
10693 [(reg FLAGS_REG) (const_int 0)]))
10694 (clobber (reg:CC FLAGS_REG))]
10695 "!TARGET_PARTIAL_REG_STALL
10696 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10698 "&& reload_completed"
10699 [(set (match_dup 2) (match_dup 1))
10700 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10701 (clobber (reg:CC FLAGS_REG))])]
10703 PUT_MODE (operands[1], QImode);
10704 operands[2] = gen_lowpart (QImode, operands[0]);
10707 (define_insn_and_split "*setcc_si_1_movzbl"
10708 [(set (match_operand:SI 0 "register_operand" "=q")
10709 (match_operator:SI 1 "ix86_comparison_operator"
10710 [(reg FLAGS_REG) (const_int 0)]))]
10711 "!TARGET_PARTIAL_REG_STALL
10712 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10714 "&& reload_completed"
10715 [(set (match_dup 2) (match_dup 1))
10716 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10718 PUT_MODE (operands[1], QImode);
10719 operands[2] = gen_lowpart (QImode, operands[0]);
10722 (define_insn "*setcc_qi"
10723 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10724 (match_operator:QI 1 "ix86_comparison_operator"
10725 [(reg FLAGS_REG) (const_int 0)]))]
10728 [(set_attr "type" "setcc")
10729 (set_attr "mode" "QI")])
10731 (define_insn "*setcc_qi_slp"
10732 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10733 (match_operator:QI 1 "ix86_comparison_operator"
10734 [(reg FLAGS_REG) (const_int 0)]))]
10737 [(set_attr "type" "setcc")
10738 (set_attr "mode" "QI")])
10740 ;; In general it is not safe to assume too much about CCmode registers,
10741 ;; so simplify-rtx stops when it sees a second one. Under certain
10742 ;; conditions this is safe on x86, so help combine not create
10749 [(set (match_operand:QI 0 "nonimmediate_operand")
10750 (ne:QI (match_operator 1 "ix86_comparison_operator"
10751 [(reg FLAGS_REG) (const_int 0)])
10754 [(set (match_dup 0) (match_dup 1))]
10755 "PUT_MODE (operands[1], QImode);")
10758 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10759 (ne:QI (match_operator 1 "ix86_comparison_operator"
10760 [(reg FLAGS_REG) (const_int 0)])
10763 [(set (match_dup 0) (match_dup 1))]
10764 "PUT_MODE (operands[1], QImode);")
10767 [(set (match_operand:QI 0 "nonimmediate_operand")
10768 (eq:QI (match_operator 1 "ix86_comparison_operator"
10769 [(reg FLAGS_REG) (const_int 0)])
10772 [(set (match_dup 0) (match_dup 1))]
10774 rtx new_op1 = copy_rtx (operands[1]);
10775 operands[1] = new_op1;
10776 PUT_MODE (new_op1, QImode);
10777 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10778 GET_MODE (XEXP (new_op1, 0))));
10780 /* Make sure that (a) the CCmode we have for the flags is strong
10781 enough for the reversed compare or (b) we have a valid FP compare. */
10782 if (! ix86_comparison_operator (new_op1, VOIDmode))
10787 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10788 (eq:QI (match_operator 1 "ix86_comparison_operator"
10789 [(reg FLAGS_REG) (const_int 0)])
10792 [(set (match_dup 0) (match_dup 1))]
10794 rtx new_op1 = copy_rtx (operands[1]);
10795 operands[1] = new_op1;
10796 PUT_MODE (new_op1, QImode);
10797 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10798 GET_MODE (XEXP (new_op1, 0))));
10800 /* Make sure that (a) the CCmode we have for the flags is strong
10801 enough for the reversed compare or (b) we have a valid FP compare. */
10802 if (! ix86_comparison_operator (new_op1, VOIDmode))
10806 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10807 ;; subsequent logical operations are used to imitate conditional moves.
10808 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10811 (define_insn "setcc_<mode>_sse"
10812 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10813 (match_operator:MODEF 3 "sse_comparison_operator"
10814 [(match_operand:MODEF 1 "register_operand" "0,x")
10815 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10816 "SSE_FLOAT_MODE_P (<MODE>mode)"
10818 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10819 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10820 [(set_attr "isa" "noavx,avx")
10821 (set_attr "type" "ssecmp")
10822 (set_attr "length_immediate" "1")
10823 (set_attr "prefix" "orig,vex")
10824 (set_attr "mode" "<MODE>")])
10826 ;; Basic conditional jump instructions.
10827 ;; We ignore the overflow flag for signed branch instructions.
10829 (define_insn "*jcc_1"
10831 (if_then_else (match_operator 1 "ix86_comparison_operator"
10832 [(reg FLAGS_REG) (const_int 0)])
10833 (label_ref (match_operand 0))
10837 [(set_attr "type" "ibr")
10838 (set_attr "modrm" "0")
10839 (set (attr "length")
10840 (if_then_else (and (ge (minus (match_dup 0) (pc))
10842 (lt (minus (match_dup 0) (pc))
10847 (define_insn "*jcc_2"
10849 (if_then_else (match_operator 1 "ix86_comparison_operator"
10850 [(reg FLAGS_REG) (const_int 0)])
10852 (label_ref (match_operand 0))))]
10855 [(set_attr "type" "ibr")
10856 (set_attr "modrm" "0")
10857 (set (attr "length")
10858 (if_then_else (and (ge (minus (match_dup 0) (pc))
10860 (lt (minus (match_dup 0) (pc))
10865 ;; In general it is not safe to assume too much about CCmode registers,
10866 ;; so simplify-rtx stops when it sees a second one. Under certain
10867 ;; conditions this is safe on x86, so help combine not create
10875 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10876 [(reg FLAGS_REG) (const_int 0)])
10878 (label_ref (match_operand 1))
10882 (if_then_else (match_dup 0)
10883 (label_ref (match_dup 1))
10885 "PUT_MODE (operands[0], VOIDmode);")
10889 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10890 [(reg FLAGS_REG) (const_int 0)])
10892 (label_ref (match_operand 1))
10896 (if_then_else (match_dup 0)
10897 (label_ref (match_dup 1))
10900 rtx new_op0 = copy_rtx (operands[0]);
10901 operands[0] = new_op0;
10902 PUT_MODE (new_op0, VOIDmode);
10903 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10904 GET_MODE (XEXP (new_op0, 0))));
10906 /* Make sure that (a) the CCmode we have for the flags is strong
10907 enough for the reversed compare or (b) we have a valid FP compare. */
10908 if (! ix86_comparison_operator (new_op0, VOIDmode))
10912 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10913 ;; pass generates from shift insn with QImode operand. Actually, the mode
10914 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10915 ;; appropriate modulo of the bit offset value.
10917 (define_insn_and_split "*jcc_bt<mode>"
10919 (if_then_else (match_operator 0 "bt_comparison_operator"
10920 [(zero_extract:SWI48
10921 (match_operand:SWI48 1 "register_operand" "r")
10924 (match_operand:QI 2 "register_operand" "r")))
10926 (label_ref (match_operand 3))
10928 (clobber (reg:CC FLAGS_REG))]
10929 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10932 [(set (reg:CCC FLAGS_REG)
10934 (zero_extract:SWI48
10940 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10941 (label_ref (match_dup 3))
10944 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10946 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10949 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10950 ;; also for DImode, this is what combine produces.
10951 (define_insn_and_split "*jcc_bt<mode>_mask"
10953 (if_then_else (match_operator 0 "bt_comparison_operator"
10954 [(zero_extract:SWI48
10955 (match_operand:SWI48 1 "register_operand" "r")
10958 (match_operand:SI 2 "register_operand" "r")
10959 (match_operand:SI 3 "const_int_operand" "n")))])
10960 (label_ref (match_operand 4))
10962 (clobber (reg:CC FLAGS_REG))]
10963 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10964 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10965 == GET_MODE_BITSIZE (<MODE>mode)-1"
10968 [(set (reg:CCC FLAGS_REG)
10970 (zero_extract:SWI48
10976 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10977 (label_ref (match_dup 4))
10980 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10982 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10985 (define_insn_and_split "*jcc_btsi_1"
10987 (if_then_else (match_operator 0 "bt_comparison_operator"
10990 (match_operand:SI 1 "register_operand" "r")
10991 (match_operand:QI 2 "register_operand" "r"))
10994 (label_ref (match_operand 3))
10996 (clobber (reg:CC FLAGS_REG))]
10997 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11000 [(set (reg:CCC FLAGS_REG)
11008 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11009 (label_ref (match_dup 3))
11012 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11014 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11017 ;; avoid useless masking of bit offset operand
11018 (define_insn_and_split "*jcc_btsi_mask_1"
11021 (match_operator 0 "bt_comparison_operator"
11024 (match_operand:SI 1 "register_operand" "r")
11027 (match_operand:SI 2 "register_operand" "r")
11028 (match_operand:SI 3 "const_int_operand" "n")) 0))
11031 (label_ref (match_operand 4))
11033 (clobber (reg:CC FLAGS_REG))]
11034 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11035 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11038 [(set (reg:CCC FLAGS_REG)
11046 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11047 (label_ref (match_dup 4))
11049 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11051 ;; Define combination compare-and-branch fp compare instructions to help
11054 (define_insn "*fp_jcc_1_387"
11056 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11057 [(match_operand 1 "register_operand" "f")
11058 (match_operand 2 "nonimmediate_operand" "fm")])
11059 (label_ref (match_operand 3))
11061 (clobber (reg:CCFP FPSR_REG))
11062 (clobber (reg:CCFP FLAGS_REG))
11063 (clobber (match_scratch:HI 4 "=a"))]
11065 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11066 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11067 && SELECT_CC_MODE (GET_CODE (operands[0]),
11068 operands[1], operands[2]) == CCFPmode
11072 (define_insn "*fp_jcc_1r_387"
11074 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11075 [(match_operand 1 "register_operand" "f")
11076 (match_operand 2 "nonimmediate_operand" "fm")])
11078 (label_ref (match_operand 3))))
11079 (clobber (reg:CCFP FPSR_REG))
11080 (clobber (reg:CCFP FLAGS_REG))
11081 (clobber (match_scratch:HI 4 "=a"))]
11083 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11084 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11085 && SELECT_CC_MODE (GET_CODE (operands[0]),
11086 operands[1], operands[2]) == CCFPmode
11090 (define_insn "*fp_jcc_2_387"
11092 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11093 [(match_operand 1 "register_operand" "f")
11094 (match_operand 2 "register_operand" "f")])
11095 (label_ref (match_operand 3))
11097 (clobber (reg:CCFP FPSR_REG))
11098 (clobber (reg:CCFP FLAGS_REG))
11099 (clobber (match_scratch:HI 4 "=a"))]
11100 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11101 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11105 (define_insn "*fp_jcc_2r_387"
11107 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11108 [(match_operand 1 "register_operand" "f")
11109 (match_operand 2 "register_operand" "f")])
11111 (label_ref (match_operand 3))))
11112 (clobber (reg:CCFP FPSR_REG))
11113 (clobber (reg:CCFP FLAGS_REG))
11114 (clobber (match_scratch:HI 4 "=a"))]
11115 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11116 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11120 (define_insn "*fp_jcc_3_387"
11122 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11123 [(match_operand 1 "register_operand" "f")
11124 (match_operand 2 "const0_operand")])
11125 (label_ref (match_operand 3))
11127 (clobber (reg:CCFP FPSR_REG))
11128 (clobber (reg:CCFP FLAGS_REG))
11129 (clobber (match_scratch:HI 4 "=a"))]
11130 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11131 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11132 && SELECT_CC_MODE (GET_CODE (operands[0]),
11133 operands[1], operands[2]) == CCFPmode
11139 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11140 [(match_operand 1 "register_operand")
11141 (match_operand 2 "nonimmediate_operand")])
11143 (match_operand 4)))
11144 (clobber (reg:CCFP FPSR_REG))
11145 (clobber (reg:CCFP FLAGS_REG))]
11149 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11150 operands[3], operands[4], NULL_RTX, NULL_RTX);
11156 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11157 [(match_operand 1 "register_operand")
11158 (match_operand 2 "general_operand")])
11160 (match_operand 4)))
11161 (clobber (reg:CCFP FPSR_REG))
11162 (clobber (reg:CCFP FLAGS_REG))
11163 (clobber (match_scratch:HI 5 "=a"))]
11167 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11168 operands[3], operands[4], operands[5], NULL_RTX);
11172 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11173 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11174 ;; with a precedence over other operators and is always put in the first
11175 ;; place. Swap condition and operands to match ficom instruction.
11177 (define_insn "*fp_jcc_4_<mode>_387"
11180 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11181 [(match_operator 1 "float_operator"
11182 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11183 (match_operand 3 "register_operand" "f,f")])
11184 (label_ref (match_operand 4))
11186 (clobber (reg:CCFP FPSR_REG))
11187 (clobber (reg:CCFP FLAGS_REG))
11188 (clobber (match_scratch:HI 5 "=a,a"))]
11189 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11190 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11191 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11192 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11199 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11200 [(match_operator 1 "float_operator"
11201 [(match_operand:SWI24 2 "memory_operand")])
11202 (match_operand 3 "register_operand")])
11204 (match_operand 5)))
11205 (clobber (reg:CCFP FPSR_REG))
11206 (clobber (reg:CCFP FLAGS_REG))
11207 (clobber (match_scratch:HI 6 "=a"))]
11211 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11213 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11214 operands[3], operands[7],
11215 operands[4], operands[5], operands[6], NULL_RTX);
11219 ;; %%% Kill this when reload knows how to do it.
11223 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11224 [(match_operator 1 "float_operator"
11225 [(match_operand:SWI24 2 "register_operand")])
11226 (match_operand 3 "register_operand")])
11228 (match_operand 5)))
11229 (clobber (reg:CCFP FPSR_REG))
11230 (clobber (reg:CCFP FLAGS_REG))
11231 (clobber (match_scratch:HI 6 "=a"))]
11235 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11236 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11238 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11239 operands[3], operands[7],
11240 operands[4], operands[5], operands[6], operands[2]);
11244 ;; Unconditional and other jump instructions
11246 (define_insn "jump"
11248 (label_ref (match_operand 0)))]
11251 [(set_attr "type" "ibr")
11252 (set (attr "length")
11253 (if_then_else (and (ge (minus (match_dup 0) (pc))
11255 (lt (minus (match_dup 0) (pc))
11259 (set_attr "modrm" "0")])
11261 (define_expand "indirect_jump"
11262 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11266 operands[0] = convert_memory_address (word_mode, operands[0]);
11269 (define_insn "*indirect_jump"
11270 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11273 [(set_attr "type" "ibr")
11274 (set_attr "length_immediate" "0")])
11276 (define_expand "tablejump"
11277 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11278 (use (label_ref (match_operand 1)))])]
11281 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11282 relative. Convert the relative address to an absolute address. */
11286 enum rtx_code code;
11288 /* We can't use @GOTOFF for text labels on VxWorks;
11289 see gotoff_operand. */
11290 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11294 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11296 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11300 op1 = pic_offset_table_rtx;
11305 op0 = pic_offset_table_rtx;
11309 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11314 operands[0] = convert_memory_address (word_mode, operands[0]);
11317 (define_insn "*tablejump_1"
11318 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11319 (use (label_ref (match_operand 1)))]
11322 [(set_attr "type" "ibr")
11323 (set_attr "length_immediate" "0")])
11325 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11328 [(set (reg FLAGS_REG) (match_operand 0))
11329 (set (match_operand:QI 1 "register_operand")
11330 (match_operator:QI 2 "ix86_comparison_operator"
11331 [(reg FLAGS_REG) (const_int 0)]))
11332 (set (match_operand 3 "q_regs_operand")
11333 (zero_extend (match_dup 1)))]
11334 "(peep2_reg_dead_p (3, operands[1])
11335 || operands_match_p (operands[1], operands[3]))
11336 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11337 [(set (match_dup 4) (match_dup 0))
11338 (set (strict_low_part (match_dup 5))
11341 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11342 operands[5] = gen_lowpart (QImode, operands[3]);
11343 ix86_expand_clear (operands[3]);
11347 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11348 (match_operand 4)])
11349 (set (match_operand:QI 1 "register_operand")
11350 (match_operator:QI 2 "ix86_comparison_operator"
11351 [(reg FLAGS_REG) (const_int 0)]))
11352 (set (match_operand 3 "q_regs_operand")
11353 (zero_extend (match_dup 1)))]
11354 "(peep2_reg_dead_p (3, operands[1])
11355 || operands_match_p (operands[1], operands[3]))
11356 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11357 [(parallel [(set (match_dup 5) (match_dup 0))
11359 (set (strict_low_part (match_dup 6))
11362 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11363 operands[6] = gen_lowpart (QImode, operands[3]);
11364 ix86_expand_clear (operands[3]);
11367 ;; Similar, but match zero extend with andsi3.
11370 [(set (reg FLAGS_REG) (match_operand 0))
11371 (set (match_operand:QI 1 "register_operand")
11372 (match_operator:QI 2 "ix86_comparison_operator"
11373 [(reg FLAGS_REG) (const_int 0)]))
11374 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11375 (and:SI (match_dup 3) (const_int 255)))
11376 (clobber (reg:CC FLAGS_REG))])]
11377 "REGNO (operands[1]) == REGNO (operands[3])
11378 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11379 [(set (match_dup 4) (match_dup 0))
11380 (set (strict_low_part (match_dup 5))
11383 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11384 operands[5] = gen_lowpart (QImode, operands[3]);
11385 ix86_expand_clear (operands[3]);
11389 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11390 (match_operand 4)])
11391 (set (match_operand:QI 1 "register_operand")
11392 (match_operator:QI 2 "ix86_comparison_operator"
11393 [(reg FLAGS_REG) (const_int 0)]))
11394 (parallel [(set (match_operand 3 "q_regs_operand")
11395 (zero_extend (match_dup 1)))
11396 (clobber (reg:CC FLAGS_REG))])]
11397 "(peep2_reg_dead_p (3, operands[1])
11398 || operands_match_p (operands[1], operands[3]))
11399 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11400 [(parallel [(set (match_dup 5) (match_dup 0))
11402 (set (strict_low_part (match_dup 6))
11405 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11406 operands[6] = gen_lowpart (QImode, operands[3]);
11407 ix86_expand_clear (operands[3]);
11410 ;; Call instructions.
11412 ;; The predicates normally associated with named expanders are not properly
11413 ;; checked for calls. This is a bug in the generic code, but it isn't that
11414 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11416 ;; P6 processors will jump to the address after the decrement when %esp
11417 ;; is used as a call operand, so they will execute return address as a code.
11418 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11420 ;; Register constraint for call instruction.
11421 (define_mode_attr c [(SI "l") (DI "r")])
11423 ;; Call subroutine returning no value.
11425 (define_expand "call"
11426 [(call (match_operand:QI 0)
11428 (use (match_operand 2))]
11431 ix86_expand_call (NULL, operands[0], operands[1],
11432 operands[2], NULL, false);
11436 (define_expand "sibcall"
11437 [(call (match_operand:QI 0)
11439 (use (match_operand 2))]
11442 ix86_expand_call (NULL, operands[0], operands[1],
11443 operands[2], NULL, true);
11447 (define_insn_and_split "*call_vzeroupper"
11448 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11450 (unspec [(match_operand 2 "const_int_operand")]
11451 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11452 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11454 "&& reload_completed"
11456 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11457 [(set_attr "type" "call")])
11459 (define_insn "*call"
11460 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11461 (match_operand 1))]
11462 "!SIBLING_CALL_P (insn)"
11463 "* return ix86_output_call_insn (insn, operands[0]);"
11464 [(set_attr "type" "call")])
11466 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11467 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11469 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11470 (clobber (reg:TI XMM6_REG))
11471 (clobber (reg:TI XMM7_REG))
11472 (clobber (reg:TI XMM8_REG))
11473 (clobber (reg:TI XMM9_REG))
11474 (clobber (reg:TI XMM10_REG))
11475 (clobber (reg:TI XMM11_REG))
11476 (clobber (reg:TI XMM12_REG))
11477 (clobber (reg:TI XMM13_REG))
11478 (clobber (reg:TI XMM14_REG))
11479 (clobber (reg:TI XMM15_REG))
11480 (clobber (reg:DI SI_REG))
11481 (clobber (reg:DI DI_REG))
11482 (unspec [(match_operand 2 "const_int_operand")]
11483 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11484 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11486 "&& reload_completed"
11488 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11489 [(set_attr "type" "call")])
11491 (define_insn "*call_rex64_ms_sysv"
11492 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11494 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11495 (clobber (reg:TI XMM6_REG))
11496 (clobber (reg:TI XMM7_REG))
11497 (clobber (reg:TI XMM8_REG))
11498 (clobber (reg:TI XMM9_REG))
11499 (clobber (reg:TI XMM10_REG))
11500 (clobber (reg:TI XMM11_REG))
11501 (clobber (reg:TI XMM12_REG))
11502 (clobber (reg:TI XMM13_REG))
11503 (clobber (reg:TI XMM14_REG))
11504 (clobber (reg:TI XMM15_REG))
11505 (clobber (reg:DI SI_REG))
11506 (clobber (reg:DI DI_REG))]
11507 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11508 "* return ix86_output_call_insn (insn, operands[0]);"
11509 [(set_attr "type" "call")])
11511 (define_insn_and_split "*sibcall_vzeroupper"
11512 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11514 (unspec [(match_operand 2 "const_int_operand")]
11515 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11516 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11518 "&& reload_completed"
11520 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11521 [(set_attr "type" "call")])
11523 (define_insn "*sibcall"
11524 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11525 (match_operand 1))]
11526 "SIBLING_CALL_P (insn)"
11527 "* return ix86_output_call_insn (insn, operands[0]);"
11528 [(set_attr "type" "call")])
11530 (define_expand "call_pop"
11531 [(parallel [(call (match_operand:QI 0)
11532 (match_operand:SI 1))
11533 (set (reg:SI SP_REG)
11534 (plus:SI (reg:SI SP_REG)
11535 (match_operand:SI 3)))])]
11538 ix86_expand_call (NULL, operands[0], operands[1],
11539 operands[2], operands[3], false);
11543 (define_insn_and_split "*call_pop_vzeroupper"
11544 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11546 (set (reg:SI SP_REG)
11547 (plus:SI (reg:SI SP_REG)
11548 (match_operand:SI 2 "immediate_operand" "i")))
11549 (unspec [(match_operand 3 "const_int_operand")]
11550 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11551 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11553 "&& reload_completed"
11555 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11556 [(set_attr "type" "call")])
11558 (define_insn "*call_pop"
11559 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11561 (set (reg:SI SP_REG)
11562 (plus:SI (reg:SI SP_REG)
11563 (match_operand:SI 2 "immediate_operand" "i")))]
11564 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11565 "* return ix86_output_call_insn (insn, operands[0]);"
11566 [(set_attr "type" "call")])
11568 (define_insn_and_split "*sibcall_pop_vzeroupper"
11569 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11571 (set (reg:SI SP_REG)
11572 (plus:SI (reg:SI SP_REG)
11573 (match_operand:SI 2 "immediate_operand" "i")))
11574 (unspec [(match_operand 3 "const_int_operand")]
11575 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11576 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11578 "&& reload_completed"
11580 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11581 [(set_attr "type" "call")])
11583 (define_insn "*sibcall_pop"
11584 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11586 (set (reg:SI SP_REG)
11587 (plus:SI (reg:SI SP_REG)
11588 (match_operand:SI 2 "immediate_operand" "i")))]
11589 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11590 "* return ix86_output_call_insn (insn, operands[0]);"
11591 [(set_attr "type" "call")])
11593 ;; Call subroutine, returning value in operand 0
11595 (define_expand "call_value"
11596 [(set (match_operand 0)
11597 (call (match_operand:QI 1)
11598 (match_operand 2)))
11599 (use (match_operand 3))]
11602 ix86_expand_call (operands[0], operands[1], operands[2],
11603 operands[3], NULL, false);
11607 (define_expand "sibcall_value"
11608 [(set (match_operand 0)
11609 (call (match_operand:QI 1)
11610 (match_operand 2)))
11611 (use (match_operand 3))]
11614 ix86_expand_call (operands[0], operands[1], operands[2],
11615 operands[3], NULL, true);
11619 (define_insn_and_split "*call_value_vzeroupper"
11620 [(set (match_operand 0)
11621 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11622 (match_operand 2)))
11623 (unspec [(match_operand 3 "const_int_operand")]
11624 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11625 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11627 "&& reload_completed"
11629 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11630 [(set_attr "type" "callv")])
11632 (define_insn "*call_value"
11633 [(set (match_operand 0)
11634 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11635 (match_operand 2)))]
11636 "!SIBLING_CALL_P (insn)"
11637 "* return ix86_output_call_insn (insn, operands[1]);"
11638 [(set_attr "type" "callv")])
11640 (define_insn_and_split "*sibcall_value_vzeroupper"
11641 [(set (match_operand 0)
11642 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11643 (match_operand 2)))
11644 (unspec [(match_operand 3 "const_int_operand")]
11645 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11646 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11648 "&& reload_completed"
11650 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11651 [(set_attr "type" "callv")])
11653 (define_insn "*sibcall_value"
11654 [(set (match_operand 0)
11655 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11656 (match_operand 2)))]
11657 "SIBLING_CALL_P (insn)"
11658 "* return ix86_output_call_insn (insn, operands[1]);"
11659 [(set_attr "type" "callv")])
11661 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11662 [(set (match_operand 0)
11663 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11664 (match_operand 2)))
11665 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11666 (clobber (reg:TI XMM6_REG))
11667 (clobber (reg:TI XMM7_REG))
11668 (clobber (reg:TI XMM8_REG))
11669 (clobber (reg:TI XMM9_REG))
11670 (clobber (reg:TI XMM10_REG))
11671 (clobber (reg:TI XMM11_REG))
11672 (clobber (reg:TI XMM12_REG))
11673 (clobber (reg:TI XMM13_REG))
11674 (clobber (reg:TI XMM14_REG))
11675 (clobber (reg:TI XMM15_REG))
11676 (clobber (reg:DI SI_REG))
11677 (clobber (reg:DI DI_REG))
11678 (unspec [(match_operand 3 "const_int_operand")]
11679 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11680 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11682 "&& reload_completed"
11684 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11685 [(set_attr "type" "callv")])
11687 (define_insn "*call_value_rex64_ms_sysv"
11688 [(set (match_operand 0)
11689 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11690 (match_operand 2)))
11691 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11692 (clobber (reg:TI XMM6_REG))
11693 (clobber (reg:TI XMM7_REG))
11694 (clobber (reg:TI XMM8_REG))
11695 (clobber (reg:TI XMM9_REG))
11696 (clobber (reg:TI XMM10_REG))
11697 (clobber (reg:TI XMM11_REG))
11698 (clobber (reg:TI XMM12_REG))
11699 (clobber (reg:TI XMM13_REG))
11700 (clobber (reg:TI XMM14_REG))
11701 (clobber (reg:TI XMM15_REG))
11702 (clobber (reg:DI SI_REG))
11703 (clobber (reg:DI DI_REG))]
11704 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11705 "* return ix86_output_call_insn (insn, operands[1]);"
11706 [(set_attr "type" "callv")])
11708 (define_expand "call_value_pop"
11709 [(parallel [(set (match_operand 0)
11710 (call (match_operand:QI 1)
11711 (match_operand:SI 2)))
11712 (set (reg:SI SP_REG)
11713 (plus:SI (reg:SI SP_REG)
11714 (match_operand:SI 4)))])]
11717 ix86_expand_call (operands[0], operands[1], operands[2],
11718 operands[3], operands[4], false);
11722 (define_insn_and_split "*call_value_pop_vzeroupper"
11723 [(set (match_operand 0)
11724 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11725 (match_operand 2)))
11726 (set (reg:SI SP_REG)
11727 (plus:SI (reg:SI SP_REG)
11728 (match_operand:SI 3 "immediate_operand" "i")))
11729 (unspec [(match_operand 4 "const_int_operand")]
11730 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11731 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11733 "&& reload_completed"
11735 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11736 [(set_attr "type" "callv")])
11738 (define_insn "*call_value_pop"
11739 [(set (match_operand 0)
11740 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11741 (match_operand 2)))
11742 (set (reg:SI SP_REG)
11743 (plus:SI (reg:SI SP_REG)
11744 (match_operand:SI 3 "immediate_operand" "i")))]
11745 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11746 "* return ix86_output_call_insn (insn, operands[1]);"
11747 [(set_attr "type" "callv")])
11749 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11750 [(set (match_operand 0)
11751 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11752 (match_operand 2)))
11753 (set (reg:SI SP_REG)
11754 (plus:SI (reg:SI SP_REG)
11755 (match_operand:SI 3 "immediate_operand" "i")))
11756 (unspec [(match_operand 4 "const_int_operand")]
11757 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11758 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11760 "&& reload_completed"
11762 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11763 [(set_attr "type" "callv")])
11765 (define_insn "*sibcall_value_pop"
11766 [(set (match_operand 0)
11767 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11768 (match_operand 2)))
11769 (set (reg:SI SP_REG)
11770 (plus:SI (reg:SI SP_REG)
11771 (match_operand:SI 3 "immediate_operand" "i")))]
11772 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11773 "* return ix86_output_call_insn (insn, operands[1]);"
11774 [(set_attr "type" "callv")])
11776 ;; Call subroutine returning any type.
11778 (define_expand "untyped_call"
11779 [(parallel [(call (match_operand 0)
11782 (match_operand 2)])]
11787 /* In order to give reg-stack an easier job in validating two
11788 coprocessor registers as containing a possible return value,
11789 simply pretend the untyped call returns a complex long double
11792 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11793 and should have the default ABI. */
11795 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11796 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11797 operands[0], const0_rtx,
11798 GEN_INT ((TARGET_64BIT
11799 ? (ix86_abi == SYSV_ABI
11800 ? X86_64_SSE_REGPARM_MAX
11801 : X86_64_MS_SSE_REGPARM_MAX)
11802 : X86_32_SSE_REGPARM_MAX)
11806 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11808 rtx set = XVECEXP (operands[2], 0, i);
11809 emit_move_insn (SET_DEST (set), SET_SRC (set));
11812 /* The optimizer does not know that the call sets the function value
11813 registers we stored in the result block. We avoid problems by
11814 claiming that all hard registers are used and clobbered at this
11816 emit_insn (gen_blockage ());
11821 ;; Prologue and epilogue instructions
11823 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11824 ;; all of memory. This blocks insns from being moved across this point.
11826 (define_insn "blockage"
11827 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11830 [(set_attr "length" "0")])
11832 ;; Do not schedule instructions accessing memory across this point.
11834 (define_expand "memory_blockage"
11835 [(set (match_dup 0)
11836 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11839 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11840 MEM_VOLATILE_P (operands[0]) = 1;
11843 (define_insn "*memory_blockage"
11844 [(set (match_operand:BLK 0)
11845 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11848 [(set_attr "length" "0")])
11850 ;; As USE insns aren't meaningful after reload, this is used instead
11851 ;; to prevent deleting instructions setting registers for PIC code
11852 (define_insn "prologue_use"
11853 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11856 [(set_attr "length" "0")])
11858 ;; Insn emitted into the body of a function to return from a function.
11859 ;; This is only done if the function's epilogue is known to be simple.
11860 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11862 (define_expand "return"
11864 "ix86_can_use_return_insn_p ()"
11866 ix86_maybe_emit_epilogue_vzeroupper ();
11867 if (crtl->args.pops_args)
11869 rtx popc = GEN_INT (crtl->args.pops_args);
11870 emit_jump_insn (gen_simple_return_pop_internal (popc));
11875 ;; We need to disable this for TARGET_SEH, as otherwise
11876 ;; shrink-wrapped prologue gets enabled too. This might exceed
11877 ;; the maximum size of prologue in unwind information.
11879 (define_expand "simple_return"
11883 ix86_maybe_emit_epilogue_vzeroupper ();
11884 if (crtl->args.pops_args)
11886 rtx popc = GEN_INT (crtl->args.pops_args);
11887 emit_jump_insn (gen_simple_return_pop_internal (popc));
11892 (define_insn "simple_return_internal"
11896 [(set_attr "length" "1")
11897 (set_attr "atom_unit" "jeu")
11898 (set_attr "length_immediate" "0")
11899 (set_attr "modrm" "0")])
11901 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11902 ;; instruction Athlon and K8 have.
11904 (define_insn "simple_return_internal_long"
11906 (unspec [(const_int 0)] UNSPEC_REP)]
11909 [(set_attr "length" "2")
11910 (set_attr "atom_unit" "jeu")
11911 (set_attr "length_immediate" "0")
11912 (set_attr "prefix_rep" "1")
11913 (set_attr "modrm" "0")])
11915 (define_insn "simple_return_pop_internal"
11917 (use (match_operand:SI 0 "const_int_operand"))]
11920 [(set_attr "length" "3")
11921 (set_attr "atom_unit" "jeu")
11922 (set_attr "length_immediate" "2")
11923 (set_attr "modrm" "0")])
11925 (define_insn "simple_return_indirect_internal"
11927 (use (match_operand:SI 0 "register_operand" "r"))]
11930 [(set_attr "type" "ibr")
11931 (set_attr "length_immediate" "0")])
11937 [(set_attr "length" "1")
11938 (set_attr "length_immediate" "0")
11939 (set_attr "modrm" "0")])
11941 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11942 (define_insn "nops"
11943 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11947 int num = INTVAL (operands[0]);
11949 gcc_assert (num >= 1 && num <= 8);
11952 fputs ("\tnop\n", asm_out_file);
11956 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11957 (set_attr "length_immediate" "0")
11958 (set_attr "modrm" "0")])
11960 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11961 ;; branch prediction penalty for the third jump in a 16-byte
11965 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11968 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11969 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11971 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11972 The align insn is used to avoid 3 jump instructions in the row to improve
11973 branch prediction and the benefits hardly outweigh the cost of extra 8
11974 nops on the average inserted by full alignment pseudo operation. */
11978 [(set_attr "length" "16")])
11980 (define_expand "prologue"
11983 "ix86_expand_prologue (); DONE;")
11985 (define_insn "set_got"
11986 [(set (match_operand:SI 0 "register_operand" "=r")
11987 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11988 (clobber (reg:CC FLAGS_REG))]
11990 "* return output_set_got (operands[0], NULL_RTX);"
11991 [(set_attr "type" "multi")
11992 (set_attr "length" "12")])
11994 (define_insn "set_got_labelled"
11995 [(set (match_operand:SI 0 "register_operand" "=r")
11996 (unspec:SI [(label_ref (match_operand 1))]
11998 (clobber (reg:CC FLAGS_REG))]
12000 "* return output_set_got (operands[0], operands[1]);"
12001 [(set_attr "type" "multi")
12002 (set_attr "length" "12")])
12004 (define_insn "set_got_rex64"
12005 [(set (match_operand:DI 0 "register_operand" "=r")
12006 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12008 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12009 [(set_attr "type" "lea")
12010 (set_attr "length_address" "4")
12011 (set_attr "mode" "DI")])
12013 (define_insn "set_rip_rex64"
12014 [(set (match_operand:DI 0 "register_operand" "=r")
12015 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12017 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12018 [(set_attr "type" "lea")
12019 (set_attr "length_address" "4")
12020 (set_attr "mode" "DI")])
12022 (define_insn "set_got_offset_rex64"
12023 [(set (match_operand:DI 0 "register_operand" "=r")
12025 [(label_ref (match_operand 1))]
12026 UNSPEC_SET_GOT_OFFSET))]
12028 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12029 [(set_attr "type" "imov")
12030 (set_attr "length_immediate" "0")
12031 (set_attr "length_address" "8")
12032 (set_attr "mode" "DI")])
12034 (define_expand "epilogue"
12037 "ix86_expand_epilogue (1); DONE;")
12039 (define_expand "sibcall_epilogue"
12042 "ix86_expand_epilogue (0); DONE;")
12044 (define_expand "eh_return"
12045 [(use (match_operand 0 "register_operand"))]
12048 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12050 /* Tricky bit: we write the address of the handler to which we will
12051 be returning into someone else's stack frame, one word below the
12052 stack address we wish to restore. */
12053 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12054 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12055 tmp = gen_rtx_MEM (Pmode, tmp);
12056 emit_move_insn (tmp, ra);
12058 emit_jump_insn (gen_eh_return_internal ());
12063 (define_insn_and_split "eh_return_internal"
12067 "epilogue_completed"
12069 "ix86_expand_epilogue (2); DONE;")
12071 (define_insn "leave"
12072 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12073 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12074 (clobber (mem:BLK (scratch)))]
12077 [(set_attr "type" "leave")])
12079 (define_insn "leave_rex64"
12080 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12081 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12082 (clobber (mem:BLK (scratch)))]
12085 [(set_attr "type" "leave")])
12087 ;; Handle -fsplit-stack.
12089 (define_expand "split_stack_prologue"
12093 ix86_expand_split_stack_prologue ();
12097 ;; In order to support the call/return predictor, we use a return
12098 ;; instruction which the middle-end doesn't see.
12099 (define_insn "split_stack_return"
12100 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12101 UNSPECV_SPLIT_STACK_RETURN)]
12104 if (operands[0] == const0_rtx)
12109 [(set_attr "atom_unit" "jeu")
12110 (set_attr "modrm" "0")
12111 (set (attr "length")
12112 (if_then_else (match_operand:SI 0 "const0_operand")
12115 (set (attr "length_immediate")
12116 (if_then_else (match_operand:SI 0 "const0_operand")
12120 ;; If there are operand 0 bytes available on the stack, jump to
12123 (define_expand "split_stack_space_check"
12124 [(set (pc) (if_then_else
12125 (ltu (minus (reg SP_REG)
12126 (match_operand 0 "register_operand"))
12127 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12128 (label_ref (match_operand 1))
12132 rtx reg, size, limit;
12134 reg = gen_reg_rtx (Pmode);
12135 size = force_reg (Pmode, operands[0]);
12136 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12137 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12138 UNSPEC_STACK_CHECK);
12139 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12140 ix86_expand_branch (GEU, reg, limit, operands[1]);
12145 ;; Bit manipulation instructions.
12147 (define_expand "ffs<mode>2"
12148 [(set (match_dup 2) (const_int -1))
12149 (parallel [(set (match_dup 3) (match_dup 4))
12150 (set (match_operand:SWI48 0 "register_operand")
12152 (match_operand:SWI48 1 "nonimmediate_operand")))])
12153 (set (match_dup 0) (if_then_else:SWI48
12154 (eq (match_dup 3) (const_int 0))
12157 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12158 (clobber (reg:CC FLAGS_REG))])]
12161 enum machine_mode flags_mode;
12163 if (<MODE>mode == SImode && !TARGET_CMOVE)
12165 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12169 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12171 operands[2] = gen_reg_rtx (<MODE>mode);
12172 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12173 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12176 (define_insn_and_split "ffssi2_no_cmove"
12177 [(set (match_operand:SI 0 "register_operand" "=r")
12178 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12179 (clobber (match_scratch:SI 2 "=&q"))
12180 (clobber (reg:CC FLAGS_REG))]
12183 "&& reload_completed"
12184 [(parallel [(set (match_dup 4) (match_dup 5))
12185 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12186 (set (strict_low_part (match_dup 3))
12187 (eq:QI (match_dup 4) (const_int 0)))
12188 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12189 (clobber (reg:CC FLAGS_REG))])
12190 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12191 (clobber (reg:CC FLAGS_REG))])
12192 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12193 (clobber (reg:CC FLAGS_REG))])]
12195 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12197 operands[3] = gen_lowpart (QImode, operands[2]);
12198 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12199 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12201 ix86_expand_clear (operands[2]);
12204 (define_insn "*tzcnt<mode>_1"
12205 [(set (reg:CCC FLAGS_REG)
12206 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12208 (set (match_operand:SWI48 0 "register_operand" "=r")
12209 (ctz:SWI48 (match_dup 1)))]
12211 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12212 [(set_attr "type" "alu1")
12213 (set_attr "prefix_0f" "1")
12214 (set_attr "prefix_rep" "1")
12215 (set_attr "mode" "<MODE>")])
12217 (define_insn "*bsf<mode>_1"
12218 [(set (reg:CCZ FLAGS_REG)
12219 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12221 (set (match_operand:SWI48 0 "register_operand" "=r")
12222 (ctz:SWI48 (match_dup 1)))]
12224 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12225 [(set_attr "type" "alu1")
12226 (set_attr "prefix_0f" "1")
12227 (set_attr "mode" "<MODE>")])
12229 (define_insn "ctz<mode>2"
12230 [(set (match_operand:SWI248 0 "register_operand" "=r")
12231 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12232 (clobber (reg:CC FLAGS_REG))]
12236 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12237 else if (optimize_function_for_size_p (cfun))
12239 else if (TARGET_GENERIC)
12240 /* tzcnt expands to rep;bsf and we can use it even if !TARGET_BMI. */
12241 return "rep; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12243 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12245 [(set_attr "type" "alu1")
12246 (set_attr "prefix_0f" "1")
12247 (set (attr "prefix_rep")
12249 (ior (match_test "TARGET_BMI")
12250 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12251 (match_test "TARGET_GENERIC")))
12253 (const_string "0")))
12254 (set_attr "mode" "<MODE>")])
12256 (define_expand "clz<mode>2"
12258 [(set (match_operand:SWI248 0 "register_operand")
12261 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12262 (clobber (reg:CC FLAGS_REG))])
12264 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12265 (clobber (reg:CC FLAGS_REG))])]
12270 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12273 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12276 (define_insn "clz<mode>2_lzcnt"
12277 [(set (match_operand:SWI248 0 "register_operand" "=r")
12278 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12279 (clobber (reg:CC FLAGS_REG))]
12281 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12282 [(set_attr "prefix_rep" "1")
12283 (set_attr "type" "bitmanip")
12284 (set_attr "mode" "<MODE>")])
12286 ;; BMI instructions.
12287 (define_insn "*bmi_andn_<mode>"
12288 [(set (match_operand:SWI48 0 "register_operand" "=r")
12291 (match_operand:SWI48 1 "register_operand" "r"))
12292 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12293 (clobber (reg:CC FLAGS_REG))]
12295 "andn\t{%2, %1, %0|%0, %1, %2}"
12296 [(set_attr "type" "bitmanip")
12297 (set_attr "mode" "<MODE>")])
12299 (define_insn "bmi_bextr_<mode>"
12300 [(set (match_operand:SWI48 0 "register_operand" "=r")
12301 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12302 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12304 (clobber (reg:CC FLAGS_REG))]
12306 "bextr\t{%2, %1, %0|%0, %1, %2}"
12307 [(set_attr "type" "bitmanip")
12308 (set_attr "mode" "<MODE>")])
12310 (define_insn "*bmi_blsi_<mode>"
12311 [(set (match_operand:SWI48 0 "register_operand" "=r")
12314 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12316 (clobber (reg:CC FLAGS_REG))]
12318 "blsi\t{%1, %0|%0, %1}"
12319 [(set_attr "type" "bitmanip")
12320 (set_attr "mode" "<MODE>")])
12322 (define_insn "*bmi_blsmsk_<mode>"
12323 [(set (match_operand:SWI48 0 "register_operand" "=r")
12326 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12329 (clobber (reg:CC FLAGS_REG))]
12331 "blsmsk\t{%1, %0|%0, %1}"
12332 [(set_attr "type" "bitmanip")
12333 (set_attr "mode" "<MODE>")])
12335 (define_insn "*bmi_blsr_<mode>"
12336 [(set (match_operand:SWI48 0 "register_operand" "=r")
12339 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12342 (clobber (reg:CC FLAGS_REG))]
12344 "blsr\t{%1, %0|%0, %1}"
12345 [(set_attr "type" "bitmanip")
12346 (set_attr "mode" "<MODE>")])
12348 ;; BMI2 instructions.
12349 (define_insn "bmi2_bzhi_<mode>3"
12350 [(set (match_operand:SWI48 0 "register_operand" "=r")
12351 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12352 (lshiftrt:SWI48 (const_int -1)
12353 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12354 (clobber (reg:CC FLAGS_REG))]
12356 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12357 [(set_attr "type" "bitmanip")
12358 (set_attr "prefix" "vex")
12359 (set_attr "mode" "<MODE>")])
12361 (define_insn "bmi2_pdep_<mode>3"
12362 [(set (match_operand:SWI48 0 "register_operand" "=r")
12363 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12364 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12367 "pdep\t{%2, %1, %0|%0, %1, %2}"
12368 [(set_attr "type" "bitmanip")
12369 (set_attr "prefix" "vex")
12370 (set_attr "mode" "<MODE>")])
12372 (define_insn "bmi2_pext_<mode>3"
12373 [(set (match_operand:SWI48 0 "register_operand" "=r")
12374 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12375 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12378 "pext\t{%2, %1, %0|%0, %1, %2}"
12379 [(set_attr "type" "bitmanip")
12380 (set_attr "prefix" "vex")
12381 (set_attr "mode" "<MODE>")])
12383 ;; TBM instructions.
12384 (define_insn "tbm_bextri_<mode>"
12385 [(set (match_operand:SWI48 0 "register_operand" "=r")
12386 (zero_extract:SWI48
12387 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12388 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12389 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12390 (clobber (reg:CC FLAGS_REG))]
12393 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12394 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12396 [(set_attr "type" "bitmanip")
12397 (set_attr "mode" "<MODE>")])
12399 (define_insn "*tbm_blcfill_<mode>"
12400 [(set (match_operand:SWI48 0 "register_operand" "=r")
12403 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12406 (clobber (reg:CC FLAGS_REG))]
12408 "blcfill\t{%1, %0|%0, %1}"
12409 [(set_attr "type" "bitmanip")
12410 (set_attr "mode" "<MODE>")])
12412 (define_insn "*tbm_blci_<mode>"
12413 [(set (match_operand:SWI48 0 "register_operand" "=r")
12417 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12420 (clobber (reg:CC FLAGS_REG))]
12422 "blci\t{%1, %0|%0, %1}"
12423 [(set_attr "type" "bitmanip")
12424 (set_attr "mode" "<MODE>")])
12426 (define_insn "*tbm_blcic_<mode>"
12427 [(set (match_operand:SWI48 0 "register_operand" "=r")
12430 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12434 (clobber (reg:CC FLAGS_REG))]
12436 "blcic\t{%1, %0|%0, %1}"
12437 [(set_attr "type" "bitmanip")
12438 (set_attr "mode" "<MODE>")])
12440 (define_insn "*tbm_blcmsk_<mode>"
12441 [(set (match_operand:SWI48 0 "register_operand" "=r")
12444 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12447 (clobber (reg:CC FLAGS_REG))]
12449 "blcmsk\t{%1, %0|%0, %1}"
12450 [(set_attr "type" "bitmanip")
12451 (set_attr "mode" "<MODE>")])
12453 (define_insn "*tbm_blcs_<mode>"
12454 [(set (match_operand:SWI48 0 "register_operand" "=r")
12457 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12460 (clobber (reg:CC FLAGS_REG))]
12462 "blcs\t{%1, %0|%0, %1}"
12463 [(set_attr "type" "bitmanip")
12464 (set_attr "mode" "<MODE>")])
12466 (define_insn "*tbm_blsfill_<mode>"
12467 [(set (match_operand:SWI48 0 "register_operand" "=r")
12470 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12473 (clobber (reg:CC FLAGS_REG))]
12475 "blsfill\t{%1, %0|%0, %1}"
12476 [(set_attr "type" "bitmanip")
12477 (set_attr "mode" "<MODE>")])
12479 (define_insn "*tbm_blsic_<mode>"
12480 [(set (match_operand:SWI48 0 "register_operand" "=r")
12483 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12487 (clobber (reg:CC FLAGS_REG))]
12489 "blsic\t{%1, %0|%0, %1}"
12490 [(set_attr "type" "bitmanip")
12491 (set_attr "mode" "<MODE>")])
12493 (define_insn "*tbm_t1mskc_<mode>"
12494 [(set (match_operand:SWI48 0 "register_operand" "=r")
12497 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12501 (clobber (reg:CC FLAGS_REG))]
12503 "t1mskc\t{%1, %0|%0, %1}"
12504 [(set_attr "type" "bitmanip")
12505 (set_attr "mode" "<MODE>")])
12507 (define_insn "*tbm_tzmsk_<mode>"
12508 [(set (match_operand:SWI48 0 "register_operand" "=r")
12511 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12515 (clobber (reg:CC FLAGS_REG))]
12517 "tzmsk\t{%1, %0|%0, %1}"
12518 [(set_attr "type" "bitmanip")
12519 (set_attr "mode" "<MODE>")])
12521 (define_insn "bsr_rex64"
12522 [(set (match_operand:DI 0 "register_operand" "=r")
12523 (minus:DI (const_int 63)
12524 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12525 (clobber (reg:CC FLAGS_REG))]
12527 "bsr{q}\t{%1, %0|%0, %1}"
12528 [(set_attr "type" "alu1")
12529 (set_attr "prefix_0f" "1")
12530 (set_attr "mode" "DI")])
12533 [(set (match_operand:SI 0 "register_operand" "=r")
12534 (minus:SI (const_int 31)
12535 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12536 (clobber (reg:CC FLAGS_REG))]
12538 "bsr{l}\t{%1, %0|%0, %1}"
12539 [(set_attr "type" "alu1")
12540 (set_attr "prefix_0f" "1")
12541 (set_attr "mode" "SI")])
12543 (define_insn "*bsrhi"
12544 [(set (match_operand:HI 0 "register_operand" "=r")
12545 (minus:HI (const_int 15)
12546 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12547 (clobber (reg:CC FLAGS_REG))]
12549 "bsr{w}\t{%1, %0|%0, %1}"
12550 [(set_attr "type" "alu1")
12551 (set_attr "prefix_0f" "1")
12552 (set_attr "mode" "HI")])
12554 (define_insn "popcount<mode>2"
12555 [(set (match_operand:SWI248 0 "register_operand" "=r")
12557 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12558 (clobber (reg:CC FLAGS_REG))]
12562 return "popcnt\t{%1, %0|%0, %1}";
12564 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12567 [(set_attr "prefix_rep" "1")
12568 (set_attr "type" "bitmanip")
12569 (set_attr "mode" "<MODE>")])
12571 (define_insn "*popcount<mode>2_cmp"
12572 [(set (reg FLAGS_REG)
12575 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12577 (set (match_operand:SWI248 0 "register_operand" "=r")
12578 (popcount:SWI248 (match_dup 1)))]
12579 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12582 return "popcnt\t{%1, %0|%0, %1}";
12584 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12587 [(set_attr "prefix_rep" "1")
12588 (set_attr "type" "bitmanip")
12589 (set_attr "mode" "<MODE>")])
12591 (define_insn "*popcountsi2_cmp_zext"
12592 [(set (reg FLAGS_REG)
12594 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12596 (set (match_operand:DI 0 "register_operand" "=r")
12597 (zero_extend:DI(popcount:SI (match_dup 1))))]
12598 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12601 return "popcnt\t{%1, %0|%0, %1}";
12603 return "popcnt{l}\t{%1, %0|%0, %1}";
12606 [(set_attr "prefix_rep" "1")
12607 (set_attr "type" "bitmanip")
12608 (set_attr "mode" "SI")])
12610 (define_expand "bswapdi2"
12611 [(set (match_operand:DI 0 "register_operand")
12612 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12615 if (TARGET_64BIT && !TARGET_MOVBE)
12616 operands[1] = force_reg (DImode, operands[1]);
12619 (define_insn_and_split "*bswapdi2_doubleword"
12620 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12622 (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12624 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12626 "&& reload_completed"
12627 [(set (match_dup 2)
12628 (bswap:SI (match_dup 1)))
12630 (bswap:SI (match_dup 3)))]
12632 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
12634 if (REG_P (operands[0]) && REG_P (operands[1]))
12636 emit_insn (gen_swapsi (operands[0], operands[2]));
12637 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12638 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12644 if (MEM_P (operands[0]))
12646 emit_insn (gen_bswapsi2 (operands[3], operands[3]));
12647 emit_insn (gen_bswapsi2 (operands[1], operands[1]));
12649 emit_move_insn (operands[0], operands[3]);
12650 emit_move_insn (operands[2], operands[1]);
12652 if (MEM_P (operands[1]))
12654 emit_move_insn (operands[2], operands[1]);
12655 emit_move_insn (operands[0], operands[3]);
12657 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12658 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12664 (define_expand "bswapsi2"
12665 [(set (match_operand:SI 0 "register_operand")
12666 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12671 else if (TARGET_BSWAP)
12672 operands[1] = force_reg (SImode, operands[1]);
12675 rtx x = operands[0];
12677 emit_move_insn (x, operands[1]);
12678 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12679 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12680 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12685 (define_insn "*bswap<mode>2_movbe"
12686 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12687 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12689 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12692 movbe\t{%1, %0|%0, %1}
12693 movbe\t{%1, %0|%0, %1}"
12694 [(set_attr "type" "bitmanip,imov,imov")
12695 (set_attr "modrm" "0,1,1")
12696 (set_attr "prefix_0f" "*,1,1")
12697 (set_attr "prefix_extra" "*,1,1")
12698 (set_attr "mode" "<MODE>")])
12700 (define_insn "*bswap<mode>2"
12701 [(set (match_operand:SWI48 0 "register_operand" "=r")
12702 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12705 [(set_attr "type" "bitmanip")
12706 (set_attr "modrm" "0")
12707 (set_attr "mode" "<MODE>")])
12709 (define_insn "*bswaphi_lowpart_1"
12710 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12711 (bswap:HI (match_dup 0)))
12712 (clobber (reg:CC FLAGS_REG))]
12713 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12715 xchg{b}\t{%h0, %b0|%b0, %h0}
12716 rol{w}\t{$8, %0|%0, 8}"
12717 [(set_attr "length" "2,4")
12718 (set_attr "mode" "QI,HI")])
12720 (define_insn "bswaphi_lowpart"
12721 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12722 (bswap:HI (match_dup 0)))
12723 (clobber (reg:CC FLAGS_REG))]
12725 "rol{w}\t{$8, %0|%0, 8}"
12726 [(set_attr "length" "4")
12727 (set_attr "mode" "HI")])
12729 (define_expand "paritydi2"
12730 [(set (match_operand:DI 0 "register_operand")
12731 (parity:DI (match_operand:DI 1 "register_operand")))]
12734 rtx scratch = gen_reg_rtx (QImode);
12737 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12738 NULL_RTX, operands[1]));
12740 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12741 gen_rtx_REG (CCmode, FLAGS_REG),
12743 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12746 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12749 rtx tmp = gen_reg_rtx (SImode);
12751 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12752 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12757 (define_expand "paritysi2"
12758 [(set (match_operand:SI 0 "register_operand")
12759 (parity:SI (match_operand:SI 1 "register_operand")))]
12762 rtx scratch = gen_reg_rtx (QImode);
12765 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12767 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12768 gen_rtx_REG (CCmode, FLAGS_REG),
12770 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12772 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12776 (define_insn_and_split "paritydi2_cmp"
12777 [(set (reg:CC FLAGS_REG)
12778 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12780 (clobber (match_scratch:DI 0 "=r"))
12781 (clobber (match_scratch:SI 1 "=&r"))
12782 (clobber (match_scratch:HI 2 "=Q"))]
12785 "&& reload_completed"
12787 [(set (match_dup 1)
12788 (xor:SI (match_dup 1) (match_dup 4)))
12789 (clobber (reg:CC FLAGS_REG))])
12791 [(set (reg:CC FLAGS_REG)
12792 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12793 (clobber (match_dup 1))
12794 (clobber (match_dup 2))])]
12796 operands[4] = gen_lowpart (SImode, operands[3]);
12800 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12801 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12804 operands[1] = gen_highpart (SImode, operands[3]);
12807 (define_insn_and_split "paritysi2_cmp"
12808 [(set (reg:CC FLAGS_REG)
12809 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12811 (clobber (match_scratch:SI 0 "=r"))
12812 (clobber (match_scratch:HI 1 "=&Q"))]
12815 "&& reload_completed"
12817 [(set (match_dup 1)
12818 (xor:HI (match_dup 1) (match_dup 3)))
12819 (clobber (reg:CC FLAGS_REG))])
12821 [(set (reg:CC FLAGS_REG)
12822 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12823 (clobber (match_dup 1))])]
12825 operands[3] = gen_lowpart (HImode, operands[2]);
12827 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12828 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12831 (define_insn "*parityhi2_cmp"
12832 [(set (reg:CC FLAGS_REG)
12833 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12835 (clobber (match_scratch:HI 0 "=Q"))]
12837 "xor{b}\t{%h0, %b0|%b0, %h0}"
12838 [(set_attr "length" "2")
12839 (set_attr "mode" "HI")])
12842 ;; Thread-local storage patterns for ELF.
12844 ;; Note that these code sequences must appear exactly as shown
12845 ;; in order to allow linker relaxation.
12847 (define_insn "*tls_global_dynamic_32_gnu"
12848 [(set (match_operand:SI 0 "register_operand" "=a")
12850 [(match_operand:SI 1 "register_operand" "b")
12851 (match_operand 2 "tls_symbolic_operand")
12852 (match_operand 3 "constant_call_address_operand" "z")]
12854 (clobber (match_scratch:SI 4 "=d"))
12855 (clobber (match_scratch:SI 5 "=c"))
12856 (clobber (reg:CC FLAGS_REG))]
12857 "!TARGET_64BIT && TARGET_GNU_TLS"
12860 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12861 if (TARGET_SUN_TLS)
12862 #ifdef HAVE_AS_IX86_TLSGDPLT
12863 return "call\t%a2@tlsgdplt";
12865 return "call\t%p3@plt";
12867 return "call\t%P3";
12869 [(set_attr "type" "multi")
12870 (set_attr "length" "12")])
12872 (define_expand "tls_global_dynamic_32"
12874 [(set (match_operand:SI 0 "register_operand")
12875 (unspec:SI [(match_operand:SI 2 "register_operand")
12876 (match_operand 1 "tls_symbolic_operand")
12877 (match_operand 3 "constant_call_address_operand")]
12879 (clobber (match_scratch:SI 4))
12880 (clobber (match_scratch:SI 5))
12881 (clobber (reg:CC FLAGS_REG))])])
12883 (define_insn "*tls_global_dynamic_64_<mode>"
12884 [(set (match_operand:P 0 "register_operand" "=a")
12886 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12887 (match_operand 3)))
12888 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12893 fputs (ASM_BYTE "0x66\n", asm_out_file);
12895 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12896 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12897 fputs ("\trex64\n", asm_out_file);
12898 if (TARGET_SUN_TLS)
12899 return "call\t%p2@plt";
12900 return "call\t%P2";
12902 [(set_attr "type" "multi")
12903 (set (attr "length")
12904 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12906 (define_expand "tls_global_dynamic_64_<mode>"
12908 [(set (match_operand:P 0 "register_operand")
12910 (mem:QI (match_operand 2 "constant_call_address_operand"))
12912 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12916 (define_insn "*tls_local_dynamic_base_32_gnu"
12917 [(set (match_operand:SI 0 "register_operand" "=a")
12919 [(match_operand:SI 1 "register_operand" "b")
12920 (match_operand 2 "constant_call_address_operand" "z")]
12921 UNSPEC_TLS_LD_BASE))
12922 (clobber (match_scratch:SI 3 "=d"))
12923 (clobber (match_scratch:SI 4 "=c"))
12924 (clobber (reg:CC FLAGS_REG))]
12925 "!TARGET_64BIT && TARGET_GNU_TLS"
12928 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12929 if (TARGET_SUN_TLS)
12930 #ifdef HAVE_AS_IX86_TLSLDMPLT
12931 return "call\t%&@tlsldmplt";
12933 return "call\t%p2@plt";
12935 return "call\t%P2";
12937 [(set_attr "type" "multi")
12938 (set_attr "length" "11")])
12940 (define_expand "tls_local_dynamic_base_32"
12942 [(set (match_operand:SI 0 "register_operand")
12944 [(match_operand:SI 1 "register_operand")
12945 (match_operand 2 "constant_call_address_operand")]
12946 UNSPEC_TLS_LD_BASE))
12947 (clobber (match_scratch:SI 3))
12948 (clobber (match_scratch:SI 4))
12949 (clobber (reg:CC FLAGS_REG))])])
12951 (define_insn "*tls_local_dynamic_base_64_<mode>"
12952 [(set (match_operand:P 0 "register_operand" "=a")
12954 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12955 (match_operand 2)))
12956 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12960 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12961 if (TARGET_SUN_TLS)
12962 return "call\t%p1@plt";
12963 return "call\t%P1";
12965 [(set_attr "type" "multi")
12966 (set_attr "length" "12")])
12968 (define_expand "tls_local_dynamic_base_64_<mode>"
12970 [(set (match_operand:P 0 "register_operand")
12972 (mem:QI (match_operand 1 "constant_call_address_operand"))
12974 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12977 ;; Local dynamic of a single variable is a lose. Show combine how
12978 ;; to convert that back to global dynamic.
12980 (define_insn_and_split "*tls_local_dynamic_32_once"
12981 [(set (match_operand:SI 0 "register_operand" "=a")
12983 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12984 (match_operand 2 "constant_call_address_operand" "z")]
12985 UNSPEC_TLS_LD_BASE)
12986 (const:SI (unspec:SI
12987 [(match_operand 3 "tls_symbolic_operand")]
12989 (clobber (match_scratch:SI 4 "=d"))
12990 (clobber (match_scratch:SI 5 "=c"))
12991 (clobber (reg:CC FLAGS_REG))]
12996 [(set (match_dup 0)
12997 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12999 (clobber (match_dup 4))
13000 (clobber (match_dup 5))
13001 (clobber (reg:CC FLAGS_REG))])])
13003 ;; Segment register for the thread base ptr load
13004 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13006 ;; Load and add the thread base pointer from %<tp_seg>:0.
13007 (define_insn "*load_tp_x32"
13008 [(set (match_operand:SI 0 "register_operand" "=r")
13009 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13011 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13012 [(set_attr "type" "imov")
13013 (set_attr "modrm" "0")
13014 (set_attr "length" "7")
13015 (set_attr "memory" "load")
13016 (set_attr "imm_disp" "false")])
13018 (define_insn "*load_tp_x32_zext"
13019 [(set (match_operand:DI 0 "register_operand" "=r")
13020 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13022 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13023 [(set_attr "type" "imov")
13024 (set_attr "modrm" "0")
13025 (set_attr "length" "7")
13026 (set_attr "memory" "load")
13027 (set_attr "imm_disp" "false")])
13029 (define_insn "*load_tp_<mode>"
13030 [(set (match_operand:P 0 "register_operand" "=r")
13031 (unspec:P [(const_int 0)] UNSPEC_TP))]
13033 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13034 [(set_attr "type" "imov")
13035 (set_attr "modrm" "0")
13036 (set_attr "length" "7")
13037 (set_attr "memory" "load")
13038 (set_attr "imm_disp" "false")])
13040 (define_insn "*add_tp_x32"
13041 [(set (match_operand:SI 0 "register_operand" "=r")
13042 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13043 (match_operand:SI 1 "register_operand" "0")))
13044 (clobber (reg:CC FLAGS_REG))]
13046 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13047 [(set_attr "type" "alu")
13048 (set_attr "modrm" "0")
13049 (set_attr "length" "7")
13050 (set_attr "memory" "load")
13051 (set_attr "imm_disp" "false")])
13053 (define_insn "*add_tp_x32_zext"
13054 [(set (match_operand:DI 0 "register_operand" "=r")
13056 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13057 (match_operand:SI 1 "register_operand" "0"))))
13058 (clobber (reg:CC FLAGS_REG))]
13060 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13061 [(set_attr "type" "alu")
13062 (set_attr "modrm" "0")
13063 (set_attr "length" "7")
13064 (set_attr "memory" "load")
13065 (set_attr "imm_disp" "false")])
13067 (define_insn "*add_tp_<mode>"
13068 [(set (match_operand:P 0 "register_operand" "=r")
13069 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13070 (match_operand:P 1 "register_operand" "0")))
13071 (clobber (reg:CC FLAGS_REG))]
13073 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13074 [(set_attr "type" "alu")
13075 (set_attr "modrm" "0")
13076 (set_attr "length" "7")
13077 (set_attr "memory" "load")
13078 (set_attr "imm_disp" "false")])
13080 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13081 ;; %rax as destination of the initial executable code sequence.
13082 (define_insn "tls_initial_exec_64_sun"
13083 [(set (match_operand:DI 0 "register_operand" "=a")
13085 [(match_operand 1 "tls_symbolic_operand")]
13086 UNSPEC_TLS_IE_SUN))
13087 (clobber (reg:CC FLAGS_REG))]
13088 "TARGET_64BIT && TARGET_SUN_TLS"
13091 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13092 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13094 [(set_attr "type" "multi")])
13096 ;; GNU2 TLS patterns can be split.
13098 (define_expand "tls_dynamic_gnu2_32"
13099 [(set (match_dup 3)
13100 (plus:SI (match_operand:SI 2 "register_operand")
13102 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13105 [(set (match_operand:SI 0 "register_operand")
13106 (unspec:SI [(match_dup 1) (match_dup 3)
13107 (match_dup 2) (reg:SI SP_REG)]
13109 (clobber (reg:CC FLAGS_REG))])]
13110 "!TARGET_64BIT && TARGET_GNU2_TLS"
13112 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13113 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13116 (define_insn "*tls_dynamic_gnu2_lea_32"
13117 [(set (match_operand:SI 0 "register_operand" "=r")
13118 (plus:SI (match_operand:SI 1 "register_operand" "b")
13120 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13121 UNSPEC_TLSDESC))))]
13122 "!TARGET_64BIT && TARGET_GNU2_TLS"
13123 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13124 [(set_attr "type" "lea")
13125 (set_attr "mode" "SI")
13126 (set_attr "length" "6")
13127 (set_attr "length_address" "4")])
13129 (define_insn "*tls_dynamic_gnu2_call_32"
13130 [(set (match_operand:SI 0 "register_operand" "=a")
13131 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13132 (match_operand:SI 2 "register_operand" "0")
13133 ;; we have to make sure %ebx still points to the GOT
13134 (match_operand:SI 3 "register_operand" "b")
13137 (clobber (reg:CC FLAGS_REG))]
13138 "!TARGET_64BIT && TARGET_GNU2_TLS"
13139 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13140 [(set_attr "type" "call")
13141 (set_attr "length" "2")
13142 (set_attr "length_address" "0")])
13144 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13145 [(set (match_operand:SI 0 "register_operand" "=&a")
13147 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13148 (match_operand:SI 4)
13149 (match_operand:SI 2 "register_operand" "b")
13152 (const:SI (unspec:SI
13153 [(match_operand 1 "tls_symbolic_operand")]
13155 (clobber (reg:CC FLAGS_REG))]
13156 "!TARGET_64BIT && TARGET_GNU2_TLS"
13159 [(set (match_dup 0) (match_dup 5))]
13161 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13162 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13165 (define_expand "tls_dynamic_gnu2_64"
13166 [(set (match_dup 2)
13167 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13170 [(set (match_operand:DI 0 "register_operand")
13171 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13173 (clobber (reg:CC FLAGS_REG))])]
13174 "TARGET_64BIT && TARGET_GNU2_TLS"
13176 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13177 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13180 (define_insn "*tls_dynamic_gnu2_lea_64"
13181 [(set (match_operand:DI 0 "register_operand" "=r")
13182 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13184 "TARGET_64BIT && TARGET_GNU2_TLS"
13185 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13186 [(set_attr "type" "lea")
13187 (set_attr "mode" "DI")
13188 (set_attr "length" "7")
13189 (set_attr "length_address" "4")])
13191 (define_insn "*tls_dynamic_gnu2_call_64"
13192 [(set (match_operand:DI 0 "register_operand" "=a")
13193 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13194 (match_operand:DI 2 "register_operand" "0")
13197 (clobber (reg:CC FLAGS_REG))]
13198 "TARGET_64BIT && TARGET_GNU2_TLS"
13199 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13200 [(set_attr "type" "call")
13201 (set_attr "length" "2")
13202 (set_attr "length_address" "0")])
13204 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13205 [(set (match_operand:DI 0 "register_operand" "=&a")
13207 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13208 (match_operand:DI 3)
13211 (const:DI (unspec:DI
13212 [(match_operand 1 "tls_symbolic_operand")]
13214 (clobber (reg:CC FLAGS_REG))]
13215 "TARGET_64BIT && TARGET_GNU2_TLS"
13218 [(set (match_dup 0) (match_dup 4))]
13220 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13221 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13224 ;; These patterns match the binary 387 instructions for addM3, subM3,
13225 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13226 ;; SFmode. The first is the normal insn, the second the same insn but
13227 ;; with one operand a conversion, and the third the same insn but with
13228 ;; the other operand a conversion. The conversion may be SFmode or
13229 ;; SImode if the target mode DFmode, but only SImode if the target mode
13232 ;; Gcc is slightly more smart about handling normal two address instructions
13233 ;; so use special patterns for add and mull.
13235 (define_insn "*fop_<mode>_comm_mixed"
13236 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13237 (match_operator:MODEF 3 "binary_fp_operator"
13238 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13239 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13240 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13241 && COMMUTATIVE_ARITH_P (operands[3])
13242 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13243 "* return output_387_binary_op (insn, operands);"
13244 [(set (attr "type")
13245 (if_then_else (eq_attr "alternative" "1,2")
13246 (if_then_else (match_operand:MODEF 3 "mult_operator")
13247 (const_string "ssemul")
13248 (const_string "sseadd"))
13249 (if_then_else (match_operand:MODEF 3 "mult_operator")
13250 (const_string "fmul")
13251 (const_string "fop"))))
13252 (set_attr "isa" "*,noavx,avx")
13253 (set_attr "prefix" "orig,orig,vex")
13254 (set_attr "mode" "<MODE>")])
13256 (define_insn "*fop_<mode>_comm_sse"
13257 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13258 (match_operator:MODEF 3 "binary_fp_operator"
13259 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13260 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13261 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13262 && COMMUTATIVE_ARITH_P (operands[3])
13263 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13264 "* return output_387_binary_op (insn, operands);"
13265 [(set (attr "type")
13266 (if_then_else (match_operand:MODEF 3 "mult_operator")
13267 (const_string "ssemul")
13268 (const_string "sseadd")))
13269 (set_attr "isa" "noavx,avx")
13270 (set_attr "prefix" "orig,vex")
13271 (set_attr "mode" "<MODE>")])
13273 (define_insn "*fop_<mode>_comm_i387"
13274 [(set (match_operand:MODEF 0 "register_operand" "=f")
13275 (match_operator:MODEF 3 "binary_fp_operator"
13276 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13277 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13278 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13279 && COMMUTATIVE_ARITH_P (operands[3])
13280 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13281 "* return output_387_binary_op (insn, operands);"
13282 [(set (attr "type")
13283 (if_then_else (match_operand:MODEF 3 "mult_operator")
13284 (const_string "fmul")
13285 (const_string "fop")))
13286 (set_attr "mode" "<MODE>")])
13288 (define_insn "*fop_<mode>_1_mixed"
13289 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13290 (match_operator:MODEF 3 "binary_fp_operator"
13291 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13292 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13293 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13294 && !COMMUTATIVE_ARITH_P (operands[3])
13295 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13296 "* return output_387_binary_op (insn, operands);"
13297 [(set (attr "type")
13298 (cond [(and (eq_attr "alternative" "2,3")
13299 (match_operand:MODEF 3 "mult_operator"))
13300 (const_string "ssemul")
13301 (and (eq_attr "alternative" "2,3")
13302 (match_operand:MODEF 3 "div_operator"))
13303 (const_string "ssediv")
13304 (eq_attr "alternative" "2,3")
13305 (const_string "sseadd")
13306 (match_operand:MODEF 3 "mult_operator")
13307 (const_string "fmul")
13308 (match_operand:MODEF 3 "div_operator")
13309 (const_string "fdiv")
13311 (const_string "fop")))
13312 (set_attr "isa" "*,*,noavx,avx")
13313 (set_attr "prefix" "orig,orig,orig,vex")
13314 (set_attr "mode" "<MODE>")])
13316 (define_insn "*rcpsf2_sse"
13317 [(set (match_operand:SF 0 "register_operand" "=x")
13318 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13321 "%vrcpss\t{%1, %d0|%d0, %1}"
13322 [(set_attr "type" "sse")
13323 (set_attr "atom_sse_attr" "rcp")
13324 (set_attr "prefix" "maybe_vex")
13325 (set_attr "mode" "SF")])
13327 (define_insn "*fop_<mode>_1_sse"
13328 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13329 (match_operator:MODEF 3 "binary_fp_operator"
13330 [(match_operand:MODEF 1 "register_operand" "0,x")
13331 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13332 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13333 && !COMMUTATIVE_ARITH_P (operands[3])"
13334 "* return output_387_binary_op (insn, operands);"
13335 [(set (attr "type")
13336 (cond [(match_operand:MODEF 3 "mult_operator")
13337 (const_string "ssemul")
13338 (match_operand:MODEF 3 "div_operator")
13339 (const_string "ssediv")
13341 (const_string "sseadd")))
13342 (set_attr "isa" "noavx,avx")
13343 (set_attr "prefix" "orig,vex")
13344 (set_attr "mode" "<MODE>")])
13346 ;; This pattern is not fully shadowed by the pattern above.
13347 (define_insn "*fop_<mode>_1_i387"
13348 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13349 (match_operator:MODEF 3 "binary_fp_operator"
13350 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13351 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13352 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13353 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13354 && !COMMUTATIVE_ARITH_P (operands[3])
13355 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13356 "* return output_387_binary_op (insn, operands);"
13357 [(set (attr "type")
13358 (cond [(match_operand:MODEF 3 "mult_operator")
13359 (const_string "fmul")
13360 (match_operand:MODEF 3 "div_operator")
13361 (const_string "fdiv")
13363 (const_string "fop")))
13364 (set_attr "mode" "<MODE>")])
13366 ;; ??? Add SSE splitters for these!
13367 (define_insn "*fop_<MODEF:mode>_2_i387"
13368 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13369 (match_operator:MODEF 3 "binary_fp_operator"
13371 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13372 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13373 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13374 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13375 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13376 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13377 [(set (attr "type")
13378 (cond [(match_operand:MODEF 3 "mult_operator")
13379 (const_string "fmul")
13380 (match_operand:MODEF 3 "div_operator")
13381 (const_string "fdiv")
13383 (const_string "fop")))
13384 (set_attr "fp_int_src" "true")
13385 (set_attr "mode" "<SWI24:MODE>")])
13387 (define_insn "*fop_<MODEF:mode>_3_i387"
13388 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13389 (match_operator:MODEF 3 "binary_fp_operator"
13390 [(match_operand:MODEF 1 "register_operand" "0,0")
13392 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13393 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13394 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13395 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13396 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13397 [(set (attr "type")
13398 (cond [(match_operand:MODEF 3 "mult_operator")
13399 (const_string "fmul")
13400 (match_operand:MODEF 3 "div_operator")
13401 (const_string "fdiv")
13403 (const_string "fop")))
13404 (set_attr "fp_int_src" "true")
13405 (set_attr "mode" "<MODE>")])
13407 (define_insn "*fop_df_4_i387"
13408 [(set (match_operand:DF 0 "register_operand" "=f,f")
13409 (match_operator:DF 3 "binary_fp_operator"
13411 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13412 (match_operand:DF 2 "register_operand" "0,f")]))]
13413 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13414 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13415 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13416 "* return output_387_binary_op (insn, operands);"
13417 [(set (attr "type")
13418 (cond [(match_operand:DF 3 "mult_operator")
13419 (const_string "fmul")
13420 (match_operand:DF 3 "div_operator")
13421 (const_string "fdiv")
13423 (const_string "fop")))
13424 (set_attr "mode" "SF")])
13426 (define_insn "*fop_df_5_i387"
13427 [(set (match_operand:DF 0 "register_operand" "=f,f")
13428 (match_operator:DF 3 "binary_fp_operator"
13429 [(match_operand:DF 1 "register_operand" "0,f")
13431 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13432 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13433 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13434 "* return output_387_binary_op (insn, operands);"
13435 [(set (attr "type")
13436 (cond [(match_operand:DF 3 "mult_operator")
13437 (const_string "fmul")
13438 (match_operand:DF 3 "div_operator")
13439 (const_string "fdiv")
13441 (const_string "fop")))
13442 (set_attr "mode" "SF")])
13444 (define_insn "*fop_df_6_i387"
13445 [(set (match_operand:DF 0 "register_operand" "=f,f")
13446 (match_operator:DF 3 "binary_fp_operator"
13448 (match_operand:SF 1 "register_operand" "0,f"))
13450 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13451 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13452 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13453 "* return output_387_binary_op (insn, operands);"
13454 [(set (attr "type")
13455 (cond [(match_operand:DF 3 "mult_operator")
13456 (const_string "fmul")
13457 (match_operand:DF 3 "div_operator")
13458 (const_string "fdiv")
13460 (const_string "fop")))
13461 (set_attr "mode" "SF")])
13463 (define_insn "*fop_xf_comm_i387"
13464 [(set (match_operand:XF 0 "register_operand" "=f")
13465 (match_operator:XF 3 "binary_fp_operator"
13466 [(match_operand:XF 1 "register_operand" "%0")
13467 (match_operand:XF 2 "register_operand" "f")]))]
13469 && COMMUTATIVE_ARITH_P (operands[3])"
13470 "* return output_387_binary_op (insn, operands);"
13471 [(set (attr "type")
13472 (if_then_else (match_operand:XF 3 "mult_operator")
13473 (const_string "fmul")
13474 (const_string "fop")))
13475 (set_attr "mode" "XF")])
13477 (define_insn "*fop_xf_1_i387"
13478 [(set (match_operand:XF 0 "register_operand" "=f,f")
13479 (match_operator:XF 3 "binary_fp_operator"
13480 [(match_operand:XF 1 "register_operand" "0,f")
13481 (match_operand:XF 2 "register_operand" "f,0")]))]
13483 && !COMMUTATIVE_ARITH_P (operands[3])"
13484 "* return output_387_binary_op (insn, operands);"
13485 [(set (attr "type")
13486 (cond [(match_operand:XF 3 "mult_operator")
13487 (const_string "fmul")
13488 (match_operand:XF 3 "div_operator")
13489 (const_string "fdiv")
13491 (const_string "fop")))
13492 (set_attr "mode" "XF")])
13494 (define_insn "*fop_xf_2_i387"
13495 [(set (match_operand:XF 0 "register_operand" "=f,f")
13496 (match_operator:XF 3 "binary_fp_operator"
13498 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13499 (match_operand:XF 2 "register_operand" "0,0")]))]
13500 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13501 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13502 [(set (attr "type")
13503 (cond [(match_operand:XF 3 "mult_operator")
13504 (const_string "fmul")
13505 (match_operand:XF 3 "div_operator")
13506 (const_string "fdiv")
13508 (const_string "fop")))
13509 (set_attr "fp_int_src" "true")
13510 (set_attr "mode" "<MODE>")])
13512 (define_insn "*fop_xf_3_i387"
13513 [(set (match_operand:XF 0 "register_operand" "=f,f")
13514 (match_operator:XF 3 "binary_fp_operator"
13515 [(match_operand:XF 1 "register_operand" "0,0")
13517 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13518 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13519 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13520 [(set (attr "type")
13521 (cond [(match_operand:XF 3 "mult_operator")
13522 (const_string "fmul")
13523 (match_operand:XF 3 "div_operator")
13524 (const_string "fdiv")
13526 (const_string "fop")))
13527 (set_attr "fp_int_src" "true")
13528 (set_attr "mode" "<MODE>")])
13530 (define_insn "*fop_xf_4_i387"
13531 [(set (match_operand:XF 0 "register_operand" "=f,f")
13532 (match_operator:XF 3 "binary_fp_operator"
13534 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13535 (match_operand:XF 2 "register_operand" "0,f")]))]
13537 "* return output_387_binary_op (insn, operands);"
13538 [(set (attr "type")
13539 (cond [(match_operand:XF 3 "mult_operator")
13540 (const_string "fmul")
13541 (match_operand:XF 3 "div_operator")
13542 (const_string "fdiv")
13544 (const_string "fop")))
13545 (set_attr "mode" "<MODE>")])
13547 (define_insn "*fop_xf_5_i387"
13548 [(set (match_operand:XF 0 "register_operand" "=f,f")
13549 (match_operator:XF 3 "binary_fp_operator"
13550 [(match_operand:XF 1 "register_operand" "0,f")
13552 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13554 "* return output_387_binary_op (insn, operands);"
13555 [(set (attr "type")
13556 (cond [(match_operand:XF 3 "mult_operator")
13557 (const_string "fmul")
13558 (match_operand:XF 3 "div_operator")
13559 (const_string "fdiv")
13561 (const_string "fop")))
13562 (set_attr "mode" "<MODE>")])
13564 (define_insn "*fop_xf_6_i387"
13565 [(set (match_operand:XF 0 "register_operand" "=f,f")
13566 (match_operator:XF 3 "binary_fp_operator"
13568 (match_operand:MODEF 1 "register_operand" "0,f"))
13570 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13572 "* return output_387_binary_op (insn, operands);"
13573 [(set (attr "type")
13574 (cond [(match_operand:XF 3 "mult_operator")
13575 (const_string "fmul")
13576 (match_operand:XF 3 "div_operator")
13577 (const_string "fdiv")
13579 (const_string "fop")))
13580 (set_attr "mode" "<MODE>")])
13583 [(set (match_operand 0 "register_operand")
13584 (match_operator 3 "binary_fp_operator"
13585 [(float (match_operand:SWI24 1 "register_operand"))
13586 (match_operand 2 "register_operand")]))]
13588 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13589 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13592 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13593 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13594 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13595 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13596 GET_MODE (operands[3]),
13599 ix86_free_from_memory (GET_MODE (operands[1]));
13604 [(set (match_operand 0 "register_operand")
13605 (match_operator 3 "binary_fp_operator"
13606 [(match_operand 1 "register_operand")
13607 (float (match_operand:SWI24 2 "register_operand"))]))]
13609 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13610 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13613 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13614 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13615 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13616 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13617 GET_MODE (operands[3]),
13620 ix86_free_from_memory (GET_MODE (operands[2]));
13624 ;; FPU special functions.
13626 ;; This pattern implements a no-op XFmode truncation for
13627 ;; all fancy i386 XFmode math functions.
13629 (define_insn "truncxf<mode>2_i387_noop_unspec"
13630 [(set (match_operand:MODEF 0 "register_operand" "=f")
13631 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13632 UNSPEC_TRUNC_NOOP))]
13633 "TARGET_USE_FANCY_MATH_387"
13634 "* return output_387_reg_move (insn, operands);"
13635 [(set_attr "type" "fmov")
13636 (set_attr "mode" "<MODE>")])
13638 (define_insn "sqrtxf2"
13639 [(set (match_operand:XF 0 "register_operand" "=f")
13640 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13641 "TARGET_USE_FANCY_MATH_387"
13643 [(set_attr "type" "fpspc")
13644 (set_attr "mode" "XF")
13645 (set_attr "athlon_decode" "direct")
13646 (set_attr "amdfam10_decode" "direct")
13647 (set_attr "bdver1_decode" "direct")])
13649 (define_insn "sqrt_extend<mode>xf2_i387"
13650 [(set (match_operand:XF 0 "register_operand" "=f")
13653 (match_operand:MODEF 1 "register_operand" "0"))))]
13654 "TARGET_USE_FANCY_MATH_387"
13656 [(set_attr "type" "fpspc")
13657 (set_attr "mode" "XF")
13658 (set_attr "athlon_decode" "direct")
13659 (set_attr "amdfam10_decode" "direct")
13660 (set_attr "bdver1_decode" "direct")])
13662 (define_insn "*rsqrtsf2_sse"
13663 [(set (match_operand:SF 0 "register_operand" "=x")
13664 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13667 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13668 [(set_attr "type" "sse")
13669 (set_attr "atom_sse_attr" "rcp")
13670 (set_attr "prefix" "maybe_vex")
13671 (set_attr "mode" "SF")])
13673 (define_expand "rsqrtsf2"
13674 [(set (match_operand:SF 0 "register_operand")
13675 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13679 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13683 (define_insn "*sqrt<mode>2_sse"
13684 [(set (match_operand:MODEF 0 "register_operand" "=x")
13686 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13687 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13688 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13689 [(set_attr "type" "sse")
13690 (set_attr "atom_sse_attr" "sqrt")
13691 (set_attr "prefix" "maybe_vex")
13692 (set_attr "mode" "<MODE>")
13693 (set_attr "athlon_decode" "*")
13694 (set_attr "amdfam10_decode" "*")
13695 (set_attr "bdver1_decode" "*")])
13697 (define_expand "sqrt<mode>2"
13698 [(set (match_operand:MODEF 0 "register_operand")
13700 (match_operand:MODEF 1 "nonimmediate_operand")))]
13701 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13702 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13704 if (<MODE>mode == SFmode
13706 && TARGET_RECIP_SQRT
13707 && !optimize_function_for_size_p (cfun)
13708 && flag_finite_math_only && !flag_trapping_math
13709 && flag_unsafe_math_optimizations)
13711 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13715 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13717 rtx op0 = gen_reg_rtx (XFmode);
13718 rtx op1 = force_reg (<MODE>mode, operands[1]);
13720 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13721 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13726 (define_insn "fpremxf4_i387"
13727 [(set (match_operand:XF 0 "register_operand" "=f")
13728 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13729 (match_operand:XF 3 "register_operand" "1")]
13731 (set (match_operand:XF 1 "register_operand" "=u")
13732 (unspec:XF [(match_dup 2) (match_dup 3)]
13734 (set (reg:CCFP FPSR_REG)
13735 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13737 "TARGET_USE_FANCY_MATH_387"
13739 [(set_attr "type" "fpspc")
13740 (set_attr "mode" "XF")])
13742 (define_expand "fmodxf3"
13743 [(use (match_operand:XF 0 "register_operand"))
13744 (use (match_operand:XF 1 "general_operand"))
13745 (use (match_operand:XF 2 "general_operand"))]
13746 "TARGET_USE_FANCY_MATH_387"
13748 rtx label = gen_label_rtx ();
13750 rtx op1 = gen_reg_rtx (XFmode);
13751 rtx op2 = gen_reg_rtx (XFmode);
13753 emit_move_insn (op2, operands[2]);
13754 emit_move_insn (op1, operands[1]);
13756 emit_label (label);
13757 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13758 ix86_emit_fp_unordered_jump (label);
13759 LABEL_NUSES (label) = 1;
13761 emit_move_insn (operands[0], op1);
13765 (define_expand "fmod<mode>3"
13766 [(use (match_operand:MODEF 0 "register_operand"))
13767 (use (match_operand:MODEF 1 "general_operand"))
13768 (use (match_operand:MODEF 2 "general_operand"))]
13769 "TARGET_USE_FANCY_MATH_387"
13771 rtx (*gen_truncxf) (rtx, rtx);
13773 rtx label = gen_label_rtx ();
13775 rtx op1 = gen_reg_rtx (XFmode);
13776 rtx op2 = gen_reg_rtx (XFmode);
13778 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13779 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13781 emit_label (label);
13782 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13783 ix86_emit_fp_unordered_jump (label);
13784 LABEL_NUSES (label) = 1;
13786 /* Truncate the result properly for strict SSE math. */
13787 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13788 && !TARGET_MIX_SSE_I387)
13789 gen_truncxf = gen_truncxf<mode>2;
13791 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13793 emit_insn (gen_truncxf (operands[0], op1));
13797 (define_insn "fprem1xf4_i387"
13798 [(set (match_operand:XF 0 "register_operand" "=f")
13799 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13800 (match_operand:XF 3 "register_operand" "1")]
13802 (set (match_operand:XF 1 "register_operand" "=u")
13803 (unspec:XF [(match_dup 2) (match_dup 3)]
13805 (set (reg:CCFP FPSR_REG)
13806 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13808 "TARGET_USE_FANCY_MATH_387"
13810 [(set_attr "type" "fpspc")
13811 (set_attr "mode" "XF")])
13813 (define_expand "remainderxf3"
13814 [(use (match_operand:XF 0 "register_operand"))
13815 (use (match_operand:XF 1 "general_operand"))
13816 (use (match_operand:XF 2 "general_operand"))]
13817 "TARGET_USE_FANCY_MATH_387"
13819 rtx label = gen_label_rtx ();
13821 rtx op1 = gen_reg_rtx (XFmode);
13822 rtx op2 = gen_reg_rtx (XFmode);
13824 emit_move_insn (op2, operands[2]);
13825 emit_move_insn (op1, operands[1]);
13827 emit_label (label);
13828 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13829 ix86_emit_fp_unordered_jump (label);
13830 LABEL_NUSES (label) = 1;
13832 emit_move_insn (operands[0], op1);
13836 (define_expand "remainder<mode>3"
13837 [(use (match_operand:MODEF 0 "register_operand"))
13838 (use (match_operand:MODEF 1 "general_operand"))
13839 (use (match_operand:MODEF 2 "general_operand"))]
13840 "TARGET_USE_FANCY_MATH_387"
13842 rtx (*gen_truncxf) (rtx, rtx);
13844 rtx label = gen_label_rtx ();
13846 rtx op1 = gen_reg_rtx (XFmode);
13847 rtx op2 = gen_reg_rtx (XFmode);
13849 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13850 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13852 emit_label (label);
13854 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13855 ix86_emit_fp_unordered_jump (label);
13856 LABEL_NUSES (label) = 1;
13858 /* Truncate the result properly for strict SSE math. */
13859 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13860 && !TARGET_MIX_SSE_I387)
13861 gen_truncxf = gen_truncxf<mode>2;
13863 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13865 emit_insn (gen_truncxf (operands[0], op1));
13869 (define_int_iterator SINCOS
13873 (define_int_attr sincos
13874 [(UNSPEC_SIN "sin")
13875 (UNSPEC_COS "cos")])
13877 (define_insn "*<sincos>xf2_i387"
13878 [(set (match_operand:XF 0 "register_operand" "=f")
13879 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13881 "TARGET_USE_FANCY_MATH_387
13882 && flag_unsafe_math_optimizations"
13884 [(set_attr "type" "fpspc")
13885 (set_attr "mode" "XF")])
13887 (define_insn "*<sincos>_extend<mode>xf2_i387"
13888 [(set (match_operand:XF 0 "register_operand" "=f")
13889 (unspec:XF [(float_extend:XF
13890 (match_operand:MODEF 1 "register_operand" "0"))]
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"
13897 [(set_attr "type" "fpspc")
13898 (set_attr "mode" "XF")])
13900 ;; When sincos pattern is defined, sin and cos builtin functions will be
13901 ;; expanded to sincos pattern with one of its outputs left unused.
13902 ;; CSE pass will figure out if two sincos patterns can be combined,
13903 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13904 ;; depending on the unused output.
13906 (define_insn "sincosxf3"
13907 [(set (match_operand:XF 0 "register_operand" "=f")
13908 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13909 UNSPEC_SINCOS_COS))
13910 (set (match_operand:XF 1 "register_operand" "=u")
13911 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13912 "TARGET_USE_FANCY_MATH_387
13913 && flag_unsafe_math_optimizations"
13915 [(set_attr "type" "fpspc")
13916 (set_attr "mode" "XF")])
13919 [(set (match_operand:XF 0 "register_operand")
13920 (unspec:XF [(match_operand:XF 2 "register_operand")]
13921 UNSPEC_SINCOS_COS))
13922 (set (match_operand:XF 1 "register_operand")
13923 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13924 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13925 && can_create_pseudo_p ()"
13926 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13929 [(set (match_operand:XF 0 "register_operand")
13930 (unspec:XF [(match_operand:XF 2 "register_operand")]
13931 UNSPEC_SINCOS_COS))
13932 (set (match_operand:XF 1 "register_operand")
13933 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13934 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13935 && can_create_pseudo_p ()"
13936 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13938 (define_insn "sincos_extend<mode>xf3_i387"
13939 [(set (match_operand:XF 0 "register_operand" "=f")
13940 (unspec:XF [(float_extend:XF
13941 (match_operand:MODEF 2 "register_operand" "0"))]
13942 UNSPEC_SINCOS_COS))
13943 (set (match_operand:XF 1 "register_operand" "=u")
13944 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13945 "TARGET_USE_FANCY_MATH_387
13946 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13947 || TARGET_MIX_SSE_I387)
13948 && flag_unsafe_math_optimizations"
13950 [(set_attr "type" "fpspc")
13951 (set_attr "mode" "XF")])
13954 [(set (match_operand:XF 0 "register_operand")
13955 (unspec:XF [(float_extend:XF
13956 (match_operand:MODEF 2 "register_operand"))]
13957 UNSPEC_SINCOS_COS))
13958 (set (match_operand:XF 1 "register_operand")
13959 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13960 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13961 && can_create_pseudo_p ()"
13962 [(set (match_dup 1)
13963 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13966 [(set (match_operand:XF 0 "register_operand")
13967 (unspec:XF [(float_extend:XF
13968 (match_operand:MODEF 2 "register_operand"))]
13969 UNSPEC_SINCOS_COS))
13970 (set (match_operand:XF 1 "register_operand")
13971 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13972 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13973 && can_create_pseudo_p ()"
13974 [(set (match_dup 0)
13975 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13977 (define_expand "sincos<mode>3"
13978 [(use (match_operand:MODEF 0 "register_operand"))
13979 (use (match_operand:MODEF 1 "register_operand"))
13980 (use (match_operand:MODEF 2 "register_operand"))]
13981 "TARGET_USE_FANCY_MATH_387
13982 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13983 || TARGET_MIX_SSE_I387)
13984 && flag_unsafe_math_optimizations"
13986 rtx op0 = gen_reg_rtx (XFmode);
13987 rtx op1 = gen_reg_rtx (XFmode);
13989 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13990 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13991 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13995 (define_insn "fptanxf4_i387"
13996 [(set (match_operand:XF 0 "register_operand" "=f")
13997 (match_operand:XF 3 "const_double_operand" "F"))
13998 (set (match_operand:XF 1 "register_operand" "=u")
13999 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14001 "TARGET_USE_FANCY_MATH_387
14002 && flag_unsafe_math_optimizations
14003 && standard_80387_constant_p (operands[3]) == 2"
14005 [(set_attr "type" "fpspc")
14006 (set_attr "mode" "XF")])
14008 (define_insn "fptan_extend<mode>xf4_i387"
14009 [(set (match_operand:MODEF 0 "register_operand" "=f")
14010 (match_operand:MODEF 3 "const_double_operand" "F"))
14011 (set (match_operand:XF 1 "register_operand" "=u")
14012 (unspec:XF [(float_extend:XF
14013 (match_operand:MODEF 2 "register_operand" "0"))]
14015 "TARGET_USE_FANCY_MATH_387
14016 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14017 || TARGET_MIX_SSE_I387)
14018 && flag_unsafe_math_optimizations
14019 && standard_80387_constant_p (operands[3]) == 2"
14021 [(set_attr "type" "fpspc")
14022 (set_attr "mode" "XF")])
14024 (define_expand "tanxf2"
14025 [(use (match_operand:XF 0 "register_operand"))
14026 (use (match_operand:XF 1 "register_operand"))]
14027 "TARGET_USE_FANCY_MATH_387
14028 && flag_unsafe_math_optimizations"
14030 rtx one = gen_reg_rtx (XFmode);
14031 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14033 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14037 (define_expand "tan<mode>2"
14038 [(use (match_operand:MODEF 0 "register_operand"))
14039 (use (match_operand:MODEF 1 "register_operand"))]
14040 "TARGET_USE_FANCY_MATH_387
14041 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14042 || TARGET_MIX_SSE_I387)
14043 && flag_unsafe_math_optimizations"
14045 rtx op0 = gen_reg_rtx (XFmode);
14047 rtx one = gen_reg_rtx (<MODE>mode);
14048 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14050 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14051 operands[1], op2));
14052 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14056 (define_insn "*fpatanxf3_i387"
14057 [(set (match_operand:XF 0 "register_operand" "=f")
14058 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14059 (match_operand:XF 2 "register_operand" "u")]
14061 (clobber (match_scratch:XF 3 "=2"))]
14062 "TARGET_USE_FANCY_MATH_387
14063 && flag_unsafe_math_optimizations"
14065 [(set_attr "type" "fpspc")
14066 (set_attr "mode" "XF")])
14068 (define_insn "fpatan_extend<mode>xf3_i387"
14069 [(set (match_operand:XF 0 "register_operand" "=f")
14070 (unspec:XF [(float_extend:XF
14071 (match_operand:MODEF 1 "register_operand" "0"))
14073 (match_operand:MODEF 2 "register_operand" "u"))]
14075 (clobber (match_scratch:XF 3 "=2"))]
14076 "TARGET_USE_FANCY_MATH_387
14077 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14078 || TARGET_MIX_SSE_I387)
14079 && flag_unsafe_math_optimizations"
14081 [(set_attr "type" "fpspc")
14082 (set_attr "mode" "XF")])
14084 (define_expand "atan2xf3"
14085 [(parallel [(set (match_operand:XF 0 "register_operand")
14086 (unspec:XF [(match_operand:XF 2 "register_operand")
14087 (match_operand:XF 1 "register_operand")]
14089 (clobber (match_scratch:XF 3))])]
14090 "TARGET_USE_FANCY_MATH_387
14091 && flag_unsafe_math_optimizations")
14093 (define_expand "atan2<mode>3"
14094 [(use (match_operand:MODEF 0 "register_operand"))
14095 (use (match_operand:MODEF 1 "register_operand"))
14096 (use (match_operand:MODEF 2 "register_operand"))]
14097 "TARGET_USE_FANCY_MATH_387
14098 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14099 || TARGET_MIX_SSE_I387)
14100 && flag_unsafe_math_optimizations"
14102 rtx op0 = gen_reg_rtx (XFmode);
14104 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14105 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14109 (define_expand "atanxf2"
14110 [(parallel [(set (match_operand:XF 0 "register_operand")
14111 (unspec:XF [(match_dup 2)
14112 (match_operand:XF 1 "register_operand")]
14114 (clobber (match_scratch:XF 3))])]
14115 "TARGET_USE_FANCY_MATH_387
14116 && flag_unsafe_math_optimizations"
14118 operands[2] = gen_reg_rtx (XFmode);
14119 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14122 (define_expand "atan<mode>2"
14123 [(use (match_operand:MODEF 0 "register_operand"))
14124 (use (match_operand:MODEF 1 "register_operand"))]
14125 "TARGET_USE_FANCY_MATH_387
14126 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14127 || TARGET_MIX_SSE_I387)
14128 && flag_unsafe_math_optimizations"
14130 rtx op0 = gen_reg_rtx (XFmode);
14132 rtx op2 = gen_reg_rtx (<MODE>mode);
14133 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14135 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14136 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14140 (define_expand "asinxf2"
14141 [(set (match_dup 2)
14142 (mult:XF (match_operand:XF 1 "register_operand")
14144 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14145 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14146 (parallel [(set (match_operand:XF 0 "register_operand")
14147 (unspec:XF [(match_dup 5) (match_dup 1)]
14149 (clobber (match_scratch:XF 6))])]
14150 "TARGET_USE_FANCY_MATH_387
14151 && flag_unsafe_math_optimizations"
14155 if (optimize_insn_for_size_p ())
14158 for (i = 2; i < 6; i++)
14159 operands[i] = gen_reg_rtx (XFmode);
14161 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14164 (define_expand "asin<mode>2"
14165 [(use (match_operand:MODEF 0 "register_operand"))
14166 (use (match_operand:MODEF 1 "general_operand"))]
14167 "TARGET_USE_FANCY_MATH_387
14168 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14169 || TARGET_MIX_SSE_I387)
14170 && flag_unsafe_math_optimizations"
14172 rtx op0 = gen_reg_rtx (XFmode);
14173 rtx op1 = gen_reg_rtx (XFmode);
14175 if (optimize_insn_for_size_p ())
14178 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14179 emit_insn (gen_asinxf2 (op0, op1));
14180 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14184 (define_expand "acosxf2"
14185 [(set (match_dup 2)
14186 (mult:XF (match_operand:XF 1 "register_operand")
14188 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14189 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14190 (parallel [(set (match_operand:XF 0 "register_operand")
14191 (unspec:XF [(match_dup 1) (match_dup 5)]
14193 (clobber (match_scratch:XF 6))])]
14194 "TARGET_USE_FANCY_MATH_387
14195 && flag_unsafe_math_optimizations"
14199 if (optimize_insn_for_size_p ())
14202 for (i = 2; i < 6; i++)
14203 operands[i] = gen_reg_rtx (XFmode);
14205 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14208 (define_expand "acos<mode>2"
14209 [(use (match_operand:MODEF 0 "register_operand"))
14210 (use (match_operand:MODEF 1 "general_operand"))]
14211 "TARGET_USE_FANCY_MATH_387
14212 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14213 || TARGET_MIX_SSE_I387)
14214 && flag_unsafe_math_optimizations"
14216 rtx op0 = gen_reg_rtx (XFmode);
14217 rtx op1 = gen_reg_rtx (XFmode);
14219 if (optimize_insn_for_size_p ())
14222 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14223 emit_insn (gen_acosxf2 (op0, op1));
14224 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14228 (define_insn "fyl2xxf3_i387"
14229 [(set (match_operand:XF 0 "register_operand" "=f")
14230 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14231 (match_operand:XF 2 "register_operand" "u")]
14233 (clobber (match_scratch:XF 3 "=2"))]
14234 "TARGET_USE_FANCY_MATH_387
14235 && flag_unsafe_math_optimizations"
14237 [(set_attr "type" "fpspc")
14238 (set_attr "mode" "XF")])
14240 (define_insn "fyl2x_extend<mode>xf3_i387"
14241 [(set (match_operand:XF 0 "register_operand" "=f")
14242 (unspec:XF [(float_extend:XF
14243 (match_operand:MODEF 1 "register_operand" "0"))
14244 (match_operand:XF 2 "register_operand" "u")]
14246 (clobber (match_scratch:XF 3 "=2"))]
14247 "TARGET_USE_FANCY_MATH_387
14248 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14249 || TARGET_MIX_SSE_I387)
14250 && flag_unsafe_math_optimizations"
14252 [(set_attr "type" "fpspc")
14253 (set_attr "mode" "XF")])
14255 (define_expand "logxf2"
14256 [(parallel [(set (match_operand:XF 0 "register_operand")
14257 (unspec:XF [(match_operand:XF 1 "register_operand")
14258 (match_dup 2)] UNSPEC_FYL2X))
14259 (clobber (match_scratch:XF 3))])]
14260 "TARGET_USE_FANCY_MATH_387
14261 && flag_unsafe_math_optimizations"
14263 operands[2] = gen_reg_rtx (XFmode);
14264 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14267 (define_expand "log<mode>2"
14268 [(use (match_operand:MODEF 0 "register_operand"))
14269 (use (match_operand:MODEF 1 "register_operand"))]
14270 "TARGET_USE_FANCY_MATH_387
14271 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14272 || TARGET_MIX_SSE_I387)
14273 && flag_unsafe_math_optimizations"
14275 rtx op0 = gen_reg_rtx (XFmode);
14277 rtx op2 = gen_reg_rtx (XFmode);
14278 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14280 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14281 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14285 (define_expand "log10xf2"
14286 [(parallel [(set (match_operand:XF 0 "register_operand")
14287 (unspec:XF [(match_operand:XF 1 "register_operand")
14288 (match_dup 2)] UNSPEC_FYL2X))
14289 (clobber (match_scratch:XF 3))])]
14290 "TARGET_USE_FANCY_MATH_387
14291 && flag_unsafe_math_optimizations"
14293 operands[2] = gen_reg_rtx (XFmode);
14294 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14297 (define_expand "log10<mode>2"
14298 [(use (match_operand:MODEF 0 "register_operand"))
14299 (use (match_operand:MODEF 1 "register_operand"))]
14300 "TARGET_USE_FANCY_MATH_387
14301 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14302 || TARGET_MIX_SSE_I387)
14303 && flag_unsafe_math_optimizations"
14305 rtx op0 = gen_reg_rtx (XFmode);
14307 rtx op2 = gen_reg_rtx (XFmode);
14308 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14310 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14311 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14315 (define_expand "log2xf2"
14316 [(parallel [(set (match_operand:XF 0 "register_operand")
14317 (unspec:XF [(match_operand:XF 1 "register_operand")
14318 (match_dup 2)] UNSPEC_FYL2X))
14319 (clobber (match_scratch:XF 3))])]
14320 "TARGET_USE_FANCY_MATH_387
14321 && flag_unsafe_math_optimizations"
14323 operands[2] = gen_reg_rtx (XFmode);
14324 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14327 (define_expand "log2<mode>2"
14328 [(use (match_operand:MODEF 0 "register_operand"))
14329 (use (match_operand:MODEF 1 "register_operand"))]
14330 "TARGET_USE_FANCY_MATH_387
14331 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14332 || TARGET_MIX_SSE_I387)
14333 && flag_unsafe_math_optimizations"
14335 rtx op0 = gen_reg_rtx (XFmode);
14337 rtx op2 = gen_reg_rtx (XFmode);
14338 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14340 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14341 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14345 (define_insn "fyl2xp1xf3_i387"
14346 [(set (match_operand:XF 0 "register_operand" "=f")
14347 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14348 (match_operand:XF 2 "register_operand" "u")]
14350 (clobber (match_scratch:XF 3 "=2"))]
14351 "TARGET_USE_FANCY_MATH_387
14352 && flag_unsafe_math_optimizations"
14354 [(set_attr "type" "fpspc")
14355 (set_attr "mode" "XF")])
14357 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14358 [(set (match_operand:XF 0 "register_operand" "=f")
14359 (unspec:XF [(float_extend:XF
14360 (match_operand:MODEF 1 "register_operand" "0"))
14361 (match_operand:XF 2 "register_operand" "u")]
14363 (clobber (match_scratch:XF 3 "=2"))]
14364 "TARGET_USE_FANCY_MATH_387
14365 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14366 || TARGET_MIX_SSE_I387)
14367 && flag_unsafe_math_optimizations"
14369 [(set_attr "type" "fpspc")
14370 (set_attr "mode" "XF")])
14372 (define_expand "log1pxf2"
14373 [(use (match_operand:XF 0 "register_operand"))
14374 (use (match_operand:XF 1 "register_operand"))]
14375 "TARGET_USE_FANCY_MATH_387
14376 && flag_unsafe_math_optimizations"
14378 if (optimize_insn_for_size_p ())
14381 ix86_emit_i387_log1p (operands[0], operands[1]);
14385 (define_expand "log1p<mode>2"
14386 [(use (match_operand:MODEF 0 "register_operand"))
14387 (use (match_operand:MODEF 1 "register_operand"))]
14388 "TARGET_USE_FANCY_MATH_387
14389 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14390 || TARGET_MIX_SSE_I387)
14391 && flag_unsafe_math_optimizations"
14395 if (optimize_insn_for_size_p ())
14398 op0 = gen_reg_rtx (XFmode);
14400 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14402 ix86_emit_i387_log1p (op0, operands[1]);
14403 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14407 (define_insn "fxtractxf3_i387"
14408 [(set (match_operand:XF 0 "register_operand" "=f")
14409 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14410 UNSPEC_XTRACT_FRACT))
14411 (set (match_operand:XF 1 "register_operand" "=u")
14412 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14413 "TARGET_USE_FANCY_MATH_387
14414 && flag_unsafe_math_optimizations"
14416 [(set_attr "type" "fpspc")
14417 (set_attr "mode" "XF")])
14419 (define_insn "fxtract_extend<mode>xf3_i387"
14420 [(set (match_operand:XF 0 "register_operand" "=f")
14421 (unspec:XF [(float_extend:XF
14422 (match_operand:MODEF 2 "register_operand" "0"))]
14423 UNSPEC_XTRACT_FRACT))
14424 (set (match_operand:XF 1 "register_operand" "=u")
14425 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14426 "TARGET_USE_FANCY_MATH_387
14427 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14428 || TARGET_MIX_SSE_I387)
14429 && flag_unsafe_math_optimizations"
14431 [(set_attr "type" "fpspc")
14432 (set_attr "mode" "XF")])
14434 (define_expand "logbxf2"
14435 [(parallel [(set (match_dup 2)
14436 (unspec:XF [(match_operand:XF 1 "register_operand")]
14437 UNSPEC_XTRACT_FRACT))
14438 (set (match_operand:XF 0 "register_operand")
14439 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14440 "TARGET_USE_FANCY_MATH_387
14441 && flag_unsafe_math_optimizations"
14442 "operands[2] = gen_reg_rtx (XFmode);")
14444 (define_expand "logb<mode>2"
14445 [(use (match_operand:MODEF 0 "register_operand"))
14446 (use (match_operand:MODEF 1 "register_operand"))]
14447 "TARGET_USE_FANCY_MATH_387
14448 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14449 || TARGET_MIX_SSE_I387)
14450 && flag_unsafe_math_optimizations"
14452 rtx op0 = gen_reg_rtx (XFmode);
14453 rtx op1 = gen_reg_rtx (XFmode);
14455 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14456 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14460 (define_expand "ilogbxf2"
14461 [(use (match_operand:SI 0 "register_operand"))
14462 (use (match_operand:XF 1 "register_operand"))]
14463 "TARGET_USE_FANCY_MATH_387
14464 && flag_unsafe_math_optimizations"
14468 if (optimize_insn_for_size_p ())
14471 op0 = gen_reg_rtx (XFmode);
14472 op1 = gen_reg_rtx (XFmode);
14474 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14475 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14479 (define_expand "ilogb<mode>2"
14480 [(use (match_operand:SI 0 "register_operand"))
14481 (use (match_operand:MODEF 1 "register_operand"))]
14482 "TARGET_USE_FANCY_MATH_387
14483 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14484 || TARGET_MIX_SSE_I387)
14485 && flag_unsafe_math_optimizations"
14489 if (optimize_insn_for_size_p ())
14492 op0 = gen_reg_rtx (XFmode);
14493 op1 = gen_reg_rtx (XFmode);
14495 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14496 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14500 (define_insn "*f2xm1xf2_i387"
14501 [(set (match_operand:XF 0 "register_operand" "=f")
14502 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14504 "TARGET_USE_FANCY_MATH_387
14505 && flag_unsafe_math_optimizations"
14507 [(set_attr "type" "fpspc")
14508 (set_attr "mode" "XF")])
14510 (define_insn "*fscalexf4_i387"
14511 [(set (match_operand:XF 0 "register_operand" "=f")
14512 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14513 (match_operand:XF 3 "register_operand" "1")]
14514 UNSPEC_FSCALE_FRACT))
14515 (set (match_operand:XF 1 "register_operand" "=u")
14516 (unspec:XF [(match_dup 2) (match_dup 3)]
14517 UNSPEC_FSCALE_EXP))]
14518 "TARGET_USE_FANCY_MATH_387
14519 && flag_unsafe_math_optimizations"
14521 [(set_attr "type" "fpspc")
14522 (set_attr "mode" "XF")])
14524 (define_expand "expNcorexf3"
14525 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14526 (match_operand:XF 2 "register_operand")))
14527 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14528 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14529 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14530 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14531 (parallel [(set (match_operand:XF 0 "register_operand")
14532 (unspec:XF [(match_dup 8) (match_dup 4)]
14533 UNSPEC_FSCALE_FRACT))
14535 (unspec:XF [(match_dup 8) (match_dup 4)]
14536 UNSPEC_FSCALE_EXP))])]
14537 "TARGET_USE_FANCY_MATH_387
14538 && flag_unsafe_math_optimizations"
14542 if (optimize_insn_for_size_p ())
14545 for (i = 3; i < 10; i++)
14546 operands[i] = gen_reg_rtx (XFmode);
14548 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14551 (define_expand "expxf2"
14552 [(use (match_operand:XF 0 "register_operand"))
14553 (use (match_operand:XF 1 "register_operand"))]
14554 "TARGET_USE_FANCY_MATH_387
14555 && flag_unsafe_math_optimizations"
14559 if (optimize_insn_for_size_p ())
14562 op2 = gen_reg_rtx (XFmode);
14563 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14565 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14569 (define_expand "exp<mode>2"
14570 [(use (match_operand:MODEF 0 "register_operand"))
14571 (use (match_operand:MODEF 1 "general_operand"))]
14572 "TARGET_USE_FANCY_MATH_387
14573 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14574 || TARGET_MIX_SSE_I387)
14575 && flag_unsafe_math_optimizations"
14579 if (optimize_insn_for_size_p ())
14582 op0 = gen_reg_rtx (XFmode);
14583 op1 = gen_reg_rtx (XFmode);
14585 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14586 emit_insn (gen_expxf2 (op0, op1));
14587 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14591 (define_expand "exp10xf2"
14592 [(use (match_operand:XF 0 "register_operand"))
14593 (use (match_operand:XF 1 "register_operand"))]
14594 "TARGET_USE_FANCY_MATH_387
14595 && flag_unsafe_math_optimizations"
14599 if (optimize_insn_for_size_p ())
14602 op2 = gen_reg_rtx (XFmode);
14603 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14605 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14609 (define_expand "exp10<mode>2"
14610 [(use (match_operand:MODEF 0 "register_operand"))
14611 (use (match_operand:MODEF 1 "general_operand"))]
14612 "TARGET_USE_FANCY_MATH_387
14613 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14614 || TARGET_MIX_SSE_I387)
14615 && flag_unsafe_math_optimizations"
14619 if (optimize_insn_for_size_p ())
14622 op0 = gen_reg_rtx (XFmode);
14623 op1 = gen_reg_rtx (XFmode);
14625 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14626 emit_insn (gen_exp10xf2 (op0, op1));
14627 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14631 (define_expand "exp2xf2"
14632 [(use (match_operand:XF 0 "register_operand"))
14633 (use (match_operand:XF 1 "register_operand"))]
14634 "TARGET_USE_FANCY_MATH_387
14635 && flag_unsafe_math_optimizations"
14639 if (optimize_insn_for_size_p ())
14642 op2 = gen_reg_rtx (XFmode);
14643 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14645 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14649 (define_expand "exp2<mode>2"
14650 [(use (match_operand:MODEF 0 "register_operand"))
14651 (use (match_operand:MODEF 1 "general_operand"))]
14652 "TARGET_USE_FANCY_MATH_387
14653 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14654 || TARGET_MIX_SSE_I387)
14655 && flag_unsafe_math_optimizations"
14659 if (optimize_insn_for_size_p ())
14662 op0 = gen_reg_rtx (XFmode);
14663 op1 = gen_reg_rtx (XFmode);
14665 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14666 emit_insn (gen_exp2xf2 (op0, op1));
14667 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14671 (define_expand "expm1xf2"
14672 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14674 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14675 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14676 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14677 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14678 (parallel [(set (match_dup 7)
14679 (unspec:XF [(match_dup 6) (match_dup 4)]
14680 UNSPEC_FSCALE_FRACT))
14682 (unspec:XF [(match_dup 6) (match_dup 4)]
14683 UNSPEC_FSCALE_EXP))])
14684 (parallel [(set (match_dup 10)
14685 (unspec:XF [(match_dup 9) (match_dup 8)]
14686 UNSPEC_FSCALE_FRACT))
14687 (set (match_dup 11)
14688 (unspec:XF [(match_dup 9) (match_dup 8)]
14689 UNSPEC_FSCALE_EXP))])
14690 (set (match_dup 12) (minus:XF (match_dup 10)
14691 (float_extend:XF (match_dup 13))))
14692 (set (match_operand:XF 0 "register_operand")
14693 (plus:XF (match_dup 12) (match_dup 7)))]
14694 "TARGET_USE_FANCY_MATH_387
14695 && flag_unsafe_math_optimizations"
14699 if (optimize_insn_for_size_p ())
14702 for (i = 2; i < 13; i++)
14703 operands[i] = gen_reg_rtx (XFmode);
14706 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14708 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14711 (define_expand "expm1<mode>2"
14712 [(use (match_operand:MODEF 0 "register_operand"))
14713 (use (match_operand:MODEF 1 "general_operand"))]
14714 "TARGET_USE_FANCY_MATH_387
14715 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14716 || TARGET_MIX_SSE_I387)
14717 && flag_unsafe_math_optimizations"
14721 if (optimize_insn_for_size_p ())
14724 op0 = gen_reg_rtx (XFmode);
14725 op1 = gen_reg_rtx (XFmode);
14727 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14728 emit_insn (gen_expm1xf2 (op0, op1));
14729 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14733 (define_expand "ldexpxf3"
14734 [(set (match_dup 3)
14735 (float:XF (match_operand:SI 2 "register_operand")))
14736 (parallel [(set (match_operand:XF 0 " register_operand")
14737 (unspec:XF [(match_operand:XF 1 "register_operand")
14739 UNSPEC_FSCALE_FRACT))
14741 (unspec:XF [(match_dup 1) (match_dup 3)]
14742 UNSPEC_FSCALE_EXP))])]
14743 "TARGET_USE_FANCY_MATH_387
14744 && flag_unsafe_math_optimizations"
14746 if (optimize_insn_for_size_p ())
14749 operands[3] = gen_reg_rtx (XFmode);
14750 operands[4] = gen_reg_rtx (XFmode);
14753 (define_expand "ldexp<mode>3"
14754 [(use (match_operand:MODEF 0 "register_operand"))
14755 (use (match_operand:MODEF 1 "general_operand"))
14756 (use (match_operand:SI 2 "register_operand"))]
14757 "TARGET_USE_FANCY_MATH_387
14758 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14759 || TARGET_MIX_SSE_I387)
14760 && flag_unsafe_math_optimizations"
14764 if (optimize_insn_for_size_p ())
14767 op0 = gen_reg_rtx (XFmode);
14768 op1 = gen_reg_rtx (XFmode);
14770 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14771 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14772 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14776 (define_expand "scalbxf3"
14777 [(parallel [(set (match_operand:XF 0 " register_operand")
14778 (unspec:XF [(match_operand:XF 1 "register_operand")
14779 (match_operand:XF 2 "register_operand")]
14780 UNSPEC_FSCALE_FRACT))
14782 (unspec:XF [(match_dup 1) (match_dup 2)]
14783 UNSPEC_FSCALE_EXP))])]
14784 "TARGET_USE_FANCY_MATH_387
14785 && flag_unsafe_math_optimizations"
14787 if (optimize_insn_for_size_p ())
14790 operands[3] = gen_reg_rtx (XFmode);
14793 (define_expand "scalb<mode>3"
14794 [(use (match_operand:MODEF 0 "register_operand"))
14795 (use (match_operand:MODEF 1 "general_operand"))
14796 (use (match_operand:MODEF 2 "general_operand"))]
14797 "TARGET_USE_FANCY_MATH_387
14798 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14799 || TARGET_MIX_SSE_I387)
14800 && flag_unsafe_math_optimizations"
14804 if (optimize_insn_for_size_p ())
14807 op0 = gen_reg_rtx (XFmode);
14808 op1 = gen_reg_rtx (XFmode);
14809 op2 = gen_reg_rtx (XFmode);
14811 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14812 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14813 emit_insn (gen_scalbxf3 (op0, op1, op2));
14814 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14818 (define_expand "significandxf2"
14819 [(parallel [(set (match_operand:XF 0 "register_operand")
14820 (unspec:XF [(match_operand:XF 1 "register_operand")]
14821 UNSPEC_XTRACT_FRACT))
14823 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14824 "TARGET_USE_FANCY_MATH_387
14825 && flag_unsafe_math_optimizations"
14826 "operands[2] = gen_reg_rtx (XFmode);")
14828 (define_expand "significand<mode>2"
14829 [(use (match_operand:MODEF 0 "register_operand"))
14830 (use (match_operand:MODEF 1 "register_operand"))]
14831 "TARGET_USE_FANCY_MATH_387
14832 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14833 || TARGET_MIX_SSE_I387)
14834 && flag_unsafe_math_optimizations"
14836 rtx op0 = gen_reg_rtx (XFmode);
14837 rtx op1 = gen_reg_rtx (XFmode);
14839 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14840 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14845 (define_insn "sse4_1_round<mode>2"
14846 [(set (match_operand:MODEF 0 "register_operand" "=x")
14847 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14848 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14851 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14852 [(set_attr "type" "ssecvt")
14853 (set_attr "prefix_extra" "1")
14854 (set_attr "prefix" "maybe_vex")
14855 (set_attr "mode" "<MODE>")])
14857 (define_insn "rintxf2"
14858 [(set (match_operand:XF 0 "register_operand" "=f")
14859 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14861 "TARGET_USE_FANCY_MATH_387
14862 && flag_unsafe_math_optimizations"
14864 [(set_attr "type" "fpspc")
14865 (set_attr "mode" "XF")])
14867 (define_expand "rint<mode>2"
14868 [(use (match_operand:MODEF 0 "register_operand"))
14869 (use (match_operand:MODEF 1 "register_operand"))]
14870 "(TARGET_USE_FANCY_MATH_387
14871 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14872 || TARGET_MIX_SSE_I387)
14873 && flag_unsafe_math_optimizations)
14874 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14875 && !flag_trapping_math)"
14877 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14878 && !flag_trapping_math)
14881 emit_insn (gen_sse4_1_round<mode>2
14882 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14883 else if (optimize_insn_for_size_p ())
14886 ix86_expand_rint (operands[0], operands[1]);
14890 rtx op0 = gen_reg_rtx (XFmode);
14891 rtx op1 = gen_reg_rtx (XFmode);
14893 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14894 emit_insn (gen_rintxf2 (op0, op1));
14896 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14901 (define_expand "round<mode>2"
14902 [(match_operand:X87MODEF 0 "register_operand")
14903 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14904 "(TARGET_USE_FANCY_MATH_387
14905 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14906 || TARGET_MIX_SSE_I387)
14907 && flag_unsafe_math_optimizations)
14908 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14909 && !flag_trapping_math && !flag_rounding_math)"
14911 if (optimize_insn_for_size_p ())
14914 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14915 && !flag_trapping_math && !flag_rounding_math)
14919 operands[1] = force_reg (<MODE>mode, operands[1]);
14920 ix86_expand_round_sse4 (operands[0], operands[1]);
14922 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14923 ix86_expand_round (operands[0], operands[1]);
14925 ix86_expand_rounddf_32 (operands[0], operands[1]);
14929 operands[1] = force_reg (<MODE>mode, operands[1]);
14930 ix86_emit_i387_round (operands[0], operands[1]);
14935 (define_insn_and_split "*fistdi2_1"
14936 [(set (match_operand:DI 0 "nonimmediate_operand")
14937 (unspec:DI [(match_operand:XF 1 "register_operand")]
14939 "TARGET_USE_FANCY_MATH_387
14940 && can_create_pseudo_p ()"
14945 if (memory_operand (operands[0], VOIDmode))
14946 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14949 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14950 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14955 [(set_attr "type" "fpspc")
14956 (set_attr "mode" "DI")])
14958 (define_insn "fistdi2"
14959 [(set (match_operand:DI 0 "memory_operand" "=m")
14960 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14962 (clobber (match_scratch:XF 2 "=&1f"))]
14963 "TARGET_USE_FANCY_MATH_387"
14964 "* return output_fix_trunc (insn, operands, false);"
14965 [(set_attr "type" "fpspc")
14966 (set_attr "mode" "DI")])
14968 (define_insn "fistdi2_with_temp"
14969 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14970 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14972 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14973 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14974 "TARGET_USE_FANCY_MATH_387"
14976 [(set_attr "type" "fpspc")
14977 (set_attr "mode" "DI")])
14980 [(set (match_operand:DI 0 "register_operand")
14981 (unspec:DI [(match_operand:XF 1 "register_operand")]
14983 (clobber (match_operand:DI 2 "memory_operand"))
14984 (clobber (match_scratch 3))]
14986 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14987 (clobber (match_dup 3))])
14988 (set (match_dup 0) (match_dup 2))])
14991 [(set (match_operand:DI 0 "memory_operand")
14992 (unspec:DI [(match_operand:XF 1 "register_operand")]
14994 (clobber (match_operand:DI 2 "memory_operand"))
14995 (clobber (match_scratch 3))]
14997 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14998 (clobber (match_dup 3))])])
15000 (define_insn_and_split "*fist<mode>2_1"
15001 [(set (match_operand:SWI24 0 "register_operand")
15002 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15004 "TARGET_USE_FANCY_MATH_387
15005 && can_create_pseudo_p ()"
15010 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15011 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15015 [(set_attr "type" "fpspc")
15016 (set_attr "mode" "<MODE>")])
15018 (define_insn "fist<mode>2"
15019 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15020 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15022 "TARGET_USE_FANCY_MATH_387"
15023 "* return output_fix_trunc (insn, operands, false);"
15024 [(set_attr "type" "fpspc")
15025 (set_attr "mode" "<MODE>")])
15027 (define_insn "fist<mode>2_with_temp"
15028 [(set (match_operand:SWI24 0 "register_operand" "=r")
15029 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15031 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15032 "TARGET_USE_FANCY_MATH_387"
15034 [(set_attr "type" "fpspc")
15035 (set_attr "mode" "<MODE>")])
15038 [(set (match_operand:SWI24 0 "register_operand")
15039 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15041 (clobber (match_operand:SWI24 2 "memory_operand"))]
15043 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15044 (set (match_dup 0) (match_dup 2))])
15047 [(set (match_operand:SWI24 0 "memory_operand")
15048 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15050 (clobber (match_operand:SWI24 2 "memory_operand"))]
15052 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15054 (define_expand "lrintxf<mode>2"
15055 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15056 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15058 "TARGET_USE_FANCY_MATH_387")
15060 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
15061 [(set (match_operand:SWI48x 0 "nonimmediate_operand")
15062 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand")]
15063 UNSPEC_FIX_NOTRUNC))]
15064 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15065 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
15067 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15068 [(match_operand:SWI248x 0 "nonimmediate_operand")
15069 (match_operand:X87MODEF 1 "register_operand")]
15070 "(TARGET_USE_FANCY_MATH_387
15071 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15072 || TARGET_MIX_SSE_I387)
15073 && flag_unsafe_math_optimizations)
15074 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15075 && <SWI248x:MODE>mode != HImode
15076 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15077 && !flag_trapping_math && !flag_rounding_math)"
15079 if (optimize_insn_for_size_p ())
15082 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15083 && <SWI248x:MODE>mode != HImode
15084 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15085 && !flag_trapping_math && !flag_rounding_math)
15086 ix86_expand_lround (operands[0], operands[1]);
15088 ix86_emit_i387_round (operands[0], operands[1]);
15092 (define_int_iterator FRNDINT_ROUNDING
15093 [UNSPEC_FRNDINT_FLOOR
15094 UNSPEC_FRNDINT_CEIL
15095 UNSPEC_FRNDINT_TRUNC])
15097 (define_int_iterator FIST_ROUNDING
15101 ;; Base name for define_insn
15102 (define_int_attr rounding_insn
15103 [(UNSPEC_FRNDINT_FLOOR "floor")
15104 (UNSPEC_FRNDINT_CEIL "ceil")
15105 (UNSPEC_FRNDINT_TRUNC "btrunc")
15106 (UNSPEC_FIST_FLOOR "floor")
15107 (UNSPEC_FIST_CEIL "ceil")])
15109 (define_int_attr rounding
15110 [(UNSPEC_FRNDINT_FLOOR "floor")
15111 (UNSPEC_FRNDINT_CEIL "ceil")
15112 (UNSPEC_FRNDINT_TRUNC "trunc")
15113 (UNSPEC_FIST_FLOOR "floor")
15114 (UNSPEC_FIST_CEIL "ceil")])
15116 (define_int_attr ROUNDING
15117 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15118 (UNSPEC_FRNDINT_CEIL "CEIL")
15119 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15120 (UNSPEC_FIST_FLOOR "FLOOR")
15121 (UNSPEC_FIST_CEIL "CEIL")])
15123 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15124 (define_insn_and_split "frndintxf2_<rounding>"
15125 [(set (match_operand:XF 0 "register_operand")
15126 (unspec:XF [(match_operand:XF 1 "register_operand")]
15128 (clobber (reg:CC FLAGS_REG))]
15129 "TARGET_USE_FANCY_MATH_387
15130 && flag_unsafe_math_optimizations
15131 && can_create_pseudo_p ()"
15136 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15138 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15139 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15141 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15142 operands[2], operands[3]));
15145 [(set_attr "type" "frndint")
15146 (set_attr "i387_cw" "<rounding>")
15147 (set_attr "mode" "XF")])
15149 (define_insn "frndintxf2_<rounding>_i387"
15150 [(set (match_operand:XF 0 "register_operand" "=f")
15151 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15153 (use (match_operand:HI 2 "memory_operand" "m"))
15154 (use (match_operand:HI 3 "memory_operand" "m"))]
15155 "TARGET_USE_FANCY_MATH_387
15156 && flag_unsafe_math_optimizations"
15157 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15158 [(set_attr "type" "frndint")
15159 (set_attr "i387_cw" "<rounding>")
15160 (set_attr "mode" "XF")])
15162 (define_expand "<rounding_insn>xf2"
15163 [(parallel [(set (match_operand:XF 0 "register_operand")
15164 (unspec:XF [(match_operand:XF 1 "register_operand")]
15166 (clobber (reg:CC FLAGS_REG))])]
15167 "TARGET_USE_FANCY_MATH_387
15168 && flag_unsafe_math_optimizations
15169 && !optimize_insn_for_size_p ()")
15171 (define_expand "<rounding_insn><mode>2"
15172 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15173 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15175 (clobber (reg:CC FLAGS_REG))])]
15176 "(TARGET_USE_FANCY_MATH_387
15177 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15178 || TARGET_MIX_SSE_I387)
15179 && flag_unsafe_math_optimizations)
15180 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15181 && !flag_trapping_math)"
15183 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15184 && !flag_trapping_math)
15187 emit_insn (gen_sse4_1_round<mode>2
15188 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15189 else if (optimize_insn_for_size_p ())
15191 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15193 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15194 ix86_expand_floorceil (operands[0], operands[1], true);
15195 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15196 ix86_expand_floorceil (operands[0], operands[1], false);
15197 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15198 ix86_expand_trunc (operands[0], operands[1]);
15200 gcc_unreachable ();
15204 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15205 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15206 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15207 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15208 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15209 ix86_expand_truncdf_32 (operands[0], operands[1]);
15211 gcc_unreachable ();
15218 if (optimize_insn_for_size_p ())
15221 op0 = gen_reg_rtx (XFmode);
15222 op1 = gen_reg_rtx (XFmode);
15223 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15224 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15226 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15231 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15232 (define_insn_and_split "frndintxf2_mask_pm"
15233 [(set (match_operand:XF 0 "register_operand")
15234 (unspec:XF [(match_operand:XF 1 "register_operand")]
15235 UNSPEC_FRNDINT_MASK_PM))
15236 (clobber (reg:CC FLAGS_REG))]
15237 "TARGET_USE_FANCY_MATH_387
15238 && flag_unsafe_math_optimizations
15239 && can_create_pseudo_p ()"
15244 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15246 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15247 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15249 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15250 operands[2], operands[3]));
15253 [(set_attr "type" "frndint")
15254 (set_attr "i387_cw" "mask_pm")
15255 (set_attr "mode" "XF")])
15257 (define_insn "frndintxf2_mask_pm_i387"
15258 [(set (match_operand:XF 0 "register_operand" "=f")
15259 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15260 UNSPEC_FRNDINT_MASK_PM))
15261 (use (match_operand:HI 2 "memory_operand" "m"))
15262 (use (match_operand:HI 3 "memory_operand" "m"))]
15263 "TARGET_USE_FANCY_MATH_387
15264 && flag_unsafe_math_optimizations"
15265 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15266 [(set_attr "type" "frndint")
15267 (set_attr "i387_cw" "mask_pm")
15268 (set_attr "mode" "XF")])
15270 (define_expand "nearbyintxf2"
15271 [(parallel [(set (match_operand:XF 0 "register_operand")
15272 (unspec:XF [(match_operand:XF 1 "register_operand")]
15273 UNSPEC_FRNDINT_MASK_PM))
15274 (clobber (reg:CC FLAGS_REG))])]
15275 "TARGET_USE_FANCY_MATH_387
15276 && flag_unsafe_math_optimizations")
15278 (define_expand "nearbyint<mode>2"
15279 [(use (match_operand:MODEF 0 "register_operand"))
15280 (use (match_operand:MODEF 1 "register_operand"))]
15281 "TARGET_USE_FANCY_MATH_387
15282 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15283 || TARGET_MIX_SSE_I387)
15284 && flag_unsafe_math_optimizations"
15286 rtx op0 = gen_reg_rtx (XFmode);
15287 rtx op1 = gen_reg_rtx (XFmode);
15289 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15290 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15292 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15296 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15297 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15298 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15299 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15301 (clobber (reg:CC FLAGS_REG))]
15302 "TARGET_USE_FANCY_MATH_387
15303 && flag_unsafe_math_optimizations
15304 && can_create_pseudo_p ()"
15309 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15311 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15312 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15313 if (memory_operand (operands[0], VOIDmode))
15314 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15315 operands[2], operands[3]));
15318 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15319 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15320 (operands[0], operands[1], operands[2],
15321 operands[3], operands[4]));
15325 [(set_attr "type" "fistp")
15326 (set_attr "i387_cw" "<rounding>")
15327 (set_attr "mode" "<MODE>")])
15329 (define_insn "fistdi2_<rounding>"
15330 [(set (match_operand:DI 0 "memory_operand" "=m")
15331 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15333 (use (match_operand:HI 2 "memory_operand" "m"))
15334 (use (match_operand:HI 3 "memory_operand" "m"))
15335 (clobber (match_scratch:XF 4 "=&1f"))]
15336 "TARGET_USE_FANCY_MATH_387
15337 && flag_unsafe_math_optimizations"
15338 "* return output_fix_trunc (insn, operands, false);"
15339 [(set_attr "type" "fistp")
15340 (set_attr "i387_cw" "<rounding>")
15341 (set_attr "mode" "DI")])
15343 (define_insn "fistdi2_<rounding>_with_temp"
15344 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15345 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15347 (use (match_operand:HI 2 "memory_operand" "m,m"))
15348 (use (match_operand:HI 3 "memory_operand" "m,m"))
15349 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15350 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15351 "TARGET_USE_FANCY_MATH_387
15352 && flag_unsafe_math_optimizations"
15354 [(set_attr "type" "fistp")
15355 (set_attr "i387_cw" "<rounding>")
15356 (set_attr "mode" "DI")])
15359 [(set (match_operand:DI 0 "register_operand")
15360 (unspec:DI [(match_operand:XF 1 "register_operand")]
15362 (use (match_operand:HI 2 "memory_operand"))
15363 (use (match_operand:HI 3 "memory_operand"))
15364 (clobber (match_operand:DI 4 "memory_operand"))
15365 (clobber (match_scratch 5))]
15367 [(parallel [(set (match_dup 4)
15368 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15369 (use (match_dup 2))
15370 (use (match_dup 3))
15371 (clobber (match_dup 5))])
15372 (set (match_dup 0) (match_dup 4))])
15375 [(set (match_operand:DI 0 "memory_operand")
15376 (unspec:DI [(match_operand:XF 1 "register_operand")]
15378 (use (match_operand:HI 2 "memory_operand"))
15379 (use (match_operand:HI 3 "memory_operand"))
15380 (clobber (match_operand:DI 4 "memory_operand"))
15381 (clobber (match_scratch 5))]
15383 [(parallel [(set (match_dup 0)
15384 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15385 (use (match_dup 2))
15386 (use (match_dup 3))
15387 (clobber (match_dup 5))])])
15389 (define_insn "fist<mode>2_<rounding>"
15390 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15391 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15393 (use (match_operand:HI 2 "memory_operand" "m"))
15394 (use (match_operand:HI 3 "memory_operand" "m"))]
15395 "TARGET_USE_FANCY_MATH_387
15396 && flag_unsafe_math_optimizations"
15397 "* return output_fix_trunc (insn, operands, false);"
15398 [(set_attr "type" "fistp")
15399 (set_attr "i387_cw" "<rounding>")
15400 (set_attr "mode" "<MODE>")])
15402 (define_insn "fist<mode>2_<rounding>_with_temp"
15403 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15404 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15406 (use (match_operand:HI 2 "memory_operand" "m,m"))
15407 (use (match_operand:HI 3 "memory_operand" "m,m"))
15408 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15409 "TARGET_USE_FANCY_MATH_387
15410 && flag_unsafe_math_optimizations"
15412 [(set_attr "type" "fistp")
15413 (set_attr "i387_cw" "<rounding>")
15414 (set_attr "mode" "<MODE>")])
15417 [(set (match_operand:SWI24 0 "register_operand")
15418 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15420 (use (match_operand:HI 2 "memory_operand"))
15421 (use (match_operand:HI 3 "memory_operand"))
15422 (clobber (match_operand:SWI24 4 "memory_operand"))]
15424 [(parallel [(set (match_dup 4)
15425 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15426 (use (match_dup 2))
15427 (use (match_dup 3))])
15428 (set (match_dup 0) (match_dup 4))])
15431 [(set (match_operand:SWI24 0 "memory_operand")
15432 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15434 (use (match_operand:HI 2 "memory_operand"))
15435 (use (match_operand:HI 3 "memory_operand"))
15436 (clobber (match_operand:SWI24 4 "memory_operand"))]
15438 [(parallel [(set (match_dup 0)
15439 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15440 (use (match_dup 2))
15441 (use (match_dup 3))])])
15443 (define_expand "l<rounding_insn>xf<mode>2"
15444 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15445 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15447 (clobber (reg:CC FLAGS_REG))])]
15448 "TARGET_USE_FANCY_MATH_387
15449 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15450 && flag_unsafe_math_optimizations")
15452 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15453 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15454 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15456 (clobber (reg:CC FLAGS_REG))])]
15457 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15458 && !flag_trapping_math"
15460 if (TARGET_64BIT && optimize_insn_for_size_p ())
15463 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15464 ix86_expand_lfloorceil (operands[0], operands[1], true);
15465 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15466 ix86_expand_lfloorceil (operands[0], operands[1], false);
15468 gcc_unreachable ();
15473 (define_insn "fxam<mode>2_i387"
15474 [(set (match_operand:HI 0 "register_operand" "=a")
15476 [(match_operand:X87MODEF 1 "register_operand" "f")]
15478 "TARGET_USE_FANCY_MATH_387"
15479 "fxam\n\tfnstsw\t%0"
15480 [(set_attr "type" "multi")
15481 (set_attr "length" "4")
15482 (set_attr "unit" "i387")
15483 (set_attr "mode" "<MODE>")])
15485 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15486 [(set (match_operand:HI 0 "register_operand")
15488 [(match_operand:MODEF 1 "memory_operand")]
15490 "TARGET_USE_FANCY_MATH_387
15491 && can_create_pseudo_p ()"
15494 [(set (match_dup 2)(match_dup 1))
15496 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15498 operands[2] = gen_reg_rtx (<MODE>mode);
15500 MEM_VOLATILE_P (operands[1]) = 1;
15502 [(set_attr "type" "multi")
15503 (set_attr "unit" "i387")
15504 (set_attr "mode" "<MODE>")])
15506 (define_expand "isinfxf2"
15507 [(use (match_operand:SI 0 "register_operand"))
15508 (use (match_operand:XF 1 "register_operand"))]
15509 "TARGET_USE_FANCY_MATH_387
15510 && TARGET_C99_FUNCTIONS"
15512 rtx mask = GEN_INT (0x45);
15513 rtx val = GEN_INT (0x05);
15517 rtx scratch = gen_reg_rtx (HImode);
15518 rtx res = gen_reg_rtx (QImode);
15520 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15522 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15523 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15524 cond = gen_rtx_fmt_ee (EQ, QImode,
15525 gen_rtx_REG (CCmode, FLAGS_REG),
15527 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15528 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15532 (define_expand "isinf<mode>2"
15533 [(use (match_operand:SI 0 "register_operand"))
15534 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15535 "TARGET_USE_FANCY_MATH_387
15536 && TARGET_C99_FUNCTIONS
15537 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15539 rtx mask = GEN_INT (0x45);
15540 rtx val = GEN_INT (0x05);
15544 rtx scratch = gen_reg_rtx (HImode);
15545 rtx res = gen_reg_rtx (QImode);
15547 /* Remove excess precision by forcing value through memory. */
15548 if (memory_operand (operands[1], VOIDmode))
15549 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15552 enum ix86_stack_slot slot = (virtuals_instantiated
15555 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15557 emit_move_insn (temp, operands[1]);
15558 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15561 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15562 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15563 cond = gen_rtx_fmt_ee (EQ, QImode,
15564 gen_rtx_REG (CCmode, FLAGS_REG),
15566 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15567 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15571 (define_expand "signbitxf2"
15572 [(use (match_operand:SI 0 "register_operand"))
15573 (use (match_operand:XF 1 "register_operand"))]
15574 "TARGET_USE_FANCY_MATH_387"
15576 rtx scratch = gen_reg_rtx (HImode);
15578 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15579 emit_insn (gen_andsi3 (operands[0],
15580 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15584 (define_insn "movmsk_df"
15585 [(set (match_operand:SI 0 "register_operand" "=r")
15587 [(match_operand:DF 1 "register_operand" "x")]
15589 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15590 "%vmovmskpd\t{%1, %0|%0, %1}"
15591 [(set_attr "type" "ssemov")
15592 (set_attr "prefix" "maybe_vex")
15593 (set_attr "mode" "DF")])
15595 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15596 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15597 (define_expand "signbitdf2"
15598 [(use (match_operand:SI 0 "register_operand"))
15599 (use (match_operand:DF 1 "register_operand"))]
15600 "TARGET_USE_FANCY_MATH_387
15601 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15603 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15605 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15606 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15610 rtx scratch = gen_reg_rtx (HImode);
15612 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15613 emit_insn (gen_andsi3 (operands[0],
15614 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15619 (define_expand "signbitsf2"
15620 [(use (match_operand:SI 0 "register_operand"))
15621 (use (match_operand:SF 1 "register_operand"))]
15622 "TARGET_USE_FANCY_MATH_387
15623 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15625 rtx scratch = gen_reg_rtx (HImode);
15627 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15628 emit_insn (gen_andsi3 (operands[0],
15629 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15633 ;; Block operation instructions
15636 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15639 [(set_attr "length" "1")
15640 (set_attr "length_immediate" "0")
15641 (set_attr "modrm" "0")])
15643 (define_expand "movmem<mode>"
15644 [(use (match_operand:BLK 0 "memory_operand"))
15645 (use (match_operand:BLK 1 "memory_operand"))
15646 (use (match_operand:SWI48 2 "nonmemory_operand"))
15647 (use (match_operand:SWI48 3 "const_int_operand"))
15648 (use (match_operand:SI 4 "const_int_operand"))
15649 (use (match_operand:SI 5 "const_int_operand"))]
15652 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15653 operands[4], operands[5]))
15659 ;; Most CPUs don't like single string operations
15660 ;; Handle this case here to simplify previous expander.
15662 (define_expand "strmov"
15663 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15664 (set (match_operand 1 "memory_operand") (match_dup 4))
15665 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15666 (clobber (reg:CC FLAGS_REG))])
15667 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15668 (clobber (reg:CC FLAGS_REG))])]
15671 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15673 /* If .md ever supports :P for Pmode, these can be directly
15674 in the pattern above. */
15675 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15676 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15678 /* Can't use this if the user has appropriated esi or edi. */
15679 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15680 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15682 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15683 operands[2], operands[3],
15684 operands[5], operands[6]));
15688 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15691 (define_expand "strmov_singleop"
15692 [(parallel [(set (match_operand 1 "memory_operand")
15693 (match_operand 3 "memory_operand"))
15694 (set (match_operand 0 "register_operand")
15696 (set (match_operand 2 "register_operand")
15697 (match_operand 5))])]
15699 "ix86_current_function_needs_cld = 1;")
15701 (define_insn "*strmovdi_rex_1"
15702 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15703 (mem:DI (match_operand:P 3 "register_operand" "1")))
15704 (set (match_operand:P 0 "register_operand" "=D")
15705 (plus:P (match_dup 2)
15707 (set (match_operand:P 1 "register_operand" "=S")
15708 (plus:P (match_dup 3)
15711 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15713 [(set_attr "type" "str")
15714 (set_attr "memory" "both")
15715 (set_attr "mode" "DI")])
15717 (define_insn "*strmovsi_1"
15718 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15719 (mem:SI (match_operand:P 3 "register_operand" "1")))
15720 (set (match_operand:P 0 "register_operand" "=D")
15721 (plus:P (match_dup 2)
15723 (set (match_operand:P 1 "register_operand" "=S")
15724 (plus:P (match_dup 3)
15726 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15728 [(set_attr "type" "str")
15729 (set_attr "memory" "both")
15730 (set_attr "mode" "SI")])
15732 (define_insn "*strmovhi_1"
15733 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15734 (mem:HI (match_operand:P 3 "register_operand" "1")))
15735 (set (match_operand:P 0 "register_operand" "=D")
15736 (plus:P (match_dup 2)
15738 (set (match_operand:P 1 "register_operand" "=S")
15739 (plus:P (match_dup 3)
15741 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15743 [(set_attr "type" "str")
15744 (set_attr "memory" "both")
15745 (set_attr "mode" "HI")])
15747 (define_insn "*strmovqi_1"
15748 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15749 (mem:QI (match_operand:P 3 "register_operand" "1")))
15750 (set (match_operand:P 0 "register_operand" "=D")
15751 (plus:P (match_dup 2)
15753 (set (match_operand:P 1 "register_operand" "=S")
15754 (plus:P (match_dup 3)
15756 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15758 [(set_attr "type" "str")
15759 (set_attr "memory" "both")
15760 (set (attr "prefix_rex")
15762 (match_test "<P:MODE>mode == DImode")
15764 (const_string "*")))
15765 (set_attr "mode" "QI")])
15767 (define_expand "rep_mov"
15768 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15769 (set (match_operand 0 "register_operand")
15771 (set (match_operand 2 "register_operand")
15773 (set (match_operand 1 "memory_operand")
15774 (match_operand 3 "memory_operand"))
15775 (use (match_dup 4))])]
15777 "ix86_current_function_needs_cld = 1;")
15779 (define_insn "*rep_movdi_rex64"
15780 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15781 (set (match_operand:P 0 "register_operand" "=D")
15782 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15784 (match_operand:P 3 "register_operand" "0")))
15785 (set (match_operand:P 1 "register_operand" "=S")
15786 (plus:P (ashift:P (match_dup 5) (const_int 3))
15787 (match_operand:P 4 "register_operand" "1")))
15788 (set (mem:BLK (match_dup 3))
15789 (mem:BLK (match_dup 4)))
15790 (use (match_dup 5))]
15792 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15794 [(set_attr "type" "str")
15795 (set_attr "prefix_rep" "1")
15796 (set_attr "memory" "both")
15797 (set_attr "mode" "DI")])
15799 (define_insn "*rep_movsi"
15800 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15801 (set (match_operand:P 0 "register_operand" "=D")
15802 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15804 (match_operand:P 3 "register_operand" "0")))
15805 (set (match_operand:P 1 "register_operand" "=S")
15806 (plus:P (ashift:P (match_dup 5) (const_int 2))
15807 (match_operand:P 4 "register_operand" "1")))
15808 (set (mem:BLK (match_dup 3))
15809 (mem:BLK (match_dup 4)))
15810 (use (match_dup 5))]
15811 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15812 "%^rep{%;} movs{l|d}"
15813 [(set_attr "type" "str")
15814 (set_attr "prefix_rep" "1")
15815 (set_attr "memory" "both")
15816 (set_attr "mode" "SI")])
15818 (define_insn "*rep_movqi"
15819 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15820 (set (match_operand:P 0 "register_operand" "=D")
15821 (plus:P (match_operand:P 3 "register_operand" "0")
15822 (match_operand:P 5 "register_operand" "2")))
15823 (set (match_operand:P 1 "register_operand" "=S")
15824 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15825 (set (mem:BLK (match_dup 3))
15826 (mem:BLK (match_dup 4)))
15827 (use (match_dup 5))]
15828 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15830 [(set_attr "type" "str")
15831 (set_attr "prefix_rep" "1")
15832 (set_attr "memory" "both")
15833 (set_attr "mode" "QI")])
15835 (define_expand "setmem<mode>"
15836 [(use (match_operand:BLK 0 "memory_operand"))
15837 (use (match_operand:SWI48 1 "nonmemory_operand"))
15838 (use (match_operand:QI 2 "nonmemory_operand"))
15839 (use (match_operand 3 "const_int_operand"))
15840 (use (match_operand:SI 4 "const_int_operand"))
15841 (use (match_operand:SI 5 "const_int_operand"))]
15844 if (ix86_expand_setmem (operands[0], operands[1],
15845 operands[2], operands[3],
15846 operands[4], operands[5]))
15852 ;; Most CPUs don't like single string operations
15853 ;; Handle this case here to simplify previous expander.
15855 (define_expand "strset"
15856 [(set (match_operand 1 "memory_operand")
15857 (match_operand 2 "register_operand"))
15858 (parallel [(set (match_operand 0 "register_operand")
15860 (clobber (reg:CC FLAGS_REG))])]
15863 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15864 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15866 /* If .md ever supports :P for Pmode, this can be directly
15867 in the pattern above. */
15868 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15869 GEN_INT (GET_MODE_SIZE (GET_MODE
15871 /* Can't use this if the user has appropriated eax or edi. */
15872 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15873 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15875 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15881 (define_expand "strset_singleop"
15882 [(parallel [(set (match_operand 1 "memory_operand")
15883 (match_operand 2 "register_operand"))
15884 (set (match_operand 0 "register_operand")
15885 (match_operand 3))])]
15887 "ix86_current_function_needs_cld = 1;")
15889 (define_insn "*strsetdi_rex_1"
15890 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15891 (match_operand:DI 2 "register_operand" "a"))
15892 (set (match_operand:P 0 "register_operand" "=D")
15893 (plus:P (match_dup 1)
15896 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15898 [(set_attr "type" "str")
15899 (set_attr "memory" "store")
15900 (set_attr "mode" "DI")])
15902 (define_insn "*strsetsi_1"
15903 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15904 (match_operand:SI 2 "register_operand" "a"))
15905 (set (match_operand:P 0 "register_operand" "=D")
15906 (plus:P (match_dup 1)
15908 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15910 [(set_attr "type" "str")
15911 (set_attr "memory" "store")
15912 (set_attr "mode" "SI")])
15914 (define_insn "*strsethi_1"
15915 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15916 (match_operand:HI 2 "register_operand" "a"))
15917 (set (match_operand:P 0 "register_operand" "=D")
15918 (plus:P (match_dup 1)
15920 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15922 [(set_attr "type" "str")
15923 (set_attr "memory" "store")
15924 (set_attr "mode" "HI")])
15926 (define_insn "*strsetqi_1"
15927 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15928 (match_operand:QI 2 "register_operand" "a"))
15929 (set (match_operand:P 0 "register_operand" "=D")
15930 (plus:P (match_dup 1)
15932 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15934 [(set_attr "type" "str")
15935 (set_attr "memory" "store")
15936 (set (attr "prefix_rex")
15938 (match_test "<P:MODE>mode == DImode")
15940 (const_string "*")))
15941 (set_attr "mode" "QI")])
15943 (define_expand "rep_stos"
15944 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15945 (set (match_operand 0 "register_operand")
15947 (set (match_operand 2 "memory_operand") (const_int 0))
15948 (use (match_operand 3 "register_operand"))
15949 (use (match_dup 1))])]
15951 "ix86_current_function_needs_cld = 1;")
15953 (define_insn "*rep_stosdi_rex64"
15954 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15955 (set (match_operand:P 0 "register_operand" "=D")
15956 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15958 (match_operand:P 3 "register_operand" "0")))
15959 (set (mem:BLK (match_dup 3))
15961 (use (match_operand:DI 2 "register_operand" "a"))
15962 (use (match_dup 4))]
15964 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15966 [(set_attr "type" "str")
15967 (set_attr "prefix_rep" "1")
15968 (set_attr "memory" "store")
15969 (set_attr "mode" "DI")])
15971 (define_insn "*rep_stossi"
15972 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15973 (set (match_operand:P 0 "register_operand" "=D")
15974 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15976 (match_operand:P 3 "register_operand" "0")))
15977 (set (mem:BLK (match_dup 3))
15979 (use (match_operand:SI 2 "register_operand" "a"))
15980 (use (match_dup 4))]
15981 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15982 "%^rep{%;} stos{l|d}"
15983 [(set_attr "type" "str")
15984 (set_attr "prefix_rep" "1")
15985 (set_attr "memory" "store")
15986 (set_attr "mode" "SI")])
15988 (define_insn "*rep_stosqi"
15989 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15990 (set (match_operand:P 0 "register_operand" "=D")
15991 (plus:P (match_operand:P 3 "register_operand" "0")
15992 (match_operand:P 4 "register_operand" "1")))
15993 (set (mem:BLK (match_dup 3))
15995 (use (match_operand:QI 2 "register_operand" "a"))
15996 (use (match_dup 4))]
15997 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15999 [(set_attr "type" "str")
16000 (set_attr "prefix_rep" "1")
16001 (set_attr "memory" "store")
16002 (set (attr "prefix_rex")
16004 (match_test "<P:MODE>mode == DImode")
16006 (const_string "*")))
16007 (set_attr "mode" "QI")])
16009 (define_expand "cmpstrnsi"
16010 [(set (match_operand:SI 0 "register_operand")
16011 (compare:SI (match_operand:BLK 1 "general_operand")
16012 (match_operand:BLK 2 "general_operand")))
16013 (use (match_operand 3 "general_operand"))
16014 (use (match_operand 4 "immediate_operand"))]
16017 rtx addr1, addr2, out, outlow, count, countreg, align;
16019 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16022 /* Can't use this if the user has appropriated ecx, esi or edi. */
16023 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16028 out = gen_reg_rtx (SImode);
16030 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16031 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16032 if (addr1 != XEXP (operands[1], 0))
16033 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16034 if (addr2 != XEXP (operands[2], 0))
16035 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16037 count = operands[3];
16038 countreg = ix86_zero_extend_to_Pmode (count);
16040 /* %%% Iff we are testing strict equality, we can use known alignment
16041 to good advantage. This may be possible with combine, particularly
16042 once cc0 is dead. */
16043 align = operands[4];
16045 if (CONST_INT_P (count))
16047 if (INTVAL (count) == 0)
16049 emit_move_insn (operands[0], const0_rtx);
16052 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16053 operands[1], operands[2]));
16057 rtx (*gen_cmp) (rtx, rtx);
16059 gen_cmp = (TARGET_64BIT
16060 ? gen_cmpdi_1 : gen_cmpsi_1);
16062 emit_insn (gen_cmp (countreg, countreg));
16063 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16064 operands[1], operands[2]));
16067 outlow = gen_lowpart (QImode, out);
16068 emit_insn (gen_cmpintqi (outlow));
16069 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16071 if (operands[0] != out)
16072 emit_move_insn (operands[0], out);
16077 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16079 (define_expand "cmpintqi"
16080 [(set (match_dup 1)
16081 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16083 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16084 (parallel [(set (match_operand:QI 0 "register_operand")
16085 (minus:QI (match_dup 1)
16087 (clobber (reg:CC FLAGS_REG))])]
16090 operands[1] = gen_reg_rtx (QImode);
16091 operands[2] = gen_reg_rtx (QImode);
16094 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16095 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16097 (define_expand "cmpstrnqi_nz_1"
16098 [(parallel [(set (reg:CC FLAGS_REG)
16099 (compare:CC (match_operand 4 "memory_operand")
16100 (match_operand 5 "memory_operand")))
16101 (use (match_operand 2 "register_operand"))
16102 (use (match_operand:SI 3 "immediate_operand"))
16103 (clobber (match_operand 0 "register_operand"))
16104 (clobber (match_operand 1 "register_operand"))
16105 (clobber (match_dup 2))])]
16107 "ix86_current_function_needs_cld = 1;")
16109 (define_insn "*cmpstrnqi_nz_1"
16110 [(set (reg:CC FLAGS_REG)
16111 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16112 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16113 (use (match_operand:P 6 "register_operand" "2"))
16114 (use (match_operand:SI 3 "immediate_operand" "i"))
16115 (clobber (match_operand:P 0 "register_operand" "=S"))
16116 (clobber (match_operand:P 1 "register_operand" "=D"))
16117 (clobber (match_operand:P 2 "register_operand" "=c"))]
16118 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16120 [(set_attr "type" "str")
16121 (set_attr "mode" "QI")
16122 (set (attr "prefix_rex")
16124 (match_test "<P:MODE>mode == DImode")
16126 (const_string "*")))
16127 (set_attr "prefix_rep" "1")])
16129 ;; The same, but the count is not known to not be zero.
16131 (define_expand "cmpstrnqi_1"
16132 [(parallel [(set (reg:CC FLAGS_REG)
16133 (if_then_else:CC (ne (match_operand 2 "register_operand")
16135 (compare:CC (match_operand 4 "memory_operand")
16136 (match_operand 5 "memory_operand"))
16138 (use (match_operand:SI 3 "immediate_operand"))
16139 (use (reg:CC FLAGS_REG))
16140 (clobber (match_operand 0 "register_operand"))
16141 (clobber (match_operand 1 "register_operand"))
16142 (clobber (match_dup 2))])]
16144 "ix86_current_function_needs_cld = 1;")
16146 (define_insn "*cmpstrnqi_1"
16147 [(set (reg:CC FLAGS_REG)
16148 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16150 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16151 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16153 (use (match_operand:SI 3 "immediate_operand" "i"))
16154 (use (reg:CC FLAGS_REG))
16155 (clobber (match_operand:P 0 "register_operand" "=S"))
16156 (clobber (match_operand:P 1 "register_operand" "=D"))
16157 (clobber (match_operand:P 2 "register_operand" "=c"))]
16158 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16160 [(set_attr "type" "str")
16161 (set_attr "mode" "QI")
16162 (set (attr "prefix_rex")
16164 (match_test "<P:MODE>mode == DImode")
16166 (const_string "*")))
16167 (set_attr "prefix_rep" "1")])
16169 (define_expand "strlen<mode>"
16170 [(set (match_operand:P 0 "register_operand")
16171 (unspec:P [(match_operand:BLK 1 "general_operand")
16172 (match_operand:QI 2 "immediate_operand")
16173 (match_operand 3 "immediate_operand")]
16177 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16183 (define_expand "strlenqi_1"
16184 [(parallel [(set (match_operand 0 "register_operand")
16186 (clobber (match_operand 1 "register_operand"))
16187 (clobber (reg:CC FLAGS_REG))])]
16189 "ix86_current_function_needs_cld = 1;")
16191 (define_insn "*strlenqi_1"
16192 [(set (match_operand:P 0 "register_operand" "=&c")
16193 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16194 (match_operand:QI 2 "register_operand" "a")
16195 (match_operand:P 3 "immediate_operand" "i")
16196 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16197 (clobber (match_operand:P 1 "register_operand" "=D"))
16198 (clobber (reg:CC FLAGS_REG))]
16199 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16200 "%^repnz{%;} scasb"
16201 [(set_attr "type" "str")
16202 (set_attr "mode" "QI")
16203 (set (attr "prefix_rex")
16205 (match_test "<P:MODE>mode == DImode")
16207 (const_string "*")))
16208 (set_attr "prefix_rep" "1")])
16210 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16211 ;; handled in combine, but it is not currently up to the task.
16212 ;; When used for their truth value, the cmpstrn* expanders generate
16221 ;; The intermediate three instructions are unnecessary.
16223 ;; This one handles cmpstrn*_nz_1...
16226 (set (reg:CC FLAGS_REG)
16227 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16228 (mem:BLK (match_operand 5 "register_operand"))))
16229 (use (match_operand 6 "register_operand"))
16230 (use (match_operand:SI 3 "immediate_operand"))
16231 (clobber (match_operand 0 "register_operand"))
16232 (clobber (match_operand 1 "register_operand"))
16233 (clobber (match_operand 2 "register_operand"))])
16234 (set (match_operand:QI 7 "register_operand")
16235 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16236 (set (match_operand:QI 8 "register_operand")
16237 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16238 (set (reg FLAGS_REG)
16239 (compare (match_dup 7) (match_dup 8)))
16241 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16243 (set (reg:CC FLAGS_REG)
16244 (compare:CC (mem:BLK (match_dup 4))
16245 (mem:BLK (match_dup 5))))
16246 (use (match_dup 6))
16247 (use (match_dup 3))
16248 (clobber (match_dup 0))
16249 (clobber (match_dup 1))
16250 (clobber (match_dup 2))])])
16252 ;; ...and this one handles cmpstrn*_1.
16255 (set (reg:CC FLAGS_REG)
16256 (if_then_else:CC (ne (match_operand 6 "register_operand")
16258 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16259 (mem:BLK (match_operand 5 "register_operand")))
16261 (use (match_operand:SI 3 "immediate_operand"))
16262 (use (reg:CC FLAGS_REG))
16263 (clobber (match_operand 0 "register_operand"))
16264 (clobber (match_operand 1 "register_operand"))
16265 (clobber (match_operand 2 "register_operand"))])
16266 (set (match_operand:QI 7 "register_operand")
16267 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16268 (set (match_operand:QI 8 "register_operand")
16269 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16270 (set (reg FLAGS_REG)
16271 (compare (match_dup 7) (match_dup 8)))
16273 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16275 (set (reg:CC FLAGS_REG)
16276 (if_then_else:CC (ne (match_dup 6)
16278 (compare:CC (mem:BLK (match_dup 4))
16279 (mem:BLK (match_dup 5)))
16281 (use (match_dup 3))
16282 (use (reg:CC FLAGS_REG))
16283 (clobber (match_dup 0))
16284 (clobber (match_dup 1))
16285 (clobber (match_dup 2))])])
16287 ;; Conditional move instructions.
16289 (define_expand "mov<mode>cc"
16290 [(set (match_operand:SWIM 0 "register_operand")
16291 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator")
16292 (match_operand:SWIM 2 "<general_operand>")
16293 (match_operand:SWIM 3 "<general_operand>")))]
16295 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16297 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16298 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16299 ;; So just document what we're doing explicitly.
16301 (define_expand "x86_mov<mode>cc_0_m1"
16303 [(set (match_operand:SWI48 0 "register_operand")
16304 (if_then_else:SWI48
16305 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16306 [(match_operand 1 "flags_reg_operand")
16310 (clobber (reg:CC FLAGS_REG))])])
16312 (define_insn "*x86_mov<mode>cc_0_m1"
16313 [(set (match_operand:SWI48 0 "register_operand" "=r")
16314 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16315 [(reg FLAGS_REG) (const_int 0)])
16318 (clobber (reg:CC FLAGS_REG))]
16320 "sbb{<imodesuffix>}\t%0, %0"
16321 ; Since we don't have the proper number of operands for an alu insn,
16322 ; fill in all the blanks.
16323 [(set_attr "type" "alu")
16324 (set_attr "use_carry" "1")
16325 (set_attr "pent_pair" "pu")
16326 (set_attr "memory" "none")
16327 (set_attr "imm_disp" "false")
16328 (set_attr "mode" "<MODE>")
16329 (set_attr "length_immediate" "0")])
16331 (define_insn "*x86_mov<mode>cc_0_m1_se"
16332 [(set (match_operand:SWI48 0 "register_operand" "=r")
16333 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16334 [(reg FLAGS_REG) (const_int 0)])
16337 (clobber (reg:CC FLAGS_REG))]
16339 "sbb{<imodesuffix>}\t%0, %0"
16340 [(set_attr "type" "alu")
16341 (set_attr "use_carry" "1")
16342 (set_attr "pent_pair" "pu")
16343 (set_attr "memory" "none")
16344 (set_attr "imm_disp" "false")
16345 (set_attr "mode" "<MODE>")
16346 (set_attr "length_immediate" "0")])
16348 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16349 [(set (match_operand:SWI48 0 "register_operand" "=r")
16350 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16351 [(reg FLAGS_REG) (const_int 0)])))
16352 (clobber (reg:CC FLAGS_REG))]
16354 "sbb{<imodesuffix>}\t%0, %0"
16355 [(set_attr "type" "alu")
16356 (set_attr "use_carry" "1")
16357 (set_attr "pent_pair" "pu")
16358 (set_attr "memory" "none")
16359 (set_attr "imm_disp" "false")
16360 (set_attr "mode" "<MODE>")
16361 (set_attr "length_immediate" "0")])
16363 (define_insn "*mov<mode>cc_noc"
16364 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16365 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16366 [(reg FLAGS_REG) (const_int 0)])
16367 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16368 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16369 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16371 cmov%O2%C1\t{%2, %0|%0, %2}
16372 cmov%O2%c1\t{%3, %0|%0, %3}"
16373 [(set_attr "type" "icmov")
16374 (set_attr "mode" "<MODE>")])
16376 (define_insn_and_split "*movqicc_noc"
16377 [(set (match_operand:QI 0 "register_operand" "=r,r")
16378 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16379 [(match_operand 4 "flags_reg_operand")
16381 (match_operand:QI 2 "register_operand" "r,0")
16382 (match_operand:QI 3 "register_operand" "0,r")))]
16383 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16385 "&& reload_completed"
16386 [(set (match_dup 0)
16387 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16390 "operands[0] = gen_lowpart (SImode, operands[0]);
16391 operands[2] = gen_lowpart (SImode, operands[2]);
16392 operands[3] = gen_lowpart (SImode, operands[3]);"
16393 [(set_attr "type" "icmov")
16394 (set_attr "mode" "SI")])
16396 (define_expand "mov<mode>cc"
16397 [(set (match_operand:X87MODEF 0 "register_operand")
16398 (if_then_else:X87MODEF
16399 (match_operand 1 "ix86_fp_comparison_operator")
16400 (match_operand:X87MODEF 2 "register_operand")
16401 (match_operand:X87MODEF 3 "register_operand")))]
16402 "(TARGET_80387 && TARGET_CMOVE)
16403 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16404 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16406 (define_insn "*movxfcc_1"
16407 [(set (match_operand:XF 0 "register_operand" "=f,f")
16408 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16409 [(reg FLAGS_REG) (const_int 0)])
16410 (match_operand:XF 2 "register_operand" "f,0")
16411 (match_operand:XF 3 "register_operand" "0,f")))]
16412 "TARGET_80387 && TARGET_CMOVE"
16414 fcmov%F1\t{%2, %0|%0, %2}
16415 fcmov%f1\t{%3, %0|%0, %3}"
16416 [(set_attr "type" "fcmov")
16417 (set_attr "mode" "XF")])
16419 (define_insn "*movdfcc_1_rex64"
16420 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16421 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16422 [(reg FLAGS_REG) (const_int 0)])
16423 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16424 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16425 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16426 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16428 fcmov%F1\t{%2, %0|%0, %2}
16429 fcmov%f1\t{%3, %0|%0, %3}
16430 cmov%O2%C1\t{%2, %0|%0, %2}
16431 cmov%O2%c1\t{%3, %0|%0, %3}"
16432 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16433 (set_attr "mode" "DF,DF,DI,DI")])
16435 (define_insn "*movdfcc_1"
16436 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16437 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16438 [(reg FLAGS_REG) (const_int 0)])
16439 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16440 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16441 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16442 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16444 fcmov%F1\t{%2, %0|%0, %2}
16445 fcmov%f1\t{%3, %0|%0, %3}
16448 [(set_attr "type" "fcmov,fcmov,multi,multi")
16449 (set_attr "mode" "DF,DF,DI,DI")])
16452 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16453 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16454 [(match_operand 4 "flags_reg_operand")
16456 (match_operand:DF 2 "nonimmediate_operand")
16457 (match_operand:DF 3 "nonimmediate_operand")))]
16458 "!TARGET_64BIT && reload_completed"
16459 [(set (match_dup 2)
16460 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16464 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16468 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16469 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16472 (define_insn "*movsfcc_1_387"
16473 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16474 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16475 [(reg FLAGS_REG) (const_int 0)])
16476 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16477 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16478 "TARGET_80387 && TARGET_CMOVE
16479 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16481 fcmov%F1\t{%2, %0|%0, %2}
16482 fcmov%f1\t{%3, %0|%0, %3}
16483 cmov%O2%C1\t{%2, %0|%0, %2}
16484 cmov%O2%c1\t{%3, %0|%0, %3}"
16485 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16486 (set_attr "mode" "SF,SF,SI,SI")])
16488 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16489 ;; the scalar versions to have only XMM registers as operands.
16491 ;; XOP conditional move
16492 (define_insn "*xop_pcmov_<mode>"
16493 [(set (match_operand:MODEF 0 "register_operand" "=x")
16494 (if_then_else:MODEF
16495 (match_operand:MODEF 1 "register_operand" "x")
16496 (match_operand:MODEF 2 "register_operand" "x")
16497 (match_operand:MODEF 3 "register_operand" "x")))]
16499 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16500 [(set_attr "type" "sse4arg")])
16502 ;; These versions of the min/max patterns are intentionally ignorant of
16503 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16504 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16505 ;; are undefined in this condition, we're certain this is correct.
16507 (define_insn "<code><mode>3"
16508 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16510 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16511 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16512 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16514 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16515 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16516 [(set_attr "isa" "noavx,avx")
16517 (set_attr "prefix" "orig,vex")
16518 (set_attr "type" "sseadd")
16519 (set_attr "mode" "<MODE>")])
16521 ;; These versions of the min/max patterns implement exactly the operations
16522 ;; min = (op1 < op2 ? op1 : op2)
16523 ;; max = (!(op1 < op2) ? op1 : op2)
16524 ;; Their operands are not commutative, and thus they may be used in the
16525 ;; presence of -0.0 and NaN.
16527 (define_int_iterator IEEE_MAXMIN
16531 (define_int_attr ieee_maxmin
16532 [(UNSPEC_IEEE_MAX "max")
16533 (UNSPEC_IEEE_MIN "min")])
16535 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16536 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16538 [(match_operand:MODEF 1 "register_operand" "0,x")
16539 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16541 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16543 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16544 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16545 [(set_attr "isa" "noavx,avx")
16546 (set_attr "prefix" "orig,vex")
16547 (set_attr "type" "sseadd")
16548 (set_attr "mode" "<MODE>")])
16550 ;; Make two stack loads independent:
16552 ;; fld %st(0) -> fld bb
16553 ;; fmul bb fmul %st(1), %st
16555 ;; Actually we only match the last two instructions for simplicity.
16557 [(set (match_operand 0 "fp_register_operand")
16558 (match_operand 1 "fp_register_operand"))
16560 (match_operator 2 "binary_fp_operator"
16562 (match_operand 3 "memory_operand")]))]
16563 "REGNO (operands[0]) != REGNO (operands[1])"
16564 [(set (match_dup 0) (match_dup 3))
16565 (set (match_dup 0) (match_dup 4))]
16567 ;; The % modifier is not operational anymore in peephole2's, so we have to
16568 ;; swap the operands manually in the case of addition and multiplication.
16572 if (COMMUTATIVE_ARITH_P (operands[2]))
16573 op0 = operands[0], op1 = operands[1];
16575 op0 = operands[1], op1 = operands[0];
16577 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16578 GET_MODE (operands[2]),
16582 ;; Conditional addition patterns
16583 (define_expand "add<mode>cc"
16584 [(match_operand:SWI 0 "register_operand")
16585 (match_operand 1 "ordered_comparison_operator")
16586 (match_operand:SWI 2 "register_operand")
16587 (match_operand:SWI 3 "const_int_operand")]
16589 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16591 ;; Misc patterns (?)
16593 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16594 ;; Otherwise there will be nothing to keep
16596 ;; [(set (reg ebp) (reg esp))]
16597 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16598 ;; (clobber (eflags)]
16599 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16601 ;; in proper program order.
16603 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16604 [(set (match_operand:P 0 "register_operand" "=r,r")
16605 (plus:P (match_operand:P 1 "register_operand" "0,r")
16606 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16607 (clobber (reg:CC FLAGS_REG))
16608 (clobber (mem:BLK (scratch)))]
16611 switch (get_attr_type (insn))
16614 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16617 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16618 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16619 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16621 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16624 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16625 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16628 [(set (attr "type")
16629 (cond [(and (eq_attr "alternative" "0")
16630 (not (match_test "TARGET_OPT_AGU")))
16631 (const_string "alu")
16632 (match_operand:<MODE> 2 "const0_operand")
16633 (const_string "imov")
16635 (const_string "lea")))
16636 (set (attr "length_immediate")
16637 (cond [(eq_attr "type" "imov")
16639 (and (eq_attr "type" "alu")
16640 (match_operand 2 "const128_operand"))
16643 (const_string "*")))
16644 (set_attr "mode" "<MODE>")])
16646 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16647 [(set (match_operand:P 0 "register_operand" "=r")
16648 (minus:P (match_operand:P 1 "register_operand" "0")
16649 (match_operand:P 2 "register_operand" "r")))
16650 (clobber (reg:CC FLAGS_REG))
16651 (clobber (mem:BLK (scratch)))]
16653 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16654 [(set_attr "type" "alu")
16655 (set_attr "mode" "<MODE>")])
16657 (define_insn "allocate_stack_worker_probe_<mode>"
16658 [(set (match_operand:P 0 "register_operand" "=a")
16659 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16660 UNSPECV_STACK_PROBE))
16661 (clobber (reg:CC FLAGS_REG))]
16662 "ix86_target_stack_probe ()"
16663 "call\t___chkstk_ms"
16664 [(set_attr "type" "multi")
16665 (set_attr "length" "5")])
16667 (define_expand "allocate_stack"
16668 [(match_operand 0 "register_operand")
16669 (match_operand 1 "general_operand")]
16670 "ix86_target_stack_probe ()"
16674 #ifndef CHECK_STACK_LIMIT
16675 #define CHECK_STACK_LIMIT 0
16678 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16679 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16683 rtx (*insn) (rtx, rtx);
16685 x = copy_to_mode_reg (Pmode, operands[1]);
16687 insn = (TARGET_64BIT
16688 ? gen_allocate_stack_worker_probe_di
16689 : gen_allocate_stack_worker_probe_si);
16691 emit_insn (insn (x, x));
16694 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16695 stack_pointer_rtx, 0, OPTAB_DIRECT);
16697 if (x != stack_pointer_rtx)
16698 emit_move_insn (stack_pointer_rtx, x);
16700 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16704 ;; Use IOR for stack probes, this is shorter.
16705 (define_expand "probe_stack"
16706 [(match_operand 0 "memory_operand")]
16709 rtx (*gen_ior3) (rtx, rtx, rtx);
16711 gen_ior3 = (GET_MODE (operands[0]) == DImode
16712 ? gen_iordi3 : gen_iorsi3);
16714 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16718 (define_insn "adjust_stack_and_probe<mode>"
16719 [(set (match_operand:P 0 "register_operand" "=r")
16720 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16721 UNSPECV_PROBE_STACK_RANGE))
16722 (set (reg:P SP_REG)
16723 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16724 (clobber (reg:CC FLAGS_REG))
16725 (clobber (mem:BLK (scratch)))]
16727 "* return output_adjust_stack_and_probe (operands[0]);"
16728 [(set_attr "type" "multi")])
16730 (define_insn "probe_stack_range<mode>"
16731 [(set (match_operand:P 0 "register_operand" "=r")
16732 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16733 (match_operand:P 2 "const_int_operand" "n")]
16734 UNSPECV_PROBE_STACK_RANGE))
16735 (clobber (reg:CC FLAGS_REG))]
16737 "* return output_probe_stack_range (operands[0], operands[2]);"
16738 [(set_attr "type" "multi")])
16740 (define_expand "builtin_setjmp_receiver"
16741 [(label_ref (match_operand 0))]
16742 "!TARGET_64BIT && flag_pic"
16748 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16749 rtx label_rtx = gen_label_rtx ();
16750 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16751 xops[0] = xops[1] = picreg;
16752 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16753 ix86_expand_binary_operator (MINUS, SImode, xops);
16757 emit_insn (gen_set_got (pic_offset_table_rtx));
16761 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16764 [(set (match_operand 0 "register_operand")
16765 (match_operator 3 "promotable_binary_operator"
16766 [(match_operand 1 "register_operand")
16767 (match_operand 2 "aligned_operand")]))
16768 (clobber (reg:CC FLAGS_REG))]
16769 "! TARGET_PARTIAL_REG_STALL && reload_completed
16770 && ((GET_MODE (operands[0]) == HImode
16771 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16772 /* ??? next two lines just !satisfies_constraint_K (...) */
16773 || !CONST_INT_P (operands[2])
16774 || satisfies_constraint_K (operands[2])))
16775 || (GET_MODE (operands[0]) == QImode
16776 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16777 [(parallel [(set (match_dup 0)
16778 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16779 (clobber (reg:CC FLAGS_REG))])]
16781 operands[0] = gen_lowpart (SImode, operands[0]);
16782 operands[1] = gen_lowpart (SImode, operands[1]);
16783 if (GET_CODE (operands[3]) != ASHIFT)
16784 operands[2] = gen_lowpart (SImode, operands[2]);
16785 PUT_MODE (operands[3], SImode);
16788 ; Promote the QImode tests, as i386 has encoding of the AND
16789 ; instruction with 32-bit sign-extended immediate and thus the
16790 ; instruction size is unchanged, except in the %eax case for
16791 ; which it is increased by one byte, hence the ! optimize_size.
16793 [(set (match_operand 0 "flags_reg_operand")
16794 (match_operator 2 "compare_operator"
16795 [(and (match_operand 3 "aligned_operand")
16796 (match_operand 4 "const_int_operand"))
16798 (set (match_operand 1 "register_operand")
16799 (and (match_dup 3) (match_dup 4)))]
16800 "! TARGET_PARTIAL_REG_STALL && reload_completed
16801 && optimize_insn_for_speed_p ()
16802 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16803 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16804 /* Ensure that the operand will remain sign-extended immediate. */
16805 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16806 [(parallel [(set (match_dup 0)
16807 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16810 (and:SI (match_dup 3) (match_dup 4)))])]
16813 = gen_int_mode (INTVAL (operands[4])
16814 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16815 operands[1] = gen_lowpart (SImode, operands[1]);
16816 operands[3] = gen_lowpart (SImode, operands[3]);
16819 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16820 ; the TEST instruction with 32-bit sign-extended immediate and thus
16821 ; the instruction size would at least double, which is not what we
16822 ; want even with ! optimize_size.
16824 [(set (match_operand 0 "flags_reg_operand")
16825 (match_operator 1 "compare_operator"
16826 [(and (match_operand:HI 2 "aligned_operand")
16827 (match_operand:HI 3 "const_int_operand"))
16829 "! TARGET_PARTIAL_REG_STALL && reload_completed
16830 && ! TARGET_FAST_PREFIX
16831 && optimize_insn_for_speed_p ()
16832 /* Ensure that the operand will remain sign-extended immediate. */
16833 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16834 [(set (match_dup 0)
16835 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16839 = gen_int_mode (INTVAL (operands[3])
16840 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16841 operands[2] = gen_lowpart (SImode, operands[2]);
16845 [(set (match_operand 0 "register_operand")
16846 (neg (match_operand 1 "register_operand")))
16847 (clobber (reg:CC FLAGS_REG))]
16848 "! TARGET_PARTIAL_REG_STALL && reload_completed
16849 && (GET_MODE (operands[0]) == HImode
16850 || (GET_MODE (operands[0]) == QImode
16851 && (TARGET_PROMOTE_QImode
16852 || optimize_insn_for_size_p ())))"
16853 [(parallel [(set (match_dup 0)
16854 (neg:SI (match_dup 1)))
16855 (clobber (reg:CC FLAGS_REG))])]
16857 operands[0] = gen_lowpart (SImode, operands[0]);
16858 operands[1] = gen_lowpart (SImode, operands[1]);
16862 [(set (match_operand 0 "register_operand")
16863 (not (match_operand 1 "register_operand")))]
16864 "! TARGET_PARTIAL_REG_STALL && reload_completed
16865 && (GET_MODE (operands[0]) == HImode
16866 || (GET_MODE (operands[0]) == QImode
16867 && (TARGET_PROMOTE_QImode
16868 || optimize_insn_for_size_p ())))"
16869 [(set (match_dup 0)
16870 (not:SI (match_dup 1)))]
16872 operands[0] = gen_lowpart (SImode, operands[0]);
16873 operands[1] = gen_lowpart (SImode, operands[1]);
16877 [(set (match_operand 0 "register_operand")
16878 (if_then_else (match_operator 1 "ordered_comparison_operator"
16879 [(reg FLAGS_REG) (const_int 0)])
16880 (match_operand 2 "register_operand")
16881 (match_operand 3 "register_operand")))]
16882 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16883 && (GET_MODE (operands[0]) == HImode
16884 || (GET_MODE (operands[0]) == QImode
16885 && (TARGET_PROMOTE_QImode
16886 || optimize_insn_for_size_p ())))"
16887 [(set (match_dup 0)
16888 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16890 operands[0] = gen_lowpart (SImode, operands[0]);
16891 operands[2] = gen_lowpart (SImode, operands[2]);
16892 operands[3] = gen_lowpart (SImode, operands[3]);
16895 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16896 ;; transform a complex memory operation into two memory to register operations.
16898 ;; Don't push memory operands
16900 [(set (match_operand:SWI 0 "push_operand")
16901 (match_operand:SWI 1 "memory_operand"))
16902 (match_scratch:SWI 2 "<r>")]
16903 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16904 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16905 [(set (match_dup 2) (match_dup 1))
16906 (set (match_dup 0) (match_dup 2))])
16908 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16911 [(set (match_operand:SF 0 "push_operand")
16912 (match_operand:SF 1 "memory_operand"))
16913 (match_scratch:SF 2 "r")]
16914 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16915 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16916 [(set (match_dup 2) (match_dup 1))
16917 (set (match_dup 0) (match_dup 2))])
16919 ;; Don't move an immediate directly to memory when the instruction
16920 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16922 [(match_scratch:SWI124 1 "<r>")
16923 (set (match_operand:SWI124 0 "memory_operand")
16925 "optimize_insn_for_speed_p ()
16926 && ((<MODE>mode == HImode
16927 && TARGET_LCP_STALL)
16928 || (!TARGET_USE_MOV0
16929 && TARGET_SPLIT_LONG_MOVES
16930 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16931 && peep2_regno_dead_p (0, FLAGS_REG)"
16932 [(parallel [(set (match_dup 2) (const_int 0))
16933 (clobber (reg:CC FLAGS_REG))])
16934 (set (match_dup 0) (match_dup 1))]
16935 "operands[2] = gen_lowpart (SImode, operands[1]);")
16938 [(match_scratch:SWI124 2 "<r>")
16939 (set (match_operand:SWI124 0 "memory_operand")
16940 (match_operand:SWI124 1 "immediate_operand"))]
16941 "optimize_insn_for_speed_p ()
16942 && ((<MODE>mode == HImode
16943 && TARGET_LCP_STALL)
16944 || (TARGET_SPLIT_LONG_MOVES
16945 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16946 [(set (match_dup 2) (match_dup 1))
16947 (set (match_dup 0) (match_dup 2))])
16949 ;; Don't compare memory with zero, load and use a test instead.
16951 [(set (match_operand 0 "flags_reg_operand")
16952 (match_operator 1 "compare_operator"
16953 [(match_operand:SI 2 "memory_operand")
16955 (match_scratch:SI 3 "r")]
16956 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16957 [(set (match_dup 3) (match_dup 2))
16958 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16960 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16961 ;; Don't split NOTs with a displacement operand, because resulting XOR
16962 ;; will not be pairable anyway.
16964 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16965 ;; represented using a modRM byte. The XOR replacement is long decoded,
16966 ;; so this split helps here as well.
16968 ;; Note: Can't do this as a regular split because we can't get proper
16969 ;; lifetime information then.
16972 [(set (match_operand:SWI124 0 "nonimmediate_operand")
16973 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16974 "optimize_insn_for_speed_p ()
16975 && ((TARGET_NOT_UNPAIRABLE
16976 && (!MEM_P (operands[0])
16977 || !memory_displacement_operand (operands[0], <MODE>mode)))
16978 || (TARGET_NOT_VECTORMODE
16979 && long_memory_operand (operands[0], <MODE>mode)))
16980 && peep2_regno_dead_p (0, FLAGS_REG)"
16981 [(parallel [(set (match_dup 0)
16982 (xor:SWI124 (match_dup 1) (const_int -1)))
16983 (clobber (reg:CC FLAGS_REG))])])
16985 ;; Non pairable "test imm, reg" instructions can be translated to
16986 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16987 ;; byte opcode instead of two, have a short form for byte operands),
16988 ;; so do it for other CPUs as well. Given that the value was dead,
16989 ;; this should not create any new dependencies. Pass on the sub-word
16990 ;; versions if we're concerned about partial register stalls.
16993 [(set (match_operand 0 "flags_reg_operand")
16994 (match_operator 1 "compare_operator"
16995 [(and:SI (match_operand:SI 2 "register_operand")
16996 (match_operand:SI 3 "immediate_operand"))
16998 "ix86_match_ccmode (insn, CCNOmode)
16999 && (true_regnum (operands[2]) != AX_REG
17000 || satisfies_constraint_K (operands[3]))
17001 && peep2_reg_dead_p (1, operands[2])"
17003 [(set (match_dup 0)
17004 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17007 (and:SI (match_dup 2) (match_dup 3)))])])
17009 ;; We don't need to handle HImode case, because it will be promoted to SImode
17010 ;; on ! TARGET_PARTIAL_REG_STALL
17013 [(set (match_operand 0 "flags_reg_operand")
17014 (match_operator 1 "compare_operator"
17015 [(and:QI (match_operand:QI 2 "register_operand")
17016 (match_operand:QI 3 "immediate_operand"))
17018 "! TARGET_PARTIAL_REG_STALL
17019 && ix86_match_ccmode (insn, CCNOmode)
17020 && true_regnum (operands[2]) != AX_REG
17021 && peep2_reg_dead_p (1, operands[2])"
17023 [(set (match_dup 0)
17024 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17027 (and:QI (match_dup 2) (match_dup 3)))])])
17030 [(set (match_operand 0 "flags_reg_operand")
17031 (match_operator 1 "compare_operator"
17034 (match_operand 2 "ext_register_operand")
17037 (match_operand 3 "const_int_operand"))
17039 "! TARGET_PARTIAL_REG_STALL
17040 && ix86_match_ccmode (insn, CCNOmode)
17041 && true_regnum (operands[2]) != AX_REG
17042 && peep2_reg_dead_p (1, operands[2])"
17043 [(parallel [(set (match_dup 0)
17052 (set (zero_extract:SI (match_dup 2)
17060 (match_dup 3)))])])
17062 ;; Don't do logical operations with memory inputs.
17064 [(match_scratch:SI 2 "r")
17065 (parallel [(set (match_operand:SI 0 "register_operand")
17066 (match_operator:SI 3 "arith_or_logical_operator"
17068 (match_operand:SI 1 "memory_operand")]))
17069 (clobber (reg:CC FLAGS_REG))])]
17070 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17071 [(set (match_dup 2) (match_dup 1))
17072 (parallel [(set (match_dup 0)
17073 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17074 (clobber (reg:CC FLAGS_REG))])])
17077 [(match_scratch:SI 2 "r")
17078 (parallel [(set (match_operand:SI 0 "register_operand")
17079 (match_operator:SI 3 "arith_or_logical_operator"
17080 [(match_operand:SI 1 "memory_operand")
17082 (clobber (reg:CC FLAGS_REG))])]
17083 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17084 [(set (match_dup 2) (match_dup 1))
17085 (parallel [(set (match_dup 0)
17086 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17087 (clobber (reg:CC FLAGS_REG))])])
17089 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17090 ;; refers to the destination of the load!
17093 [(set (match_operand:SI 0 "register_operand")
17094 (match_operand:SI 1 "register_operand"))
17095 (parallel [(set (match_dup 0)
17096 (match_operator:SI 3 "commutative_operator"
17098 (match_operand:SI 2 "memory_operand")]))
17099 (clobber (reg:CC FLAGS_REG))])]
17100 "REGNO (operands[0]) != REGNO (operands[1])
17101 && GENERAL_REGNO_P (REGNO (operands[0]))
17102 && GENERAL_REGNO_P (REGNO (operands[1]))"
17103 [(set (match_dup 0) (match_dup 4))
17104 (parallel [(set (match_dup 0)
17105 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17106 (clobber (reg:CC FLAGS_REG))])]
17107 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17110 [(set (match_operand 0 "register_operand")
17111 (match_operand 1 "register_operand"))
17113 (match_operator 3 "commutative_operator"
17115 (match_operand 2 "memory_operand")]))]
17116 "REGNO (operands[0]) != REGNO (operands[1])
17117 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17118 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17119 [(set (match_dup 0) (match_dup 2))
17121 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17123 ; Don't do logical operations with memory outputs
17125 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17126 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17127 ; the same decoder scheduling characteristics as the original.
17130 [(match_scratch:SI 2 "r")
17131 (parallel [(set (match_operand:SI 0 "memory_operand")
17132 (match_operator:SI 3 "arith_or_logical_operator"
17134 (match_operand:SI 1 "nonmemory_operand")]))
17135 (clobber (reg:CC FLAGS_REG))])]
17136 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17137 /* Do not split stack checking probes. */
17138 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17139 [(set (match_dup 2) (match_dup 0))
17140 (parallel [(set (match_dup 2)
17141 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17142 (clobber (reg:CC FLAGS_REG))])
17143 (set (match_dup 0) (match_dup 2))])
17146 [(match_scratch:SI 2 "r")
17147 (parallel [(set (match_operand:SI 0 "memory_operand")
17148 (match_operator:SI 3 "arith_or_logical_operator"
17149 [(match_operand:SI 1 "nonmemory_operand")
17151 (clobber (reg:CC FLAGS_REG))])]
17152 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17153 /* Do not split stack checking probes. */
17154 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17155 [(set (match_dup 2) (match_dup 0))
17156 (parallel [(set (match_dup 2)
17157 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17158 (clobber (reg:CC FLAGS_REG))])
17159 (set (match_dup 0) (match_dup 2))])
17161 ;; Attempt to use arith or logical operations with memory outputs with
17162 ;; setting of flags.
17164 [(set (match_operand:SWI 0 "register_operand")
17165 (match_operand:SWI 1 "memory_operand"))
17166 (parallel [(set (match_dup 0)
17167 (match_operator:SWI 3 "plusminuslogic_operator"
17169 (match_operand:SWI 2 "<nonmemory_operand>")]))
17170 (clobber (reg:CC FLAGS_REG))])
17171 (set (match_dup 1) (match_dup 0))
17172 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17173 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17174 && peep2_reg_dead_p (4, operands[0])
17175 && !reg_overlap_mentioned_p (operands[0], operands[1])
17176 && (<MODE>mode != QImode
17177 || immediate_operand (operands[2], QImode)
17178 || q_regs_operand (operands[2], QImode))
17179 && ix86_match_ccmode (peep2_next_insn (3),
17180 (GET_CODE (operands[3]) == PLUS
17181 || GET_CODE (operands[3]) == MINUS)
17182 ? CCGOCmode : CCNOmode)"
17183 [(parallel [(set (match_dup 4) (match_dup 5))
17184 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17185 (match_dup 2)]))])]
17187 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17188 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17189 copy_rtx (operands[1]),
17190 copy_rtx (operands[2]));
17191 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17192 operands[5], const0_rtx);
17196 [(parallel [(set (match_operand:SWI 0 "register_operand")
17197 (match_operator:SWI 2 "plusminuslogic_operator"
17199 (match_operand:SWI 1 "memory_operand")]))
17200 (clobber (reg:CC FLAGS_REG))])
17201 (set (match_dup 1) (match_dup 0))
17202 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17203 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17204 && GET_CODE (operands[2]) != MINUS
17205 && peep2_reg_dead_p (3, operands[0])
17206 && !reg_overlap_mentioned_p (operands[0], operands[1])
17207 && ix86_match_ccmode (peep2_next_insn (2),
17208 GET_CODE (operands[2]) == PLUS
17209 ? CCGOCmode : CCNOmode)"
17210 [(parallel [(set (match_dup 3) (match_dup 4))
17211 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17212 (match_dup 0)]))])]
17214 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17215 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17216 copy_rtx (operands[1]),
17217 copy_rtx (operands[0]));
17218 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17219 operands[4], const0_rtx);
17223 [(set (match_operand:SWI12 0 "register_operand")
17224 (match_operand:SWI12 1 "memory_operand"))
17225 (parallel [(set (match_operand:SI 4 "register_operand")
17226 (match_operator:SI 3 "plusminuslogic_operator"
17228 (match_operand:SI 2 "nonmemory_operand")]))
17229 (clobber (reg:CC FLAGS_REG))])
17230 (set (match_dup 1) (match_dup 0))
17231 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17232 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17233 && REG_P (operands[0]) && REG_P (operands[4])
17234 && REGNO (operands[0]) == REGNO (operands[4])
17235 && peep2_reg_dead_p (4, operands[0])
17236 && (<MODE>mode != QImode
17237 || immediate_operand (operands[2], SImode)
17238 || q_regs_operand (operands[2], SImode))
17239 && !reg_overlap_mentioned_p (operands[0], operands[1])
17240 && ix86_match_ccmode (peep2_next_insn (3),
17241 (GET_CODE (operands[3]) == PLUS
17242 || GET_CODE (operands[3]) == MINUS)
17243 ? CCGOCmode : CCNOmode)"
17244 [(parallel [(set (match_dup 4) (match_dup 5))
17245 (set (match_dup 1) (match_dup 6))])]
17247 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17248 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17249 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17250 copy_rtx (operands[1]), operands[2]);
17251 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17252 operands[5], const0_rtx);
17253 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17254 copy_rtx (operands[1]),
17255 copy_rtx (operands[2]));
17258 ;; Attempt to always use XOR for zeroing registers.
17260 [(set (match_operand 0 "register_operand")
17261 (match_operand 1 "const0_operand"))]
17262 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17263 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17264 && GENERAL_REG_P (operands[0])
17265 && peep2_regno_dead_p (0, FLAGS_REG)"
17266 [(parallel [(set (match_dup 0) (const_int 0))
17267 (clobber (reg:CC FLAGS_REG))])]
17268 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17271 [(set (strict_low_part (match_operand 0 "register_operand"))
17273 "(GET_MODE (operands[0]) == QImode
17274 || GET_MODE (operands[0]) == HImode)
17275 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17276 && peep2_regno_dead_p (0, FLAGS_REG)"
17277 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17278 (clobber (reg:CC FLAGS_REG))])])
17280 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17282 [(set (match_operand:SWI248 0 "register_operand")
17284 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17285 && peep2_regno_dead_p (0, FLAGS_REG)"
17286 [(parallel [(set (match_dup 0) (const_int -1))
17287 (clobber (reg:CC FLAGS_REG))])]
17289 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17290 operands[0] = gen_lowpart (SImode, operands[0]);
17293 ;; Attempt to convert simple lea to add/shift.
17294 ;; These can be created by move expanders.
17297 [(set (match_operand:SWI48 0 "register_operand")
17298 (plus:SWI48 (match_dup 0)
17299 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17300 "peep2_regno_dead_p (0, FLAGS_REG)"
17301 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17302 (clobber (reg:CC FLAGS_REG))])])
17305 [(set (match_operand:SI 0 "register_operand")
17306 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand")
17307 (match_operand:DI 2 "nonmemory_operand")) 0))]
17309 && peep2_regno_dead_p (0, FLAGS_REG)
17310 && REGNO (operands[0]) == REGNO (operands[1])"
17311 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17312 (clobber (reg:CC FLAGS_REG))])]
17313 "operands[2] = gen_lowpart (SImode, operands[2]);")
17316 [(set (match_operand:SWI48 0 "register_operand")
17317 (mult:SWI48 (match_dup 0)
17318 (match_operand:SWI48 1 "const_int_operand")))]
17319 "exact_log2 (INTVAL (operands[1])) >= 0
17320 && peep2_regno_dead_p (0, FLAGS_REG)"
17321 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17322 (clobber (reg:CC FLAGS_REG))])]
17323 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17326 [(set (match_operand:SI 0 "register_operand")
17327 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand")
17328 (match_operand:DI 2 "const_int_operand")) 0))]
17330 && exact_log2 (INTVAL (operands[2])) >= 0
17331 && REGNO (operands[0]) == REGNO (operands[1])
17332 && peep2_regno_dead_p (0, FLAGS_REG)"
17333 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17334 (clobber (reg:CC FLAGS_REG))])]
17335 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17337 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17338 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17339 ;; On many CPUs it is also faster, since special hardware to avoid esp
17340 ;; dependencies is present.
17342 ;; While some of these conversions may be done using splitters, we use
17343 ;; peepholes in order to allow combine_stack_adjustments pass to see
17344 ;; nonobfuscated RTL.
17346 ;; Convert prologue esp subtractions to push.
17347 ;; We need register to push. In order to keep verify_flow_info happy we have
17349 ;; - use scratch and clobber it in order to avoid dependencies
17350 ;; - use already live register
17351 ;; We can't use the second way right now, since there is no reliable way how to
17352 ;; verify that given register is live. First choice will also most likely in
17353 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17354 ;; call clobbered registers are dead. We may want to use base pointer as an
17355 ;; alternative when no register is available later.
17358 [(match_scratch:W 1 "r")
17359 (parallel [(set (reg:P SP_REG)
17360 (plus:P (reg:P SP_REG)
17361 (match_operand:P 0 "const_int_operand")))
17362 (clobber (reg:CC FLAGS_REG))
17363 (clobber (mem:BLK (scratch)))])]
17364 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17365 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17366 [(clobber (match_dup 1))
17367 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17368 (clobber (mem:BLK (scratch)))])])
17371 [(match_scratch:W 1 "r")
17372 (parallel [(set (reg:P SP_REG)
17373 (plus:P (reg:P SP_REG)
17374 (match_operand:P 0 "const_int_operand")))
17375 (clobber (reg:CC FLAGS_REG))
17376 (clobber (mem:BLK (scratch)))])]
17377 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17378 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17379 [(clobber (match_dup 1))
17380 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17381 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17382 (clobber (mem:BLK (scratch)))])])
17384 ;; Convert esp subtractions to push.
17386 [(match_scratch:W 1 "r")
17387 (parallel [(set (reg:P SP_REG)
17388 (plus:P (reg:P SP_REG)
17389 (match_operand:P 0 "const_int_operand")))
17390 (clobber (reg:CC FLAGS_REG))])]
17391 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17392 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17393 [(clobber (match_dup 1))
17394 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17397 [(match_scratch:W 1 "r")
17398 (parallel [(set (reg:P SP_REG)
17399 (plus:P (reg:P SP_REG)
17400 (match_operand:P 0 "const_int_operand")))
17401 (clobber (reg:CC FLAGS_REG))])]
17402 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17403 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17404 [(clobber (match_dup 1))
17405 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17406 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17408 ;; Convert epilogue deallocator to pop.
17410 [(match_scratch:W 1 "r")
17411 (parallel [(set (reg:P SP_REG)
17412 (plus:P (reg:P SP_REG)
17413 (match_operand:P 0 "const_int_operand")))
17414 (clobber (reg:CC FLAGS_REG))
17415 (clobber (mem:BLK (scratch)))])]
17416 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17417 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17418 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17419 (clobber (mem:BLK (scratch)))])])
17421 ;; Two pops case is tricky, since pop causes dependency
17422 ;; on destination register. We use two registers if available.
17424 [(match_scratch:W 1 "r")
17425 (match_scratch:W 2 "r")
17426 (parallel [(set (reg:P SP_REG)
17427 (plus:P (reg:P SP_REG)
17428 (match_operand:P 0 "const_int_operand")))
17429 (clobber (reg:CC FLAGS_REG))
17430 (clobber (mem:BLK (scratch)))])]
17431 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17432 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17433 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17434 (clobber (mem:BLK (scratch)))])
17435 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17438 [(match_scratch:W 1 "r")
17439 (parallel [(set (reg:P SP_REG)
17440 (plus:P (reg:P SP_REG)
17441 (match_operand:P 0 "const_int_operand")))
17442 (clobber (reg:CC FLAGS_REG))
17443 (clobber (mem:BLK (scratch)))])]
17444 "optimize_insn_for_size_p ()
17445 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17446 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17447 (clobber (mem:BLK (scratch)))])
17448 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17450 ;; Convert esp additions to pop.
17452 [(match_scratch:W 1 "r")
17453 (parallel [(set (reg:P SP_REG)
17454 (plus:P (reg:P SP_REG)
17455 (match_operand:P 0 "const_int_operand")))
17456 (clobber (reg:CC FLAGS_REG))])]
17457 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17458 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17460 ;; Two pops case is tricky, since pop causes dependency
17461 ;; on destination register. We use two registers if available.
17463 [(match_scratch:W 1 "r")
17464 (match_scratch:W 2 "r")
17465 (parallel [(set (reg:P SP_REG)
17466 (plus:P (reg:P SP_REG)
17467 (match_operand:P 0 "const_int_operand")))
17468 (clobber (reg:CC FLAGS_REG))])]
17469 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17470 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17471 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17474 [(match_scratch:W 1 "r")
17475 (parallel [(set (reg:P SP_REG)
17476 (plus:P (reg:P SP_REG)
17477 (match_operand:P 0 "const_int_operand")))
17478 (clobber (reg:CC FLAGS_REG))])]
17479 "optimize_insn_for_size_p ()
17480 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17481 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17482 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17484 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17485 ;; required and register dies. Similarly for 128 to -128.
17487 [(set (match_operand 0 "flags_reg_operand")
17488 (match_operator 1 "compare_operator"
17489 [(match_operand 2 "register_operand")
17490 (match_operand 3 "const_int_operand")]))]
17491 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17492 && incdec_operand (operands[3], GET_MODE (operands[3])))
17493 || (!TARGET_FUSE_CMP_AND_BRANCH
17494 && INTVAL (operands[3]) == 128))
17495 && ix86_match_ccmode (insn, CCGCmode)
17496 && peep2_reg_dead_p (1, operands[2])"
17497 [(parallel [(set (match_dup 0)
17498 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17499 (clobber (match_dup 2))])])
17501 ;; Convert imul by three, five and nine into lea
17504 [(set (match_operand:SWI48 0 "register_operand")
17505 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17506 (match_operand:SWI48 2 "const359_operand")))
17507 (clobber (reg:CC FLAGS_REG))])]
17508 "!TARGET_PARTIAL_REG_STALL
17509 || <MODE>mode == SImode
17510 || optimize_function_for_size_p (cfun)"
17511 [(set (match_dup 0)
17512 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17514 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17518 [(set (match_operand:SWI48 0 "register_operand")
17519 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17520 (match_operand:SWI48 2 "const359_operand")))
17521 (clobber (reg:CC FLAGS_REG))])]
17522 "optimize_insn_for_speed_p ()
17523 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17524 [(set (match_dup 0) (match_dup 1))
17526 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17528 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17530 ;; imul $32bit_imm, mem, reg is vector decoded, while
17531 ;; imul $32bit_imm, reg, reg is direct decoded.
17533 [(match_scratch:SWI48 3 "r")
17534 (parallel [(set (match_operand:SWI48 0 "register_operand")
17535 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17536 (match_operand:SWI48 2 "immediate_operand")))
17537 (clobber (reg:CC FLAGS_REG))])]
17538 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17539 && !satisfies_constraint_K (operands[2])"
17540 [(set (match_dup 3) (match_dup 1))
17541 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17542 (clobber (reg:CC FLAGS_REG))])])
17545 [(match_scratch:SI 3 "r")
17546 (parallel [(set (match_operand:DI 0 "register_operand")
17548 (mult:SI (match_operand:SI 1 "memory_operand")
17549 (match_operand:SI 2 "immediate_operand"))))
17550 (clobber (reg:CC FLAGS_REG))])]
17552 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17553 && !satisfies_constraint_K (operands[2])"
17554 [(set (match_dup 3) (match_dup 1))
17555 (parallel [(set (match_dup 0)
17556 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17557 (clobber (reg:CC FLAGS_REG))])])
17559 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17560 ;; Convert it into imul reg, reg
17561 ;; It would be better to force assembler to encode instruction using long
17562 ;; immediate, but there is apparently no way to do so.
17564 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17566 (match_operand:SWI248 1 "nonimmediate_operand")
17567 (match_operand:SWI248 2 "const_int_operand")))
17568 (clobber (reg:CC FLAGS_REG))])
17569 (match_scratch:SWI248 3 "r")]
17570 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17571 && satisfies_constraint_K (operands[2])"
17572 [(set (match_dup 3) (match_dup 2))
17573 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17574 (clobber (reg:CC FLAGS_REG))])]
17576 if (!rtx_equal_p (operands[0], operands[1]))
17577 emit_move_insn (operands[0], operands[1]);
17580 ;; After splitting up read-modify operations, array accesses with memory
17581 ;; operands might end up in form:
17583 ;; movl 4(%esp), %edx
17585 ;; instead of pre-splitting:
17587 ;; addl 4(%esp), %eax
17589 ;; movl 4(%esp), %edx
17590 ;; leal (%edx,%eax,4), %eax
17593 [(match_scratch:W 5 "r")
17594 (parallel [(set (match_operand 0 "register_operand")
17595 (ashift (match_operand 1 "register_operand")
17596 (match_operand 2 "const_int_operand")))
17597 (clobber (reg:CC FLAGS_REG))])
17598 (parallel [(set (match_operand 3 "register_operand")
17599 (plus (match_dup 0)
17600 (match_operand 4 "x86_64_general_operand")))
17601 (clobber (reg:CC FLAGS_REG))])]
17602 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17603 /* Validate MODE for lea. */
17604 && ((!TARGET_PARTIAL_REG_STALL
17605 && (GET_MODE (operands[0]) == QImode
17606 || GET_MODE (operands[0]) == HImode))
17607 || GET_MODE (operands[0]) == SImode
17608 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17609 && (rtx_equal_p (operands[0], operands[3])
17610 || peep2_reg_dead_p (2, operands[0]))
17611 /* We reorder load and the shift. */
17612 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17613 [(set (match_dup 5) (match_dup 4))
17614 (set (match_dup 0) (match_dup 1))]
17616 enum machine_mode op1mode = GET_MODE (operands[1]);
17617 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17618 int scale = 1 << INTVAL (operands[2]);
17619 rtx index = gen_lowpart (word_mode, operands[1]);
17620 rtx base = gen_lowpart (word_mode, operands[5]);
17621 rtx dest = gen_lowpart (mode, operands[3]);
17623 operands[1] = gen_rtx_PLUS (word_mode, base,
17624 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17625 operands[5] = base;
17626 if (mode != word_mode)
17627 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17628 if (op1mode != word_mode)
17629 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17630 operands[0] = dest;
17633 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17634 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17635 ;; caught for use by garbage collectors and the like. Using an insn that
17636 ;; maps to SIGILL makes it more likely the program will rightfully die.
17637 ;; Keeping with tradition, "6" is in honor of #UD.
17638 (define_insn "trap"
17639 [(trap_if (const_int 1) (const_int 6))]
17641 { return ASM_SHORT "0x0b0f"; }
17642 [(set_attr "length" "2")])
17644 (define_expand "prefetch"
17645 [(prefetch (match_operand 0 "address_operand")
17646 (match_operand:SI 1 "const_int_operand")
17647 (match_operand:SI 2 "const_int_operand"))]
17648 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17650 int rw = INTVAL (operands[1]);
17651 int locality = INTVAL (operands[2]);
17653 gcc_assert (rw == 0 || rw == 1);
17654 gcc_assert (locality >= 0 && locality <= 3);
17655 gcc_assert (GET_MODE (operands[0]) == Pmode
17656 || GET_MODE (operands[0]) == VOIDmode);
17658 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17659 supported by SSE counterpart or the SSE prefetch is not available
17660 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17662 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17663 operands[2] = GEN_INT (3);
17665 operands[1] = const0_rtx;
17668 (define_insn "*prefetch_sse_<mode>"
17669 [(prefetch (match_operand:P 0 "address_operand" "p")
17671 (match_operand:SI 1 "const_int_operand"))]
17672 "TARGET_PREFETCH_SSE"
17674 static const char * const patterns[4] = {
17675 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17678 int locality = INTVAL (operands[1]);
17679 gcc_assert (locality >= 0 && locality <= 3);
17681 return patterns[locality];
17683 [(set_attr "type" "sse")
17684 (set_attr "atom_sse_attr" "prefetch")
17685 (set (attr "length_address")
17686 (symbol_ref "memory_address_length (operands[0])"))
17687 (set_attr "memory" "none")])
17689 (define_insn "*prefetch_3dnow_<mode>"
17690 [(prefetch (match_operand:P 0 "address_operand" "p")
17691 (match_operand:SI 1 "const_int_operand" "n")
17695 if (INTVAL (operands[1]) == 0)
17696 return "prefetch\t%a0";
17698 return "prefetchw\t%a0";
17700 [(set_attr "type" "mmx")
17701 (set (attr "length_address")
17702 (symbol_ref "memory_address_length (operands[0])"))
17703 (set_attr "memory" "none")])
17705 (define_expand "stack_protect_set"
17706 [(match_operand 0 "memory_operand")
17707 (match_operand 1 "memory_operand")]
17710 rtx (*insn)(rtx, rtx);
17712 #ifdef TARGET_THREAD_SSP_OFFSET
17713 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17714 insn = (TARGET_LP64
17715 ? gen_stack_tls_protect_set_di
17716 : gen_stack_tls_protect_set_si);
17718 insn = (TARGET_LP64
17719 ? gen_stack_protect_set_di
17720 : gen_stack_protect_set_si);
17723 emit_insn (insn (operands[0], operands[1]));
17727 (define_insn "stack_protect_set_<mode>"
17728 [(set (match_operand:PTR 0 "memory_operand" "=m")
17729 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17731 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17732 (clobber (reg:CC FLAGS_REG))]
17734 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17735 [(set_attr "type" "multi")])
17737 (define_insn "stack_tls_protect_set_<mode>"
17738 [(set (match_operand:PTR 0 "memory_operand" "=m")
17739 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17740 UNSPEC_SP_TLS_SET))
17741 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17742 (clobber (reg:CC FLAGS_REG))]
17744 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17745 [(set_attr "type" "multi")])
17747 (define_expand "stack_protect_test"
17748 [(match_operand 0 "memory_operand")
17749 (match_operand 1 "memory_operand")
17753 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17755 rtx (*insn)(rtx, rtx, rtx);
17757 #ifdef TARGET_THREAD_SSP_OFFSET
17758 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17759 insn = (TARGET_LP64
17760 ? gen_stack_tls_protect_test_di
17761 : gen_stack_tls_protect_test_si);
17763 insn = (TARGET_LP64
17764 ? gen_stack_protect_test_di
17765 : gen_stack_protect_test_si);
17768 emit_insn (insn (flags, operands[0], operands[1]));
17770 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17771 flags, const0_rtx, operands[2]));
17775 (define_insn "stack_protect_test_<mode>"
17776 [(set (match_operand:CCZ 0 "flags_reg_operand")
17777 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17778 (match_operand:PTR 2 "memory_operand" "m")]
17780 (clobber (match_scratch:PTR 3 "=&r"))]
17782 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17783 [(set_attr "type" "multi")])
17785 (define_insn "stack_tls_protect_test_<mode>"
17786 [(set (match_operand:CCZ 0 "flags_reg_operand")
17787 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17788 (match_operand:PTR 2 "const_int_operand" "i")]
17789 UNSPEC_SP_TLS_TEST))
17790 (clobber (match_scratch:PTR 3 "=r"))]
17792 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17793 [(set_attr "type" "multi")])
17795 (define_insn "sse4_2_crc32<mode>"
17796 [(set (match_operand:SI 0 "register_operand" "=r")
17798 [(match_operand:SI 1 "register_operand" "0")
17799 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17801 "TARGET_SSE4_2 || TARGET_CRC32"
17802 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17803 [(set_attr "type" "sselog1")
17804 (set_attr "prefix_rep" "1")
17805 (set_attr "prefix_extra" "1")
17806 (set (attr "prefix_data16")
17807 (if_then_else (match_operand:HI 2)
17809 (const_string "*")))
17810 (set (attr "prefix_rex")
17811 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17813 (const_string "*")))
17814 (set_attr "mode" "SI")])
17816 (define_insn "sse4_2_crc32di"
17817 [(set (match_operand:DI 0 "register_operand" "=r")
17819 [(match_operand:DI 1 "register_operand" "0")
17820 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17822 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17823 "crc32{q}\t{%2, %0|%0, %2}"
17824 [(set_attr "type" "sselog1")
17825 (set_attr "prefix_rep" "1")
17826 (set_attr "prefix_extra" "1")
17827 (set_attr "mode" "DI")])
17829 (define_expand "rdpmc"
17830 [(match_operand:DI 0 "register_operand")
17831 (match_operand:SI 1 "register_operand")]
17834 rtx reg = gen_reg_rtx (DImode);
17837 /* Force operand 1 into ECX. */
17838 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17839 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17840 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17845 rtvec vec = rtvec_alloc (2);
17846 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17847 rtx upper = gen_reg_rtx (DImode);
17848 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17849 gen_rtvec (1, const0_rtx),
17851 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17852 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17854 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17855 NULL, 1, OPTAB_DIRECT);
17856 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17860 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17861 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17865 (define_insn "*rdpmc"
17866 [(set (match_operand:DI 0 "register_operand" "=A")
17867 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17871 [(set_attr "type" "other")
17872 (set_attr "length" "2")])
17874 (define_insn "*rdpmc_rex64"
17875 [(set (match_operand:DI 0 "register_operand" "=a")
17876 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17878 (set (match_operand:DI 1 "register_operand" "=d")
17879 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17882 [(set_attr "type" "other")
17883 (set_attr "length" "2")])
17885 (define_expand "rdtsc"
17886 [(set (match_operand:DI 0 "register_operand")
17887 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17892 rtvec vec = rtvec_alloc (2);
17893 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17894 rtx upper = gen_reg_rtx (DImode);
17895 rtx lower = gen_reg_rtx (DImode);
17896 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17897 gen_rtvec (1, const0_rtx),
17899 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17900 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17902 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17903 NULL, 1, OPTAB_DIRECT);
17904 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17906 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17911 (define_insn "*rdtsc"
17912 [(set (match_operand:DI 0 "register_operand" "=A")
17913 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17916 [(set_attr "type" "other")
17917 (set_attr "length" "2")])
17919 (define_insn "*rdtsc_rex64"
17920 [(set (match_operand:DI 0 "register_operand" "=a")
17921 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17922 (set (match_operand:DI 1 "register_operand" "=d")
17923 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17926 [(set_attr "type" "other")
17927 (set_attr "length" "2")])
17929 (define_expand "rdtscp"
17930 [(match_operand:DI 0 "register_operand")
17931 (match_operand:SI 1 "memory_operand")]
17934 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17935 gen_rtvec (1, const0_rtx),
17937 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17938 gen_rtvec (1, const0_rtx),
17940 rtx reg = gen_reg_rtx (DImode);
17941 rtx tmp = gen_reg_rtx (SImode);
17945 rtvec vec = rtvec_alloc (3);
17946 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17947 rtx upper = gen_reg_rtx (DImode);
17948 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17949 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17950 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17952 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17953 NULL, 1, OPTAB_DIRECT);
17954 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17959 rtvec vec = rtvec_alloc (2);
17960 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17961 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17962 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17965 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17966 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17970 (define_insn "*rdtscp"
17971 [(set (match_operand:DI 0 "register_operand" "=A")
17972 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17973 (set (match_operand:SI 1 "register_operand" "=c")
17974 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17977 [(set_attr "type" "other")
17978 (set_attr "length" "3")])
17980 (define_insn "*rdtscp_rex64"
17981 [(set (match_operand:DI 0 "register_operand" "=a")
17982 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17983 (set (match_operand:DI 1 "register_operand" "=d")
17984 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17985 (set (match_operand:SI 2 "register_operand" "=c")
17986 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17989 [(set_attr "type" "other")
17990 (set_attr "length" "3")])
17992 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17994 ;; LWP instructions
17996 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17998 (define_expand "lwp_llwpcb"
17999 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18000 UNSPECV_LLWP_INTRINSIC)]
18003 (define_insn "*lwp_llwpcb<mode>1"
18004 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18005 UNSPECV_LLWP_INTRINSIC)]
18008 [(set_attr "type" "lwp")
18009 (set_attr "mode" "<MODE>")
18010 (set_attr "length" "5")])
18012 (define_expand "lwp_slwpcb"
18013 [(set (match_operand 0 "register_operand" "=r")
18014 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18019 insn = (Pmode == DImode
18021 : gen_lwp_slwpcbsi);
18023 emit_insn (insn (operands[0]));
18027 (define_insn "lwp_slwpcb<mode>"
18028 [(set (match_operand:P 0 "register_operand" "=r")
18029 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18032 [(set_attr "type" "lwp")
18033 (set_attr "mode" "<MODE>")
18034 (set_attr "length" "5")])
18036 (define_expand "lwp_lwpval<mode>3"
18037 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18038 (match_operand:SI 2 "nonimmediate_operand" "rm")
18039 (match_operand:SI 3 "const_int_operand" "i")]
18040 UNSPECV_LWPVAL_INTRINSIC)]
18042 ;; Avoid unused variable warning.
18043 "(void) operands[0];")
18045 (define_insn "*lwp_lwpval<mode>3_1"
18046 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18047 (match_operand:SI 1 "nonimmediate_operand" "rm")
18048 (match_operand:SI 2 "const_int_operand" "i")]
18049 UNSPECV_LWPVAL_INTRINSIC)]
18051 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18052 [(set_attr "type" "lwp")
18053 (set_attr "mode" "<MODE>")
18054 (set (attr "length")
18055 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18057 (define_expand "lwp_lwpins<mode>3"
18058 [(set (reg:CCC FLAGS_REG)
18059 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18060 (match_operand:SI 2 "nonimmediate_operand" "rm")
18061 (match_operand:SI 3 "const_int_operand" "i")]
18062 UNSPECV_LWPINS_INTRINSIC))
18063 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18064 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18067 (define_insn "*lwp_lwpins<mode>3_1"
18068 [(set (reg:CCC FLAGS_REG)
18069 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18070 (match_operand:SI 1 "nonimmediate_operand" "rm")
18071 (match_operand:SI 2 "const_int_operand" "i")]
18072 UNSPECV_LWPINS_INTRINSIC))]
18074 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18075 [(set_attr "type" "lwp")
18076 (set_attr "mode" "<MODE>")
18077 (set (attr "length")
18078 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18080 (define_int_iterator RDFSGSBASE
18084 (define_int_iterator WRFSGSBASE
18088 (define_int_attr fsgs
18089 [(UNSPECV_RDFSBASE "fs")
18090 (UNSPECV_RDGSBASE "gs")
18091 (UNSPECV_WRFSBASE "fs")
18092 (UNSPECV_WRGSBASE "gs")])
18094 (define_insn "rd<fsgs>base<mode>"
18095 [(set (match_operand:SWI48 0 "register_operand" "=r")
18096 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18097 "TARGET_64BIT && TARGET_FSGSBASE"
18099 [(set_attr "type" "other")
18100 (set_attr "prefix_extra" "2")])
18102 (define_insn "wr<fsgs>base<mode>"
18103 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18105 "TARGET_64BIT && TARGET_FSGSBASE"
18107 [(set_attr "type" "other")
18108 (set_attr "prefix_extra" "2")])
18110 (define_insn "rdrand<mode>_1"
18111 [(set (match_operand:SWI248 0 "register_operand" "=r")
18112 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18113 (set (reg:CCC FLAGS_REG)
18114 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18117 [(set_attr "type" "other")
18118 (set_attr "prefix_extra" "1")])
18120 (define_expand "pause"
18121 [(set (match_dup 0)
18122 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18125 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18126 MEM_VOLATILE_P (operands[0]) = 1;
18129 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18130 ;; They have the same encoding.
18131 (define_insn "*pause"
18132 [(set (match_operand:BLK 0)
18133 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18136 [(set_attr "length" "2")
18137 (set_attr "memory" "unknown")])
18139 (define_expand "xbegin"
18140 [(set (match_operand:SI 0 "register_operand")
18141 (unspec_volatile:SI [(match_dup 1)] UNSPECV_XBEGIN))]
18144 rtx label = gen_label_rtx ();
18146 operands[1] = force_reg (SImode, constm1_rtx);
18148 emit_jump_insn (gen_xbegin_1 (operands[1], label));
18150 emit_label (label);
18151 LABEL_NUSES (label) = 1;
18153 emit_move_insn (operands[0], operands[1]);
18158 (define_insn "xbegin_1"
18160 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18162 (label_ref (match_operand 1))
18164 (set (match_operand:SI 0 "register_operand" "+a")
18165 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18168 [(set_attr "type" "other")
18169 (set_attr "length" "6")])
18171 (define_insn "xend"
18172 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18175 [(set_attr "type" "other")
18176 (set_attr "length" "3")])
18178 (define_insn "xabort"
18179 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18183 [(set_attr "type" "other")
18184 (set_attr "length" "3")])
18186 (define_expand "xtest"
18187 [(set (match_operand:QI 0 "register_operand")
18188 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18191 emit_insn (gen_xtest_1 ());
18193 ix86_expand_setcc (operands[0], NE,
18194 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18198 (define_insn "xtest_1"
18199 [(set (reg:CCZ FLAGS_REG)
18200 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18203 [(set_attr "type" "other")
18204 (set_attr "length" "3")])
18208 (include "sync.md")