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
179 ;; For RDRAND support
190 (define_c_enum "unspecv" [
193 UNSPECV_PROBE_STACK_RANGE
196 UNSPECV_SPLIT_STACK_RETURN
202 UNSPECV_LLWP_INTRINSIC
203 UNSPECV_SLWP_INTRINSIC
204 UNSPECV_LWPVAL_INTRINSIC
205 UNSPECV_LWPINS_INTRINSIC
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 ;; Base name for define_insn
715 (define_code_attr shift_insn
716 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
718 ;; Base name for insn mnemonic.
719 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
720 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
722 ;; Mapping of rotate operators
723 (define_code_iterator any_rotate [rotate rotatert])
725 ;; Base name for define_insn
726 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
728 ;; Base name for insn mnemonic.
729 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
731 ;; Mapping of abs neg operators
732 (define_code_iterator absneg [abs neg])
734 ;; Base name for x87 insn mnemonic.
735 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
737 ;; Used in signed and unsigned widening multiplications.
738 (define_code_iterator any_extend [sign_extend zero_extend])
740 ;; Prefix for insn menmonic.
741 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
743 ;; Prefix for define_insn
744 (define_code_attr u [(sign_extend "") (zero_extend "u")])
745 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
747 ;; All integer modes.
748 (define_mode_iterator SWI1248x [QI HI SI DI])
750 ;; All integer modes without QImode.
751 (define_mode_iterator SWI248x [HI SI DI])
753 ;; All integer modes without QImode and HImode.
754 (define_mode_iterator SWI48x [SI DI])
756 ;; All integer modes without SImode and DImode.
757 (define_mode_iterator SWI12 [QI HI])
759 ;; All integer modes without DImode.
760 (define_mode_iterator SWI124 [QI HI SI])
762 ;; All integer modes without QImode and DImode.
763 (define_mode_iterator SWI24 [HI SI])
765 ;; Single word integer modes.
766 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
768 ;; Single word integer modes without QImode.
769 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
771 ;; Single word integer modes without QImode and HImode.
772 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
774 ;; All math-dependant single and double word integer modes.
775 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
776 (HI "TARGET_HIMODE_MATH")
777 SI DI (TI "TARGET_64BIT")])
779 ;; Math-dependant single word integer modes.
780 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
781 (HI "TARGET_HIMODE_MATH")
782 SI (DI "TARGET_64BIT")])
784 ;; Math-dependant integer modes without DImode.
785 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
786 (HI "TARGET_HIMODE_MATH")
789 ;; Math-dependant single word integer modes without QImode.
790 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
791 SI (DI "TARGET_64BIT")])
793 ;; Double word integer modes.
794 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
795 (TI "TARGET_64BIT")])
797 ;; Double word integer modes as mode attribute.
798 (define_mode_attr DWI [(SI "DI") (DI "TI")])
799 (define_mode_attr dwi [(SI "di") (DI "ti")])
801 ;; Half mode for double word integer modes.
802 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
803 (DI "TARGET_64BIT")])
805 ;; Instruction suffix for integer modes.
806 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
808 ;; Pointer size prefix for integer modes (Intel asm dialect)
809 (define_mode_attr iptrsize [(QI "BYTE")
814 ;; Register class for integer modes.
815 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
817 ;; Immediate operand constraint for integer modes.
818 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
820 ;; General operand constraint for word modes.
821 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
823 ;; Immediate operand constraint for double integer modes.
824 (define_mode_attr di [(SI "nF") (DI "e")])
826 ;; Immediate operand constraint for shifts.
827 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
829 ;; General operand predicate for integer modes.
830 (define_mode_attr general_operand
831 [(QI "general_operand")
832 (HI "general_operand")
833 (SI "x86_64_general_operand")
834 (DI "x86_64_general_operand")
835 (TI "x86_64_general_operand")])
837 ;; General sign/zero extend operand predicate for integer modes.
838 (define_mode_attr general_szext_operand
839 [(QI "general_operand")
840 (HI "general_operand")
841 (SI "x86_64_szext_general_operand")
842 (DI "x86_64_szext_general_operand")])
844 ;; Immediate operand predicate for integer modes.
845 (define_mode_attr immediate_operand
846 [(QI "immediate_operand")
847 (HI "immediate_operand")
848 (SI "x86_64_immediate_operand")
849 (DI "x86_64_immediate_operand")])
851 ;; Nonmemory operand predicate for integer modes.
852 (define_mode_attr nonmemory_operand
853 [(QI "nonmemory_operand")
854 (HI "nonmemory_operand")
855 (SI "x86_64_nonmemory_operand")
856 (DI "x86_64_nonmemory_operand")])
858 ;; Operand predicate for shifts.
859 (define_mode_attr shift_operand
860 [(QI "nonimmediate_operand")
861 (HI "nonimmediate_operand")
862 (SI "nonimmediate_operand")
863 (DI "shiftdi_operand")
864 (TI "register_operand")])
866 ;; Operand predicate for shift argument.
867 (define_mode_attr shift_immediate_operand
868 [(QI "const_1_to_31_operand")
869 (HI "const_1_to_31_operand")
870 (SI "const_1_to_31_operand")
871 (DI "const_1_to_63_operand")])
873 ;; Input operand predicate for arithmetic left shifts.
874 (define_mode_attr ashl_input_operand
875 [(QI "nonimmediate_operand")
876 (HI "nonimmediate_operand")
877 (SI "nonimmediate_operand")
878 (DI "ashldi_input_operand")
879 (TI "reg_or_pm1_operand")])
881 ;; SSE and x87 SFmode and DFmode floating point modes
882 (define_mode_iterator MODEF [SF DF])
884 ;; All x87 floating point modes
885 (define_mode_iterator X87MODEF [SF DF XF])
887 ;; SSE instruction suffix for various modes
888 (define_mode_attr ssemodesuffix
890 (V8SF "ps") (V4DF "pd")
891 (V4SF "ps") (V2DF "pd")
892 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
893 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
895 ;; SSE vector suffix for floating point modes
896 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
898 ;; SSE vector mode corresponding to a scalar mode
899 (define_mode_attr ssevecmode
900 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
902 ;; Instruction suffix for REX 64bit operators.
903 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
905 ;; This mode iterator allows :P to be used for patterns that operate on
906 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
907 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
909 ;; This mode iterator allows :W to be used for patterns that operate on
910 ;; word_mode sized quantities.
911 (define_mode_iterator W
912 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
914 ;; This mode iterator allows :PTR to be used for patterns that operate on
915 ;; ptr_mode sized quantities.
916 (define_mode_iterator PTR
917 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
919 ;; Scheduling descriptions
921 (include "pentium.md")
924 (include "athlon.md")
925 (include "bdver1.md")
931 ;; Operand and operator predicates and constraints
933 (include "predicates.md")
934 (include "constraints.md")
937 ;; Compare and branch/compare and store instructions.
939 (define_expand "cbranch<mode>4"
940 [(set (reg:CC FLAGS_REG)
941 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
942 (match_operand:SDWIM 2 "<general_operand>")))
943 (set (pc) (if_then_else
944 (match_operator 0 "ordered_comparison_operator"
945 [(reg:CC FLAGS_REG) (const_int 0)])
946 (label_ref (match_operand 3))
950 if (MEM_P (operands[1]) && MEM_P (operands[2]))
951 operands[1] = force_reg (<MODE>mode, operands[1]);
952 ix86_expand_branch (GET_CODE (operands[0]),
953 operands[1], operands[2], operands[3]);
957 (define_expand "cstore<mode>4"
958 [(set (reg:CC FLAGS_REG)
959 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
960 (match_operand:SWIM 3 "<general_operand>")))
961 (set (match_operand:QI 0 "register_operand")
962 (match_operator 1 "ordered_comparison_operator"
963 [(reg:CC FLAGS_REG) (const_int 0)]))]
966 if (MEM_P (operands[2]) && MEM_P (operands[3]))
967 operands[2] = force_reg (<MODE>mode, operands[2]);
968 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
969 operands[2], operands[3]);
973 (define_expand "cmp<mode>_1"
974 [(set (reg:CC FLAGS_REG)
975 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
976 (match_operand:SWI48 1 "<general_operand>")))])
978 (define_insn "*cmp<mode>_ccno_1"
979 [(set (reg FLAGS_REG)
980 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
981 (match_operand:SWI 1 "const0_operand")))]
982 "ix86_match_ccmode (insn, CCNOmode)"
984 test{<imodesuffix>}\t%0, %0
985 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
986 [(set_attr "type" "test,icmp")
987 (set_attr "length_immediate" "0,1")
988 (set_attr "mode" "<MODE>")])
990 (define_insn "*cmp<mode>_1"
991 [(set (reg FLAGS_REG)
992 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
993 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
994 "ix86_match_ccmode (insn, CCmode)"
995 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
996 [(set_attr "type" "icmp")
997 (set_attr "mode" "<MODE>")])
999 (define_insn "*cmp<mode>_minus_1"
1000 [(set (reg FLAGS_REG)
1002 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1003 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1005 "ix86_match_ccmode (insn, CCGOCmode)"
1006 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1007 [(set_attr "type" "icmp")
1008 (set_attr "mode" "<MODE>")])
1010 (define_insn "*cmpqi_ext_1"
1011 [(set (reg FLAGS_REG)
1013 (match_operand:QI 0 "general_operand" "Qm")
1016 (match_operand 1 "ext_register_operand" "Q")
1018 (const_int 8)) 0)))]
1019 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1020 "cmp{b}\t{%h1, %0|%0, %h1}"
1021 [(set_attr "type" "icmp")
1022 (set_attr "mode" "QI")])
1024 (define_insn "*cmpqi_ext_1_rex64"
1025 [(set (reg FLAGS_REG)
1027 (match_operand:QI 0 "register_operand" "Q")
1030 (match_operand 1 "ext_register_operand" "Q")
1032 (const_int 8)) 0)))]
1033 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1034 "cmp{b}\t{%h1, %0|%0, %h1}"
1035 [(set_attr "type" "icmp")
1036 (set_attr "mode" "QI")])
1038 (define_insn "*cmpqi_ext_2"
1039 [(set (reg FLAGS_REG)
1043 (match_operand 0 "ext_register_operand" "Q")
1046 (match_operand:QI 1 "const0_operand")))]
1047 "ix86_match_ccmode (insn, CCNOmode)"
1049 [(set_attr "type" "test")
1050 (set_attr "length_immediate" "0")
1051 (set_attr "mode" "QI")])
1053 (define_expand "cmpqi_ext_3"
1054 [(set (reg:CC FLAGS_REG)
1058 (match_operand 0 "ext_register_operand")
1061 (match_operand:QI 1 "immediate_operand")))])
1063 (define_insn "*cmpqi_ext_3_insn"
1064 [(set (reg FLAGS_REG)
1068 (match_operand 0 "ext_register_operand" "Q")
1071 (match_operand:QI 1 "general_operand" "Qmn")))]
1072 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1073 "cmp{b}\t{%1, %h0|%h0, %1}"
1074 [(set_attr "type" "icmp")
1075 (set_attr "modrm" "1")
1076 (set_attr "mode" "QI")])
1078 (define_insn "*cmpqi_ext_3_insn_rex64"
1079 [(set (reg FLAGS_REG)
1083 (match_operand 0 "ext_register_operand" "Q")
1086 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1087 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1088 "cmp{b}\t{%1, %h0|%h0, %1}"
1089 [(set_attr "type" "icmp")
1090 (set_attr "modrm" "1")
1091 (set_attr "mode" "QI")])
1093 (define_insn "*cmpqi_ext_4"
1094 [(set (reg FLAGS_REG)
1098 (match_operand 0 "ext_register_operand" "Q")
1103 (match_operand 1 "ext_register_operand" "Q")
1105 (const_int 8)) 0)))]
1106 "ix86_match_ccmode (insn, CCmode)"
1107 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1108 [(set_attr "type" "icmp")
1109 (set_attr "mode" "QI")])
1111 ;; These implement float point compares.
1112 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1113 ;; which would allow mix and match FP modes on the compares. Which is what
1114 ;; the old patterns did, but with many more of them.
1116 (define_expand "cbranchxf4"
1117 [(set (reg:CC FLAGS_REG)
1118 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1119 (match_operand:XF 2 "nonmemory_operand")))
1120 (set (pc) (if_then_else
1121 (match_operator 0 "ix86_fp_comparison_operator"
1124 (label_ref (match_operand 3))
1128 ix86_expand_branch (GET_CODE (operands[0]),
1129 operands[1], operands[2], operands[3]);
1133 (define_expand "cstorexf4"
1134 [(set (reg:CC FLAGS_REG)
1135 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1136 (match_operand:XF 3 "nonmemory_operand")))
1137 (set (match_operand:QI 0 "register_operand")
1138 (match_operator 1 "ix86_fp_comparison_operator"
1143 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1144 operands[2], operands[3]);
1148 (define_expand "cbranch<mode>4"
1149 [(set (reg:CC FLAGS_REG)
1150 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1151 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1152 (set (pc) (if_then_else
1153 (match_operator 0 "ix86_fp_comparison_operator"
1156 (label_ref (match_operand 3))
1158 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1160 ix86_expand_branch (GET_CODE (operands[0]),
1161 operands[1], operands[2], operands[3]);
1165 (define_expand "cstore<mode>4"
1166 [(set (reg:CC FLAGS_REG)
1167 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1168 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1169 (set (match_operand:QI 0 "register_operand")
1170 (match_operator 1 "ix86_fp_comparison_operator"
1173 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1175 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1176 operands[2], operands[3]);
1180 (define_expand "cbranchcc4"
1181 [(set (pc) (if_then_else
1182 (match_operator 0 "comparison_operator"
1183 [(match_operand 1 "flags_reg_operand")
1184 (match_operand 2 "const0_operand")])
1185 (label_ref (match_operand 3))
1189 ix86_expand_branch (GET_CODE (operands[0]),
1190 operands[1], operands[2], operands[3]);
1194 (define_expand "cstorecc4"
1195 [(set (match_operand:QI 0 "register_operand")
1196 (match_operator 1 "comparison_operator"
1197 [(match_operand 2 "flags_reg_operand")
1198 (match_operand 3 "const0_operand")]))]
1201 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1202 operands[2], operands[3]);
1207 ;; FP compares, step 1:
1208 ;; Set the FP condition codes.
1210 ;; CCFPmode compare with exceptions
1211 ;; CCFPUmode compare with no exceptions
1213 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1214 ;; used to manage the reg stack popping would not be preserved.
1216 (define_insn "*cmpfp_0"
1217 [(set (match_operand:HI 0 "register_operand" "=a")
1220 (match_operand 1 "register_operand" "f")
1221 (match_operand 2 "const0_operand"))]
1223 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1224 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1225 "* return output_fp_compare (insn, operands, false, false);"
1226 [(set_attr "type" "multi")
1227 (set_attr "unit" "i387")
1229 (cond [(match_operand:SF 1)
1231 (match_operand:DF 1)
1234 (const_string "XF")))])
1236 (define_insn_and_split "*cmpfp_0_cc"
1237 [(set (reg:CCFP FLAGS_REG)
1239 (match_operand 1 "register_operand" "f")
1240 (match_operand 2 "const0_operand")))
1241 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1242 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1243 && TARGET_SAHF && !TARGET_CMOVE
1244 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1246 "&& reload_completed"
1249 [(compare:CCFP (match_dup 1)(match_dup 2))]
1251 (set (reg:CC FLAGS_REG)
1252 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1254 [(set_attr "type" "multi")
1255 (set_attr "unit" "i387")
1257 (cond [(match_operand:SF 1)
1259 (match_operand:DF 1)
1262 (const_string "XF")))])
1264 (define_insn "*cmpfp_xf"
1265 [(set (match_operand:HI 0 "register_operand" "=a")
1268 (match_operand:XF 1 "register_operand" "f")
1269 (match_operand:XF 2 "register_operand" "f"))]
1272 "* return output_fp_compare (insn, operands, false, false);"
1273 [(set_attr "type" "multi")
1274 (set_attr "unit" "i387")
1275 (set_attr "mode" "XF")])
1277 (define_insn_and_split "*cmpfp_xf_cc"
1278 [(set (reg:CCFP FLAGS_REG)
1280 (match_operand:XF 1 "register_operand" "f")
1281 (match_operand:XF 2 "register_operand" "f")))
1282 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1284 && TARGET_SAHF && !TARGET_CMOVE"
1286 "&& reload_completed"
1289 [(compare:CCFP (match_dup 1)(match_dup 2))]
1291 (set (reg:CC FLAGS_REG)
1292 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1294 [(set_attr "type" "multi")
1295 (set_attr "unit" "i387")
1296 (set_attr "mode" "XF")])
1298 (define_insn "*cmpfp_<mode>"
1299 [(set (match_operand:HI 0 "register_operand" "=a")
1302 (match_operand:MODEF 1 "register_operand" "f")
1303 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1306 "* return output_fp_compare (insn, operands, false, false);"
1307 [(set_attr "type" "multi")
1308 (set_attr "unit" "i387")
1309 (set_attr "mode" "<MODE>")])
1311 (define_insn_and_split "*cmpfp_<mode>_cc"
1312 [(set (reg:CCFP FLAGS_REG)
1314 (match_operand:MODEF 1 "register_operand" "f")
1315 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1316 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1318 && TARGET_SAHF && !TARGET_CMOVE"
1320 "&& reload_completed"
1323 [(compare:CCFP (match_dup 1)(match_dup 2))]
1325 (set (reg:CC FLAGS_REG)
1326 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1328 [(set_attr "type" "multi")
1329 (set_attr "unit" "i387")
1330 (set_attr "mode" "<MODE>")])
1332 (define_insn "*cmpfp_u"
1333 [(set (match_operand:HI 0 "register_operand" "=a")
1336 (match_operand 1 "register_operand" "f")
1337 (match_operand 2 "register_operand" "f"))]
1339 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1340 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1341 "* return output_fp_compare (insn, operands, false, true);"
1342 [(set_attr "type" "multi")
1343 (set_attr "unit" "i387")
1345 (cond [(match_operand:SF 1)
1347 (match_operand:DF 1)
1350 (const_string "XF")))])
1352 (define_insn_and_split "*cmpfp_u_cc"
1353 [(set (reg:CCFPU FLAGS_REG)
1355 (match_operand 1 "register_operand" "f")
1356 (match_operand 2 "register_operand" "f")))
1357 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1358 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1359 && TARGET_SAHF && !TARGET_CMOVE
1360 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1362 "&& reload_completed"
1365 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1367 (set (reg:CC FLAGS_REG)
1368 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1370 [(set_attr "type" "multi")
1371 (set_attr "unit" "i387")
1373 (cond [(match_operand:SF 1)
1375 (match_operand:DF 1)
1378 (const_string "XF")))])
1380 (define_insn "*cmpfp_<mode>"
1381 [(set (match_operand:HI 0 "register_operand" "=a")
1384 (match_operand 1 "register_operand" "f")
1385 (match_operator 3 "float_operator"
1386 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1388 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1389 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1390 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1391 "* return output_fp_compare (insn, operands, false, false);"
1392 [(set_attr "type" "multi")
1393 (set_attr "unit" "i387")
1394 (set_attr "fp_int_src" "true")
1395 (set_attr "mode" "<MODE>")])
1397 (define_insn_and_split "*cmpfp_<mode>_cc"
1398 [(set (reg:CCFP FLAGS_REG)
1400 (match_operand 1 "register_operand" "f")
1401 (match_operator 3 "float_operator"
1402 [(match_operand:SWI24 2 "memory_operand" "m")])))
1403 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1404 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1405 && TARGET_SAHF && !TARGET_CMOVE
1406 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1407 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1409 "&& reload_completed"
1414 (match_op_dup 3 [(match_dup 2)]))]
1416 (set (reg:CC FLAGS_REG)
1417 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1419 [(set_attr "type" "multi")
1420 (set_attr "unit" "i387")
1421 (set_attr "fp_int_src" "true")
1422 (set_attr "mode" "<MODE>")])
1424 ;; FP compares, step 2
1425 ;; Move the fpsw to ax.
1427 (define_insn "x86_fnstsw_1"
1428 [(set (match_operand:HI 0 "register_operand" "=a")
1429 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1432 [(set (attr "length")
1433 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1434 (set_attr "mode" "SI")
1435 (set_attr "unit" "i387")])
1437 ;; FP compares, step 3
1438 ;; Get ax into flags, general case.
1440 (define_insn "x86_sahf_1"
1441 [(set (reg:CC FLAGS_REG)
1442 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1446 #ifndef HAVE_AS_IX86_SAHF
1448 return ASM_BYTE "0x9e";
1453 [(set_attr "length" "1")
1454 (set_attr "athlon_decode" "vector")
1455 (set_attr "amdfam10_decode" "direct")
1456 (set_attr "bdver1_decode" "direct")
1457 (set_attr "mode" "SI")])
1459 ;; Pentium Pro can do steps 1 through 3 in one go.
1460 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1461 ;; (these i387 instructions set flags directly)
1462 (define_insn "*cmpfp_i_mixed"
1463 [(set (reg:CCFP FLAGS_REG)
1464 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1465 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1466 "TARGET_MIX_SSE_I387
1467 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1468 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1469 "* return output_fp_compare (insn, operands, true, false);"
1470 [(set_attr "type" "fcmp,ssecomi")
1471 (set_attr "prefix" "orig,maybe_vex")
1473 (if_then_else (match_operand:SF 1)
1475 (const_string "DF")))
1476 (set (attr "prefix_rep")
1477 (if_then_else (eq_attr "type" "ssecomi")
1479 (const_string "*")))
1480 (set (attr "prefix_data16")
1481 (cond [(eq_attr "type" "fcmp")
1483 (eq_attr "mode" "DF")
1486 (const_string "0")))
1487 (set_attr "athlon_decode" "vector")
1488 (set_attr "amdfam10_decode" "direct")
1489 (set_attr "bdver1_decode" "double")])
1491 (define_insn "*cmpfp_i_sse"
1492 [(set (reg:CCFP FLAGS_REG)
1493 (compare:CCFP (match_operand 0 "register_operand" "x")
1494 (match_operand 1 "nonimmediate_operand" "xm")))]
1496 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1497 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1498 "* return output_fp_compare (insn, operands, true, false);"
1499 [(set_attr "type" "ssecomi")
1500 (set_attr "prefix" "maybe_vex")
1502 (if_then_else (match_operand:SF 1)
1504 (const_string "DF")))
1505 (set_attr "prefix_rep" "0")
1506 (set (attr "prefix_data16")
1507 (if_then_else (eq_attr "mode" "DF")
1509 (const_string "0")))
1510 (set_attr "athlon_decode" "vector")
1511 (set_attr "amdfam10_decode" "direct")
1512 (set_attr "bdver1_decode" "double")])
1514 (define_insn "*cmpfp_i_i387"
1515 [(set (reg:CCFP FLAGS_REG)
1516 (compare:CCFP (match_operand 0 "register_operand" "f")
1517 (match_operand 1 "register_operand" "f")))]
1518 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1520 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1521 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1522 "* return output_fp_compare (insn, operands, true, false);"
1523 [(set_attr "type" "fcmp")
1525 (cond [(match_operand:SF 1)
1527 (match_operand:DF 1)
1530 (const_string "XF")))
1531 (set_attr "athlon_decode" "vector")
1532 (set_attr "amdfam10_decode" "direct")
1533 (set_attr "bdver1_decode" "double")])
1535 (define_insn "*cmpfp_iu_mixed"
1536 [(set (reg:CCFPU FLAGS_REG)
1537 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1538 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1539 "TARGET_MIX_SSE_I387
1540 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1541 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1542 "* return output_fp_compare (insn, operands, true, true);"
1543 [(set_attr "type" "fcmp,ssecomi")
1544 (set_attr "prefix" "orig,maybe_vex")
1546 (if_then_else (match_operand:SF 1)
1548 (const_string "DF")))
1549 (set (attr "prefix_rep")
1550 (if_then_else (eq_attr "type" "ssecomi")
1552 (const_string "*")))
1553 (set (attr "prefix_data16")
1554 (cond [(eq_attr "type" "fcmp")
1556 (eq_attr "mode" "DF")
1559 (const_string "0")))
1560 (set_attr "athlon_decode" "vector")
1561 (set_attr "amdfam10_decode" "direct")
1562 (set_attr "bdver1_decode" "double")])
1564 (define_insn "*cmpfp_iu_sse"
1565 [(set (reg:CCFPU FLAGS_REG)
1566 (compare:CCFPU (match_operand 0 "register_operand" "x")
1567 (match_operand 1 "nonimmediate_operand" "xm")))]
1569 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1570 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1571 "* return output_fp_compare (insn, operands, true, true);"
1572 [(set_attr "type" "ssecomi")
1573 (set_attr "prefix" "maybe_vex")
1575 (if_then_else (match_operand:SF 1)
1577 (const_string "DF")))
1578 (set_attr "prefix_rep" "0")
1579 (set (attr "prefix_data16")
1580 (if_then_else (eq_attr "mode" "DF")
1582 (const_string "0")))
1583 (set_attr "athlon_decode" "vector")
1584 (set_attr "amdfam10_decode" "direct")
1585 (set_attr "bdver1_decode" "double")])
1587 (define_insn "*cmpfp_iu_387"
1588 [(set (reg:CCFPU FLAGS_REG)
1589 (compare:CCFPU (match_operand 0 "register_operand" "f")
1590 (match_operand 1 "register_operand" "f")))]
1591 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1593 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1594 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1595 "* return output_fp_compare (insn, operands, true, true);"
1596 [(set_attr "type" "fcmp")
1598 (cond [(match_operand:SF 1)
1600 (match_operand:DF 1)
1603 (const_string "XF")))
1604 (set_attr "athlon_decode" "vector")
1605 (set_attr "amdfam10_decode" "direct")
1606 (set_attr "bdver1_decode" "direct")])
1608 ;; Push/pop instructions.
1610 (define_insn "*push<mode>2"
1611 [(set (match_operand:DWI 0 "push_operand" "=<")
1612 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1615 [(set_attr "type" "multi")
1616 (set_attr "mode" "<MODE>")])
1619 [(set (match_operand:TI 0 "push_operand")
1620 (match_operand:TI 1 "general_operand"))]
1621 "TARGET_64BIT && reload_completed
1622 && !SSE_REG_P (operands[1])"
1624 "ix86_split_long_move (operands); DONE;")
1626 (define_insn "*pushdi2_rex64"
1627 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1628 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1633 [(set_attr "type" "push,multi")
1634 (set_attr "mode" "DI")])
1636 ;; Convert impossible pushes of immediate to existing instructions.
1637 ;; First try to get scratch register and go through it. In case this
1638 ;; fails, push sign extended lower part first and then overwrite
1639 ;; upper part by 32bit move.
1641 [(match_scratch:DI 2 "r")
1642 (set (match_operand:DI 0 "push_operand")
1643 (match_operand:DI 1 "immediate_operand"))]
1644 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1645 && !x86_64_immediate_operand (operands[1], DImode)"
1646 [(set (match_dup 2) (match_dup 1))
1647 (set (match_dup 0) (match_dup 2))])
1649 ;; We need to define this as both peepholer and splitter for case
1650 ;; peephole2 pass is not run.
1651 ;; "&& 1" is needed to keep it from matching the previous pattern.
1653 [(set (match_operand:DI 0 "push_operand")
1654 (match_operand:DI 1 "immediate_operand"))]
1655 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1656 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1657 [(set (match_dup 0) (match_dup 1))
1658 (set (match_dup 2) (match_dup 3))]
1660 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1662 operands[1] = gen_lowpart (DImode, operands[2]);
1663 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1668 [(set (match_operand:DI 0 "push_operand")
1669 (match_operand:DI 1 "immediate_operand"))]
1670 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1671 ? epilogue_completed : reload_completed)
1672 && !symbolic_operand (operands[1], DImode)
1673 && !x86_64_immediate_operand (operands[1], DImode)"
1674 [(set (match_dup 0) (match_dup 1))
1675 (set (match_dup 2) (match_dup 3))]
1677 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1679 operands[1] = gen_lowpart (DImode, operands[2]);
1680 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1685 [(set (match_operand:DI 0 "push_operand")
1686 (match_operand:DI 1 "general_operand"))]
1687 "!TARGET_64BIT && reload_completed
1688 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1690 "ix86_split_long_move (operands); DONE;")
1692 (define_insn "*pushsi2"
1693 [(set (match_operand:SI 0 "push_operand" "=<")
1694 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1697 [(set_attr "type" "push")
1698 (set_attr "mode" "SI")])
1700 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1701 ;; "push a byte/word". But actually we use pushl, which has the effect
1702 ;; of rounding the amount pushed up to a word.
1704 ;; For TARGET_64BIT we always round up to 8 bytes.
1705 (define_insn "*push<mode>2_rex64"
1706 [(set (match_operand:SWI124 0 "push_operand" "=X")
1707 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1710 [(set_attr "type" "push")
1711 (set_attr "mode" "DI")])
1713 (define_insn "*push<mode>2"
1714 [(set (match_operand:SWI12 0 "push_operand" "=X")
1715 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1718 [(set_attr "type" "push")
1719 (set_attr "mode" "SI")])
1721 (define_insn "*push<mode>2_prologue"
1722 [(set (match_operand:W 0 "push_operand" "=<")
1723 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1724 (clobber (mem:BLK (scratch)))]
1726 "push{<imodesuffix>}\t%1"
1727 [(set_attr "type" "push")
1728 (set_attr "mode" "<MODE>")])
1730 (define_insn "*pop<mode>1"
1731 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1732 (match_operand:W 1 "pop_operand" ">"))]
1734 "pop{<imodesuffix>}\t%0"
1735 [(set_attr "type" "pop")
1736 (set_attr "mode" "<MODE>")])
1738 (define_insn "*pop<mode>1_epilogue"
1739 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1740 (match_operand:W 1 "pop_operand" ">"))
1741 (clobber (mem:BLK (scratch)))]
1743 "pop{<imodesuffix>}\t%0"
1744 [(set_attr "type" "pop")
1745 (set_attr "mode" "<MODE>")])
1747 ;; Move instructions.
1749 (define_expand "movoi"
1750 [(set (match_operand:OI 0 "nonimmediate_operand")
1751 (match_operand:OI 1 "general_operand"))]
1753 "ix86_expand_move (OImode, operands); DONE;")
1755 (define_expand "movti"
1756 [(set (match_operand:TI 0 "nonimmediate_operand")
1757 (match_operand:TI 1 "nonimmediate_operand"))]
1758 "TARGET_64BIT || TARGET_SSE"
1761 ix86_expand_move (TImode, operands);
1762 else if (push_operand (operands[0], TImode))
1763 ix86_expand_push (TImode, operands[1]);
1765 ix86_expand_vector_move (TImode, operands);
1769 ;; This expands to what emit_move_complex would generate if we didn't
1770 ;; have a movti pattern. Having this avoids problems with reload on
1771 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1772 ;; to have around all the time.
1773 (define_expand "movcdi"
1774 [(set (match_operand:CDI 0 "nonimmediate_operand")
1775 (match_operand:CDI 1 "general_operand"))]
1778 if (push_operand (operands[0], CDImode))
1779 emit_move_complex_push (CDImode, operands[0], operands[1]);
1781 emit_move_complex_parts (operands[0], operands[1]);
1785 (define_expand "mov<mode>"
1786 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1787 (match_operand:SWI1248x 1 "general_operand"))]
1789 "ix86_expand_move (<MODE>mode, operands); DONE;")
1791 (define_insn "*mov<mode>_xor"
1792 [(set (match_operand:SWI48 0 "register_operand" "=r")
1793 (match_operand:SWI48 1 "const0_operand"))
1794 (clobber (reg:CC FLAGS_REG))]
1797 [(set_attr "type" "alu1")
1798 (set_attr "mode" "SI")
1799 (set_attr "length_immediate" "0")])
1801 (define_insn "*mov<mode>_or"
1802 [(set (match_operand:SWI48 0 "register_operand" "=r")
1803 (match_operand:SWI48 1 "const_int_operand"))
1804 (clobber (reg:CC FLAGS_REG))]
1806 && operands[1] == constm1_rtx"
1807 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1808 [(set_attr "type" "alu1")
1809 (set_attr "mode" "<MODE>")
1810 (set_attr "length_immediate" "1")])
1812 (define_insn "*movoi_internal_avx"
1813 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1814 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1815 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1817 switch (which_alternative)
1820 return standard_sse_constant_opcode (insn, operands[1]);
1823 if (misaligned_operand (operands[0], OImode)
1824 || misaligned_operand (operands[1], OImode))
1826 if (get_attr_mode (insn) == MODE_V8SF)
1827 return "vmovups\t{%1, %0|%0, %1}";
1829 return "vmovdqu\t{%1, %0|%0, %1}";
1833 if (get_attr_mode (insn) == MODE_V8SF)
1834 return "vmovaps\t{%1, %0|%0, %1}";
1836 return "vmovdqa\t{%1, %0|%0, %1}";
1842 [(set_attr "type" "sselog1,ssemov,ssemov")
1843 (set_attr "prefix" "vex")
1845 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1846 (const_string "V8SF")
1847 (and (eq_attr "alternative" "2")
1848 (match_test "TARGET_SSE_TYPELESS_STORES"))
1849 (const_string "V8SF")
1851 (const_string "OI")))])
1853 (define_insn "*movti_internal_rex64"
1854 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1855 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1856 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1858 switch (which_alternative)
1864 return standard_sse_constant_opcode (insn, operands[1]);
1867 /* TDmode values are passed as TImode on the stack. Moving them
1868 to stack may result in unaligned memory access. */
1869 if (misaligned_operand (operands[0], TImode)
1870 || misaligned_operand (operands[1], TImode))
1872 if (get_attr_mode (insn) == MODE_V4SF)
1873 return "%vmovups\t{%1, %0|%0, %1}";
1875 return "%vmovdqu\t{%1, %0|%0, %1}";
1879 if (get_attr_mode (insn) == MODE_V4SF)
1880 return "%vmovaps\t{%1, %0|%0, %1}";
1882 return "%vmovdqa\t{%1, %0|%0, %1}";
1888 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1889 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1891 (cond [(eq_attr "alternative" "0,1")
1893 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1894 (const_string "V4SF")
1895 (and (eq_attr "alternative" "4")
1896 (match_test "TARGET_SSE_TYPELESS_STORES"))
1897 (const_string "V4SF")
1898 (match_test "TARGET_AVX")
1900 (match_test "optimize_function_for_size_p (cfun)")
1901 (const_string "V4SF")
1903 (const_string "TI")))])
1906 [(set (match_operand:TI 0 "nonimmediate_operand")
1907 (match_operand:TI 1 "general_operand"))]
1909 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1911 "ix86_split_long_move (operands); DONE;")
1913 (define_insn "*movti_internal_sse"
1914 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x ,m")
1915 (match_operand:TI 1 "vector_move_operand" "C ,xm,x"))]
1916 "TARGET_SSE && !TARGET_64BIT
1917 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1919 switch (which_alternative)
1922 return standard_sse_constant_opcode (insn, operands[1]);
1925 /* TDmode values are passed as TImode on the stack. Moving them
1926 to stack may result in unaligned memory access. */
1927 if (misaligned_operand (operands[0], TImode)
1928 || misaligned_operand (operands[1], TImode))
1930 if (get_attr_mode (insn) == MODE_V4SF)
1931 return "%vmovups\t{%1, %0|%0, %1}";
1933 return "%vmovdqu\t{%1, %0|%0, %1}";
1937 if (get_attr_mode (insn) == MODE_V4SF)
1938 return "%vmovaps\t{%1, %0|%0, %1}";
1940 return "%vmovdqa\t{%1, %0|%0, %1}";
1946 [(set_attr "type" "sselog1,ssemov,ssemov")
1947 (set_attr "prefix" "maybe_vex")
1949 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1950 (const_string "V4SF")
1951 (and (eq_attr "alternative" "2")
1952 (match_test "TARGET_SSE_TYPELESS_STORES"))
1953 (const_string "V4SF")
1954 (match_test "TARGET_AVX")
1956 (ior (not (match_test "TARGET_SSE2"))
1957 (match_test "optimize_function_for_size_p (cfun)"))
1958 (const_string "V4SF")
1960 (const_string "TI")))])
1962 (define_insn "*movdi_internal_rex64"
1963 [(set (match_operand:DI 0 "nonimmediate_operand"
1964 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1965 (match_operand:DI 1 "general_operand"
1966 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1967 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1969 switch (get_attr_type (insn))
1972 if (SSE_REG_P (operands[0]))
1973 return "movq2dq\t{%1, %0|%0, %1}";
1975 return "movdq2q\t{%1, %0|%0, %1}";
1978 if (get_attr_mode (insn) == MODE_V4SF)
1979 return "%vmovaps\t{%1, %0|%0, %1}";
1980 else if (get_attr_mode (insn) == MODE_TI)
1981 return "%vmovdqa\t{%1, %0|%0, %1}";
1983 /* Handle broken assemblers that require movd instead of movq. */
1984 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1985 return "%vmovd\t{%1, %0|%0, %1}";
1987 return "%vmovq\t{%1, %0|%0, %1}";
1990 /* Handle broken assemblers that require movd instead of movq. */
1991 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1992 return "movd\t{%1, %0|%0, %1}";
1994 return "movq\t{%1, %0|%0, %1}";
1997 return standard_sse_constant_opcode (insn, operands[1]);
2000 return "pxor\t%0, %0";
2006 return "lea{q}\t{%E1, %0|%0, %E1}";
2009 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2010 if (get_attr_mode (insn) == MODE_SI)
2011 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2012 else if (which_alternative == 2)
2013 return "movabs{q}\t{%1, %0|%0, %1}";
2014 else if (ix86_use_lea_for_mov (insn, operands))
2015 return "lea{q}\t{%E1, %0|%0, %E1}";
2017 return "mov{q}\t{%1, %0|%0, %1}";
2021 (cond [(eq_attr "alternative" "4")
2022 (const_string "multi")
2023 (eq_attr "alternative" "5")
2024 (const_string "mmx")
2025 (eq_attr "alternative" "6,7,8,9")
2026 (const_string "mmxmov")
2027 (eq_attr "alternative" "10")
2028 (const_string "sselog1")
2029 (eq_attr "alternative" "11,12,13,14,15")
2030 (const_string "ssemov")
2031 (eq_attr "alternative" "16,17")
2032 (const_string "ssecvt")
2033 (match_operand 1 "pic_32bit_operand")
2034 (const_string "lea")
2036 (const_string "imov")))
2039 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2041 (const_string "*")))
2042 (set (attr "length_immediate")
2044 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2046 (const_string "*")))
2047 (set (attr "prefix_rex")
2048 (if_then_else (eq_attr "alternative" "8,9")
2050 (const_string "*")))
2051 (set (attr "prefix_data16")
2052 (if_then_else (eq_attr "alternative" "11")
2054 (const_string "*")))
2055 (set (attr "prefix")
2056 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2057 (const_string "maybe_vex")
2058 (const_string "orig")))
2060 (cond [(eq_attr "alternative" "0,4")
2062 (eq_attr "alternative" "10,12")
2063 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2064 (const_string "V4SF")
2065 (match_test "TARGET_AVX")
2067 (match_test "optimize_function_for_size_p (cfun)")
2068 (const_string "V4SF")
2070 (const_string "TI"))
2072 (const_string "DI")))])
2074 ;; Reload patterns to support multi-word load/store
2075 ;; with non-offsetable address.
2076 (define_expand "reload_noff_store"
2077 [(parallel [(match_operand 0 "memory_operand" "=m")
2078 (match_operand 1 "register_operand" "r")
2079 (match_operand:DI 2 "register_operand" "=&r")])]
2082 rtx mem = operands[0];
2083 rtx addr = XEXP (mem, 0);
2085 emit_move_insn (operands[2], addr);
2086 mem = replace_equiv_address_nv (mem, operands[2]);
2088 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2092 (define_expand "reload_noff_load"
2093 [(parallel [(match_operand 0 "register_operand" "=r")
2094 (match_operand 1 "memory_operand" "m")
2095 (match_operand:DI 2 "register_operand" "=r")])]
2098 rtx mem = operands[1];
2099 rtx addr = XEXP (mem, 0);
2101 emit_move_insn (operands[2], addr);
2102 mem = replace_equiv_address_nv (mem, operands[2]);
2104 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2108 ;; Convert impossible stores of immediate to existing instructions.
2109 ;; First try to get scratch register and go through it. In case this
2110 ;; fails, move by 32bit parts.
2112 [(match_scratch:DI 2 "r")
2113 (set (match_operand:DI 0 "memory_operand")
2114 (match_operand:DI 1 "immediate_operand"))]
2115 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2116 && !x86_64_immediate_operand (operands[1], DImode)"
2117 [(set (match_dup 2) (match_dup 1))
2118 (set (match_dup 0) (match_dup 2))])
2120 ;; We need to define this as both peepholer and splitter for case
2121 ;; peephole2 pass is not run.
2122 ;; "&& 1" is needed to keep it from matching the previous pattern.
2124 [(set (match_operand:DI 0 "memory_operand")
2125 (match_operand:DI 1 "immediate_operand"))]
2126 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2127 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2128 [(set (match_dup 2) (match_dup 3))
2129 (set (match_dup 4) (match_dup 5))]
2130 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2133 [(set (match_operand:DI 0 "memory_operand")
2134 (match_operand:DI 1 "immediate_operand"))]
2135 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2136 ? epilogue_completed : reload_completed)
2137 && !symbolic_operand (operands[1], DImode)
2138 && !x86_64_immediate_operand (operands[1], DImode)"
2139 [(set (match_dup 2) (match_dup 3))
2140 (set (match_dup 4) (match_dup 5))]
2141 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2143 (define_insn "*movdi_internal"
2144 [(set (match_operand:DI 0 "nonimmediate_operand"
2145 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2146 (match_operand:DI 1 "general_operand"
2147 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2148 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2150 switch (get_attr_type (insn))
2153 if (SSE_REG_P (operands[0]))
2154 return "movq2dq\t{%1, %0|%0, %1}";
2156 return "movdq2q\t{%1, %0|%0, %1}";
2159 switch (get_attr_mode (insn))
2162 return "%vmovdqa\t{%1, %0|%0, %1}";
2164 return "%vmovq\t{%1, %0|%0, %1}";
2166 return "%vmovaps\t{%1, %0|%0, %1}";
2168 return "movlps\t{%1, %0|%0, %1}";
2174 return "movq\t{%1, %0|%0, %1}";
2177 return standard_sse_constant_opcode (insn, operands[1]);
2180 return "pxor\t%0, %0";
2190 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2191 (const_string "sse2")
2192 (eq_attr "alternative" "9,10,11,12")
2193 (const_string "noavx")
2195 (const_string "*")))
2197 (cond [(eq_attr "alternative" "0,1")
2198 (const_string "multi")
2199 (eq_attr "alternative" "2")
2200 (const_string "mmx")
2201 (eq_attr "alternative" "3,4")
2202 (const_string "mmxmov")
2203 (eq_attr "alternative" "5,9")
2204 (const_string "sselog1")
2205 (eq_attr "alternative" "13,14")
2206 (const_string "ssecvt")
2208 (const_string "ssemov")))
2209 (set (attr "prefix")
2210 (if_then_else (eq_attr "alternative" "5,6,7,8")
2211 (const_string "maybe_vex")
2212 (const_string "orig")))
2214 (cond [(eq_attr "alternative" "9,11")
2215 (const_string "V4SF")
2216 (eq_attr "alternative" "10,12")
2217 (const_string "V2SF")
2218 (eq_attr "alternative" "5,7")
2219 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2220 (const_string "V4SF")
2221 (match_test "TARGET_AVX")
2223 (match_test "optimize_function_for_size_p (cfun)")
2224 (const_string "V4SF")
2226 (const_string "TI"))
2228 (const_string "DI")))])
2231 [(set (match_operand:DI 0 "nonimmediate_operand")
2232 (match_operand:DI 1 "general_operand"))]
2233 "!TARGET_64BIT && reload_completed
2234 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2235 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2237 "ix86_split_long_move (operands); DONE;")
2239 (define_insn "*movsi_internal"
2240 [(set (match_operand:SI 0 "nonimmediate_operand"
2241 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2242 (match_operand:SI 1 "general_operand"
2243 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2244 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2246 switch (get_attr_type (insn))
2249 return standard_sse_constant_opcode (insn, operands[1]);
2252 switch (get_attr_mode (insn))
2255 return "%vmovdqa\t{%1, %0|%0, %1}";
2257 return "%vmovaps\t{%1, %0|%0, %1}";
2259 return "%vmovd\t{%1, %0|%0, %1}";
2261 return "%vmovss\t{%1, %0|%0, %1}";
2267 return "pxor\t%0, %0";
2270 if (get_attr_mode (insn) == MODE_DI)
2271 return "movq\t{%1, %0|%0, %1}";
2272 return "movd\t{%1, %0|%0, %1}";
2275 return "lea{l}\t{%E1, %0|%0, %E1}";
2278 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2279 if (ix86_use_lea_for_mov (insn, operands))
2280 return "lea{l}\t{%E1, %0|%0, %E1}";
2282 return "mov{l}\t{%1, %0|%0, %1}";
2286 (cond [(eq_attr "alternative" "2")
2287 (const_string "mmx")
2288 (eq_attr "alternative" "3,4,5")
2289 (const_string "mmxmov")
2290 (eq_attr "alternative" "6")
2291 (const_string "sselog1")
2292 (eq_attr "alternative" "7,8,9,10,11")
2293 (const_string "ssemov")
2294 (match_operand 1 "pic_32bit_operand")
2295 (const_string "lea")
2297 (const_string "imov")))
2298 (set (attr "prefix")
2299 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2300 (const_string "orig")
2301 (const_string "maybe_vex")))
2302 (set (attr "prefix_data16")
2303 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2305 (const_string "*")))
2307 (cond [(eq_attr "alternative" "2,3")
2309 (eq_attr "alternative" "6,7")
2310 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2311 (const_string "V4SF")
2312 (match_test "TARGET_AVX")
2314 (ior (not (match_test "TARGET_SSE2"))
2315 (match_test "optimize_function_for_size_p (cfun)"))
2316 (const_string "V4SF")
2318 (const_string "TI"))
2319 (and (eq_attr "alternative" "8,9,10,11")
2320 (not (match_test "TARGET_SSE2")))
2323 (const_string "SI")))])
2325 (define_insn "*movhi_internal"
2326 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2327 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2328 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2330 switch (get_attr_type (insn))
2333 /* movzwl is faster than movw on p2 due to partial word stalls,
2334 though not as fast as an aligned movl. */
2335 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2337 if (get_attr_mode (insn) == MODE_SI)
2338 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2340 return "mov{w}\t{%1, %0|%0, %1}";
2344 (cond [(match_test "optimize_function_for_size_p (cfun)")
2345 (const_string "imov")
2346 (and (eq_attr "alternative" "0")
2347 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2348 (not (match_test "TARGET_HIMODE_MATH"))))
2349 (const_string "imov")
2350 (and (eq_attr "alternative" "1,2")
2351 (match_operand:HI 1 "aligned_operand"))
2352 (const_string "imov")
2353 (and (match_test "TARGET_MOVX")
2354 (eq_attr "alternative" "0,2"))
2355 (const_string "imovx")
2357 (const_string "imov")))
2359 (cond [(eq_attr "type" "imovx")
2361 (and (eq_attr "alternative" "1,2")
2362 (match_operand:HI 1 "aligned_operand"))
2364 (and (eq_attr "alternative" "0")
2365 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2366 (not (match_test "TARGET_HIMODE_MATH"))))
2369 (const_string "HI")))])
2371 ;; Situation is quite tricky about when to choose full sized (SImode) move
2372 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2373 ;; partial register dependency machines (such as AMD Athlon), where QImode
2374 ;; moves issue extra dependency and for partial register stalls machines
2375 ;; that don't use QImode patterns (and QImode move cause stall on the next
2378 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2379 ;; register stall machines with, where we use QImode instructions, since
2380 ;; partial register stall can be caused there. Then we use movzx.
2381 (define_insn "*movqi_internal"
2382 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2383 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2384 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2386 switch (get_attr_type (insn))
2389 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2390 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2392 if (get_attr_mode (insn) == MODE_SI)
2393 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2395 return "mov{b}\t{%1, %0|%0, %1}";
2399 (cond [(and (eq_attr "alternative" "5")
2400 (not (match_operand:QI 1 "aligned_operand")))
2401 (const_string "imovx")
2402 (match_test "optimize_function_for_size_p (cfun)")
2403 (const_string "imov")
2404 (and (eq_attr "alternative" "3")
2405 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2406 (not (match_test "TARGET_QIMODE_MATH"))))
2407 (const_string "imov")
2408 (eq_attr "alternative" "3,5")
2409 (const_string "imovx")
2410 (and (match_test "TARGET_MOVX")
2411 (eq_attr "alternative" "2"))
2412 (const_string "imovx")
2414 (const_string "imov")))
2416 (cond [(eq_attr "alternative" "3,4,5")
2418 (eq_attr "alternative" "6")
2420 (eq_attr "type" "imovx")
2422 (and (eq_attr "type" "imov")
2423 (and (eq_attr "alternative" "0,1")
2424 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2425 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2426 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2428 ;; Avoid partial register stalls when not using QImode arithmetic
2429 (and (eq_attr "type" "imov")
2430 (and (eq_attr "alternative" "0,1")
2431 (and (match_test "TARGET_PARTIAL_REG_STALL")
2432 (not (match_test "TARGET_QIMODE_MATH")))))
2435 (const_string "QI")))])
2437 ;; Stores and loads of ax to arbitrary constant address.
2438 ;; We fake an second form of instruction to force reload to load address
2439 ;; into register when rax is not available
2440 (define_insn "*movabs<mode>_1"
2441 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2442 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2443 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2445 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2446 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2447 [(set_attr "type" "imov")
2448 (set_attr "modrm" "0,*")
2449 (set_attr "length_address" "8,0")
2450 (set_attr "length_immediate" "0,*")
2451 (set_attr "memory" "store")
2452 (set_attr "mode" "<MODE>")])
2454 (define_insn "*movabs<mode>_2"
2455 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2456 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2457 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2459 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2460 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2461 [(set_attr "type" "imov")
2462 (set_attr "modrm" "0,*")
2463 (set_attr "length_address" "8,0")
2464 (set_attr "length_immediate" "0")
2465 (set_attr "memory" "load")
2466 (set_attr "mode" "<MODE>")])
2468 (define_insn "swap<mode>"
2469 [(set (match_operand:SWI48 0 "register_operand" "+r")
2470 (match_operand:SWI48 1 "register_operand" "+r"))
2474 "xchg{<imodesuffix>}\t%1, %0"
2475 [(set_attr "type" "imov")
2476 (set_attr "mode" "<MODE>")
2477 (set_attr "pent_pair" "np")
2478 (set_attr "athlon_decode" "vector")
2479 (set_attr "amdfam10_decode" "double")
2480 (set_attr "bdver1_decode" "double")])
2482 (define_insn "*swap<mode>_1"
2483 [(set (match_operand:SWI12 0 "register_operand" "+r")
2484 (match_operand:SWI12 1 "register_operand" "+r"))
2487 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2489 [(set_attr "type" "imov")
2490 (set_attr "mode" "SI")
2491 (set_attr "pent_pair" "np")
2492 (set_attr "athlon_decode" "vector")
2493 (set_attr "amdfam10_decode" "double")
2494 (set_attr "bdver1_decode" "double")])
2496 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2497 ;; is disabled for AMDFAM10
2498 (define_insn "*swap<mode>_2"
2499 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2500 (match_operand:SWI12 1 "register_operand" "+<r>"))
2503 "TARGET_PARTIAL_REG_STALL"
2504 "xchg{<imodesuffix>}\t%1, %0"
2505 [(set_attr "type" "imov")
2506 (set_attr "mode" "<MODE>")
2507 (set_attr "pent_pair" "np")
2508 (set_attr "athlon_decode" "vector")])
2510 (define_expand "movstrict<mode>"
2511 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2512 (match_operand:SWI12 1 "general_operand"))]
2515 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2517 if (GET_CODE (operands[0]) == SUBREG
2518 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2520 /* Don't generate memory->memory moves, go through a register */
2521 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2522 operands[1] = force_reg (<MODE>mode, operands[1]);
2525 (define_insn "*movstrict<mode>_1"
2526 [(set (strict_low_part
2527 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2528 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2529 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2530 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2531 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2532 [(set_attr "type" "imov")
2533 (set_attr "mode" "<MODE>")])
2535 (define_insn "*movstrict<mode>_xor"
2536 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2537 (match_operand:SWI12 1 "const0_operand"))
2538 (clobber (reg:CC FLAGS_REG))]
2540 "xor{<imodesuffix>}\t%0, %0"
2541 [(set_attr "type" "alu1")
2542 (set_attr "mode" "<MODE>")
2543 (set_attr "length_immediate" "0")])
2545 (define_insn "*mov<mode>_extv_1"
2546 [(set (match_operand:SWI24 0 "register_operand" "=R")
2547 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2551 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2552 [(set_attr "type" "imovx")
2553 (set_attr "mode" "SI")])
2555 (define_insn "*movqi_extv_1_rex64"
2556 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2557 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2562 switch (get_attr_type (insn))
2565 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2567 return "mov{b}\t{%h1, %0|%0, %h1}";
2571 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2572 (match_test "TARGET_MOVX"))
2573 (const_string "imovx")
2574 (const_string "imov")))
2576 (if_then_else (eq_attr "type" "imovx")
2578 (const_string "QI")))])
2580 (define_insn "*movqi_extv_1"
2581 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2582 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2587 switch (get_attr_type (insn))
2590 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2592 return "mov{b}\t{%h1, %0|%0, %h1}";
2596 (if_then_else (and (match_operand:QI 0 "register_operand")
2597 (ior (not (match_operand:QI 0 "QIreg_operand"))
2598 (match_test "TARGET_MOVX")))
2599 (const_string "imovx")
2600 (const_string "imov")))
2602 (if_then_else (eq_attr "type" "imovx")
2604 (const_string "QI")))])
2606 (define_insn "*mov<mode>_extzv_1"
2607 [(set (match_operand:SWI48 0 "register_operand" "=R")
2608 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2612 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2613 [(set_attr "type" "imovx")
2614 (set_attr "mode" "SI")])
2616 (define_insn "*movqi_extzv_2_rex64"
2617 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2619 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2624 switch (get_attr_type (insn))
2627 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2629 return "mov{b}\t{%h1, %0|%0, %h1}";
2633 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2634 (match_test "TARGET_MOVX"))
2635 (const_string "imovx")
2636 (const_string "imov")))
2638 (if_then_else (eq_attr "type" "imovx")
2640 (const_string "QI")))])
2642 (define_insn "*movqi_extzv_2"
2643 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2645 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2650 switch (get_attr_type (insn))
2653 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2655 return "mov{b}\t{%h1, %0|%0, %h1}";
2659 (if_then_else (and (match_operand:QI 0 "register_operand")
2660 (ior (not (match_operand:QI 0 "QIreg_operand"))
2661 (match_test "TARGET_MOVX")))
2662 (const_string "imovx")
2663 (const_string "imov")))
2665 (if_then_else (eq_attr "type" "imovx")
2667 (const_string "QI")))])
2669 (define_expand "mov<mode>_insv_1"
2670 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2673 (match_operand:SWI48 1 "nonmemory_operand"))])
2675 (define_insn "*mov<mode>_insv_1_rex64"
2676 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2679 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2681 "mov{b}\t{%b1, %h0|%h0, %b1}"
2682 [(set_attr "type" "imov")
2683 (set_attr "mode" "QI")])
2685 (define_insn "*movsi_insv_1"
2686 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2689 (match_operand:SI 1 "general_operand" "Qmn"))]
2691 "mov{b}\t{%b1, %h0|%h0, %b1}"
2692 [(set_attr "type" "imov")
2693 (set_attr "mode" "QI")])
2695 (define_insn "*movqi_insv_2"
2696 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2699 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2702 "mov{b}\t{%h1, %h0|%h0, %h1}"
2703 [(set_attr "type" "imov")
2704 (set_attr "mode" "QI")])
2706 ;; Floating point push instructions.
2708 (define_insn "*pushtf"
2709 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2710 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2713 /* This insn should be already split before reg-stack. */
2716 [(set_attr "type" "multi")
2717 (set_attr "unit" "sse,*,*")
2718 (set_attr "mode" "TF,SI,SI")])
2720 ;; %%% Kill this when call knows how to work this out.
2722 [(set (match_operand:TF 0 "push_operand")
2723 (match_operand:TF 1 "sse_reg_operand"))]
2724 "TARGET_SSE && reload_completed"
2725 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2726 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2728 (define_insn "*pushxf"
2729 [(set (match_operand:XF 0 "push_operand" "=<,<")
2730 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2731 "optimize_function_for_speed_p (cfun)"
2733 /* This insn should be already split before reg-stack. */
2736 [(set_attr "type" "multi")
2737 (set_attr "unit" "i387,*")
2738 (set_attr "mode" "XF,SI")])
2740 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2741 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2742 ;; Pushing using integer instructions is longer except for constants
2743 ;; and direct memory references (assuming that any given constant is pushed
2744 ;; only once, but this ought to be handled elsewhere).
2746 (define_insn "*pushxf_nointeger"
2747 [(set (match_operand:XF 0 "push_operand" "=<,<")
2748 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2749 "optimize_function_for_size_p (cfun)"
2751 /* This insn should be already split before reg-stack. */
2754 [(set_attr "type" "multi")
2755 (set_attr "unit" "i387,*")
2756 (set_attr "mode" "XF,SI")])
2758 ;; %%% Kill this when call knows how to work this out.
2760 [(set (match_operand:XF 0 "push_operand")
2761 (match_operand:XF 1 "fp_register_operand"))]
2763 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2764 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2765 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2767 (define_insn "*pushdf_rex64"
2768 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2769 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2772 /* This insn should be already split before reg-stack. */
2775 [(set_attr "type" "multi")
2776 (set_attr "unit" "i387,*,*")
2777 (set_attr "mode" "DF,DI,DF")])
2779 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2780 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2781 ;; On the average, pushdf using integers can be still shorter.
2783 (define_insn "*pushdf"
2784 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2785 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2788 /* This insn should be already split before reg-stack. */
2791 [(set_attr "isa" "*,*,sse2")
2792 (set_attr "type" "multi")
2793 (set_attr "unit" "i387,*,*")
2794 (set_attr "mode" "DF,DI,DF")])
2796 ;; %%% Kill this when call knows how to work this out.
2798 [(set (match_operand:DF 0 "push_operand")
2799 (match_operand:DF 1 "any_fp_register_operand"))]
2801 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2802 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2804 (define_insn "*pushsf_rex64"
2805 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2806 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2809 /* Anything else should be already split before reg-stack. */
2810 gcc_assert (which_alternative == 1);
2811 return "push{q}\t%q1";
2813 [(set_attr "type" "multi,push,multi")
2814 (set_attr "unit" "i387,*,*")
2815 (set_attr "mode" "SF,DI,SF")])
2817 (define_insn "*pushsf"
2818 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2819 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2822 /* Anything else should be already split before reg-stack. */
2823 gcc_assert (which_alternative == 1);
2824 return "push{l}\t%1";
2826 [(set_attr "type" "multi,push,multi")
2827 (set_attr "unit" "i387,*,*")
2828 (set_attr "mode" "SF,SI,SF")])
2830 ;; %%% Kill this when call knows how to work this out.
2832 [(set (match_operand:SF 0 "push_operand")
2833 (match_operand:SF 1 "any_fp_register_operand"))]
2835 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2836 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2837 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2840 [(set (match_operand:SF 0 "push_operand")
2841 (match_operand:SF 1 "memory_operand"))]
2843 && (operands[2] = find_constant_src (insn))"
2844 [(set (match_dup 0) (match_dup 2))])
2847 [(set (match_operand 0 "push_operand")
2848 (match_operand 1 "general_operand"))]
2850 && (GET_MODE (operands[0]) == TFmode
2851 || GET_MODE (operands[0]) == XFmode
2852 || GET_MODE (operands[0]) == DFmode)
2853 && !ANY_FP_REG_P (operands[1])"
2855 "ix86_split_long_move (operands); DONE;")
2857 ;; Floating point move instructions.
2859 (define_expand "movtf"
2860 [(set (match_operand:TF 0 "nonimmediate_operand")
2861 (match_operand:TF 1 "nonimmediate_operand"))]
2864 ix86_expand_move (TFmode, operands);
2868 (define_expand "mov<mode>"
2869 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2870 (match_operand:X87MODEF 1 "general_operand"))]
2872 "ix86_expand_move (<MODE>mode, operands); DONE;")
2874 (define_insn "*movtf_internal"
2875 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2876 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,F*r"))]
2878 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2879 && (!can_create_pseudo_p ()
2880 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2881 || GET_CODE (operands[1]) != CONST_DOUBLE
2882 || (optimize_function_for_size_p (cfun)
2883 && standard_sse_constant_p (operands[1])
2884 && !memory_operand (operands[0], TFmode))
2885 || (!TARGET_MEMORY_MISMATCH_STALL
2886 && memory_operand (operands[0], TFmode)))"
2888 switch (which_alternative)
2891 return standard_sse_constant_opcode (insn, operands[1]);
2894 /* Handle misaligned load/store since we
2895 don't have movmisaligntf pattern. */
2896 if (misaligned_operand (operands[0], TFmode)
2897 || misaligned_operand (operands[1], TFmode))
2899 if (get_attr_mode (insn) == MODE_V4SF)
2900 return "%vmovups\t{%1, %0|%0, %1}";
2902 return "%vmovdqu\t{%1, %0|%0, %1}";
2906 if (get_attr_mode (insn) == MODE_V4SF)
2907 return "%vmovaps\t{%1, %0|%0, %1}";
2909 return "%vmovdqa\t{%1, %0|%0, %1}";
2920 [(set_attr "type" "sselog1,ssemov,ssemov,*,*")
2921 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2923 (cond [(eq_attr "alternative" "3,4")
2925 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2926 (const_string "V4SF")
2927 (and (eq_attr "alternative" "2")
2928 (match_test "TARGET_SSE_TYPELESS_STORES"))
2929 (const_string "V4SF")
2930 (match_test "TARGET_AVX")
2932 (ior (not (match_test "TARGET_SSE2"))
2933 (match_test "optimize_function_for_size_p (cfun)"))
2934 (const_string "V4SF")
2936 (const_string "TI")))])
2938 ;; Possible store forwarding (partial memory) stall in alternative 4.
2939 (define_insn "*movxf_internal"
2940 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2941 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2942 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2943 && (!can_create_pseudo_p ()
2944 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2945 || GET_CODE (operands[1]) != CONST_DOUBLE
2946 || (optimize_function_for_size_p (cfun)
2947 && standard_80387_constant_p (operands[1]) > 0
2948 && !memory_operand (operands[0], XFmode))
2949 || (!TARGET_MEMORY_MISMATCH_STALL
2950 && memory_operand (operands[0], XFmode)))"
2952 switch (which_alternative)
2956 return output_387_reg_move (insn, operands);
2959 return standard_80387_constant_opcode (operands[1]);
2969 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2970 (set_attr "mode" "XF,XF,XF,SI,SI")])
2972 (define_insn "*movdf_internal_rex64"
2973 [(set (match_operand:DF 0 "nonimmediate_operand"
2974 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2975 (match_operand:DF 1 "general_operand"
2976 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2977 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2978 && (!can_create_pseudo_p ()
2979 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2980 || GET_CODE (operands[1]) != CONST_DOUBLE
2981 || (optimize_function_for_size_p (cfun)
2982 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2983 && standard_80387_constant_p (operands[1]) > 0)
2984 || (TARGET_SSE2 && TARGET_SSE_MATH
2985 && standard_sse_constant_p (operands[1]))))
2986 || memory_operand (operands[0], DFmode))"
2988 switch (which_alternative)
2992 return output_387_reg_move (insn, operands);
2995 return standard_80387_constant_opcode (operands[1]);
2999 return "mov{q}\t{%1, %0|%0, %1}";
3002 return "movabs{q}\t{%1, %0|%0, %1}";
3008 return standard_sse_constant_opcode (insn, operands[1]);
3013 switch (get_attr_mode (insn))
3016 return "%vmovapd\t{%1, %0|%0, %1}";
3018 return "%vmovaps\t{%1, %0|%0, %1}";
3021 return "%vmovq\t{%1, %0|%0, %1}";
3023 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3024 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3025 return "%vmovsd\t{%1, %0|%0, %1}";
3027 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3029 return "%vmovlps\t{%1, %d0|%d0, %1}";
3036 /* Handle broken assemblers that require movd instead of movq. */
3037 return "%vmovd\t{%1, %0|%0, %1}";
3044 (cond [(eq_attr "alternative" "0,1,2")
3045 (const_string "fmov")
3046 (eq_attr "alternative" "3,4,5")
3047 (const_string "imov")
3048 (eq_attr "alternative" "6")
3049 (const_string "multi")
3050 (eq_attr "alternative" "7")
3051 (const_string "sselog1")
3053 (const_string "ssemov")))
3056 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3058 (const_string "*")))
3059 (set (attr "length_immediate")
3061 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3063 (const_string "*")))
3064 (set (attr "prefix")
3065 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3066 (const_string "orig")
3067 (const_string "maybe_vex")))
3068 (set (attr "prefix_data16")
3069 (if_then_else (eq_attr "mode" "V1DF")
3071 (const_string "*")))
3073 (cond [(eq_attr "alternative" "0,1,2")
3075 (eq_attr "alternative" "3,4,5,6,11,12")
3078 /* xorps is one byte shorter for !TARGET_AVX. */
3079 (eq_attr "alternative" "7")
3080 (cond [(match_test "TARGET_AVX")
3081 (const_string "V2DF")
3082 (match_test "optimize_function_for_size_p (cfun)")
3083 (const_string "V4SF")
3084 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3087 (const_string "V2DF"))
3089 /* For architectures resolving dependencies on
3090 whole SSE registers use APD move to break dependency
3091 chains, otherwise use short move to avoid extra work.
3093 movaps encodes one byte shorter for !TARGET_AVX. */
3094 (eq_attr "alternative" "8")
3095 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3096 (const_string "V4SF")
3097 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3098 (const_string "V2DF")
3099 (match_test "TARGET_AVX")
3101 (match_test "optimize_function_for_size_p (cfun)")
3102 (const_string "V4SF")
3104 (const_string "DF"))
3105 /* For architectures resolving dependencies on register
3106 parts we may avoid extra work to zero out upper part
3108 (eq_attr "alternative" "9")
3110 (match_test "TARGET_SSE_SPLIT_REGS")
3111 (const_string "V1DF")
3112 (const_string "DF"))
3114 (const_string "DF")))])
3116 ;; Possible store forwarding (partial memory) stall in alternative 4.
3117 (define_insn "*movdf_internal"
3118 [(set (match_operand:DF 0 "nonimmediate_operand"
3119 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3120 (match_operand:DF 1 "general_operand"
3121 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3122 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3123 && (!can_create_pseudo_p ()
3124 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3125 || GET_CODE (operands[1]) != CONST_DOUBLE
3126 || (optimize_function_for_size_p (cfun)
3127 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3128 && standard_80387_constant_p (operands[1]) > 0)
3129 || (TARGET_SSE2 && TARGET_SSE_MATH
3130 && standard_sse_constant_p (operands[1])))
3131 && !memory_operand (operands[0], DFmode))
3132 || (!TARGET_MEMORY_MISMATCH_STALL
3133 && memory_operand (operands[0], DFmode)))"
3135 switch (which_alternative)
3139 return output_387_reg_move (insn, operands);
3142 return standard_80387_constant_opcode (operands[1]);
3150 return standard_sse_constant_opcode (insn, operands[1]);
3158 switch (get_attr_mode (insn))
3161 return "%vmovapd\t{%1, %0|%0, %1}";
3163 return "%vmovaps\t{%1, %0|%0, %1}";
3166 return "%vmovq\t{%1, %0|%0, %1}";
3168 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3169 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3170 return "%vmovsd\t{%1, %0|%0, %1}";
3172 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3174 return "%vmovlps\t{%1, %d0|%d0, %1}";
3184 (if_then_else (eq_attr "alternative" "5,6,7,8")
3185 (const_string "sse2")
3186 (const_string "*")))
3188 (cond [(eq_attr "alternative" "0,1,2")
3189 (const_string "fmov")
3190 (eq_attr "alternative" "3,4")
3191 (const_string "multi")
3192 (eq_attr "alternative" "5,9")
3193 (const_string "sselog1")
3195 (const_string "ssemov")))
3196 (set (attr "prefix")
3197 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3198 (const_string "orig")
3199 (const_string "maybe_vex")))
3200 (set (attr "prefix_data16")
3201 (if_then_else (eq_attr "mode" "V1DF")
3203 (const_string "*")))
3205 (cond [(eq_attr "alternative" "0,1,2")
3207 (eq_attr "alternative" "3,4")
3210 /* For SSE1, we have many fewer alternatives. */
3211 (not (match_test "TARGET_SSE2"))
3213 (eq_attr "alternative" "5,6,9,10")
3214 (const_string "V4SF")
3215 (const_string "V2SF"))
3217 /* xorps is one byte shorter for !TARGET_AVX. */
3218 (eq_attr "alternative" "5,9")
3219 (cond [(match_test "TARGET_AVX")
3220 (const_string "V2DF")
3221 (match_test "optimize_function_for_size_p (cfun)")
3222 (const_string "V4SF")
3223 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3226 (const_string "V2DF"))
3228 /* For architectures resolving dependencies on
3229 whole SSE registers use APD move to break dependency
3230 chains, otherwise use short move to avoid extra work.
3232 movaps encodes one byte shorter for !TARGET_AVX. */
3233 (eq_attr "alternative" "6,10")
3234 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3235 (const_string "V4SF")
3236 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3237 (const_string "V2DF")
3238 (match_test "TARGET_AVX")
3240 (match_test "optimize_function_for_size_p (cfun)")
3241 (const_string "V4SF")
3243 (const_string "DF"))
3245 /* For architectures resolving dependencies on register
3246 parts we may avoid extra work to zero out upper part
3248 (eq_attr "alternative" "7,11")
3250 (match_test "TARGET_SSE_SPLIT_REGS")
3251 (const_string "V1DF")
3252 (const_string "DF"))
3254 (const_string "DF")))])
3256 (define_insn "*movsf_internal"
3257 [(set (match_operand:SF 0 "nonimmediate_operand"
3258 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3259 (match_operand:SF 1 "general_operand"
3260 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3261 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3262 && (!can_create_pseudo_p ()
3263 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3264 || GET_CODE (operands[1]) != CONST_DOUBLE
3265 || (optimize_function_for_size_p (cfun)
3266 && ((!TARGET_SSE_MATH
3267 && standard_80387_constant_p (operands[1]) > 0)
3269 && standard_sse_constant_p (operands[1]))))
3270 || memory_operand (operands[0], SFmode))"
3272 switch (which_alternative)
3276 return output_387_reg_move (insn, operands);
3279 return standard_80387_constant_opcode (operands[1]);
3283 return "mov{l}\t{%1, %0|%0, %1}";
3286 return standard_sse_constant_opcode (insn, operands[1]);
3289 if (get_attr_mode (insn) == MODE_V4SF)
3290 return "%vmovaps\t{%1, %0|%0, %1}";
3292 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3296 return "%vmovss\t{%1, %0|%0, %1}";
3302 return "movd\t{%1, %0|%0, %1}";
3305 return "movq\t{%1, %0|%0, %1}";
3309 return "%vmovd\t{%1, %0|%0, %1}";
3316 (cond [(eq_attr "alternative" "0,1,2")
3317 (const_string "fmov")
3318 (eq_attr "alternative" "3,4")
3319 (const_string "multi")
3320 (eq_attr "alternative" "5")
3321 (const_string "sselog1")
3322 (eq_attr "alternative" "9,10,11,14,15")
3323 (const_string "mmxmov")
3325 (const_string "ssemov")))
3326 (set (attr "prefix")
3327 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3328 (const_string "maybe_vex")
3329 (const_string "orig")))
3331 (cond [(eq_attr "alternative" "3,4,9,10")
3333 (eq_attr "alternative" "5")
3334 (cond [(match_test "TARGET_AVX")
3335 (const_string "V4SF")
3336 (ior (not (match_test "TARGET_SSE2"))
3337 (match_test "optimize_function_for_size_p (cfun)"))
3338 (const_string "V4SF")
3339 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3342 (const_string "V4SF"))
3344 /* For architectures resolving dependencies on
3345 whole SSE registers use APS move to break dependency
3346 chains, otherwise use short move to avoid extra work.
3348 Do the same for architectures resolving dependencies on
3349 the parts. While in DF mode it is better to always handle
3350 just register parts, the SF mode is different due to lack
3351 of instructions to load just part of the register. It is
3352 better to maintain the whole registers in single format
3353 to avoid problems on using packed logical operations. */
3354 (eq_attr "alternative" "6")
3356 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3357 (match_test "TARGET_SSE_SPLIT_REGS"))
3358 (const_string "V4SF")
3359 (const_string "SF"))
3360 (eq_attr "alternative" "11")
3361 (const_string "DI")]
3362 (const_string "SF")))])
3365 [(set (match_operand 0 "any_fp_register_operand")
3366 (match_operand 1 "memory_operand"))]
3368 && (GET_MODE (operands[0]) == TFmode
3369 || GET_MODE (operands[0]) == XFmode
3370 || GET_MODE (operands[0]) == DFmode
3371 || GET_MODE (operands[0]) == SFmode)
3372 && (operands[2] = find_constant_src (insn))"
3373 [(set (match_dup 0) (match_dup 2))]
3375 rtx c = operands[2];
3376 int r = REGNO (operands[0]);
3378 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3379 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3384 [(set (match_operand 0 "any_fp_register_operand")
3385 (float_extend (match_operand 1 "memory_operand")))]
3387 && (GET_MODE (operands[0]) == TFmode
3388 || GET_MODE (operands[0]) == XFmode
3389 || GET_MODE (operands[0]) == DFmode)
3390 && (operands[2] = find_constant_src (insn))"
3391 [(set (match_dup 0) (match_dup 2))]
3393 rtx c = operands[2];
3394 int r = REGNO (operands[0]);
3396 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3397 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3401 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3403 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3404 (match_operand:X87MODEF 1 "immediate_operand"))]
3406 && (standard_80387_constant_p (operands[1]) == 8
3407 || standard_80387_constant_p (operands[1]) == 9)"
3408 [(set (match_dup 0)(match_dup 1))
3410 (neg:X87MODEF (match_dup 0)))]
3414 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3415 if (real_isnegzero (&r))
3416 operands[1] = CONST0_RTX (<MODE>mode);
3418 operands[1] = CONST1_RTX (<MODE>mode);
3422 [(set (match_operand 0 "nonimmediate_operand")
3423 (match_operand 1 "general_operand"))]
3425 && (GET_MODE (operands[0]) == TFmode
3426 || GET_MODE (operands[0]) == XFmode
3427 || GET_MODE (operands[0]) == DFmode)
3428 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3430 "ix86_split_long_move (operands); DONE;")
3432 (define_insn "swapxf"
3433 [(set (match_operand:XF 0 "register_operand" "+f")
3434 (match_operand:XF 1 "register_operand" "+f"))
3439 if (STACK_TOP_P (operands[0]))
3444 [(set_attr "type" "fxch")
3445 (set_attr "mode" "XF")])
3447 (define_insn "*swap<mode>"
3448 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3449 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3452 "TARGET_80387 || reload_completed"
3454 if (STACK_TOP_P (operands[0]))
3459 [(set_attr "type" "fxch")
3460 (set_attr "mode" "<MODE>")])
3462 ;; Zero extension instructions
3464 (define_expand "zero_extendsidi2"
3465 [(set (match_operand:DI 0 "nonimmediate_operand")
3466 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3468 (define_insn "*zero_extendsidi2_rex64"
3469 [(set (match_operand:DI 0 "nonimmediate_operand"
3470 "=r ,o,?*Ym,?*y,?*Yi,!*x")
3472 (match_operand:SI 1 "x86_64_zext_general_operand"
3473 "rmWz,0,r ,m ,r ,m*x")))]
3476 mov{l}\t{%1, %k0|%k0, %1}
3478 movd\t{%1, %0|%0, %1}
3479 movd\t{%1, %0|%0, %1}
3480 %vmovd\t{%1, %0|%0, %1}
3481 %vmovd\t{%1, %0|%0, %1}"
3482 [(set_attr "isa" "*,*,*,*,*,sse2")
3483 (set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3484 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3485 (set_attr "prefix_0f" "0,*,*,*,*,*")
3486 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3488 (define_insn "*zero_extendsidi2"
3489 [(set (match_operand:DI 0 "nonimmediate_operand"
3490 "=ro,?r,?o,?*Ym,?*y,?*Yi,!*x")
3491 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3492 "0 ,rm,r ,r ,m ,r ,m*x")))]
3498 movd\t{%1, %0|%0, %1}
3499 movd\t{%1, %0|%0, %1}
3500 %vmovd\t{%1, %0|%0, %1}
3501 %vmovd\t{%1, %0|%0, %1}"
3502 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3503 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3504 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3505 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3508 [(set (match_operand:DI 0 "memory_operand")
3509 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3511 [(set (match_dup 4) (const_int 0))]
3512 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3515 [(set (match_operand:DI 0 "register_operand")
3516 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3517 "!TARGET_64BIT && reload_completed
3518 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3519 && true_regnum (operands[0]) == true_regnum (operands[1])"
3520 [(set (match_dup 4) (const_int 0))]
3521 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3524 [(set (match_operand:DI 0 "nonimmediate_operand")
3525 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3526 "!TARGET_64BIT && reload_completed
3527 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3528 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3529 [(set (match_dup 3) (match_dup 1))
3530 (set (match_dup 4) (const_int 0))]
3531 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3533 (define_insn "zero_extend<mode>di2"
3534 [(set (match_operand:DI 0 "register_operand" "=r")
3536 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3538 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3539 [(set_attr "type" "imovx")
3540 (set_attr "mode" "SI")])
3542 (define_expand "zero_extend<mode>si2"
3543 [(set (match_operand:SI 0 "register_operand")
3544 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3547 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3549 operands[1] = force_reg (<MODE>mode, operands[1]);
3550 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3555 (define_insn_and_split "zero_extend<mode>si2_and"
3556 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3558 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3559 (clobber (reg:CC FLAGS_REG))]
3560 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3562 "&& reload_completed"
3563 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3564 (clobber (reg:CC FLAGS_REG))])]
3566 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3568 ix86_expand_clear (operands[0]);
3570 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3571 emit_insn (gen_movstrict<mode>
3572 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3576 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3578 [(set_attr "type" "alu1")
3579 (set_attr "mode" "SI")])
3581 (define_insn "*zero_extend<mode>si2"
3582 [(set (match_operand:SI 0 "register_operand" "=r")
3584 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3585 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3586 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3587 [(set_attr "type" "imovx")
3588 (set_attr "mode" "SI")])
3590 (define_expand "zero_extendqihi2"
3591 [(set (match_operand:HI 0 "register_operand")
3592 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3595 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3597 operands[1] = force_reg (QImode, operands[1]);
3598 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3603 (define_insn_and_split "zero_extendqihi2_and"
3604 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3605 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3606 (clobber (reg:CC FLAGS_REG))]
3607 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3609 "&& reload_completed"
3610 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3611 (clobber (reg:CC FLAGS_REG))])]
3613 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3615 ix86_expand_clear (operands[0]);
3617 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3618 emit_insn (gen_movstrictqi
3619 (gen_lowpart (QImode, operands[0]), operands[1]));
3623 operands[0] = gen_lowpart (SImode, operands[0]);
3625 [(set_attr "type" "alu1")
3626 (set_attr "mode" "SI")])
3628 ; zero extend to SImode to avoid partial register stalls
3629 (define_insn "*zero_extendqihi2"
3630 [(set (match_operand:HI 0 "register_operand" "=r")
3631 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3632 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3633 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3634 [(set_attr "type" "imovx")
3635 (set_attr "mode" "SI")])
3637 ;; Sign extension instructions
3639 (define_expand "extendsidi2"
3640 [(set (match_operand:DI 0 "register_operand")
3641 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3646 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3651 (define_insn "*extendsidi2_rex64"
3652 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3653 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3657 movs{lq|x}\t{%1, %0|%0, %1}"
3658 [(set_attr "type" "imovx")
3659 (set_attr "mode" "DI")
3660 (set_attr "prefix_0f" "0")
3661 (set_attr "modrm" "0,1")])
3663 (define_insn "extendsidi2_1"
3664 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3665 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3666 (clobber (reg:CC FLAGS_REG))
3667 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3671 ;; Extend to memory case when source register does die.
3673 [(set (match_operand:DI 0 "memory_operand")
3674 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3675 (clobber (reg:CC FLAGS_REG))
3676 (clobber (match_operand:SI 2 "register_operand"))]
3678 && dead_or_set_p (insn, operands[1])
3679 && !reg_mentioned_p (operands[1], operands[0]))"
3680 [(set (match_dup 3) (match_dup 1))
3681 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3682 (clobber (reg:CC FLAGS_REG))])
3683 (set (match_dup 4) (match_dup 1))]
3684 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3686 ;; Extend to memory case when source register does not die.
3688 [(set (match_operand:DI 0 "memory_operand")
3689 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3690 (clobber (reg:CC FLAGS_REG))
3691 (clobber (match_operand:SI 2 "register_operand"))]
3695 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3697 emit_move_insn (operands[3], operands[1]);
3699 /* Generate a cltd if possible and doing so it profitable. */
3700 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3701 && true_regnum (operands[1]) == AX_REG
3702 && true_regnum (operands[2]) == DX_REG)
3704 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3708 emit_move_insn (operands[2], operands[1]);
3709 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3711 emit_move_insn (operands[4], operands[2]);
3715 ;; Extend to register case. Optimize case where source and destination
3716 ;; registers match and cases where we can use cltd.
3718 [(set (match_operand:DI 0 "register_operand")
3719 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3720 (clobber (reg:CC FLAGS_REG))
3721 (clobber (match_scratch:SI 2))]
3725 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3727 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3728 emit_move_insn (operands[3], operands[1]);
3730 /* Generate a cltd if possible and doing so it profitable. */
3731 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3732 && true_regnum (operands[3]) == AX_REG
3733 && true_regnum (operands[4]) == DX_REG)
3735 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3739 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3740 emit_move_insn (operands[4], operands[1]);
3742 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3746 (define_insn "extend<mode>di2"
3747 [(set (match_operand:DI 0 "register_operand" "=r")
3749 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3751 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3752 [(set_attr "type" "imovx")
3753 (set_attr "mode" "DI")])
3755 (define_insn "extendhisi2"
3756 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3757 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3760 switch (get_attr_prefix_0f (insn))
3763 return "{cwtl|cwde}";
3765 return "movs{wl|x}\t{%1, %0|%0, %1}";
3768 [(set_attr "type" "imovx")
3769 (set_attr "mode" "SI")
3770 (set (attr "prefix_0f")
3771 ;; movsx is short decodable while cwtl is vector decoded.
3772 (if_then_else (and (eq_attr "cpu" "!k6")
3773 (eq_attr "alternative" "0"))
3775 (const_string "1")))
3777 (if_then_else (eq_attr "prefix_0f" "0")
3779 (const_string "1")))])
3781 (define_insn "*extendhisi2_zext"
3782 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3785 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3788 switch (get_attr_prefix_0f (insn))
3791 return "{cwtl|cwde}";
3793 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3796 [(set_attr "type" "imovx")
3797 (set_attr "mode" "SI")
3798 (set (attr "prefix_0f")
3799 ;; movsx is short decodable while cwtl is vector decoded.
3800 (if_then_else (and (eq_attr "cpu" "!k6")
3801 (eq_attr "alternative" "0"))
3803 (const_string "1")))
3805 (if_then_else (eq_attr "prefix_0f" "0")
3807 (const_string "1")))])
3809 (define_insn "extendqisi2"
3810 [(set (match_operand:SI 0 "register_operand" "=r")
3811 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3813 "movs{bl|x}\t{%1, %0|%0, %1}"
3814 [(set_attr "type" "imovx")
3815 (set_attr "mode" "SI")])
3817 (define_insn "*extendqisi2_zext"
3818 [(set (match_operand:DI 0 "register_operand" "=r")
3820 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3822 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3823 [(set_attr "type" "imovx")
3824 (set_attr "mode" "SI")])
3826 (define_insn "extendqihi2"
3827 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3828 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3831 switch (get_attr_prefix_0f (insn))
3834 return "{cbtw|cbw}";
3836 return "movs{bw|x}\t{%1, %0|%0, %1}";
3839 [(set_attr "type" "imovx")
3840 (set_attr "mode" "HI")
3841 (set (attr "prefix_0f")
3842 ;; movsx is short decodable while cwtl is vector decoded.
3843 (if_then_else (and (eq_attr "cpu" "!k6")
3844 (eq_attr "alternative" "0"))
3846 (const_string "1")))
3848 (if_then_else (eq_attr "prefix_0f" "0")
3850 (const_string "1")))])
3852 ;; Conversions between float and double.
3854 ;; These are all no-ops in the model used for the 80387.
3855 ;; So just emit moves.
3857 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3859 [(set (match_operand:DF 0 "push_operand")
3860 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3862 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3863 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3866 [(set (match_operand:XF 0 "push_operand")
3867 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3869 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3870 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3871 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3873 (define_expand "extendsfdf2"
3874 [(set (match_operand:DF 0 "nonimmediate_operand")
3875 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3876 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3878 /* ??? Needed for compress_float_constant since all fp constants
3879 are TARGET_LEGITIMATE_CONSTANT_P. */
3880 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3882 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3883 && standard_80387_constant_p (operands[1]) > 0)
3885 operands[1] = simplify_const_unary_operation
3886 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3887 emit_move_insn_1 (operands[0], operands[1]);
3890 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3894 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3896 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3898 We do the conversion post reload to avoid producing of 128bit spills
3899 that might lead to ICE on 32bit target. The sequence unlikely combine
3902 [(set (match_operand:DF 0 "register_operand")
3904 (match_operand:SF 1 "nonimmediate_operand")))]
3905 "TARGET_USE_VECTOR_FP_CONVERTS
3906 && optimize_insn_for_speed_p ()
3907 && reload_completed && SSE_REG_P (operands[0])"
3912 (parallel [(const_int 0) (const_int 1)]))))]
3914 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3915 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3916 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3917 Try to avoid move when unpacking can be done in source. */
3918 if (REG_P (operands[1]))
3920 /* If it is unsafe to overwrite upper half of source, we need
3921 to move to destination and unpack there. */
3922 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3923 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3924 && true_regnum (operands[0]) != true_regnum (operands[1]))
3926 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3927 emit_move_insn (tmp, operands[1]);
3930 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3931 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3935 emit_insn (gen_vec_setv4sf_0 (operands[3],
3936 CONST0_RTX (V4SFmode), operands[1]));
3939 (define_insn "*extendsfdf2_mixed"
3940 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3942 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3943 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3945 switch (which_alternative)
3949 return output_387_reg_move (insn, operands);
3952 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3958 [(set_attr "type" "fmov,fmov,ssecvt")
3959 (set_attr "prefix" "orig,orig,maybe_vex")
3960 (set_attr "mode" "SF,XF,DF")])
3962 (define_insn "*extendsfdf2_sse"
3963 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3964 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3965 "TARGET_SSE2 && TARGET_SSE_MATH"
3966 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3967 [(set_attr "type" "ssecvt")
3968 (set_attr "prefix" "maybe_vex")
3969 (set_attr "mode" "DF")])
3971 (define_insn "*extendsfdf2_i387"
3972 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3973 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3975 "* return output_387_reg_move (insn, operands);"
3976 [(set_attr "type" "fmov")
3977 (set_attr "mode" "SF,XF")])
3979 (define_expand "extend<mode>xf2"
3980 [(set (match_operand:XF 0 "nonimmediate_operand")
3981 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3984 /* ??? Needed for compress_float_constant since all fp constants
3985 are TARGET_LEGITIMATE_CONSTANT_P. */
3986 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3988 if (standard_80387_constant_p (operands[1]) > 0)
3990 operands[1] = simplify_const_unary_operation
3991 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3992 emit_move_insn_1 (operands[0], operands[1]);
3995 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3999 (define_insn "*extend<mode>xf2_i387"
4000 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4002 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4004 "* return output_387_reg_move (insn, operands);"
4005 [(set_attr "type" "fmov")
4006 (set_attr "mode" "<MODE>,XF")])
4008 ;; %%% This seems bad bad news.
4009 ;; This cannot output into an f-reg because there is no way to be sure
4010 ;; of truncating in that case. Otherwise this is just like a simple move
4011 ;; insn. So we pretend we can output to a reg in order to get better
4012 ;; register preferencing, but we really use a stack slot.
4014 ;; Conversion from DFmode to SFmode.
4016 (define_expand "truncdfsf2"
4017 [(set (match_operand:SF 0 "nonimmediate_operand")
4019 (match_operand:DF 1 "nonimmediate_operand")))]
4020 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4022 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4024 else if (flag_unsafe_math_optimizations)
4028 enum ix86_stack_slot slot = (virtuals_instantiated
4031 rtx temp = assign_386_stack_local (SFmode, slot);
4032 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4037 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4039 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4041 We do the conversion post reload to avoid producing of 128bit spills
4042 that might lead to ICE on 32bit target. The sequence unlikely combine
4045 [(set (match_operand:SF 0 "register_operand")
4047 (match_operand:DF 1 "nonimmediate_operand")))]
4048 "TARGET_USE_VECTOR_FP_CONVERTS
4049 && optimize_insn_for_speed_p ()
4050 && reload_completed && SSE_REG_P (operands[0])"
4053 (float_truncate:V2SF
4057 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4058 operands[3] = CONST0_RTX (V2SFmode);
4059 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4060 /* Use movsd for loading from memory, unpcklpd for registers.
4061 Try to avoid move when unpacking can be done in source, or SSE3
4062 movddup is available. */
4063 if (REG_P (operands[1]))
4066 && true_regnum (operands[0]) != true_regnum (operands[1])
4067 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4068 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4070 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4071 emit_move_insn (tmp, operands[1]);
4074 else if (!TARGET_SSE3)
4075 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4076 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4079 emit_insn (gen_sse2_loadlpd (operands[4],
4080 CONST0_RTX (V2DFmode), operands[1]));
4083 (define_expand "truncdfsf2_with_temp"
4084 [(parallel [(set (match_operand:SF 0)
4085 (float_truncate:SF (match_operand:DF 1)))
4086 (clobber (match_operand:SF 2))])])
4088 (define_insn "*truncdfsf_fast_mixed"
4089 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4091 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4092 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4094 switch (which_alternative)
4097 return output_387_reg_move (insn, operands);
4099 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4104 [(set_attr "type" "fmov,ssecvt")
4105 (set_attr "prefix" "orig,maybe_vex")
4106 (set_attr "mode" "SF")])
4108 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4109 ;; because nothing we do here is unsafe.
4110 (define_insn "*truncdfsf_fast_sse"
4111 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4113 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4114 "TARGET_SSE2 && TARGET_SSE_MATH"
4115 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4116 [(set_attr "type" "ssecvt")
4117 (set_attr "prefix" "maybe_vex")
4118 (set_attr "mode" "SF")])
4120 (define_insn "*truncdfsf_fast_i387"
4121 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4123 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4124 "TARGET_80387 && flag_unsafe_math_optimizations"
4125 "* return output_387_reg_move (insn, operands);"
4126 [(set_attr "type" "fmov")
4127 (set_attr "mode" "SF")])
4129 (define_insn "*truncdfsf_mixed"
4130 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4132 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4133 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4134 "TARGET_MIX_SSE_I387"
4136 switch (which_alternative)
4139 return output_387_reg_move (insn, operands);
4141 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4147 [(set_attr "isa" "*,sse2,*,*,*")
4148 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4149 (set_attr "unit" "*,*,i387,i387,i387")
4150 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4151 (set_attr "mode" "SF")])
4153 (define_insn "*truncdfsf_i387"
4154 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4156 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4157 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4160 switch (which_alternative)
4163 return output_387_reg_move (insn, operands);
4169 [(set_attr "type" "fmov,multi,multi,multi")
4170 (set_attr "unit" "*,i387,i387,i387")
4171 (set_attr "mode" "SF")])
4173 (define_insn "*truncdfsf2_i387_1"
4174 [(set (match_operand:SF 0 "memory_operand" "=m")
4176 (match_operand:DF 1 "register_operand" "f")))]
4178 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4179 && !TARGET_MIX_SSE_I387"
4180 "* return output_387_reg_move (insn, operands);"
4181 [(set_attr "type" "fmov")
4182 (set_attr "mode" "SF")])
4185 [(set (match_operand:SF 0 "register_operand")
4187 (match_operand:DF 1 "fp_register_operand")))
4188 (clobber (match_operand 2))]
4190 [(set (match_dup 2) (match_dup 1))
4191 (set (match_dup 0) (match_dup 2))]
4192 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4194 ;; Conversion from XFmode to {SF,DF}mode
4196 (define_expand "truncxf<mode>2"
4197 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4198 (float_truncate:MODEF
4199 (match_operand:XF 1 "register_operand")))
4200 (clobber (match_dup 2))])]
4203 if (flag_unsafe_math_optimizations)
4205 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4206 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4207 if (reg != operands[0])
4208 emit_move_insn (operands[0], reg);
4213 enum ix86_stack_slot slot = (virtuals_instantiated
4216 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4220 (define_insn "*truncxfsf2_mixed"
4221 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4223 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4224 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4227 gcc_assert (!which_alternative);
4228 return output_387_reg_move (insn, operands);
4230 [(set_attr "type" "fmov,multi,multi,multi")
4231 (set_attr "unit" "*,i387,i387,i387")
4232 (set_attr "mode" "SF")])
4234 (define_insn "*truncxfdf2_mixed"
4235 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4237 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4238 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4241 gcc_assert (!which_alternative);
4242 return output_387_reg_move (insn, operands);
4244 [(set_attr "isa" "*,*,sse2,*")
4245 (set_attr "type" "fmov,multi,multi,multi")
4246 (set_attr "unit" "*,i387,i387,i387")
4247 (set_attr "mode" "DF")])
4249 (define_insn "truncxf<mode>2_i387_noop"
4250 [(set (match_operand:MODEF 0 "register_operand" "=f")
4251 (float_truncate:MODEF
4252 (match_operand:XF 1 "register_operand" "f")))]
4253 "TARGET_80387 && flag_unsafe_math_optimizations"
4254 "* return output_387_reg_move (insn, operands);"
4255 [(set_attr "type" "fmov")
4256 (set_attr "mode" "<MODE>")])
4258 (define_insn "*truncxf<mode>2_i387"
4259 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4260 (float_truncate:MODEF
4261 (match_operand:XF 1 "register_operand" "f")))]
4263 "* return output_387_reg_move (insn, operands);"
4264 [(set_attr "type" "fmov")
4265 (set_attr "mode" "<MODE>")])
4268 [(set (match_operand:MODEF 0 "register_operand")
4269 (float_truncate:MODEF
4270 (match_operand:XF 1 "register_operand")))
4271 (clobber (match_operand:MODEF 2 "memory_operand"))]
4272 "TARGET_80387 && reload_completed"
4273 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4274 (set (match_dup 0) (match_dup 2))])
4277 [(set (match_operand:MODEF 0 "memory_operand")
4278 (float_truncate:MODEF
4279 (match_operand:XF 1 "register_operand")))
4280 (clobber (match_operand:MODEF 2 "memory_operand"))]
4282 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4284 ;; Signed conversion to DImode.
4286 (define_expand "fix_truncxfdi2"
4287 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4288 (fix:DI (match_operand:XF 1 "register_operand")))
4289 (clobber (reg:CC FLAGS_REG))])]
4294 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4299 (define_expand "fix_trunc<mode>di2"
4300 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4301 (fix:DI (match_operand:MODEF 1 "register_operand")))
4302 (clobber (reg:CC FLAGS_REG))])]
4303 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4306 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4308 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4311 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4313 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4314 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4315 if (out != operands[0])
4316 emit_move_insn (operands[0], out);
4321 ;; Signed conversion to SImode.
4323 (define_expand "fix_truncxfsi2"
4324 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4325 (fix:SI (match_operand:XF 1 "register_operand")))
4326 (clobber (reg:CC FLAGS_REG))])]
4331 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4336 (define_expand "fix_trunc<mode>si2"
4337 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4338 (fix:SI (match_operand:MODEF 1 "register_operand")))
4339 (clobber (reg:CC FLAGS_REG))])]
4340 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4343 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4345 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4348 if (SSE_FLOAT_MODE_P (<MODE>mode))
4350 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4351 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4352 if (out != operands[0])
4353 emit_move_insn (operands[0], out);
4358 ;; Signed conversion to HImode.
4360 (define_expand "fix_trunc<mode>hi2"
4361 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4362 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4363 (clobber (reg:CC FLAGS_REG))])]
4365 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4369 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4374 ;; Unsigned conversion to SImode.
4376 (define_expand "fixuns_trunc<mode>si2"
4378 [(set (match_operand:SI 0 "register_operand")
4380 (match_operand:MODEF 1 "nonimmediate_operand")))
4382 (clobber (match_scratch:<ssevecmode> 3))
4383 (clobber (match_scratch:<ssevecmode> 4))])]
4384 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4386 enum machine_mode mode = <MODE>mode;
4387 enum machine_mode vecmode = <ssevecmode>mode;
4388 REAL_VALUE_TYPE TWO31r;
4391 if (optimize_insn_for_size_p ())
4394 real_ldexp (&TWO31r, &dconst1, 31);
4395 two31 = const_double_from_real_value (TWO31r, mode);
4396 two31 = ix86_build_const_vector (vecmode, true, two31);
4397 operands[2] = force_reg (vecmode, two31);
4400 (define_insn_and_split "*fixuns_trunc<mode>_1"
4401 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4403 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4404 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4405 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4406 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4407 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4408 && optimize_function_for_speed_p (cfun)"
4410 "&& reload_completed"
4413 ix86_split_convert_uns_si_sse (operands);
4417 ;; Unsigned conversion to HImode.
4418 ;; Without these patterns, we'll try the unsigned SI conversion which
4419 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4421 (define_expand "fixuns_trunc<mode>hi2"
4423 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4424 (set (match_operand:HI 0 "nonimmediate_operand")
4425 (subreg:HI (match_dup 2) 0))]
4426 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4427 "operands[2] = gen_reg_rtx (SImode);")
4429 ;; When SSE is available, it is always faster to use it!
4430 (define_insn "fix_trunc<mode>di_sse"
4431 [(set (match_operand:DI 0 "register_operand" "=r,r")
4432 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4433 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4434 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4435 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4436 [(set_attr "type" "sseicvt")
4437 (set_attr "prefix" "maybe_vex")
4438 (set_attr "prefix_rex" "1")
4439 (set_attr "mode" "<MODE>")
4440 (set_attr "athlon_decode" "double,vector")
4441 (set_attr "amdfam10_decode" "double,double")
4442 (set_attr "bdver1_decode" "double,double")])
4444 (define_insn "fix_trunc<mode>si_sse"
4445 [(set (match_operand:SI 0 "register_operand" "=r,r")
4446 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4447 "SSE_FLOAT_MODE_P (<MODE>mode)
4448 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4449 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4450 [(set_attr "type" "sseicvt")
4451 (set_attr "prefix" "maybe_vex")
4452 (set_attr "mode" "<MODE>")
4453 (set_attr "athlon_decode" "double,vector")
4454 (set_attr "amdfam10_decode" "double,double")
4455 (set_attr "bdver1_decode" "double,double")])
4457 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4459 [(set (match_operand:MODEF 0 "register_operand")
4460 (match_operand:MODEF 1 "memory_operand"))
4461 (set (match_operand:SWI48x 2 "register_operand")
4462 (fix:SWI48x (match_dup 0)))]
4463 "TARGET_SHORTEN_X87_SSE
4464 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4465 && peep2_reg_dead_p (2, operands[0])"
4466 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4468 ;; Avoid vector decoded forms of the instruction.
4470 [(match_scratch:DF 2 "x")
4471 (set (match_operand:SWI48x 0 "register_operand")
4472 (fix:SWI48x (match_operand:DF 1 "memory_operand")))]
4473 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4474 [(set (match_dup 2) (match_dup 1))
4475 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4478 [(match_scratch:SF 2 "x")
4479 (set (match_operand:SWI48x 0 "register_operand")
4480 (fix:SWI48x (match_operand:SF 1 "memory_operand")))]
4481 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4482 [(set (match_dup 2) (match_dup 1))
4483 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4485 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4486 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4487 (fix:SWI248x (match_operand 1 "register_operand")))]
4488 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4490 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4491 && (TARGET_64BIT || <MODE>mode != DImode))
4493 && can_create_pseudo_p ()"
4498 if (memory_operand (operands[0], VOIDmode))
4499 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4502 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4503 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4509 [(set_attr "type" "fisttp")
4510 (set_attr "mode" "<MODE>")])
4512 (define_insn "fix_trunc<mode>_i387_fisttp"
4513 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4514 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4515 (clobber (match_scratch:XF 2 "=&1f"))]
4516 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4518 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4519 && (TARGET_64BIT || <MODE>mode != DImode))
4520 && TARGET_SSE_MATH)"
4521 "* return output_fix_trunc (insn, operands, true);"
4522 [(set_attr "type" "fisttp")
4523 (set_attr "mode" "<MODE>")])
4525 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4526 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4527 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4528 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4529 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4530 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4532 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4533 && (TARGET_64BIT || <MODE>mode != DImode))
4534 && TARGET_SSE_MATH)"
4536 [(set_attr "type" "fisttp")
4537 (set_attr "mode" "<MODE>")])
4540 [(set (match_operand:SWI248x 0 "register_operand")
4541 (fix:SWI248x (match_operand 1 "register_operand")))
4542 (clobber (match_operand:SWI248x 2 "memory_operand"))
4543 (clobber (match_scratch 3))]
4545 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4546 (clobber (match_dup 3))])
4547 (set (match_dup 0) (match_dup 2))])
4550 [(set (match_operand:SWI248x 0 "memory_operand")
4551 (fix:SWI248x (match_operand 1 "register_operand")))
4552 (clobber (match_operand:SWI248x 2 "memory_operand"))
4553 (clobber (match_scratch 3))]
4555 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4556 (clobber (match_dup 3))])])
4558 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4559 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4560 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4561 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4562 ;; function in i386.c.
4563 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4564 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4565 (fix:SWI248x (match_operand 1 "register_operand")))
4566 (clobber (reg:CC FLAGS_REG))]
4567 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4569 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4570 && (TARGET_64BIT || <MODE>mode != DImode))
4571 && can_create_pseudo_p ()"
4576 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4578 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4579 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4580 if (memory_operand (operands[0], VOIDmode))
4581 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4582 operands[2], operands[3]));
4585 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4586 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4587 operands[2], operands[3],
4592 [(set_attr "type" "fistp")
4593 (set_attr "i387_cw" "trunc")
4594 (set_attr "mode" "<MODE>")])
4596 (define_insn "fix_truncdi_i387"
4597 [(set (match_operand:DI 0 "memory_operand" "=m")
4598 (fix:DI (match_operand 1 "register_operand" "f")))
4599 (use (match_operand:HI 2 "memory_operand" "m"))
4600 (use (match_operand:HI 3 "memory_operand" "m"))
4601 (clobber (match_scratch:XF 4 "=&1f"))]
4602 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4604 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4605 "* return output_fix_trunc (insn, operands, false);"
4606 [(set_attr "type" "fistp")
4607 (set_attr "i387_cw" "trunc")
4608 (set_attr "mode" "DI")])
4610 (define_insn "fix_truncdi_i387_with_temp"
4611 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4612 (fix:DI (match_operand 1 "register_operand" "f,f")))
4613 (use (match_operand:HI 2 "memory_operand" "m,m"))
4614 (use (match_operand:HI 3 "memory_operand" "m,m"))
4615 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4616 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4617 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4619 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4621 [(set_attr "type" "fistp")
4622 (set_attr "i387_cw" "trunc")
4623 (set_attr "mode" "DI")])
4626 [(set (match_operand:DI 0 "register_operand")
4627 (fix:DI (match_operand 1 "register_operand")))
4628 (use (match_operand:HI 2 "memory_operand"))
4629 (use (match_operand:HI 3 "memory_operand"))
4630 (clobber (match_operand:DI 4 "memory_operand"))
4631 (clobber (match_scratch 5))]
4633 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4636 (clobber (match_dup 5))])
4637 (set (match_dup 0) (match_dup 4))])
4640 [(set (match_operand:DI 0 "memory_operand")
4641 (fix:DI (match_operand 1 "register_operand")))
4642 (use (match_operand:HI 2 "memory_operand"))
4643 (use (match_operand:HI 3 "memory_operand"))
4644 (clobber (match_operand:DI 4 "memory_operand"))
4645 (clobber (match_scratch 5))]
4647 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4650 (clobber (match_dup 5))])])
4652 (define_insn "fix_trunc<mode>_i387"
4653 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4654 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4655 (use (match_operand:HI 2 "memory_operand" "m"))
4656 (use (match_operand:HI 3 "memory_operand" "m"))]
4657 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4659 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4660 "* return output_fix_trunc (insn, operands, false);"
4661 [(set_attr "type" "fistp")
4662 (set_attr "i387_cw" "trunc")
4663 (set_attr "mode" "<MODE>")])
4665 (define_insn "fix_trunc<mode>_i387_with_temp"
4666 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4667 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4668 (use (match_operand:HI 2 "memory_operand" "m,m"))
4669 (use (match_operand:HI 3 "memory_operand" "m,m"))
4670 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4671 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4673 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4675 [(set_attr "type" "fistp")
4676 (set_attr "i387_cw" "trunc")
4677 (set_attr "mode" "<MODE>")])
4680 [(set (match_operand:SWI24 0 "register_operand")
4681 (fix:SWI24 (match_operand 1 "register_operand")))
4682 (use (match_operand:HI 2 "memory_operand"))
4683 (use (match_operand:HI 3 "memory_operand"))
4684 (clobber (match_operand:SWI24 4 "memory_operand"))]
4686 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4688 (use (match_dup 3))])
4689 (set (match_dup 0) (match_dup 4))])
4692 [(set (match_operand:SWI24 0 "memory_operand")
4693 (fix:SWI24 (match_operand 1 "register_operand")))
4694 (use (match_operand:HI 2 "memory_operand"))
4695 (use (match_operand:HI 3 "memory_operand"))
4696 (clobber (match_operand:SWI24 4 "memory_operand"))]
4698 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4700 (use (match_dup 3))])])
4702 (define_insn "x86_fnstcw_1"
4703 [(set (match_operand:HI 0 "memory_operand" "=m")
4704 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4707 [(set (attr "length")
4708 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4709 (set_attr "mode" "HI")
4710 (set_attr "unit" "i387")
4711 (set_attr "bdver1_decode" "vector")])
4713 (define_insn "x86_fldcw_1"
4714 [(set (reg:HI FPCR_REG)
4715 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4718 [(set (attr "length")
4719 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4720 (set_attr "mode" "HI")
4721 (set_attr "unit" "i387")
4722 (set_attr "athlon_decode" "vector")
4723 (set_attr "amdfam10_decode" "vector")
4724 (set_attr "bdver1_decode" "vector")])
4726 ;; Conversion between fixed point and floating point.
4728 ;; Even though we only accept memory inputs, the backend _really_
4729 ;; wants to be able to do this between registers.
4731 (define_expand "floathi<mode>2"
4732 [(set (match_operand:X87MODEF 0 "register_operand")
4733 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4735 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4736 || TARGET_MIX_SSE_I387)")
4738 ;; Pre-reload splitter to add memory clobber to the pattern.
4739 (define_insn_and_split "*floathi<mode>2_1"
4740 [(set (match_operand:X87MODEF 0 "register_operand")
4741 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4743 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4744 || TARGET_MIX_SSE_I387)
4745 && can_create_pseudo_p ()"
4748 [(parallel [(set (match_dup 0)
4749 (float:X87MODEF (match_dup 1)))
4750 (clobber (match_dup 2))])]
4751 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4753 (define_insn "*floathi<mode>2_i387_with_temp"
4754 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4755 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4756 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4758 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4759 || TARGET_MIX_SSE_I387)"
4761 [(set_attr "type" "fmov,multi")
4762 (set_attr "mode" "<MODE>")
4763 (set_attr "unit" "*,i387")
4764 (set_attr "fp_int_src" "true")])
4766 (define_insn "*floathi<mode>2_i387"
4767 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4768 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4770 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4771 || TARGET_MIX_SSE_I387)"
4773 [(set_attr "type" "fmov")
4774 (set_attr "mode" "<MODE>")
4775 (set_attr "fp_int_src" "true")])
4778 [(set (match_operand:X87MODEF 0 "register_operand")
4779 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4780 (clobber (match_operand:HI 2 "memory_operand"))]
4782 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4783 || TARGET_MIX_SSE_I387)
4784 && reload_completed"
4785 [(set (match_dup 2) (match_dup 1))
4786 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4789 [(set (match_operand:X87MODEF 0 "register_operand")
4790 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4791 (clobber (match_operand:HI 2 "memory_operand"))]
4793 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4794 || TARGET_MIX_SSE_I387)
4795 && reload_completed"
4796 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4798 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4799 [(set (match_operand:X87MODEF 0 "register_operand")
4801 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4803 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4804 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4806 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4807 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4808 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4810 rtx reg = gen_reg_rtx (XFmode);
4811 rtx (*insn)(rtx, rtx);
4813 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4815 if (<X87MODEF:MODE>mode == SFmode)
4816 insn = gen_truncxfsf2;
4817 else if (<X87MODEF:MODE>mode == DFmode)
4818 insn = gen_truncxfdf2;
4822 emit_insn (insn (operands[0], reg));
4827 ;; Pre-reload splitter to add memory clobber to the pattern.
4828 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4829 [(set (match_operand:X87MODEF 0 "register_operand")
4830 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4832 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4833 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4834 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4835 || TARGET_MIX_SSE_I387))
4836 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4837 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4838 && ((<SWI48x:MODE>mode == SImode
4839 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4840 && optimize_function_for_speed_p (cfun)
4841 && flag_trapping_math)
4842 || !(TARGET_INTER_UNIT_CONVERSIONS
4843 || optimize_function_for_size_p (cfun)))))
4844 && can_create_pseudo_p ()"
4847 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4848 (clobber (match_dup 2))])]
4850 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4852 /* Avoid store forwarding (partial memory) stall penalty
4853 by passing DImode value through XMM registers. */
4854 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4855 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4856 && optimize_function_for_speed_p (cfun))
4858 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4865 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4866 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4868 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4869 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4870 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4871 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4873 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4874 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4875 (set_attr "unit" "*,i387,*,*,*")
4876 (set_attr "athlon_decode" "*,*,double,direct,double")
4877 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4878 (set_attr "bdver1_decode" "*,*,double,direct,double")
4879 (set_attr "fp_int_src" "true")])
4881 (define_insn "*floatsi<mode>2_vector_mixed"
4882 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4883 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4884 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4885 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4889 [(set_attr "type" "fmov,sseicvt")
4890 (set_attr "mode" "<MODE>,<ssevecmode>")
4891 (set_attr "unit" "i387,*")
4892 (set_attr "athlon_decode" "*,direct")
4893 (set_attr "amdfam10_decode" "*,double")
4894 (set_attr "bdver1_decode" "*,direct")
4895 (set_attr "fp_int_src" "true")])
4897 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4898 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4900 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4901 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4902 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4903 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4905 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4906 (set_attr "mode" "<MODEF:MODE>")
4907 (set_attr "unit" "*,i387,*,*")
4908 (set_attr "athlon_decode" "*,*,double,direct")
4909 (set_attr "amdfam10_decode" "*,*,vector,double")
4910 (set_attr "bdver1_decode" "*,*,double,direct")
4911 (set_attr "fp_int_src" "true")])
4914 [(set (match_operand:MODEF 0 "register_operand")
4915 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4916 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4917 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4918 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4919 && TARGET_INTER_UNIT_CONVERSIONS
4921 && (SSE_REG_P (operands[0])
4922 || (GET_CODE (operands[0]) == SUBREG
4923 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4924 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4927 [(set (match_operand:MODEF 0 "register_operand")
4928 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4929 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4930 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4931 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4932 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4934 && (SSE_REG_P (operands[0])
4935 || (GET_CODE (operands[0]) == SUBREG
4936 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4937 [(set (match_dup 2) (match_dup 1))
4938 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4940 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4941 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4943 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4944 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4945 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4946 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4949 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4950 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4951 [(set_attr "type" "fmov,sseicvt,sseicvt")
4952 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4953 (set_attr "mode" "<MODEF:MODE>")
4954 (set (attr "prefix_rex")
4956 (and (eq_attr "prefix" "maybe_vex")
4957 (match_test "<SWI48x:MODE>mode == DImode"))
4959 (const_string "*")))
4960 (set_attr "unit" "i387,*,*")
4961 (set_attr "athlon_decode" "*,double,direct")
4962 (set_attr "amdfam10_decode" "*,vector,double")
4963 (set_attr "bdver1_decode" "*,double,direct")
4964 (set_attr "fp_int_src" "true")])
4966 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4967 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4969 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4970 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4971 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4972 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4975 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4976 [(set_attr "type" "fmov,sseicvt")
4977 (set_attr "prefix" "orig,maybe_vex")
4978 (set_attr "mode" "<MODEF:MODE>")
4979 (set (attr "prefix_rex")
4981 (and (eq_attr "prefix" "maybe_vex")
4982 (match_test "<SWI48x:MODE>mode == DImode"))
4984 (const_string "*")))
4985 (set_attr "athlon_decode" "*,direct")
4986 (set_attr "amdfam10_decode" "*,double")
4987 (set_attr "bdver1_decode" "*,direct")
4988 (set_attr "fp_int_src" "true")])
4990 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4991 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4993 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4994 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4995 "TARGET_SSE2 && TARGET_SSE_MATH
4996 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4998 [(set_attr "type" "sseicvt")
4999 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5000 (set_attr "athlon_decode" "double,direct,double")
5001 (set_attr "amdfam10_decode" "vector,double,double")
5002 (set_attr "bdver1_decode" "double,direct,double")
5003 (set_attr "fp_int_src" "true")])
5005 (define_insn "*floatsi<mode>2_vector_sse"
5006 [(set (match_operand:MODEF 0 "register_operand" "=x")
5007 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5008 "TARGET_SSE2 && TARGET_SSE_MATH
5009 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5011 [(set_attr "type" "sseicvt")
5012 (set_attr "mode" "<MODE>")
5013 (set_attr "athlon_decode" "direct")
5014 (set_attr "amdfam10_decode" "double")
5015 (set_attr "bdver1_decode" "direct")
5016 (set_attr "fp_int_src" "true")])
5019 [(set (match_operand:MODEF 0 "register_operand")
5020 (float:MODEF (match_operand:SI 1 "register_operand")))
5021 (clobber (match_operand:SI 2 "memory_operand"))]
5022 "TARGET_SSE2 && TARGET_SSE_MATH
5023 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5025 && (SSE_REG_P (operands[0])
5026 || (GET_CODE (operands[0]) == SUBREG
5027 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5030 rtx op1 = operands[1];
5032 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5034 if (GET_CODE (op1) == SUBREG)
5035 op1 = SUBREG_REG (op1);
5037 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5039 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5040 emit_insn (gen_sse2_loadld (operands[4],
5041 CONST0_RTX (V4SImode), operands[1]));
5043 /* We can ignore possible trapping value in the
5044 high part of SSE register for non-trapping math. */
5045 else if (SSE_REG_P (op1) && !flag_trapping_math)
5046 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5049 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5050 emit_move_insn (operands[2], operands[1]);
5051 emit_insn (gen_sse2_loadld (operands[4],
5052 CONST0_RTX (V4SImode), operands[2]));
5054 if (<ssevecmode>mode == V4SFmode)
5055 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5057 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5062 [(set (match_operand:MODEF 0 "register_operand")
5063 (float:MODEF (match_operand:SI 1 "memory_operand")))
5064 (clobber (match_operand:SI 2 "memory_operand"))]
5065 "TARGET_SSE2 && TARGET_SSE_MATH
5066 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5068 && (SSE_REG_P (operands[0])
5069 || (GET_CODE (operands[0]) == SUBREG
5070 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5073 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5075 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5077 emit_insn (gen_sse2_loadld (operands[4],
5078 CONST0_RTX (V4SImode), operands[1]));
5079 if (<ssevecmode>mode == V4SFmode)
5080 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5082 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5087 [(set (match_operand:MODEF 0 "register_operand")
5088 (float:MODEF (match_operand:SI 1 "register_operand")))]
5089 "TARGET_SSE2 && TARGET_SSE_MATH
5090 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5092 && (SSE_REG_P (operands[0])
5093 || (GET_CODE (operands[0]) == SUBREG
5094 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5097 rtx op1 = operands[1];
5099 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5101 if (GET_CODE (op1) == SUBREG)
5102 op1 = SUBREG_REG (op1);
5104 if (GENERAL_REG_P (op1))
5106 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5107 if (TARGET_INTER_UNIT_MOVES)
5108 emit_insn (gen_sse2_loadld (operands[4],
5109 CONST0_RTX (V4SImode), operands[1]));
5112 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5114 emit_insn (gen_sse2_loadld (operands[4],
5115 CONST0_RTX (V4SImode), operands[5]));
5116 ix86_free_from_memory (GET_MODE (operands[1]));
5119 /* We can ignore possible trapping value in the
5120 high part of SSE register for non-trapping math. */
5121 else if (SSE_REG_P (op1) && !flag_trapping_math)
5122 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5125 if (<ssevecmode>mode == V4SFmode)
5126 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5128 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5133 [(set (match_operand:MODEF 0 "register_operand")
5134 (float:MODEF (match_operand:SI 1 "memory_operand")))]
5135 "TARGET_SSE2 && TARGET_SSE_MATH
5136 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5138 && (SSE_REG_P (operands[0])
5139 || (GET_CODE (operands[0]) == SUBREG
5140 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5143 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5145 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5147 emit_insn (gen_sse2_loadld (operands[4],
5148 CONST0_RTX (V4SImode), operands[1]));
5149 if (<ssevecmode>mode == V4SFmode)
5150 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5152 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5156 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5157 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5159 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5160 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5161 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5162 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5164 [(set_attr "type" "sseicvt")
5165 (set_attr "mode" "<MODEF:MODE>")
5166 (set_attr "athlon_decode" "double,direct")
5167 (set_attr "amdfam10_decode" "vector,double")
5168 (set_attr "bdver1_decode" "double,direct")
5169 (set_attr "fp_int_src" "true")])
5171 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5172 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5174 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5175 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5176 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5177 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5178 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5179 [(set_attr "type" "sseicvt")
5180 (set_attr "prefix" "maybe_vex")
5181 (set_attr "mode" "<MODEF:MODE>")
5182 (set (attr "prefix_rex")
5184 (and (eq_attr "prefix" "maybe_vex")
5185 (match_test "<SWI48x:MODE>mode == DImode"))
5187 (const_string "*")))
5188 (set_attr "athlon_decode" "double,direct")
5189 (set_attr "amdfam10_decode" "vector,double")
5190 (set_attr "bdver1_decode" "double,direct")
5191 (set_attr "fp_int_src" "true")])
5194 [(set (match_operand:MODEF 0 "register_operand")
5195 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))
5196 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5197 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5198 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5199 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5201 && (SSE_REG_P (operands[0])
5202 || (GET_CODE (operands[0]) == SUBREG
5203 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5204 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5206 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5207 [(set (match_operand:MODEF 0 "register_operand" "=x")
5209 (match_operand:SWI48x 1 "memory_operand" "m")))]
5210 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5211 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5212 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5213 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5214 [(set_attr "type" "sseicvt")
5215 (set_attr "prefix" "maybe_vex")
5216 (set_attr "mode" "<MODEF:MODE>")
5217 (set (attr "prefix_rex")
5219 (and (eq_attr "prefix" "maybe_vex")
5220 (match_test "<SWI48x:MODE>mode == DImode"))
5222 (const_string "*")))
5223 (set_attr "athlon_decode" "direct")
5224 (set_attr "amdfam10_decode" "double")
5225 (set_attr "bdver1_decode" "direct")
5226 (set_attr "fp_int_src" "true")])
5229 [(set (match_operand:MODEF 0 "register_operand")
5230 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
5231 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5232 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5233 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5234 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5236 && (SSE_REG_P (operands[0])
5237 || (GET_CODE (operands[0]) == SUBREG
5238 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5239 [(set (match_dup 2) (match_dup 1))
5240 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5243 [(set (match_operand:MODEF 0 "register_operand")
5244 (float:MODEF (match_operand:SWI48x 1 "memory_operand")))
5245 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5246 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5247 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5249 && (SSE_REG_P (operands[0])
5250 || (GET_CODE (operands[0]) == SUBREG
5251 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5252 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5254 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5255 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5257 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5258 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5260 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5264 [(set_attr "type" "fmov,multi")
5265 (set_attr "mode" "<X87MODEF:MODE>")
5266 (set_attr "unit" "*,i387")
5267 (set_attr "fp_int_src" "true")])
5269 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5270 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5272 (match_operand:SWI48x 1 "memory_operand" "m")))]
5274 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5276 [(set_attr "type" "fmov")
5277 (set_attr "mode" "<X87MODEF:MODE>")
5278 (set_attr "fp_int_src" "true")])
5281 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5282 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5283 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5285 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5286 && reload_completed"
5287 [(set (match_dup 2) (match_dup 1))
5288 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5291 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5292 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5293 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5295 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5296 && reload_completed"
5297 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5299 ;; Avoid store forwarding (partial memory) stall penalty
5300 ;; by passing DImode value through XMM registers. */
5302 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5303 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5305 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5306 (clobber (match_scratch:V4SI 3 "=X,x"))
5307 (clobber (match_scratch:V4SI 4 "=X,x"))
5308 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5309 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5310 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5311 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5313 [(set_attr "type" "multi")
5314 (set_attr "mode" "<X87MODEF:MODE>")
5315 (set_attr "unit" "i387")
5316 (set_attr "fp_int_src" "true")])
5319 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5320 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5321 (clobber (match_scratch:V4SI 3))
5322 (clobber (match_scratch:V4SI 4))
5323 (clobber (match_operand:DI 2 "memory_operand"))]
5324 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5325 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5326 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5327 && reload_completed"
5328 [(set (match_dup 2) (match_dup 3))
5329 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5331 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5332 Assemble the 64-bit DImode value in an xmm register. */
5333 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5334 gen_rtx_SUBREG (SImode, operands[1], 0)));
5335 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5336 gen_rtx_SUBREG (SImode, operands[1], 4)));
5337 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5340 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5344 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5345 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5346 (clobber (match_scratch:V4SI 3))
5347 (clobber (match_scratch:V4SI 4))
5348 (clobber (match_operand:DI 2 "memory_operand"))]
5349 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5350 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5351 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5352 && reload_completed"
5353 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5355 ;; Avoid store forwarding (partial memory) stall penalty by extending
5356 ;; SImode value to DImode through XMM register instead of pushing two
5357 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5358 ;; targets benefit from this optimization. Also note that fild
5359 ;; loads from memory only.
5361 (define_insn "*floatunssi<mode>2_1"
5362 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5363 (unsigned_float:X87MODEF
5364 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5365 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5366 (clobber (match_scratch:SI 3 "=X,x"))]
5368 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5371 [(set_attr "type" "multi")
5372 (set_attr "mode" "<MODE>")])
5375 [(set (match_operand:X87MODEF 0 "register_operand")
5376 (unsigned_float:X87MODEF
5377 (match_operand:SI 1 "register_operand")))
5378 (clobber (match_operand:DI 2 "memory_operand"))
5379 (clobber (match_scratch:SI 3))]
5381 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5383 && reload_completed"
5384 [(set (match_dup 2) (match_dup 1))
5386 (float:X87MODEF (match_dup 2)))]
5387 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5390 [(set (match_operand:X87MODEF 0 "register_operand")
5391 (unsigned_float:X87MODEF
5392 (match_operand:SI 1 "memory_operand")))
5393 (clobber (match_operand:DI 2 "memory_operand"))
5394 (clobber (match_scratch:SI 3))]
5396 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5398 && reload_completed"
5399 [(set (match_dup 2) (match_dup 3))
5401 (float:X87MODEF (match_dup 2)))]
5403 emit_move_insn (operands[3], operands[1]);
5404 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5407 (define_expand "floatunssi<mode>2"
5409 [(set (match_operand:X87MODEF 0 "register_operand")
5410 (unsigned_float:X87MODEF
5411 (match_operand:SI 1 "nonimmediate_operand")))
5412 (clobber (match_dup 2))
5413 (clobber (match_scratch:SI 3))])]
5415 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5417 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5419 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5421 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5426 enum ix86_stack_slot slot = (virtuals_instantiated
5429 operands[2] = assign_386_stack_local (DImode, slot);
5433 (define_expand "floatunsdisf2"
5434 [(use (match_operand:SF 0 "register_operand"))
5435 (use (match_operand:DI 1 "nonimmediate_operand"))]
5436 "TARGET_64BIT && TARGET_SSE_MATH"
5437 "x86_emit_floatuns (operands); DONE;")
5439 (define_expand "floatunsdidf2"
5440 [(use (match_operand:DF 0 "register_operand"))
5441 (use (match_operand:DI 1 "nonimmediate_operand"))]
5442 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5443 && TARGET_SSE2 && TARGET_SSE_MATH"
5446 x86_emit_floatuns (operands);
5448 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5454 (define_expand "add<mode>3"
5455 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5456 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5457 (match_operand:SDWIM 2 "<general_operand>")))]
5459 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5461 (define_insn_and_split "*add<dwi>3_doubleword"
5462 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5464 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5465 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5466 (clobber (reg:CC FLAGS_REG))]
5467 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5470 [(parallel [(set (reg:CC FLAGS_REG)
5471 (unspec:CC [(match_dup 1) (match_dup 2)]
5474 (plus:DWIH (match_dup 1) (match_dup 2)))])
5475 (parallel [(set (match_dup 3)
5479 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5481 (clobber (reg:CC FLAGS_REG))])]
5482 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5484 (define_insn "*add<mode>3_cc"
5485 [(set (reg:CC FLAGS_REG)
5487 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5488 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5490 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5491 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5492 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5493 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5494 [(set_attr "type" "alu")
5495 (set_attr "mode" "<MODE>")])
5497 (define_insn "addqi3_cc"
5498 [(set (reg:CC FLAGS_REG)
5500 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5501 (match_operand:QI 2 "general_operand" "qn,qm")]
5503 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5504 (plus:QI (match_dup 1) (match_dup 2)))]
5505 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5506 "add{b}\t{%2, %0|%0, %2}"
5507 [(set_attr "type" "alu")
5508 (set_attr "mode" "QI")])
5510 (define_insn_and_split "*lea_1"
5511 [(set (match_operand:SI 0 "register_operand" "=r")
5512 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5514 "lea{l}\t{%E1, %0|%0, %E1}"
5515 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5518 ix86_split_lea_for_addr (operands, SImode);
5521 [(set_attr "type" "lea")
5522 (set_attr "mode" "SI")])
5524 (define_insn_and_split "*lea<mode>_2"
5525 [(set (match_operand:SWI48 0 "register_operand" "=r")
5526 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5528 "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"
5529 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5532 ix86_split_lea_for_addr (operands, <MODE>mode);
5535 [(set_attr "type" "lea")
5536 (set_attr "mode" "<MODE>")])
5538 (define_insn "*lea_3_zext"
5539 [(set (match_operand:DI 0 "register_operand" "=r")
5541 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5543 "lea{l}\t{%E1, %k0|%k0, %E1}"
5544 [(set_attr "type" "lea")
5545 (set_attr "mode" "SI")])
5547 (define_insn "*lea_4_zext"
5548 [(set (match_operand:DI 0 "register_operand" "=r")
5550 (match_operand:SI 1 "lea_address_operand" "j")))]
5552 "lea{l}\t{%E1, %k0|%k0, %E1}"
5553 [(set_attr "type" "lea")
5554 (set_attr "mode" "SI")])
5556 (define_insn "*lea_5_zext"
5557 [(set (match_operand:DI 0 "register_operand" "=r")
5559 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5560 (match_operand:DI 2 "const_32bit_mask" "n")))]
5562 "lea{l}\t{%E1, %k0|%k0, %E1}"
5563 [(set_attr "type" "lea")
5564 (set_attr "mode" "SI")])
5566 (define_insn "*lea_6_zext"
5567 [(set (match_operand:DI 0 "register_operand" "=r")
5569 (match_operand:DI 1 "lea_address_operand" "p")
5570 (match_operand:DI 2 "const_32bit_mask" "n")))]
5572 "lea{l}\t{%E1, %k0|%k0, %E1}"
5573 [(set_attr "type" "lea")
5574 (set_attr "mode" "SI")])
5576 (define_insn "*add<mode>_1"
5577 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5579 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5580 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5581 (clobber (reg:CC FLAGS_REG))]
5582 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5584 switch (get_attr_type (insn))
5590 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5591 if (operands[2] == const1_rtx)
5592 return "inc{<imodesuffix>}\t%0";
5595 gcc_assert (operands[2] == constm1_rtx);
5596 return "dec{<imodesuffix>}\t%0";
5600 /* For most processors, ADD is faster than LEA. This alternative
5601 was added to use ADD as much as possible. */
5602 if (which_alternative == 2)
5605 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5608 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5609 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5610 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5612 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5616 (cond [(eq_attr "alternative" "3")
5617 (const_string "lea")
5618 (match_operand:SWI48 2 "incdec_operand")
5619 (const_string "incdec")
5621 (const_string "alu")))
5622 (set (attr "length_immediate")
5624 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5626 (const_string "*")))
5627 (set_attr "mode" "<MODE>")])
5629 ;; It may seem that nonimmediate operand is proper one for operand 1.
5630 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5631 ;; we take care in ix86_binary_operator_ok to not allow two memory
5632 ;; operands so proper swapping will be done in reload. This allow
5633 ;; patterns constructed from addsi_1 to match.
5635 (define_insn "addsi_1_zext"
5636 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5638 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5639 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5640 (clobber (reg:CC FLAGS_REG))]
5641 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5643 switch (get_attr_type (insn))
5649 if (operands[2] == const1_rtx)
5650 return "inc{l}\t%k0";
5653 gcc_assert (operands[2] == constm1_rtx);
5654 return "dec{l}\t%k0";
5658 /* For most processors, ADD is faster than LEA. This alternative
5659 was added to use ADD as much as possible. */
5660 if (which_alternative == 1)
5663 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5666 if (x86_maybe_negate_const_int (&operands[2], SImode))
5667 return "sub{l}\t{%2, %k0|%k0, %2}";
5669 return "add{l}\t{%2, %k0|%k0, %2}";
5673 (cond [(eq_attr "alternative" "2")
5674 (const_string "lea")
5675 (match_operand:SI 2 "incdec_operand")
5676 (const_string "incdec")
5678 (const_string "alu")))
5679 (set (attr "length_immediate")
5681 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5683 (const_string "*")))
5684 (set_attr "mode" "SI")])
5686 (define_insn "*addhi_1"
5687 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5688 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5689 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5690 (clobber (reg:CC FLAGS_REG))]
5691 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5693 switch (get_attr_type (insn))
5699 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5700 if (operands[2] == const1_rtx)
5701 return "inc{w}\t%0";
5704 gcc_assert (operands[2] == constm1_rtx);
5705 return "dec{w}\t%0";
5709 /* For most processors, ADD is faster than LEA. This alternative
5710 was added to use ADD as much as possible. */
5711 if (which_alternative == 2)
5714 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5717 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5718 if (x86_maybe_negate_const_int (&operands[2], HImode))
5719 return "sub{w}\t{%2, %0|%0, %2}";
5721 return "add{w}\t{%2, %0|%0, %2}";
5725 (cond [(eq_attr "alternative" "3")
5726 (const_string "lea")
5727 (match_operand:HI 2 "incdec_operand")
5728 (const_string "incdec")
5730 (const_string "alu")))
5731 (set (attr "length_immediate")
5733 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5735 (const_string "*")))
5736 (set_attr "mode" "HI,HI,HI,SI")])
5738 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5739 (define_insn "*addqi_1"
5740 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5741 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5742 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5743 (clobber (reg:CC FLAGS_REG))]
5744 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5746 bool widen = (which_alternative == 3 || which_alternative == 4);
5748 switch (get_attr_type (insn))
5754 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5755 if (operands[2] == const1_rtx)
5756 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5759 gcc_assert (operands[2] == constm1_rtx);
5760 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5764 /* For most processors, ADD is faster than LEA. These alternatives
5765 were added to use ADD as much as possible. */
5766 if (which_alternative == 2 || which_alternative == 4)
5769 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5772 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5773 if (x86_maybe_negate_const_int (&operands[2], QImode))
5776 return "sub{l}\t{%2, %k0|%k0, %2}";
5778 return "sub{b}\t{%2, %0|%0, %2}";
5781 return "add{l}\t{%k2, %k0|%k0, %k2}";
5783 return "add{b}\t{%2, %0|%0, %2}";
5787 (cond [(eq_attr "alternative" "5")
5788 (const_string "lea")
5789 (match_operand:QI 2 "incdec_operand")
5790 (const_string "incdec")
5792 (const_string "alu")))
5793 (set (attr "length_immediate")
5795 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5797 (const_string "*")))
5798 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5800 (define_insn "*addqi_1_slp"
5801 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5802 (plus:QI (match_dup 0)
5803 (match_operand:QI 1 "general_operand" "qn,qm")))
5804 (clobber (reg:CC FLAGS_REG))]
5805 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5806 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5808 switch (get_attr_type (insn))
5811 if (operands[1] == const1_rtx)
5812 return "inc{b}\t%0";
5815 gcc_assert (operands[1] == constm1_rtx);
5816 return "dec{b}\t%0";
5820 if (x86_maybe_negate_const_int (&operands[1], QImode))
5821 return "sub{b}\t{%1, %0|%0, %1}";
5823 return "add{b}\t{%1, %0|%0, %1}";
5827 (if_then_else (match_operand:QI 1 "incdec_operand")
5828 (const_string "incdec")
5829 (const_string "alu1")))
5830 (set (attr "memory")
5831 (if_then_else (match_operand 1 "memory_operand")
5832 (const_string "load")
5833 (const_string "none")))
5834 (set_attr "mode" "QI")])
5836 ;; Split non destructive adds if we cannot use lea.
5838 [(set (match_operand:SWI48 0 "register_operand")
5839 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5840 (match_operand:SWI48 2 "nonmemory_operand")))
5841 (clobber (reg:CC FLAGS_REG))]
5842 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5843 [(set (match_dup 0) (match_dup 1))
5844 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5845 (clobber (reg:CC FLAGS_REG))])])
5847 ;; Convert add to the lea pattern to avoid flags dependency.
5849 [(set (match_operand:SWI 0 "register_operand")
5850 (plus:SWI (match_operand:SWI 1 "register_operand")
5851 (match_operand:SWI 2 "<nonmemory_operand>")))
5852 (clobber (reg:CC FLAGS_REG))]
5853 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5856 enum machine_mode mode = <MODE>mode;
5859 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5862 operands[0] = gen_lowpart (mode, operands[0]);
5863 operands[1] = gen_lowpart (mode, operands[1]);
5864 operands[2] = gen_lowpart (mode, operands[2]);
5867 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5869 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5873 ;; Convert add to the lea pattern to avoid flags dependency.
5875 [(set (match_operand:DI 0 "register_operand")
5877 (plus:SI (match_operand:SI 1 "register_operand")
5878 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5879 (clobber (reg:CC FLAGS_REG))]
5880 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5882 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5884 (define_insn "*add<mode>_2"
5885 [(set (reg FLAGS_REG)
5888 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5889 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5891 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5892 (plus:SWI (match_dup 1) (match_dup 2)))]
5893 "ix86_match_ccmode (insn, CCGOCmode)
5894 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5896 switch (get_attr_type (insn))
5899 if (operands[2] == const1_rtx)
5900 return "inc{<imodesuffix>}\t%0";
5903 gcc_assert (operands[2] == constm1_rtx);
5904 return "dec{<imodesuffix>}\t%0";
5908 if (which_alternative == 2)
5911 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5914 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5915 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5916 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5918 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5922 (if_then_else (match_operand:SWI 2 "incdec_operand")
5923 (const_string "incdec")
5924 (const_string "alu")))
5925 (set (attr "length_immediate")
5927 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5929 (const_string "*")))
5930 (set_attr "mode" "<MODE>")])
5932 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5933 (define_insn "*addsi_2_zext"
5934 [(set (reg FLAGS_REG)
5936 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5937 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5939 (set (match_operand:DI 0 "register_operand" "=r,r")
5940 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5941 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5942 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5944 switch (get_attr_type (insn))
5947 if (operands[2] == const1_rtx)
5948 return "inc{l}\t%k0";
5951 gcc_assert (operands[2] == constm1_rtx);
5952 return "dec{l}\t%k0";
5956 if (which_alternative == 1)
5959 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5962 if (x86_maybe_negate_const_int (&operands[2], SImode))
5963 return "sub{l}\t{%2, %k0|%k0, %2}";
5965 return "add{l}\t{%2, %k0|%k0, %2}";
5969 (if_then_else (match_operand:SI 2 "incdec_operand")
5970 (const_string "incdec")
5971 (const_string "alu")))
5972 (set (attr "length_immediate")
5974 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5976 (const_string "*")))
5977 (set_attr "mode" "SI")])
5979 (define_insn "*add<mode>_3"
5980 [(set (reg FLAGS_REG)
5982 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5983 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5984 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5985 "ix86_match_ccmode (insn, CCZmode)
5986 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5988 switch (get_attr_type (insn))
5991 if (operands[2] == const1_rtx)
5992 return "inc{<imodesuffix>}\t%0";
5995 gcc_assert (operands[2] == constm1_rtx);
5996 return "dec{<imodesuffix>}\t%0";
6000 if (which_alternative == 1)
6003 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6006 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6007 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6008 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6010 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6014 (if_then_else (match_operand:SWI 2 "incdec_operand")
6015 (const_string "incdec")
6016 (const_string "alu")))
6017 (set (attr "length_immediate")
6019 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6021 (const_string "*")))
6022 (set_attr "mode" "<MODE>")])
6024 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6025 (define_insn "*addsi_3_zext"
6026 [(set (reg FLAGS_REG)
6028 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6029 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6030 (set (match_operand:DI 0 "register_operand" "=r,r")
6031 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6032 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6033 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6035 switch (get_attr_type (insn))
6038 if (operands[2] == const1_rtx)
6039 return "inc{l}\t%k0";
6042 gcc_assert (operands[2] == constm1_rtx);
6043 return "dec{l}\t%k0";
6047 if (which_alternative == 1)
6050 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6053 if (x86_maybe_negate_const_int (&operands[2], SImode))
6054 return "sub{l}\t{%2, %k0|%k0, %2}";
6056 return "add{l}\t{%2, %k0|%k0, %2}";
6060 (if_then_else (match_operand:SI 2 "incdec_operand")
6061 (const_string "incdec")
6062 (const_string "alu")))
6063 (set (attr "length_immediate")
6065 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6067 (const_string "*")))
6068 (set_attr "mode" "SI")])
6070 ; For comparisons against 1, -1 and 128, we may generate better code
6071 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6072 ; is matched then. We can't accept general immediate, because for
6073 ; case of overflows, the result is messed up.
6074 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6075 ; only for comparisons not depending on it.
6077 (define_insn "*adddi_4"
6078 [(set (reg FLAGS_REG)
6080 (match_operand:DI 1 "nonimmediate_operand" "0")
6081 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6082 (clobber (match_scratch:DI 0 "=rm"))]
6084 && ix86_match_ccmode (insn, CCGCmode)"
6086 switch (get_attr_type (insn))
6089 if (operands[2] == constm1_rtx)
6090 return "inc{q}\t%0";
6093 gcc_assert (operands[2] == const1_rtx);
6094 return "dec{q}\t%0";
6098 if (x86_maybe_negate_const_int (&operands[2], DImode))
6099 return "add{q}\t{%2, %0|%0, %2}";
6101 return "sub{q}\t{%2, %0|%0, %2}";
6105 (if_then_else (match_operand:DI 2 "incdec_operand")
6106 (const_string "incdec")
6107 (const_string "alu")))
6108 (set (attr "length_immediate")
6110 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6112 (const_string "*")))
6113 (set_attr "mode" "DI")])
6115 ; For comparisons against 1, -1 and 128, we may generate better code
6116 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6117 ; is matched then. We can't accept general immediate, because for
6118 ; case of overflows, the result is messed up.
6119 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6120 ; only for comparisons not depending on it.
6122 (define_insn "*add<mode>_4"
6123 [(set (reg FLAGS_REG)
6125 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6126 (match_operand:SWI124 2 "const_int_operand" "n")))
6127 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6128 "ix86_match_ccmode (insn, CCGCmode)"
6130 switch (get_attr_type (insn))
6133 if (operands[2] == constm1_rtx)
6134 return "inc{<imodesuffix>}\t%0";
6137 gcc_assert (operands[2] == const1_rtx);
6138 return "dec{<imodesuffix>}\t%0";
6142 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6143 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6145 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6149 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6150 (const_string "incdec")
6151 (const_string "alu")))
6152 (set (attr "length_immediate")
6154 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6156 (const_string "*")))
6157 (set_attr "mode" "<MODE>")])
6159 (define_insn "*add<mode>_5"
6160 [(set (reg FLAGS_REG)
6163 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6164 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6166 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6167 "ix86_match_ccmode (insn, CCGOCmode)
6168 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6170 switch (get_attr_type (insn))
6173 if (operands[2] == const1_rtx)
6174 return "inc{<imodesuffix>}\t%0";
6177 gcc_assert (operands[2] == constm1_rtx);
6178 return "dec{<imodesuffix>}\t%0";
6182 if (which_alternative == 1)
6185 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6188 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6189 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6190 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6192 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6196 (if_then_else (match_operand:SWI 2 "incdec_operand")
6197 (const_string "incdec")
6198 (const_string "alu")))
6199 (set (attr "length_immediate")
6201 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6203 (const_string "*")))
6204 (set_attr "mode" "<MODE>")])
6206 (define_insn "*addqi_ext_1_rex64"
6207 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6212 (match_operand 1 "ext_register_operand" "0")
6215 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6216 (clobber (reg:CC FLAGS_REG))]
6219 switch (get_attr_type (insn))
6222 if (operands[2] == const1_rtx)
6223 return "inc{b}\t%h0";
6226 gcc_assert (operands[2] == constm1_rtx);
6227 return "dec{b}\t%h0";
6231 return "add{b}\t{%2, %h0|%h0, %2}";
6235 (if_then_else (match_operand:QI 2 "incdec_operand")
6236 (const_string "incdec")
6237 (const_string "alu")))
6238 (set_attr "modrm" "1")
6239 (set_attr "mode" "QI")])
6241 (define_insn "addqi_ext_1"
6242 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6247 (match_operand 1 "ext_register_operand" "0")
6250 (match_operand:QI 2 "general_operand" "Qmn")))
6251 (clobber (reg:CC FLAGS_REG))]
6254 switch (get_attr_type (insn))
6257 if (operands[2] == const1_rtx)
6258 return "inc{b}\t%h0";
6261 gcc_assert (operands[2] == constm1_rtx);
6262 return "dec{b}\t%h0";
6266 return "add{b}\t{%2, %h0|%h0, %2}";
6270 (if_then_else (match_operand:QI 2 "incdec_operand")
6271 (const_string "incdec")
6272 (const_string "alu")))
6273 (set_attr "modrm" "1")
6274 (set_attr "mode" "QI")])
6276 (define_insn "*addqi_ext_2"
6277 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6282 (match_operand 1 "ext_register_operand" "%0")
6286 (match_operand 2 "ext_register_operand" "Q")
6289 (clobber (reg:CC FLAGS_REG))]
6291 "add{b}\t{%h2, %h0|%h0, %h2}"
6292 [(set_attr "type" "alu")
6293 (set_attr "mode" "QI")])
6295 ;; The lea patterns for modes less than 32 bits need to be matched by
6296 ;; several insns converted to real lea by splitters.
6298 (define_insn_and_split "*lea_general_1"
6299 [(set (match_operand 0 "register_operand" "=r")
6300 (plus (plus (match_operand 1 "index_register_operand" "l")
6301 (match_operand 2 "register_operand" "r"))
6302 (match_operand 3 "immediate_operand" "i")))]
6303 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6304 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6305 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6306 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6307 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6308 || GET_MODE (operands[3]) == VOIDmode)"
6310 "&& reload_completed"
6313 enum machine_mode mode = SImode;
6316 operands[0] = gen_lowpart (mode, operands[0]);
6317 operands[1] = gen_lowpart (mode, operands[1]);
6318 operands[2] = gen_lowpart (mode, operands[2]);
6319 operands[3] = gen_lowpart (mode, operands[3]);
6321 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6324 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6327 [(set_attr "type" "lea")
6328 (set_attr "mode" "SI")])
6330 (define_insn_and_split "*lea_general_2"
6331 [(set (match_operand 0 "register_operand" "=r")
6332 (plus (mult (match_operand 1 "index_register_operand" "l")
6333 (match_operand 2 "const248_operand" "n"))
6334 (match_operand 3 "nonmemory_operand" "ri")))]
6335 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6336 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6337 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6338 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6339 || GET_MODE (operands[3]) == VOIDmode)"
6341 "&& reload_completed"
6344 enum machine_mode mode = SImode;
6347 operands[0] = gen_lowpart (mode, operands[0]);
6348 operands[1] = gen_lowpart (mode, operands[1]);
6349 operands[3] = gen_lowpart (mode, operands[3]);
6351 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6354 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6357 [(set_attr "type" "lea")
6358 (set_attr "mode" "SI")])
6360 (define_insn_and_split "*lea_general_3"
6361 [(set (match_operand 0 "register_operand" "=r")
6362 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6363 (match_operand 2 "const248_operand" "n"))
6364 (match_operand 3 "register_operand" "r"))
6365 (match_operand 4 "immediate_operand" "i")))]
6366 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6367 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6368 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6369 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6371 "&& reload_completed"
6374 enum machine_mode mode = SImode;
6377 operands[0] = gen_lowpart (mode, operands[0]);
6378 operands[1] = gen_lowpart (mode, operands[1]);
6379 operands[3] = gen_lowpart (mode, operands[3]);
6380 operands[4] = gen_lowpart (mode, operands[4]);
6382 pat = gen_rtx_PLUS (mode,
6384 gen_rtx_MULT (mode, operands[1],
6389 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6392 [(set_attr "type" "lea")
6393 (set_attr "mode" "SI")])
6395 (define_insn_and_split "*lea_general_4"
6396 [(set (match_operand 0 "register_operand" "=r")
6398 (match_operand 1 "index_register_operand" "l")
6399 (match_operand 2 "const_int_operand" "n"))
6400 (match_operand 3 "const_int_operand" "n")))]
6401 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6402 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6403 || GET_MODE (operands[0]) == SImode
6404 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6405 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6406 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6407 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6408 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6410 "&& reload_completed"
6413 enum machine_mode mode = GET_MODE (operands[0]);
6416 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6419 operands[0] = gen_lowpart (mode, operands[0]);
6420 operands[1] = gen_lowpart (mode, operands[1]);
6423 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6425 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6426 INTVAL (operands[3]));
6428 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6431 [(set_attr "type" "lea")
6433 (if_then_else (match_operand:DI 0)
6435 (const_string "SI")))])
6437 ;; Subtract instructions
6439 (define_expand "sub<mode>3"
6440 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6441 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6442 (match_operand:SDWIM 2 "<general_operand>")))]
6444 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6446 (define_insn_and_split "*sub<dwi>3_doubleword"
6447 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6449 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6450 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6451 (clobber (reg:CC FLAGS_REG))]
6452 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6455 [(parallel [(set (reg:CC FLAGS_REG)
6456 (compare:CC (match_dup 1) (match_dup 2)))
6458 (minus:DWIH (match_dup 1) (match_dup 2)))])
6459 (parallel [(set (match_dup 3)
6463 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6465 (clobber (reg:CC FLAGS_REG))])]
6466 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6468 (define_insn "*sub<mode>_1"
6469 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6471 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6472 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6473 (clobber (reg:CC FLAGS_REG))]
6474 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6475 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6476 [(set_attr "type" "alu")
6477 (set_attr "mode" "<MODE>")])
6479 (define_insn "*subsi_1_zext"
6480 [(set (match_operand:DI 0 "register_operand" "=r")
6482 (minus:SI (match_operand:SI 1 "register_operand" "0")
6483 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6484 (clobber (reg:CC FLAGS_REG))]
6485 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6486 "sub{l}\t{%2, %k0|%k0, %2}"
6487 [(set_attr "type" "alu")
6488 (set_attr "mode" "SI")])
6490 (define_insn "*subqi_1_slp"
6491 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6492 (minus:QI (match_dup 0)
6493 (match_operand:QI 1 "general_operand" "qn,qm")))
6494 (clobber (reg:CC FLAGS_REG))]
6495 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6496 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6497 "sub{b}\t{%1, %0|%0, %1}"
6498 [(set_attr "type" "alu1")
6499 (set_attr "mode" "QI")])
6501 (define_insn "*sub<mode>_2"
6502 [(set (reg FLAGS_REG)
6505 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6506 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6508 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6509 (minus:SWI (match_dup 1) (match_dup 2)))]
6510 "ix86_match_ccmode (insn, CCGOCmode)
6511 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6512 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6513 [(set_attr "type" "alu")
6514 (set_attr "mode" "<MODE>")])
6516 (define_insn "*subsi_2_zext"
6517 [(set (reg FLAGS_REG)
6519 (minus:SI (match_operand:SI 1 "register_operand" "0")
6520 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6522 (set (match_operand:DI 0 "register_operand" "=r")
6524 (minus:SI (match_dup 1)
6526 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6527 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6528 "sub{l}\t{%2, %k0|%k0, %2}"
6529 [(set_attr "type" "alu")
6530 (set_attr "mode" "SI")])
6532 (define_insn "*sub<mode>_3"
6533 [(set (reg FLAGS_REG)
6534 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6535 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6536 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6537 (minus:SWI (match_dup 1) (match_dup 2)))]
6538 "ix86_match_ccmode (insn, CCmode)
6539 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6540 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6541 [(set_attr "type" "alu")
6542 (set_attr "mode" "<MODE>")])
6544 (define_insn "*subsi_3_zext"
6545 [(set (reg FLAGS_REG)
6546 (compare (match_operand:SI 1 "register_operand" "0")
6547 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6548 (set (match_operand:DI 0 "register_operand" "=r")
6550 (minus:SI (match_dup 1)
6552 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6553 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6554 "sub{l}\t{%2, %1|%1, %2}"
6555 [(set_attr "type" "alu")
6556 (set_attr "mode" "SI")])
6558 ;; Add with carry and subtract with borrow
6560 (define_expand "<plusminus_insn><mode>3_carry"
6562 [(set (match_operand:SWI 0 "nonimmediate_operand")
6564 (match_operand:SWI 1 "nonimmediate_operand")
6565 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6566 [(match_operand 3 "flags_reg_operand")
6568 (match_operand:SWI 2 "<general_operand>"))))
6569 (clobber (reg:CC FLAGS_REG))])]
6570 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6572 (define_insn "*<plusminus_insn><mode>3_carry"
6573 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6575 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6577 (match_operator 3 "ix86_carry_flag_operator"
6578 [(reg FLAGS_REG) (const_int 0)])
6579 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6580 (clobber (reg:CC FLAGS_REG))]
6581 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6582 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6583 [(set_attr "type" "alu")
6584 (set_attr "use_carry" "1")
6585 (set_attr "pent_pair" "pu")
6586 (set_attr "mode" "<MODE>")])
6588 (define_insn "*addsi3_carry_zext"
6589 [(set (match_operand:DI 0 "register_operand" "=r")
6591 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6592 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6593 [(reg FLAGS_REG) (const_int 0)])
6594 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6595 (clobber (reg:CC FLAGS_REG))]
6596 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6597 "adc{l}\t{%2, %k0|%k0, %2}"
6598 [(set_attr "type" "alu")
6599 (set_attr "use_carry" "1")
6600 (set_attr "pent_pair" "pu")
6601 (set_attr "mode" "SI")])
6603 (define_insn "*subsi3_carry_zext"
6604 [(set (match_operand:DI 0 "register_operand" "=r")
6606 (minus:SI (match_operand:SI 1 "register_operand" "0")
6607 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6608 [(reg FLAGS_REG) (const_int 0)])
6609 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6610 (clobber (reg:CC FLAGS_REG))]
6611 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6612 "sbb{l}\t{%2, %k0|%k0, %2}"
6613 [(set_attr "type" "alu")
6614 (set_attr "pent_pair" "pu")
6615 (set_attr "mode" "SI")])
6617 ;; Overflow setting add and subtract instructions
6619 (define_insn "*add<mode>3_cconly_overflow"
6620 [(set (reg:CCC FLAGS_REG)
6623 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6624 (match_operand:SWI 2 "<general_operand>" "<g>"))
6626 (clobber (match_scratch:SWI 0 "=<r>"))]
6627 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6628 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6629 [(set_attr "type" "alu")
6630 (set_attr "mode" "<MODE>")])
6632 (define_insn "*sub<mode>3_cconly_overflow"
6633 [(set (reg:CCC FLAGS_REG)
6636 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6637 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6640 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6641 [(set_attr "type" "icmp")
6642 (set_attr "mode" "<MODE>")])
6644 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6645 [(set (reg:CCC FLAGS_REG)
6648 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6649 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6651 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6652 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6653 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6654 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6655 [(set_attr "type" "alu")
6656 (set_attr "mode" "<MODE>")])
6658 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6659 [(set (reg:CCC FLAGS_REG)
6662 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6663 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6665 (set (match_operand:DI 0 "register_operand" "=r")
6666 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6667 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6668 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6669 [(set_attr "type" "alu")
6670 (set_attr "mode" "SI")])
6672 ;; The patterns that match these are at the end of this file.
6674 (define_expand "<plusminus_insn>xf3"
6675 [(set (match_operand:XF 0 "register_operand")
6677 (match_operand:XF 1 "register_operand")
6678 (match_operand:XF 2 "register_operand")))]
6681 (define_expand "<plusminus_insn><mode>3"
6682 [(set (match_operand:MODEF 0 "register_operand")
6684 (match_operand:MODEF 1 "register_operand")
6685 (match_operand:MODEF 2 "nonimmediate_operand")))]
6686 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6687 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6689 ;; Multiply instructions
6691 (define_expand "mul<mode>3"
6692 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6694 (match_operand:SWIM248 1 "register_operand")
6695 (match_operand:SWIM248 2 "<general_operand>")))
6696 (clobber (reg:CC FLAGS_REG))])])
6698 (define_expand "mulqi3"
6699 [(parallel [(set (match_operand:QI 0 "register_operand")
6701 (match_operand:QI 1 "register_operand")
6702 (match_operand:QI 2 "nonimmediate_operand")))
6703 (clobber (reg:CC FLAGS_REG))])]
6704 "TARGET_QIMODE_MATH")
6707 ;; IMUL reg32/64, reg32/64, imm8 Direct
6708 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6709 ;; IMUL reg32/64, reg32/64, imm32 Direct
6710 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6711 ;; IMUL reg32/64, reg32/64 Direct
6712 ;; IMUL reg32/64, mem32/64 Direct
6714 ;; On BDVER1, all above IMULs use DirectPath
6716 (define_insn "*mul<mode>3_1"
6717 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6719 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6720 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6721 (clobber (reg:CC FLAGS_REG))]
6722 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6724 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6725 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6726 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6727 [(set_attr "type" "imul")
6728 (set_attr "prefix_0f" "0,0,1")
6729 (set (attr "athlon_decode")
6730 (cond [(eq_attr "cpu" "athlon")
6731 (const_string "vector")
6732 (eq_attr "alternative" "1")
6733 (const_string "vector")
6734 (and (eq_attr "alternative" "2")
6735 (match_operand 1 "memory_operand"))
6736 (const_string "vector")]
6737 (const_string "direct")))
6738 (set (attr "amdfam10_decode")
6739 (cond [(and (eq_attr "alternative" "0,1")
6740 (match_operand 1 "memory_operand"))
6741 (const_string "vector")]
6742 (const_string "direct")))
6743 (set_attr "bdver1_decode" "direct")
6744 (set_attr "mode" "<MODE>")])
6746 (define_insn "*mulsi3_1_zext"
6747 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6749 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6750 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6751 (clobber (reg:CC FLAGS_REG))]
6753 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6755 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6756 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6757 imul{l}\t{%2, %k0|%k0, %2}"
6758 [(set_attr "type" "imul")
6759 (set_attr "prefix_0f" "0,0,1")
6760 (set (attr "athlon_decode")
6761 (cond [(eq_attr "cpu" "athlon")
6762 (const_string "vector")
6763 (eq_attr "alternative" "1")
6764 (const_string "vector")
6765 (and (eq_attr "alternative" "2")
6766 (match_operand 1 "memory_operand"))
6767 (const_string "vector")]
6768 (const_string "direct")))
6769 (set (attr "amdfam10_decode")
6770 (cond [(and (eq_attr "alternative" "0,1")
6771 (match_operand 1 "memory_operand"))
6772 (const_string "vector")]
6773 (const_string "direct")))
6774 (set_attr "bdver1_decode" "direct")
6775 (set_attr "mode" "SI")])
6778 ;; IMUL reg16, reg16, imm8 VectorPath
6779 ;; IMUL reg16, mem16, imm8 VectorPath
6780 ;; IMUL reg16, reg16, imm16 VectorPath
6781 ;; IMUL reg16, mem16, imm16 VectorPath
6782 ;; IMUL reg16, reg16 Direct
6783 ;; IMUL reg16, mem16 Direct
6785 ;; On BDVER1, all HI MULs use DoublePath
6787 (define_insn "*mulhi3_1"
6788 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6789 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6790 (match_operand:HI 2 "general_operand" "K,n,mr")))
6791 (clobber (reg:CC FLAGS_REG))]
6793 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6795 imul{w}\t{%2, %1, %0|%0, %1, %2}
6796 imul{w}\t{%2, %1, %0|%0, %1, %2}
6797 imul{w}\t{%2, %0|%0, %2}"
6798 [(set_attr "type" "imul")
6799 (set_attr "prefix_0f" "0,0,1")
6800 (set (attr "athlon_decode")
6801 (cond [(eq_attr "cpu" "athlon")
6802 (const_string "vector")
6803 (eq_attr "alternative" "1,2")
6804 (const_string "vector")]
6805 (const_string "direct")))
6806 (set (attr "amdfam10_decode")
6807 (cond [(eq_attr "alternative" "0,1")
6808 (const_string "vector")]
6809 (const_string "direct")))
6810 (set_attr "bdver1_decode" "double")
6811 (set_attr "mode" "HI")])
6813 ;;On AMDFAM10 and BDVER1
6817 (define_insn "*mulqi3_1"
6818 [(set (match_operand:QI 0 "register_operand" "=a")
6819 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6820 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6821 (clobber (reg:CC FLAGS_REG))]
6823 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6825 [(set_attr "type" "imul")
6826 (set_attr "length_immediate" "0")
6827 (set (attr "athlon_decode")
6828 (if_then_else (eq_attr "cpu" "athlon")
6829 (const_string "vector")
6830 (const_string "direct")))
6831 (set_attr "amdfam10_decode" "direct")
6832 (set_attr "bdver1_decode" "direct")
6833 (set_attr "mode" "QI")])
6835 (define_expand "<u>mul<mode><dwi>3"
6836 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6839 (match_operand:DWIH 1 "nonimmediate_operand"))
6841 (match_operand:DWIH 2 "register_operand"))))
6842 (clobber (reg:CC FLAGS_REG))])])
6844 (define_expand "<u>mulqihi3"
6845 [(parallel [(set (match_operand:HI 0 "register_operand")
6848 (match_operand:QI 1 "nonimmediate_operand"))
6850 (match_operand:QI 2 "register_operand"))))
6851 (clobber (reg:CC FLAGS_REG))])]
6852 "TARGET_QIMODE_MATH")
6854 (define_insn "*bmi2_umulditi3_1"
6855 [(set (match_operand:DI 0 "register_operand" "=r")
6857 (match_operand:DI 2 "nonimmediate_operand" "%d")
6858 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6859 (set (match_operand:DI 1 "register_operand" "=r")
6862 (mult:TI (zero_extend:TI (match_dup 2))
6863 (zero_extend:TI (match_dup 3)))
6865 "TARGET_64BIT && TARGET_BMI2
6866 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6867 "mulx\t{%3, %0, %1|%1, %0, %3}"
6868 [(set_attr "type" "imulx")
6869 (set_attr "prefix" "vex")
6870 (set_attr "mode" "DI")])
6872 (define_insn "*bmi2_umulsidi3_1"
6873 [(set (match_operand:SI 0 "register_operand" "=r")
6875 (match_operand:SI 2 "nonimmediate_operand" "%d")
6876 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6877 (set (match_operand:SI 1 "register_operand" "=r")
6880 (mult:DI (zero_extend:DI (match_dup 2))
6881 (zero_extend:DI (match_dup 3)))
6883 "!TARGET_64BIT && TARGET_BMI2
6884 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6885 "mulx\t{%3, %0, %1|%1, %0, %3}"
6886 [(set_attr "type" "imulx")
6887 (set_attr "prefix" "vex")
6888 (set_attr "mode" "SI")])
6890 (define_insn "*umul<mode><dwi>3_1"
6891 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6894 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6896 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6897 (clobber (reg:CC FLAGS_REG))]
6898 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6901 mul{<imodesuffix>}\t%2"
6902 [(set_attr "isa" "bmi2,*")
6903 (set_attr "type" "imulx,imul")
6904 (set_attr "length_immediate" "*,0")
6905 (set (attr "athlon_decode")
6906 (cond [(eq_attr "alternative" "1")
6907 (if_then_else (eq_attr "cpu" "athlon")
6908 (const_string "vector")
6909 (const_string "double"))]
6910 (const_string "*")))
6911 (set_attr "amdfam10_decode" "*,double")
6912 (set_attr "bdver1_decode" "*,direct")
6913 (set_attr "prefix" "vex,orig")
6914 (set_attr "mode" "<MODE>")])
6916 ;; Convert mul to the mulx pattern to avoid flags dependency.
6918 [(set (match_operand:<DWI> 0 "register_operand")
6921 (match_operand:DWIH 1 "register_operand"))
6923 (match_operand:DWIH 2 "nonimmediate_operand"))))
6924 (clobber (reg:CC FLAGS_REG))]
6925 "TARGET_BMI2 && reload_completed
6926 && true_regnum (operands[1]) == DX_REG"
6927 [(parallel [(set (match_dup 3)
6928 (mult:DWIH (match_dup 1) (match_dup 2)))
6932 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6933 (zero_extend:<DWI> (match_dup 2)))
6936 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6938 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6941 (define_insn "*mul<mode><dwi>3_1"
6942 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6945 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6947 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6948 (clobber (reg:CC FLAGS_REG))]
6949 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6950 "imul{<imodesuffix>}\t%2"
6951 [(set_attr "type" "imul")
6952 (set_attr "length_immediate" "0")
6953 (set (attr "athlon_decode")
6954 (if_then_else (eq_attr "cpu" "athlon")
6955 (const_string "vector")
6956 (const_string "double")))
6957 (set_attr "amdfam10_decode" "double")
6958 (set_attr "bdver1_decode" "direct")
6959 (set_attr "mode" "<MODE>")])
6961 (define_insn "*<u>mulqihi3_1"
6962 [(set (match_operand:HI 0 "register_operand" "=a")
6965 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6967 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6968 (clobber (reg:CC FLAGS_REG))]
6970 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6971 "<sgnprefix>mul{b}\t%2"
6972 [(set_attr "type" "imul")
6973 (set_attr "length_immediate" "0")
6974 (set (attr "athlon_decode")
6975 (if_then_else (eq_attr "cpu" "athlon")
6976 (const_string "vector")
6977 (const_string "direct")))
6978 (set_attr "amdfam10_decode" "direct")
6979 (set_attr "bdver1_decode" "direct")
6980 (set_attr "mode" "QI")])
6982 (define_expand "<s>mul<mode>3_highpart"
6983 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6988 (match_operand:SWI48 1 "nonimmediate_operand"))
6990 (match_operand:SWI48 2 "register_operand")))
6992 (clobber (match_scratch:SWI48 3))
6993 (clobber (reg:CC FLAGS_REG))])]
6995 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6997 (define_insn "*<s>muldi3_highpart_1"
6998 [(set (match_operand:DI 0 "register_operand" "=d")
7003 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7005 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7007 (clobber (match_scratch:DI 3 "=1"))
7008 (clobber (reg:CC FLAGS_REG))]
7010 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7011 "<sgnprefix>mul{q}\t%2"
7012 [(set_attr "type" "imul")
7013 (set_attr "length_immediate" "0")
7014 (set (attr "athlon_decode")
7015 (if_then_else (eq_attr "cpu" "athlon")
7016 (const_string "vector")
7017 (const_string "double")))
7018 (set_attr "amdfam10_decode" "double")
7019 (set_attr "bdver1_decode" "direct")
7020 (set_attr "mode" "DI")])
7022 (define_insn "*<s>mulsi3_highpart_1"
7023 [(set (match_operand:SI 0 "register_operand" "=d")
7028 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7030 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7032 (clobber (match_scratch:SI 3 "=1"))
7033 (clobber (reg:CC FLAGS_REG))]
7034 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7035 "<sgnprefix>mul{l}\t%2"
7036 [(set_attr "type" "imul")
7037 (set_attr "length_immediate" "0")
7038 (set (attr "athlon_decode")
7039 (if_then_else (eq_attr "cpu" "athlon")
7040 (const_string "vector")
7041 (const_string "double")))
7042 (set_attr "amdfam10_decode" "double")
7043 (set_attr "bdver1_decode" "direct")
7044 (set_attr "mode" "SI")])
7046 (define_insn "*<s>mulsi3_highpart_zext"
7047 [(set (match_operand:DI 0 "register_operand" "=d")
7048 (zero_extend:DI (truncate:SI
7050 (mult:DI (any_extend:DI
7051 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7053 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7055 (clobber (match_scratch:SI 3 "=1"))
7056 (clobber (reg:CC FLAGS_REG))]
7058 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7059 "<sgnprefix>mul{l}\t%2"
7060 [(set_attr "type" "imul")
7061 (set_attr "length_immediate" "0")
7062 (set (attr "athlon_decode")
7063 (if_then_else (eq_attr "cpu" "athlon")
7064 (const_string "vector")
7065 (const_string "double")))
7066 (set_attr "amdfam10_decode" "double")
7067 (set_attr "bdver1_decode" "direct")
7068 (set_attr "mode" "SI")])
7070 ;; The patterns that match these are at the end of this file.
7072 (define_expand "mulxf3"
7073 [(set (match_operand:XF 0 "register_operand")
7074 (mult:XF (match_operand:XF 1 "register_operand")
7075 (match_operand:XF 2 "register_operand")))]
7078 (define_expand "mul<mode>3"
7079 [(set (match_operand:MODEF 0 "register_operand")
7080 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7081 (match_operand:MODEF 2 "nonimmediate_operand")))]
7082 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7083 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7085 ;; Divide instructions
7087 ;; The patterns that match these are at the end of this file.
7089 (define_expand "divxf3"
7090 [(set (match_operand:XF 0 "register_operand")
7091 (div:XF (match_operand:XF 1 "register_operand")
7092 (match_operand:XF 2 "register_operand")))]
7095 (define_expand "divdf3"
7096 [(set (match_operand:DF 0 "register_operand")
7097 (div:DF (match_operand:DF 1 "register_operand")
7098 (match_operand:DF 2 "nonimmediate_operand")))]
7099 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7100 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7102 (define_expand "divsf3"
7103 [(set (match_operand:SF 0 "register_operand")
7104 (div:SF (match_operand:SF 1 "register_operand")
7105 (match_operand:SF 2 "nonimmediate_operand")))]
7106 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7111 && optimize_insn_for_speed_p ()
7112 && flag_finite_math_only && !flag_trapping_math
7113 && flag_unsafe_math_optimizations)
7115 ix86_emit_swdivsf (operands[0], operands[1],
7116 operands[2], SFmode);
7121 ;; Divmod instructions.
7123 (define_expand "divmod<mode>4"
7124 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7126 (match_operand:SWIM248 1 "register_operand")
7127 (match_operand:SWIM248 2 "nonimmediate_operand")))
7128 (set (match_operand:SWIM248 3 "register_operand")
7129 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7130 (clobber (reg:CC FLAGS_REG))])])
7132 ;; Split with 8bit unsigned divide:
7133 ;; if (dividend an divisor are in [0-255])
7134 ;; use 8bit unsigned integer divide
7136 ;; use original integer divide
7138 [(set (match_operand:SWI48 0 "register_operand")
7139 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7140 (match_operand:SWI48 3 "nonimmediate_operand")))
7141 (set (match_operand:SWI48 1 "register_operand")
7142 (mod:SWI48 (match_dup 2) (match_dup 3)))
7143 (clobber (reg:CC FLAGS_REG))]
7144 "TARGET_USE_8BIT_IDIV
7145 && TARGET_QIMODE_MATH
7146 && can_create_pseudo_p ()
7147 && !optimize_insn_for_size_p ()"
7149 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7151 (define_insn_and_split "divmod<mode>4_1"
7152 [(set (match_operand:SWI48 0 "register_operand" "=a")
7153 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7154 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7155 (set (match_operand:SWI48 1 "register_operand" "=&d")
7156 (mod:SWI48 (match_dup 2) (match_dup 3)))
7157 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7158 (clobber (reg:CC FLAGS_REG))]
7162 [(parallel [(set (match_dup 1)
7163 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7164 (clobber (reg:CC FLAGS_REG))])
7165 (parallel [(set (match_dup 0)
7166 (div:SWI48 (match_dup 2) (match_dup 3)))
7168 (mod:SWI48 (match_dup 2) (match_dup 3)))
7170 (clobber (reg:CC FLAGS_REG))])]
7172 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7174 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7175 operands[4] = operands[2];
7178 /* Avoid use of cltd in favor of a mov+shift. */
7179 emit_move_insn (operands[1], operands[2]);
7180 operands[4] = operands[1];
7183 [(set_attr "type" "multi")
7184 (set_attr "mode" "<MODE>")])
7186 (define_insn_and_split "*divmod<mode>4"
7187 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7188 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7189 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7190 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7191 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7192 (clobber (reg:CC FLAGS_REG))]
7196 [(parallel [(set (match_dup 1)
7197 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7198 (clobber (reg:CC FLAGS_REG))])
7199 (parallel [(set (match_dup 0)
7200 (div:SWIM248 (match_dup 2) (match_dup 3)))
7202 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7204 (clobber (reg:CC FLAGS_REG))])]
7206 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7208 if (<MODE>mode != HImode
7209 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7210 operands[4] = operands[2];
7213 /* Avoid use of cltd in favor of a mov+shift. */
7214 emit_move_insn (operands[1], operands[2]);
7215 operands[4] = operands[1];
7218 [(set_attr "type" "multi")
7219 (set_attr "mode" "<MODE>")])
7221 (define_insn "*divmod<mode>4_noext"
7222 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7223 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7224 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7225 (set (match_operand:SWIM248 1 "register_operand" "=d")
7226 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7227 (use (match_operand:SWIM248 4 "register_operand" "1"))
7228 (clobber (reg:CC FLAGS_REG))]
7230 "idiv{<imodesuffix>}\t%3"
7231 [(set_attr "type" "idiv")
7232 (set_attr "mode" "<MODE>")])
7234 (define_expand "divmodqi4"
7235 [(parallel [(set (match_operand:QI 0 "register_operand")
7237 (match_operand:QI 1 "register_operand")
7238 (match_operand:QI 2 "nonimmediate_operand")))
7239 (set (match_operand:QI 3 "register_operand")
7240 (mod:QI (match_dup 1) (match_dup 2)))
7241 (clobber (reg:CC FLAGS_REG))])]
7242 "TARGET_QIMODE_MATH"
7247 tmp0 = gen_reg_rtx (HImode);
7248 tmp1 = gen_reg_rtx (HImode);
7250 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7252 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7253 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7255 /* Extract remainder from AH. */
7256 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7257 insn = emit_move_insn (operands[3], tmp1);
7259 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7260 set_unique_reg_note (insn, REG_EQUAL, mod);
7262 /* Extract quotient from AL. */
7263 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7265 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7266 set_unique_reg_note (insn, REG_EQUAL, div);
7271 ;; Divide AX by r/m8, with result stored in
7274 ;; Change div/mod to HImode and extend the second argument to HImode
7275 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7276 ;; combine may fail.
7277 (define_insn "divmodhiqi3"
7278 [(set (match_operand:HI 0 "register_operand" "=a")
7283 (mod:HI (match_operand:HI 1 "register_operand" "0")
7285 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7289 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7290 (clobber (reg:CC FLAGS_REG))]
7291 "TARGET_QIMODE_MATH"
7293 [(set_attr "type" "idiv")
7294 (set_attr "mode" "QI")])
7296 (define_expand "udivmod<mode>4"
7297 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7299 (match_operand:SWIM248 1 "register_operand")
7300 (match_operand:SWIM248 2 "nonimmediate_operand")))
7301 (set (match_operand:SWIM248 3 "register_operand")
7302 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7303 (clobber (reg:CC FLAGS_REG))])])
7305 ;; Split with 8bit unsigned divide:
7306 ;; if (dividend an divisor are in [0-255])
7307 ;; use 8bit unsigned integer divide
7309 ;; use original integer divide
7311 [(set (match_operand:SWI48 0 "register_operand")
7312 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7313 (match_operand:SWI48 3 "nonimmediate_operand")))
7314 (set (match_operand:SWI48 1 "register_operand")
7315 (umod:SWI48 (match_dup 2) (match_dup 3)))
7316 (clobber (reg:CC FLAGS_REG))]
7317 "TARGET_USE_8BIT_IDIV
7318 && TARGET_QIMODE_MATH
7319 && can_create_pseudo_p ()
7320 && !optimize_insn_for_size_p ()"
7322 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7324 (define_insn_and_split "udivmod<mode>4_1"
7325 [(set (match_operand:SWI48 0 "register_operand" "=a")
7326 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7327 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7328 (set (match_operand:SWI48 1 "register_operand" "=&d")
7329 (umod:SWI48 (match_dup 2) (match_dup 3)))
7330 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7331 (clobber (reg:CC FLAGS_REG))]
7335 [(set (match_dup 1) (const_int 0))
7336 (parallel [(set (match_dup 0)
7337 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7339 (umod:SWI48 (match_dup 2) (match_dup 3)))
7341 (clobber (reg:CC FLAGS_REG))])]
7343 [(set_attr "type" "multi")
7344 (set_attr "mode" "<MODE>")])
7346 (define_insn_and_split "*udivmod<mode>4"
7347 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7348 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7349 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7350 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7351 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7352 (clobber (reg:CC FLAGS_REG))]
7356 [(set (match_dup 1) (const_int 0))
7357 (parallel [(set (match_dup 0)
7358 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7360 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7362 (clobber (reg:CC FLAGS_REG))])]
7364 [(set_attr "type" "multi")
7365 (set_attr "mode" "<MODE>")])
7367 (define_insn "*udivmod<mode>4_noext"
7368 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7369 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7370 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7371 (set (match_operand:SWIM248 1 "register_operand" "=d")
7372 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7373 (use (match_operand:SWIM248 4 "register_operand" "1"))
7374 (clobber (reg:CC FLAGS_REG))]
7376 "div{<imodesuffix>}\t%3"
7377 [(set_attr "type" "idiv")
7378 (set_attr "mode" "<MODE>")])
7380 (define_expand "udivmodqi4"
7381 [(parallel [(set (match_operand:QI 0 "register_operand")
7383 (match_operand:QI 1 "register_operand")
7384 (match_operand:QI 2 "nonimmediate_operand")))
7385 (set (match_operand:QI 3 "register_operand")
7386 (umod:QI (match_dup 1) (match_dup 2)))
7387 (clobber (reg:CC FLAGS_REG))])]
7388 "TARGET_QIMODE_MATH"
7393 tmp0 = gen_reg_rtx (HImode);
7394 tmp1 = gen_reg_rtx (HImode);
7396 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7398 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7399 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7401 /* Extract remainder from AH. */
7402 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7403 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7404 insn = emit_move_insn (operands[3], tmp1);
7406 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7407 set_unique_reg_note (insn, REG_EQUAL, mod);
7409 /* Extract quotient from AL. */
7410 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7412 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7413 set_unique_reg_note (insn, REG_EQUAL, div);
7418 (define_insn "udivmodhiqi3"
7419 [(set (match_operand:HI 0 "register_operand" "=a")
7424 (mod:HI (match_operand:HI 1 "register_operand" "0")
7426 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7430 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7431 (clobber (reg:CC FLAGS_REG))]
7432 "TARGET_QIMODE_MATH"
7434 [(set_attr "type" "idiv")
7435 (set_attr "mode" "QI")])
7437 ;; We cannot use div/idiv for double division, because it causes
7438 ;; "division by zero" on the overflow and that's not what we expect
7439 ;; from truncate. Because true (non truncating) double division is
7440 ;; never generated, we can't create this insn anyway.
7443 ; [(set (match_operand:SI 0 "register_operand" "=a")
7445 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7447 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7448 ; (set (match_operand:SI 3 "register_operand" "=d")
7450 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7451 ; (clobber (reg:CC FLAGS_REG))]
7453 ; "div{l}\t{%2, %0|%0, %2}"
7454 ; [(set_attr "type" "idiv")])
7456 ;;- Logical AND instructions
7458 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7459 ;; Note that this excludes ah.
7461 (define_expand "testsi_ccno_1"
7462 [(set (reg:CCNO FLAGS_REG)
7464 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7465 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7468 (define_expand "testqi_ccz_1"
7469 [(set (reg:CCZ FLAGS_REG)
7470 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7471 (match_operand:QI 1 "nonmemory_operand"))
7474 (define_expand "testdi_ccno_1"
7475 [(set (reg:CCNO FLAGS_REG)
7477 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7478 (match_operand:DI 1 "x86_64_szext_general_operand"))
7480 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7482 (define_insn "*testdi_1"
7483 [(set (reg FLAGS_REG)
7486 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7487 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7489 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7490 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7492 test{l}\t{%k1, %k0|%k0, %k1}
7493 test{l}\t{%k1, %k0|%k0, %k1}
7494 test{q}\t{%1, %0|%0, %1}
7495 test{q}\t{%1, %0|%0, %1}
7496 test{q}\t{%1, %0|%0, %1}"
7497 [(set_attr "type" "test")
7498 (set_attr "modrm" "0,1,0,1,1")
7499 (set_attr "mode" "SI,SI,DI,DI,DI")])
7501 (define_insn "*testqi_1_maybe_si"
7502 [(set (reg FLAGS_REG)
7505 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7506 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7508 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7509 && ix86_match_ccmode (insn,
7510 CONST_INT_P (operands[1])
7511 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7513 if (which_alternative == 3)
7515 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7516 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7517 return "test{l}\t{%1, %k0|%k0, %1}";
7519 return "test{b}\t{%1, %0|%0, %1}";
7521 [(set_attr "type" "test")
7522 (set_attr "modrm" "0,1,1,1")
7523 (set_attr "mode" "QI,QI,QI,SI")
7524 (set_attr "pent_pair" "uv,np,uv,np")])
7526 (define_insn "*test<mode>_1"
7527 [(set (reg FLAGS_REG)
7530 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7531 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7533 "ix86_match_ccmode (insn, CCNOmode)
7534 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7535 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7536 [(set_attr "type" "test")
7537 (set_attr "modrm" "0,1,1")
7538 (set_attr "mode" "<MODE>")
7539 (set_attr "pent_pair" "uv,np,uv")])
7541 (define_expand "testqi_ext_ccno_0"
7542 [(set (reg:CCNO FLAGS_REG)
7546 (match_operand 0 "ext_register_operand")
7549 (match_operand 1 "const_int_operand"))
7552 (define_insn "*testqi_ext_0"
7553 [(set (reg FLAGS_REG)
7557 (match_operand 0 "ext_register_operand" "Q")
7560 (match_operand 1 "const_int_operand" "n"))
7562 "ix86_match_ccmode (insn, CCNOmode)"
7563 "test{b}\t{%1, %h0|%h0, %1}"
7564 [(set_attr "type" "test")
7565 (set_attr "mode" "QI")
7566 (set_attr "length_immediate" "1")
7567 (set_attr "modrm" "1")
7568 (set_attr "pent_pair" "np")])
7570 (define_insn "*testqi_ext_1_rex64"
7571 [(set (reg FLAGS_REG)
7575 (match_operand 0 "ext_register_operand" "Q")
7579 (match_operand:QI 1 "register_operand" "Q")))
7581 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7582 "test{b}\t{%1, %h0|%h0, %1}"
7583 [(set_attr "type" "test")
7584 (set_attr "mode" "QI")])
7586 (define_insn "*testqi_ext_1"
7587 [(set (reg FLAGS_REG)
7591 (match_operand 0 "ext_register_operand" "Q")
7595 (match_operand:QI 1 "general_operand" "Qm")))
7597 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7598 "test{b}\t{%1, %h0|%h0, %1}"
7599 [(set_attr "type" "test")
7600 (set_attr "mode" "QI")])
7602 (define_insn "*testqi_ext_2"
7603 [(set (reg FLAGS_REG)
7607 (match_operand 0 "ext_register_operand" "Q")
7611 (match_operand 1 "ext_register_operand" "Q")
7615 "ix86_match_ccmode (insn, CCNOmode)"
7616 "test{b}\t{%h1, %h0|%h0, %h1}"
7617 [(set_attr "type" "test")
7618 (set_attr "mode" "QI")])
7620 (define_insn "*testqi_ext_3_rex64"
7621 [(set (reg FLAGS_REG)
7622 (compare (zero_extract:DI
7623 (match_operand 0 "nonimmediate_operand" "rm")
7624 (match_operand:DI 1 "const_int_operand")
7625 (match_operand:DI 2 "const_int_operand"))
7628 && ix86_match_ccmode (insn, CCNOmode)
7629 && INTVAL (operands[1]) > 0
7630 && INTVAL (operands[2]) >= 0
7631 /* Ensure that resulting mask is zero or sign extended operand. */
7632 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7633 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7634 && INTVAL (operands[1]) > 32))
7635 && (GET_MODE (operands[0]) == SImode
7636 || GET_MODE (operands[0]) == DImode
7637 || GET_MODE (operands[0]) == HImode
7638 || GET_MODE (operands[0]) == QImode)"
7641 ;; Combine likes to form bit extractions for some tests. Humor it.
7642 (define_insn "*testqi_ext_3"
7643 [(set (reg FLAGS_REG)
7644 (compare (zero_extract:SI
7645 (match_operand 0 "nonimmediate_operand" "rm")
7646 (match_operand:SI 1 "const_int_operand")
7647 (match_operand:SI 2 "const_int_operand"))
7649 "ix86_match_ccmode (insn, CCNOmode)
7650 && INTVAL (operands[1]) > 0
7651 && INTVAL (operands[2]) >= 0
7652 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7653 && (GET_MODE (operands[0]) == SImode
7654 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7655 || GET_MODE (operands[0]) == HImode
7656 || GET_MODE (operands[0]) == QImode)"
7660 [(set (match_operand 0 "flags_reg_operand")
7661 (match_operator 1 "compare_operator"
7663 (match_operand 2 "nonimmediate_operand")
7664 (match_operand 3 "const_int_operand")
7665 (match_operand 4 "const_int_operand"))
7667 "ix86_match_ccmode (insn, CCNOmode)"
7668 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7670 rtx val = operands[2];
7671 HOST_WIDE_INT len = INTVAL (operands[3]);
7672 HOST_WIDE_INT pos = INTVAL (operands[4]);
7674 enum machine_mode mode, submode;
7676 mode = GET_MODE (val);
7679 /* ??? Combine likes to put non-volatile mem extractions in QImode
7680 no matter the size of the test. So find a mode that works. */
7681 if (! MEM_VOLATILE_P (val))
7683 mode = smallest_mode_for_size (pos + len, MODE_INT);
7684 val = adjust_address (val, mode, 0);
7687 else if (GET_CODE (val) == SUBREG
7688 && (submode = GET_MODE (SUBREG_REG (val)),
7689 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7690 && pos + len <= GET_MODE_BITSIZE (submode)
7691 && GET_MODE_CLASS (submode) == MODE_INT)
7693 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7695 val = SUBREG_REG (val);
7697 else if (mode == HImode && pos + len <= 8)
7699 /* Small HImode tests can be converted to QImode. */
7701 val = gen_lowpart (QImode, val);
7704 if (len == HOST_BITS_PER_WIDE_INT)
7707 mask = ((HOST_WIDE_INT)1 << len) - 1;
7710 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7713 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7714 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7715 ;; this is relatively important trick.
7716 ;; Do the conversion only post-reload to avoid limiting of the register class
7719 [(set (match_operand 0 "flags_reg_operand")
7720 (match_operator 1 "compare_operator"
7721 [(and (match_operand 2 "register_operand")
7722 (match_operand 3 "const_int_operand"))
7725 && QI_REG_P (operands[2])
7726 && GET_MODE (operands[2]) != QImode
7727 && ((ix86_match_ccmode (insn, CCZmode)
7728 && !(INTVAL (operands[3]) & ~(255 << 8)))
7729 || (ix86_match_ccmode (insn, CCNOmode)
7730 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7733 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7737 operands[2] = gen_lowpart (SImode, operands[2]);
7738 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7742 [(set (match_operand 0 "flags_reg_operand")
7743 (match_operator 1 "compare_operator"
7744 [(and (match_operand 2 "nonimmediate_operand")
7745 (match_operand 3 "const_int_operand"))
7748 && GET_MODE (operands[2]) != QImode
7749 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7750 && ((ix86_match_ccmode (insn, CCZmode)
7751 && !(INTVAL (operands[3]) & ~255))
7752 || (ix86_match_ccmode (insn, CCNOmode)
7753 && !(INTVAL (operands[3]) & ~127)))"
7755 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7758 operands[2] = gen_lowpart (QImode, operands[2]);
7759 operands[3] = gen_lowpart (QImode, operands[3]);
7762 ;; %%% This used to optimize known byte-wide and operations to memory,
7763 ;; and sometimes to QImode registers. If this is considered useful,
7764 ;; it should be done with splitters.
7766 (define_expand "and<mode>3"
7767 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7768 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7769 (match_operand:SWIM 2 "<general_szext_operand>")))]
7772 enum machine_mode mode = <MODE>mode;
7773 rtx (*insn) (rtx, rtx);
7775 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7777 HOST_WIDE_INT ival = INTVAL (operands[2]);
7779 if (ival == (HOST_WIDE_INT) 0xffffffff)
7781 else if (ival == 0xffff)
7783 else if (ival == 0xff)
7787 if (mode == <MODE>mode)
7789 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7793 if (<MODE>mode == DImode)
7794 insn = (mode == SImode)
7795 ? gen_zero_extendsidi2
7797 ? gen_zero_extendhidi2
7798 : gen_zero_extendqidi2;
7799 else if (<MODE>mode == SImode)
7800 insn = (mode == HImode)
7801 ? gen_zero_extendhisi2
7802 : gen_zero_extendqisi2;
7803 else if (<MODE>mode == HImode)
7804 insn = gen_zero_extendqihi2;
7808 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7812 (define_insn "*anddi_1"
7813 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7815 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7816 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7817 (clobber (reg:CC FLAGS_REG))]
7818 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7820 switch (get_attr_type (insn))
7826 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7827 if (get_attr_mode (insn) == MODE_SI)
7828 return "and{l}\t{%k2, %k0|%k0, %k2}";
7830 return "and{q}\t{%2, %0|%0, %2}";
7833 [(set_attr "type" "alu,alu,alu,imovx")
7834 (set_attr "length_immediate" "*,*,*,0")
7835 (set (attr "prefix_rex")
7837 (and (eq_attr "type" "imovx")
7838 (and (match_test "INTVAL (operands[2]) == 0xff")
7839 (match_operand 1 "ext_QIreg_operand")))
7841 (const_string "*")))
7842 (set_attr "mode" "SI,DI,DI,SI")])
7844 (define_insn "*andsi_1"
7845 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7846 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7847 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7848 (clobber (reg:CC FLAGS_REG))]
7849 "ix86_binary_operator_ok (AND, SImode, operands)"
7851 switch (get_attr_type (insn))
7857 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7858 return "and{l}\t{%2, %0|%0, %2}";
7861 [(set_attr "type" "alu,alu,imovx")
7862 (set (attr "prefix_rex")
7864 (and (eq_attr "type" "imovx")
7865 (and (match_test "INTVAL (operands[2]) == 0xff")
7866 (match_operand 1 "ext_QIreg_operand")))
7868 (const_string "*")))
7869 (set_attr "length_immediate" "*,*,0")
7870 (set_attr "mode" "SI")])
7872 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7873 (define_insn "*andsi_1_zext"
7874 [(set (match_operand:DI 0 "register_operand" "=r")
7876 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7877 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7878 (clobber (reg:CC FLAGS_REG))]
7879 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7880 "and{l}\t{%2, %k0|%k0, %2}"
7881 [(set_attr "type" "alu")
7882 (set_attr "mode" "SI")])
7884 (define_insn "*andhi_1"
7885 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7886 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7887 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7888 (clobber (reg:CC FLAGS_REG))]
7889 "ix86_binary_operator_ok (AND, HImode, operands)"
7891 switch (get_attr_type (insn))
7897 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7898 return "and{w}\t{%2, %0|%0, %2}";
7901 [(set_attr "type" "alu,alu,imovx")
7902 (set_attr "length_immediate" "*,*,0")
7903 (set (attr "prefix_rex")
7905 (and (eq_attr "type" "imovx")
7906 (match_operand 1 "ext_QIreg_operand"))
7908 (const_string "*")))
7909 (set_attr "mode" "HI,HI,SI")])
7911 ;; %%% Potential partial reg stall on alternative 2. What to do?
7912 (define_insn "*andqi_1"
7913 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7914 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7915 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7916 (clobber (reg:CC FLAGS_REG))]
7917 "ix86_binary_operator_ok (AND, QImode, operands)"
7919 and{b}\t{%2, %0|%0, %2}
7920 and{b}\t{%2, %0|%0, %2}
7921 and{l}\t{%k2, %k0|%k0, %k2}"
7922 [(set_attr "type" "alu")
7923 (set_attr "mode" "QI,QI,SI")])
7925 (define_insn "*andqi_1_slp"
7926 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7927 (and:QI (match_dup 0)
7928 (match_operand:QI 1 "general_operand" "qn,qmn")))
7929 (clobber (reg:CC FLAGS_REG))]
7930 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7931 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7932 "and{b}\t{%1, %0|%0, %1}"
7933 [(set_attr "type" "alu1")
7934 (set_attr "mode" "QI")])
7937 [(set (match_operand:SWI248 0 "register_operand")
7938 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7939 (match_operand:SWI248 2 "const_int_operand")))
7940 (clobber (reg:CC FLAGS_REG))]
7942 && true_regnum (operands[0]) != true_regnum (operands[1])"
7945 HOST_WIDE_INT ival = INTVAL (operands[2]);
7946 enum machine_mode mode;
7947 rtx (*insn) (rtx, rtx);
7949 if (ival == (HOST_WIDE_INT) 0xffffffff)
7951 else if (ival == 0xffff)
7955 gcc_assert (ival == 0xff);
7959 if (<MODE>mode == DImode)
7960 insn = (mode == SImode)
7961 ? gen_zero_extendsidi2
7963 ? gen_zero_extendhidi2
7964 : gen_zero_extendqidi2;
7967 if (<MODE>mode != SImode)
7968 /* Zero extend to SImode to avoid partial register stalls. */
7969 operands[0] = gen_lowpart (SImode, operands[0]);
7971 insn = (mode == HImode)
7972 ? gen_zero_extendhisi2
7973 : gen_zero_extendqisi2;
7975 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7980 [(set (match_operand 0 "register_operand")
7982 (const_int -65536)))
7983 (clobber (reg:CC FLAGS_REG))]
7984 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7985 || optimize_function_for_size_p (cfun)"
7986 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7987 "operands[1] = gen_lowpart (HImode, operands[0]);")
7990 [(set (match_operand 0 "ext_register_operand")
7993 (clobber (reg:CC FLAGS_REG))]
7994 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7995 && reload_completed"
7996 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7997 "operands[1] = gen_lowpart (QImode, operands[0]);")
8000 [(set (match_operand 0 "ext_register_operand")
8002 (const_int -65281)))
8003 (clobber (reg:CC FLAGS_REG))]
8004 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8005 && reload_completed"
8006 [(parallel [(set (zero_extract:SI (match_dup 0)
8010 (zero_extract:SI (match_dup 0)
8013 (zero_extract:SI (match_dup 0)
8016 (clobber (reg:CC FLAGS_REG))])]
8017 "operands[0] = gen_lowpart (SImode, operands[0]);")
8019 (define_insn "*anddi_2"
8020 [(set (reg FLAGS_REG)
8023 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8024 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8026 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8027 (and:DI (match_dup 1) (match_dup 2)))]
8028 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8029 && ix86_binary_operator_ok (AND, DImode, operands)"
8031 and{l}\t{%k2, %k0|%k0, %k2}
8032 and{q}\t{%2, %0|%0, %2}
8033 and{q}\t{%2, %0|%0, %2}"
8034 [(set_attr "type" "alu")
8035 (set_attr "mode" "SI,DI,DI")])
8037 (define_insn "*andqi_2_maybe_si"
8038 [(set (reg FLAGS_REG)
8040 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8041 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8043 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8044 (and:QI (match_dup 1) (match_dup 2)))]
8045 "ix86_binary_operator_ok (AND, QImode, operands)
8046 && ix86_match_ccmode (insn,
8047 CONST_INT_P (operands[2])
8048 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8050 if (which_alternative == 2)
8052 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8053 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8054 return "and{l}\t{%2, %k0|%k0, %2}";
8056 return "and{b}\t{%2, %0|%0, %2}";
8058 [(set_attr "type" "alu")
8059 (set_attr "mode" "QI,QI,SI")])
8061 (define_insn "*and<mode>_2"
8062 [(set (reg FLAGS_REG)
8063 (compare (and:SWI124
8064 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8065 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8067 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8068 (and:SWI124 (match_dup 1) (match_dup 2)))]
8069 "ix86_match_ccmode (insn, CCNOmode)
8070 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8071 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8072 [(set_attr "type" "alu")
8073 (set_attr "mode" "<MODE>")])
8075 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8076 (define_insn "*andsi_2_zext"
8077 [(set (reg FLAGS_REG)
8079 (match_operand:SI 1 "nonimmediate_operand" "%0")
8080 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8082 (set (match_operand:DI 0 "register_operand" "=r")
8083 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8084 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8085 && ix86_binary_operator_ok (AND, SImode, operands)"
8086 "and{l}\t{%2, %k0|%k0, %2}"
8087 [(set_attr "type" "alu")
8088 (set_attr "mode" "SI")])
8090 (define_insn "*andqi_2_slp"
8091 [(set (reg FLAGS_REG)
8093 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8094 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8096 (set (strict_low_part (match_dup 0))
8097 (and:QI (match_dup 0) (match_dup 1)))]
8098 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8099 && ix86_match_ccmode (insn, CCNOmode)
8100 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8101 "and{b}\t{%1, %0|%0, %1}"
8102 [(set_attr "type" "alu1")
8103 (set_attr "mode" "QI")])
8105 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8106 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8107 ;; for a QImode operand, which of course failed.
8108 (define_insn "andqi_ext_0"
8109 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8114 (match_operand 1 "ext_register_operand" "0")
8117 (match_operand 2 "const_int_operand" "n")))
8118 (clobber (reg:CC FLAGS_REG))]
8120 "and{b}\t{%2, %h0|%h0, %2}"
8121 [(set_attr "type" "alu")
8122 (set_attr "length_immediate" "1")
8123 (set_attr "modrm" "1")
8124 (set_attr "mode" "QI")])
8126 ;; Generated by peephole translating test to and. This shows up
8127 ;; often in fp comparisons.
8128 (define_insn "*andqi_ext_0_cc"
8129 [(set (reg FLAGS_REG)
8133 (match_operand 1 "ext_register_operand" "0")
8136 (match_operand 2 "const_int_operand" "n"))
8138 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8147 "ix86_match_ccmode (insn, CCNOmode)"
8148 "and{b}\t{%2, %h0|%h0, %2}"
8149 [(set_attr "type" "alu")
8150 (set_attr "length_immediate" "1")
8151 (set_attr "modrm" "1")
8152 (set_attr "mode" "QI")])
8154 (define_insn "*andqi_ext_1_rex64"
8155 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8160 (match_operand 1 "ext_register_operand" "0")
8164 (match_operand 2 "ext_register_operand" "Q"))))
8165 (clobber (reg:CC FLAGS_REG))]
8167 "and{b}\t{%2, %h0|%h0, %2}"
8168 [(set_attr "type" "alu")
8169 (set_attr "length_immediate" "0")
8170 (set_attr "mode" "QI")])
8172 (define_insn "*andqi_ext_1"
8173 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8178 (match_operand 1 "ext_register_operand" "0")
8182 (match_operand:QI 2 "general_operand" "Qm"))))
8183 (clobber (reg:CC FLAGS_REG))]
8185 "and{b}\t{%2, %h0|%h0, %2}"
8186 [(set_attr "type" "alu")
8187 (set_attr "length_immediate" "0")
8188 (set_attr "mode" "QI")])
8190 (define_insn "*andqi_ext_2"
8191 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8196 (match_operand 1 "ext_register_operand" "%0")
8200 (match_operand 2 "ext_register_operand" "Q")
8203 (clobber (reg:CC FLAGS_REG))]
8205 "and{b}\t{%h2, %h0|%h0, %h2}"
8206 [(set_attr "type" "alu")
8207 (set_attr "length_immediate" "0")
8208 (set_attr "mode" "QI")])
8210 ;; Convert wide AND instructions with immediate operand to shorter QImode
8211 ;; equivalents when possible.
8212 ;; Don't do the splitting with memory operands, since it introduces risk
8213 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8214 ;; for size, but that can (should?) be handled by generic code instead.
8216 [(set (match_operand 0 "register_operand")
8217 (and (match_operand 1 "register_operand")
8218 (match_operand 2 "const_int_operand")))
8219 (clobber (reg:CC FLAGS_REG))]
8221 && QI_REG_P (operands[0])
8222 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8223 && !(~INTVAL (operands[2]) & ~(255 << 8))
8224 && GET_MODE (operands[0]) != QImode"
8225 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8226 (and:SI (zero_extract:SI (match_dup 1)
8227 (const_int 8) (const_int 8))
8229 (clobber (reg:CC FLAGS_REG))])]
8231 operands[0] = gen_lowpart (SImode, operands[0]);
8232 operands[1] = gen_lowpart (SImode, operands[1]);
8233 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8236 ;; Since AND can be encoded with sign extended immediate, this is only
8237 ;; profitable when 7th bit is not set.
8239 [(set (match_operand 0 "register_operand")
8240 (and (match_operand 1 "general_operand")
8241 (match_operand 2 "const_int_operand")))
8242 (clobber (reg:CC FLAGS_REG))]
8244 && ANY_QI_REG_P (operands[0])
8245 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8246 && !(~INTVAL (operands[2]) & ~255)
8247 && !(INTVAL (operands[2]) & 128)
8248 && GET_MODE (operands[0]) != QImode"
8249 [(parallel [(set (strict_low_part (match_dup 0))
8250 (and:QI (match_dup 1)
8252 (clobber (reg:CC FLAGS_REG))])]
8254 operands[0] = gen_lowpart (QImode, operands[0]);
8255 operands[1] = gen_lowpart (QImode, operands[1]);
8256 operands[2] = gen_lowpart (QImode, operands[2]);
8259 ;; Logical inclusive and exclusive OR instructions
8261 ;; %%% This used to optimize known byte-wide and operations to memory.
8262 ;; If this is considered useful, it should be done with splitters.
8264 (define_expand "<code><mode>3"
8265 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8266 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8267 (match_operand:SWIM 2 "<general_operand>")))]
8269 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8271 (define_insn "*<code><mode>_1"
8272 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8274 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8275 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8276 (clobber (reg:CC FLAGS_REG))]
8277 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8278 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8279 [(set_attr "type" "alu")
8280 (set_attr "mode" "<MODE>")])
8282 ;; %%% Potential partial reg stall on alternative 2. What to do?
8283 (define_insn "*<code>qi_1"
8284 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8285 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8286 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8287 (clobber (reg:CC FLAGS_REG))]
8288 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8290 <logic>{b}\t{%2, %0|%0, %2}
8291 <logic>{b}\t{%2, %0|%0, %2}
8292 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8293 [(set_attr "type" "alu")
8294 (set_attr "mode" "QI,QI,SI")])
8296 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8297 (define_insn "*<code>si_1_zext"
8298 [(set (match_operand:DI 0 "register_operand" "=r")
8300 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8301 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8302 (clobber (reg:CC FLAGS_REG))]
8303 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8304 "<logic>{l}\t{%2, %k0|%k0, %2}"
8305 [(set_attr "type" "alu")
8306 (set_attr "mode" "SI")])
8308 (define_insn "*<code>si_1_zext_imm"
8309 [(set (match_operand:DI 0 "register_operand" "=r")
8311 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8312 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8313 (clobber (reg:CC FLAGS_REG))]
8314 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8315 "<logic>{l}\t{%2, %k0|%k0, %2}"
8316 [(set_attr "type" "alu")
8317 (set_attr "mode" "SI")])
8319 (define_insn "*<code>qi_1_slp"
8320 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8321 (any_or:QI (match_dup 0)
8322 (match_operand:QI 1 "general_operand" "qmn,qn")))
8323 (clobber (reg:CC FLAGS_REG))]
8324 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8325 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8326 "<logic>{b}\t{%1, %0|%0, %1}"
8327 [(set_attr "type" "alu1")
8328 (set_attr "mode" "QI")])
8330 (define_insn "*<code><mode>_2"
8331 [(set (reg FLAGS_REG)
8332 (compare (any_or:SWI
8333 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8334 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8336 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8337 (any_or:SWI (match_dup 1) (match_dup 2)))]
8338 "ix86_match_ccmode (insn, CCNOmode)
8339 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8340 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8341 [(set_attr "type" "alu")
8342 (set_attr "mode" "<MODE>")])
8344 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8345 ;; ??? Special case for immediate operand is missing - it is tricky.
8346 (define_insn "*<code>si_2_zext"
8347 [(set (reg FLAGS_REG)
8348 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8349 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8351 (set (match_operand:DI 0 "register_operand" "=r")
8352 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8353 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8354 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8355 "<logic>{l}\t{%2, %k0|%k0, %2}"
8356 [(set_attr "type" "alu")
8357 (set_attr "mode" "SI")])
8359 (define_insn "*<code>si_2_zext_imm"
8360 [(set (reg FLAGS_REG)
8362 (match_operand:SI 1 "nonimmediate_operand" "%0")
8363 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8365 (set (match_operand:DI 0 "register_operand" "=r")
8366 (any_or:DI (zero_extend:DI (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>qi_2_slp"
8374 [(set (reg FLAGS_REG)
8375 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8376 (match_operand:QI 1 "general_operand" "qmn,qn"))
8378 (set (strict_low_part (match_dup 0))
8379 (any_or:QI (match_dup 0) (match_dup 1)))]
8380 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8381 && ix86_match_ccmode (insn, CCNOmode)
8382 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8383 "<logic>{b}\t{%1, %0|%0, %1}"
8384 [(set_attr "type" "alu1")
8385 (set_attr "mode" "QI")])
8387 (define_insn "*<code><mode>_3"
8388 [(set (reg FLAGS_REG)
8389 (compare (any_or:SWI
8390 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8391 (match_operand:SWI 2 "<general_operand>" "<g>"))
8393 (clobber (match_scratch:SWI 0 "=<r>"))]
8394 "ix86_match_ccmode (insn, CCNOmode)
8395 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8396 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8397 [(set_attr "type" "alu")
8398 (set_attr "mode" "<MODE>")])
8400 (define_insn "*<code>qi_ext_0"
8401 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8406 (match_operand 1 "ext_register_operand" "0")
8409 (match_operand 2 "const_int_operand" "n")))
8410 (clobber (reg:CC FLAGS_REG))]
8411 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8412 "<logic>{b}\t{%2, %h0|%h0, %2}"
8413 [(set_attr "type" "alu")
8414 (set_attr "length_immediate" "1")
8415 (set_attr "modrm" "1")
8416 (set_attr "mode" "QI")])
8418 (define_insn "*<code>qi_ext_1_rex64"
8419 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8424 (match_operand 1 "ext_register_operand" "0")
8428 (match_operand 2 "ext_register_operand" "Q"))))
8429 (clobber (reg:CC FLAGS_REG))]
8431 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8432 "<logic>{b}\t{%2, %h0|%h0, %2}"
8433 [(set_attr "type" "alu")
8434 (set_attr "length_immediate" "0")
8435 (set_attr "mode" "QI")])
8437 (define_insn "*<code>qi_ext_1"
8438 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8443 (match_operand 1 "ext_register_operand" "0")
8447 (match_operand:QI 2 "general_operand" "Qm"))))
8448 (clobber (reg:CC FLAGS_REG))]
8450 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8451 "<logic>{b}\t{%2, %h0|%h0, %2}"
8452 [(set_attr "type" "alu")
8453 (set_attr "length_immediate" "0")
8454 (set_attr "mode" "QI")])
8456 (define_insn "*<code>qi_ext_2"
8457 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8461 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8464 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8467 (clobber (reg:CC FLAGS_REG))]
8468 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8469 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8470 [(set_attr "type" "alu")
8471 (set_attr "length_immediate" "0")
8472 (set_attr "mode" "QI")])
8475 [(set (match_operand 0 "register_operand")
8476 (any_or (match_operand 1 "register_operand")
8477 (match_operand 2 "const_int_operand")))
8478 (clobber (reg:CC FLAGS_REG))]
8480 && QI_REG_P (operands[0])
8481 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8482 && !(INTVAL (operands[2]) & ~(255 << 8))
8483 && GET_MODE (operands[0]) != QImode"
8484 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8485 (any_or:SI (zero_extract:SI (match_dup 1)
8486 (const_int 8) (const_int 8))
8488 (clobber (reg:CC FLAGS_REG))])]
8490 operands[0] = gen_lowpart (SImode, operands[0]);
8491 operands[1] = gen_lowpart (SImode, operands[1]);
8492 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8495 ;; Since OR can be encoded with sign extended immediate, this is only
8496 ;; profitable when 7th bit is set.
8498 [(set (match_operand 0 "register_operand")
8499 (any_or (match_operand 1 "general_operand")
8500 (match_operand 2 "const_int_operand")))
8501 (clobber (reg:CC FLAGS_REG))]
8503 && ANY_QI_REG_P (operands[0])
8504 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8505 && !(INTVAL (operands[2]) & ~255)
8506 && (INTVAL (operands[2]) & 128)
8507 && GET_MODE (operands[0]) != QImode"
8508 [(parallel [(set (strict_low_part (match_dup 0))
8509 (any_or:QI (match_dup 1)
8511 (clobber (reg:CC FLAGS_REG))])]
8513 operands[0] = gen_lowpart (QImode, operands[0]);
8514 operands[1] = gen_lowpart (QImode, operands[1]);
8515 operands[2] = gen_lowpart (QImode, operands[2]);
8518 (define_expand "xorqi_cc_ext_1"
8520 (set (reg:CCNO FLAGS_REG)
8524 (match_operand 1 "ext_register_operand")
8527 (match_operand:QI 2 "general_operand"))
8529 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8539 (define_insn "*xorqi_cc_ext_1_rex64"
8540 [(set (reg FLAGS_REG)
8544 (match_operand 1 "ext_register_operand" "0")
8547 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8549 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8558 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8559 "xor{b}\t{%2, %h0|%h0, %2}"
8560 [(set_attr "type" "alu")
8561 (set_attr "modrm" "1")
8562 (set_attr "mode" "QI")])
8564 (define_insn "*xorqi_cc_ext_1"
8565 [(set (reg FLAGS_REG)
8569 (match_operand 1 "ext_register_operand" "0")
8572 (match_operand:QI 2 "general_operand" "qmn"))
8574 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8583 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8584 "xor{b}\t{%2, %h0|%h0, %2}"
8585 [(set_attr "type" "alu")
8586 (set_attr "modrm" "1")
8587 (set_attr "mode" "QI")])
8589 ;; Negation instructions
8591 (define_expand "neg<mode>2"
8592 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8593 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8595 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8597 (define_insn_and_split "*neg<dwi>2_doubleword"
8598 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8599 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8600 (clobber (reg:CC FLAGS_REG))]
8601 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8605 [(set (reg:CCZ FLAGS_REG)
8606 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8607 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8610 (plus:DWIH (match_dup 3)
8611 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8613 (clobber (reg:CC FLAGS_REG))])
8616 (neg:DWIH (match_dup 2)))
8617 (clobber (reg:CC FLAGS_REG))])]
8618 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8620 (define_insn "*neg<mode>2_1"
8621 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8622 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8623 (clobber (reg:CC FLAGS_REG))]
8624 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8625 "neg{<imodesuffix>}\t%0"
8626 [(set_attr "type" "negnot")
8627 (set_attr "mode" "<MODE>")])
8629 ;; Combine is quite creative about this pattern.
8630 (define_insn "*negsi2_1_zext"
8631 [(set (match_operand:DI 0 "register_operand" "=r")
8633 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8636 (clobber (reg:CC FLAGS_REG))]
8637 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8639 [(set_attr "type" "negnot")
8640 (set_attr "mode" "SI")])
8642 ;; The problem with neg is that it does not perform (compare x 0),
8643 ;; it really performs (compare 0 x), which leaves us with the zero
8644 ;; flag being the only useful item.
8646 (define_insn "*neg<mode>2_cmpz"
8647 [(set (reg:CCZ FLAGS_REG)
8649 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8651 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8652 (neg:SWI (match_dup 1)))]
8653 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8654 "neg{<imodesuffix>}\t%0"
8655 [(set_attr "type" "negnot")
8656 (set_attr "mode" "<MODE>")])
8658 (define_insn "*negsi2_cmpz_zext"
8659 [(set (reg:CCZ FLAGS_REG)
8663 (match_operand:DI 1 "register_operand" "0")
8667 (set (match_operand:DI 0 "register_operand" "=r")
8668 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8671 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8673 [(set_attr "type" "negnot")
8674 (set_attr "mode" "SI")])
8676 ;; Changing of sign for FP values is doable using integer unit too.
8678 (define_expand "<code><mode>2"
8679 [(set (match_operand:X87MODEF 0 "register_operand")
8680 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8681 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8682 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8684 (define_insn "*absneg<mode>2_mixed"
8685 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8686 (match_operator:MODEF 3 "absneg_operator"
8687 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8688 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8689 (clobber (reg:CC FLAGS_REG))]
8690 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8693 (define_insn "*absneg<mode>2_sse"
8694 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8695 (match_operator:MODEF 3 "absneg_operator"
8696 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8697 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8698 (clobber (reg:CC FLAGS_REG))]
8699 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8702 (define_insn "*absneg<mode>2_i387"
8703 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8704 (match_operator:X87MODEF 3 "absneg_operator"
8705 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8706 (use (match_operand 2))
8707 (clobber (reg:CC FLAGS_REG))]
8708 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8711 (define_expand "<code>tf2"
8712 [(set (match_operand:TF 0 "register_operand")
8713 (absneg:TF (match_operand:TF 1 "register_operand")))]
8715 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8717 (define_insn "*absnegtf2_sse"
8718 [(set (match_operand:TF 0 "register_operand" "=x,x")
8719 (match_operator:TF 3 "absneg_operator"
8720 [(match_operand:TF 1 "register_operand" "0,x")]))
8721 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8722 (clobber (reg:CC FLAGS_REG))]
8726 ;; Splitters for fp abs and neg.
8729 [(set (match_operand 0 "fp_register_operand")
8730 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8731 (use (match_operand 2))
8732 (clobber (reg:CC FLAGS_REG))]
8734 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8737 [(set (match_operand 0 "register_operand")
8738 (match_operator 3 "absneg_operator"
8739 [(match_operand 1 "register_operand")]))
8740 (use (match_operand 2 "nonimmediate_operand"))
8741 (clobber (reg:CC FLAGS_REG))]
8742 "reload_completed && SSE_REG_P (operands[0])"
8743 [(set (match_dup 0) (match_dup 3))]
8745 enum machine_mode mode = GET_MODE (operands[0]);
8746 enum machine_mode vmode = GET_MODE (operands[2]);
8749 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8750 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8751 if (operands_match_p (operands[0], operands[2]))
8754 operands[1] = operands[2];
8757 if (GET_CODE (operands[3]) == ABS)
8758 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8760 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8765 [(set (match_operand:SF 0 "register_operand")
8766 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8767 (use (match_operand:V4SF 2))
8768 (clobber (reg:CC FLAGS_REG))]
8770 [(parallel [(set (match_dup 0) (match_dup 1))
8771 (clobber (reg:CC FLAGS_REG))])]
8774 operands[0] = gen_lowpart (SImode, operands[0]);
8775 if (GET_CODE (operands[1]) == ABS)
8777 tmp = gen_int_mode (0x7fffffff, SImode);
8778 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8782 tmp = gen_int_mode (0x80000000, SImode);
8783 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8789 [(set (match_operand:DF 0 "register_operand")
8790 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8791 (use (match_operand 2))
8792 (clobber (reg:CC FLAGS_REG))]
8794 [(parallel [(set (match_dup 0) (match_dup 1))
8795 (clobber (reg:CC FLAGS_REG))])]
8800 tmp = gen_lowpart (DImode, operands[0]);
8801 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8804 if (GET_CODE (operands[1]) == ABS)
8807 tmp = gen_rtx_NOT (DImode, tmp);
8811 operands[0] = gen_highpart (SImode, operands[0]);
8812 if (GET_CODE (operands[1]) == ABS)
8814 tmp = gen_int_mode (0x7fffffff, SImode);
8815 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8819 tmp = gen_int_mode (0x80000000, SImode);
8820 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8827 [(set (match_operand:XF 0 "register_operand")
8828 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8829 (use (match_operand 2))
8830 (clobber (reg:CC FLAGS_REG))]
8832 [(parallel [(set (match_dup 0) (match_dup 1))
8833 (clobber (reg:CC FLAGS_REG))])]
8836 operands[0] = gen_rtx_REG (SImode,
8837 true_regnum (operands[0])
8838 + (TARGET_64BIT ? 1 : 2));
8839 if (GET_CODE (operands[1]) == ABS)
8841 tmp = GEN_INT (0x7fff);
8842 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8846 tmp = GEN_INT (0x8000);
8847 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8852 ;; Conditionalize these after reload. If they match before reload, we
8853 ;; lose the clobber and ability to use integer instructions.
8855 (define_insn "*<code><mode>2_1"
8856 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8857 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8859 && (reload_completed
8860 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8861 "f<absneg_mnemonic>"
8862 [(set_attr "type" "fsgn")
8863 (set_attr "mode" "<MODE>")])
8865 (define_insn "*<code>extendsfdf2"
8866 [(set (match_operand:DF 0 "register_operand" "=f")
8867 (absneg:DF (float_extend:DF
8868 (match_operand:SF 1 "register_operand" "0"))))]
8869 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8870 "f<absneg_mnemonic>"
8871 [(set_attr "type" "fsgn")
8872 (set_attr "mode" "DF")])
8874 (define_insn "*<code>extendsfxf2"
8875 [(set (match_operand:XF 0 "register_operand" "=f")
8876 (absneg:XF (float_extend:XF
8877 (match_operand:SF 1 "register_operand" "0"))))]
8879 "f<absneg_mnemonic>"
8880 [(set_attr "type" "fsgn")
8881 (set_attr "mode" "XF")])
8883 (define_insn "*<code>extenddfxf2"
8884 [(set (match_operand:XF 0 "register_operand" "=f")
8885 (absneg:XF (float_extend:XF
8886 (match_operand:DF 1 "register_operand" "0"))))]
8888 "f<absneg_mnemonic>"
8889 [(set_attr "type" "fsgn")
8890 (set_attr "mode" "XF")])
8892 ;; Copysign instructions
8894 (define_mode_iterator CSGNMODE [SF DF TF])
8895 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8897 (define_expand "copysign<mode>3"
8898 [(match_operand:CSGNMODE 0 "register_operand")
8899 (match_operand:CSGNMODE 1 "nonmemory_operand")
8900 (match_operand:CSGNMODE 2 "register_operand")]
8901 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8902 || (TARGET_SSE && (<MODE>mode == TFmode))"
8903 "ix86_expand_copysign (operands); DONE;")
8905 (define_insn_and_split "copysign<mode>3_const"
8906 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8908 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8909 (match_operand:CSGNMODE 2 "register_operand" "0")
8910 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8912 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8913 || (TARGET_SSE && (<MODE>mode == TFmode))"
8915 "&& reload_completed"
8917 "ix86_split_copysign_const (operands); DONE;")
8919 (define_insn "copysign<mode>3_var"
8920 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8922 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8923 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8924 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8925 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8927 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8928 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8929 || (TARGET_SSE && (<MODE>mode == TFmode))"
8933 [(set (match_operand:CSGNMODE 0 "register_operand")
8935 [(match_operand:CSGNMODE 2 "register_operand")
8936 (match_operand:CSGNMODE 3 "register_operand")
8937 (match_operand:<CSGNVMODE> 4)
8938 (match_operand:<CSGNVMODE> 5)]
8940 (clobber (match_scratch:<CSGNVMODE> 1))]
8941 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8942 || (TARGET_SSE && (<MODE>mode == TFmode)))
8943 && reload_completed"
8945 "ix86_split_copysign_var (operands); DONE;")
8947 ;; One complement instructions
8949 (define_expand "one_cmpl<mode>2"
8950 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8951 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8953 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8955 (define_insn "*one_cmpl<mode>2_1"
8956 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8957 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8958 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8959 "not{<imodesuffix>}\t%0"
8960 [(set_attr "type" "negnot")
8961 (set_attr "mode" "<MODE>")])
8963 ;; %%% Potential partial reg stall on alternative 1. What to do?
8964 (define_insn "*one_cmplqi2_1"
8965 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8966 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8967 "ix86_unary_operator_ok (NOT, QImode, operands)"
8971 [(set_attr "type" "negnot")
8972 (set_attr "mode" "QI,SI")])
8974 ;; ??? Currently never generated - xor is used instead.
8975 (define_insn "*one_cmplsi2_1_zext"
8976 [(set (match_operand:DI 0 "register_operand" "=r")
8978 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8979 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8981 [(set_attr "type" "negnot")
8982 (set_attr "mode" "SI")])
8984 (define_insn "*one_cmpl<mode>2_2"
8985 [(set (reg FLAGS_REG)
8986 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8988 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8989 (not:SWI (match_dup 1)))]
8990 "ix86_match_ccmode (insn, CCNOmode)
8991 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8993 [(set_attr "type" "alu1")
8994 (set_attr "mode" "<MODE>")])
8997 [(set (match_operand 0 "flags_reg_operand")
8998 (match_operator 2 "compare_operator"
8999 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9001 (set (match_operand:SWI 1 "nonimmediate_operand")
9002 (not:SWI (match_dup 3)))]
9003 "ix86_match_ccmode (insn, CCNOmode)"
9004 [(parallel [(set (match_dup 0)
9005 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9008 (xor:SWI (match_dup 3) (const_int -1)))])])
9010 ;; ??? Currently never generated - xor is used instead.
9011 (define_insn "*one_cmplsi2_2_zext"
9012 [(set (reg FLAGS_REG)
9013 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9015 (set (match_operand:DI 0 "register_operand" "=r")
9016 (zero_extend:DI (not:SI (match_dup 1))))]
9017 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9018 && ix86_unary_operator_ok (NOT, SImode, operands)"
9020 [(set_attr "type" "alu1")
9021 (set_attr "mode" "SI")])
9024 [(set (match_operand 0 "flags_reg_operand")
9025 (match_operator 2 "compare_operator"
9026 [(not:SI (match_operand:SI 3 "register_operand"))
9028 (set (match_operand:DI 1 "register_operand")
9029 (zero_extend:DI (not:SI (match_dup 3))))]
9030 "ix86_match_ccmode (insn, CCNOmode)"
9031 [(parallel [(set (match_dup 0)
9032 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9035 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9037 ;; Shift instructions
9039 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9040 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9041 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9042 ;; from the assembler input.
9044 ;; This instruction shifts the target reg/mem as usual, but instead of
9045 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9046 ;; is a left shift double, bits are taken from the high order bits of
9047 ;; reg, else if the insn is a shift right double, bits are taken from the
9048 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9049 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9051 ;; Since sh[lr]d does not change the `reg' operand, that is done
9052 ;; separately, making all shifts emit pairs of shift double and normal
9053 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9054 ;; support a 63 bit shift, each shift where the count is in a reg expands
9055 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9057 ;; If the shift count is a constant, we need never emit more than one
9058 ;; shift pair, instead using moves and sign extension for counts greater
9061 (define_expand "ashl<mode>3"
9062 [(set (match_operand:SDWIM 0 "<shift_operand>")
9063 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9064 (match_operand:QI 2 "nonmemory_operand")))]
9066 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9068 (define_insn "*ashl<mode>3_doubleword"
9069 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9070 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9071 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9072 (clobber (reg:CC FLAGS_REG))]
9075 [(set_attr "type" "multi")])
9078 [(set (match_operand:DWI 0 "register_operand")
9079 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9080 (match_operand:QI 2 "nonmemory_operand")))
9081 (clobber (reg:CC FLAGS_REG))]
9082 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9084 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9086 ;; By default we don't ask for a scratch register, because when DWImode
9087 ;; values are manipulated, registers are already at a premium. But if
9088 ;; we have one handy, we won't turn it away.
9091 [(match_scratch:DWIH 3 "r")
9092 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9094 (match_operand:<DWI> 1 "nonmemory_operand")
9095 (match_operand:QI 2 "nonmemory_operand")))
9096 (clobber (reg:CC FLAGS_REG))])
9100 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9102 (define_insn "x86_64_shld"
9103 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9104 (ior:DI (ashift:DI (match_dup 0)
9105 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9106 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9107 (minus:QI (const_int 64) (match_dup 2)))))
9108 (clobber (reg:CC FLAGS_REG))]
9110 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9111 [(set_attr "type" "ishift")
9112 (set_attr "prefix_0f" "1")
9113 (set_attr "mode" "DI")
9114 (set_attr "athlon_decode" "vector")
9115 (set_attr "amdfam10_decode" "vector")
9116 (set_attr "bdver1_decode" "vector")])
9118 (define_insn "x86_shld"
9119 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9120 (ior:SI (ashift:SI (match_dup 0)
9121 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9122 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9123 (minus:QI (const_int 32) (match_dup 2)))))
9124 (clobber (reg:CC FLAGS_REG))]
9126 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9127 [(set_attr "type" "ishift")
9128 (set_attr "prefix_0f" "1")
9129 (set_attr "mode" "SI")
9130 (set_attr "pent_pair" "np")
9131 (set_attr "athlon_decode" "vector")
9132 (set_attr "amdfam10_decode" "vector")
9133 (set_attr "bdver1_decode" "vector")])
9135 (define_expand "x86_shift<mode>_adj_1"
9136 [(set (reg:CCZ FLAGS_REG)
9137 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9140 (set (match_operand:SWI48 0 "register_operand")
9141 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9142 (match_operand:SWI48 1 "register_operand")
9145 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9146 (match_operand:SWI48 3 "register_operand")
9149 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9151 (define_expand "x86_shift<mode>_adj_2"
9152 [(use (match_operand:SWI48 0 "register_operand"))
9153 (use (match_operand:SWI48 1 "register_operand"))
9154 (use (match_operand:QI 2 "register_operand"))]
9157 rtx label = gen_label_rtx ();
9160 emit_insn (gen_testqi_ccz_1 (operands[2],
9161 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9163 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9164 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9165 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9166 gen_rtx_LABEL_REF (VOIDmode, label),
9168 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9169 JUMP_LABEL (tmp) = label;
9171 emit_move_insn (operands[0], operands[1]);
9172 ix86_expand_clear (operands[1]);
9175 LABEL_NUSES (label) = 1;
9180 ;; Avoid useless masking of count operand.
9181 (define_insn_and_split "*ashl<mode>3_mask"
9182 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9184 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9187 (match_operand:SI 2 "nonimmediate_operand" "c")
9188 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9189 (clobber (reg:CC FLAGS_REG))]
9190 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9191 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9192 == GET_MODE_BITSIZE (<MODE>mode)-1"
9195 [(parallel [(set (match_dup 0)
9196 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9197 (clobber (reg:CC FLAGS_REG))])]
9199 if (can_create_pseudo_p ())
9200 operands [2] = force_reg (SImode, operands[2]);
9202 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9204 [(set_attr "type" "ishift")
9205 (set_attr "mode" "<MODE>")])
9207 (define_insn "*bmi2_ashl<mode>3_1"
9208 [(set (match_operand:SWI48 0 "register_operand" "=r")
9209 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9210 (match_operand:SWI48 2 "register_operand" "r")))]
9212 "shlx\t{%2, %1, %0|%0, %1, %2}"
9213 [(set_attr "type" "ishiftx")
9214 (set_attr "mode" "<MODE>")])
9216 (define_insn "*ashl<mode>3_1"
9217 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9218 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9219 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9220 (clobber (reg:CC FLAGS_REG))]
9221 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9223 switch (get_attr_type (insn))
9230 gcc_assert (operands[2] == const1_rtx);
9231 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9232 return "add{<imodesuffix>}\t%0, %0";
9235 if (operands[2] == const1_rtx
9236 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9237 return "sal{<imodesuffix>}\t%0";
9239 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9242 [(set_attr "isa" "*,*,bmi2")
9244 (cond [(eq_attr "alternative" "1")
9245 (const_string "lea")
9246 (eq_attr "alternative" "2")
9247 (const_string "ishiftx")
9248 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9249 (match_operand 0 "register_operand"))
9250 (match_operand 2 "const1_operand"))
9251 (const_string "alu")
9253 (const_string "ishift")))
9254 (set (attr "length_immediate")
9256 (ior (eq_attr "type" "alu")
9257 (and (eq_attr "type" "ishift")
9258 (and (match_operand 2 "const1_operand")
9259 (ior (match_test "TARGET_SHIFT1")
9260 (match_test "optimize_function_for_size_p (cfun)")))))
9262 (const_string "*")))
9263 (set_attr "mode" "<MODE>")])
9265 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9267 [(set (match_operand:SWI48 0 "register_operand")
9268 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9269 (match_operand:QI 2 "register_operand")))
9270 (clobber (reg:CC FLAGS_REG))]
9271 "TARGET_BMI2 && reload_completed"
9273 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9274 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9276 (define_insn "*bmi2_ashlsi3_1_zext"
9277 [(set (match_operand:DI 0 "register_operand" "=r")
9279 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9280 (match_operand:SI 2 "register_operand" "r"))))]
9281 "TARGET_64BIT && TARGET_BMI2"
9282 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9283 [(set_attr "type" "ishiftx")
9284 (set_attr "mode" "SI")])
9286 (define_insn "*ashlsi3_1_zext"
9287 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9289 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9290 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9291 (clobber (reg:CC FLAGS_REG))]
9292 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9294 switch (get_attr_type (insn))
9301 gcc_assert (operands[2] == const1_rtx);
9302 return "add{l}\t%k0, %k0";
9305 if (operands[2] == const1_rtx
9306 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9307 return "sal{l}\t%k0";
9309 return "sal{l}\t{%2, %k0|%k0, %2}";
9312 [(set_attr "isa" "*,*,bmi2")
9314 (cond [(eq_attr "alternative" "1")
9315 (const_string "lea")
9316 (eq_attr "alternative" "2")
9317 (const_string "ishiftx")
9318 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9319 (match_operand 2 "const1_operand"))
9320 (const_string "alu")
9322 (const_string "ishift")))
9323 (set (attr "length_immediate")
9325 (ior (eq_attr "type" "alu")
9326 (and (eq_attr "type" "ishift")
9327 (and (match_operand 2 "const1_operand")
9328 (ior (match_test "TARGET_SHIFT1")
9329 (match_test "optimize_function_for_size_p (cfun)")))))
9331 (const_string "*")))
9332 (set_attr "mode" "SI")])
9334 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9336 [(set (match_operand:DI 0 "register_operand")
9338 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9339 (match_operand:QI 2 "register_operand"))))
9340 (clobber (reg:CC FLAGS_REG))]
9341 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9343 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9344 "operands[2] = gen_lowpart (SImode, operands[2]);")
9346 (define_insn "*ashlhi3_1"
9347 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9348 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9349 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9350 (clobber (reg:CC FLAGS_REG))]
9351 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9353 switch (get_attr_type (insn))
9359 gcc_assert (operands[2] == const1_rtx);
9360 return "add{w}\t%0, %0";
9363 if (operands[2] == const1_rtx
9364 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9365 return "sal{w}\t%0";
9367 return "sal{w}\t{%2, %0|%0, %2}";
9371 (cond [(eq_attr "alternative" "1")
9372 (const_string "lea")
9373 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9374 (match_operand 0 "register_operand"))
9375 (match_operand 2 "const1_operand"))
9376 (const_string "alu")
9378 (const_string "ishift")))
9379 (set (attr "length_immediate")
9381 (ior (eq_attr "type" "alu")
9382 (and (eq_attr "type" "ishift")
9383 (and (match_operand 2 "const1_operand")
9384 (ior (match_test "TARGET_SHIFT1")
9385 (match_test "optimize_function_for_size_p (cfun)")))))
9387 (const_string "*")))
9388 (set_attr "mode" "HI,SI")])
9390 ;; %%% Potential partial reg stall on alternative 1. What to do?
9391 (define_insn "*ashlqi3_1"
9392 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9393 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9394 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9395 (clobber (reg:CC FLAGS_REG))]
9396 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9398 switch (get_attr_type (insn))
9404 gcc_assert (operands[2] == const1_rtx);
9405 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9406 return "add{l}\t%k0, %k0";
9408 return "add{b}\t%0, %0";
9411 if (operands[2] == const1_rtx
9412 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9414 if (get_attr_mode (insn) == MODE_SI)
9415 return "sal{l}\t%k0";
9417 return "sal{b}\t%0";
9421 if (get_attr_mode (insn) == MODE_SI)
9422 return "sal{l}\t{%2, %k0|%k0, %2}";
9424 return "sal{b}\t{%2, %0|%0, %2}";
9429 (cond [(eq_attr "alternative" "2")
9430 (const_string "lea")
9431 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9432 (match_operand 0 "register_operand"))
9433 (match_operand 2 "const1_operand"))
9434 (const_string "alu")
9436 (const_string "ishift")))
9437 (set (attr "length_immediate")
9439 (ior (eq_attr "type" "alu")
9440 (and (eq_attr "type" "ishift")
9441 (and (match_operand 2 "const1_operand")
9442 (ior (match_test "TARGET_SHIFT1")
9443 (match_test "optimize_function_for_size_p (cfun)")))))
9445 (const_string "*")))
9446 (set_attr "mode" "QI,SI,SI")])
9448 (define_insn "*ashlqi3_1_slp"
9449 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9450 (ashift:QI (match_dup 0)
9451 (match_operand:QI 1 "nonmemory_operand" "cI")))
9452 (clobber (reg:CC FLAGS_REG))]
9453 "(optimize_function_for_size_p (cfun)
9454 || !TARGET_PARTIAL_FLAG_REG_STALL
9455 || (operands[1] == const1_rtx
9457 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9459 switch (get_attr_type (insn))
9462 gcc_assert (operands[1] == const1_rtx);
9463 return "add{b}\t%0, %0";
9466 if (operands[1] == const1_rtx
9467 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9468 return "sal{b}\t%0";
9470 return "sal{b}\t{%1, %0|%0, %1}";
9474 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9475 (match_operand 0 "register_operand"))
9476 (match_operand 1 "const1_operand"))
9477 (const_string "alu")
9479 (const_string "ishift1")))
9480 (set (attr "length_immediate")
9482 (ior (eq_attr "type" "alu")
9483 (and (eq_attr "type" "ishift1")
9484 (and (match_operand 1 "const1_operand")
9485 (ior (match_test "TARGET_SHIFT1")
9486 (match_test "optimize_function_for_size_p (cfun)")))))
9488 (const_string "*")))
9489 (set_attr "mode" "QI")])
9491 ;; Convert ashift to the lea pattern to avoid flags dependency.
9493 [(set (match_operand 0 "register_operand")
9494 (ashift (match_operand 1 "index_register_operand")
9495 (match_operand:QI 2 "const_int_operand")))
9496 (clobber (reg:CC FLAGS_REG))]
9497 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9499 && true_regnum (operands[0]) != true_regnum (operands[1])"
9502 enum machine_mode mode = GET_MODE (operands[0]);
9505 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9508 operands[0] = gen_lowpart (mode, operands[0]);
9509 operands[1] = gen_lowpart (mode, operands[1]);
9512 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9514 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9516 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9520 ;; Convert ashift to the lea pattern to avoid flags dependency.
9522 [(set (match_operand:DI 0 "register_operand")
9524 (ashift:SI (match_operand:SI 1 "index_register_operand")
9525 (match_operand:QI 2 "const_int_operand"))))
9526 (clobber (reg:CC FLAGS_REG))]
9527 "TARGET_64BIT && reload_completed
9528 && true_regnum (operands[0]) != true_regnum (operands[1])"
9530 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9532 operands[1] = gen_lowpart (DImode, operands[1]);
9533 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9536 ;; This pattern can't accept a variable shift count, since shifts by
9537 ;; zero don't affect the flags. We assume that shifts by constant
9538 ;; zero are optimized away.
9539 (define_insn "*ashl<mode>3_cmp"
9540 [(set (reg FLAGS_REG)
9542 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9543 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9545 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9546 (ashift:SWI (match_dup 1) (match_dup 2)))]
9547 "(optimize_function_for_size_p (cfun)
9548 || !TARGET_PARTIAL_FLAG_REG_STALL
9549 || (operands[2] == const1_rtx
9551 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9552 && ix86_match_ccmode (insn, CCGOCmode)
9553 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9555 switch (get_attr_type (insn))
9558 gcc_assert (operands[2] == const1_rtx);
9559 return "add{<imodesuffix>}\t%0, %0";
9562 if (operands[2] == const1_rtx
9563 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9564 return "sal{<imodesuffix>}\t%0";
9566 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9570 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9571 (match_operand 0 "register_operand"))
9572 (match_operand 2 "const1_operand"))
9573 (const_string "alu")
9575 (const_string "ishift")))
9576 (set (attr "length_immediate")
9578 (ior (eq_attr "type" "alu")
9579 (and (eq_attr "type" "ishift")
9580 (and (match_operand 2 "const1_operand")
9581 (ior (match_test "TARGET_SHIFT1")
9582 (match_test "optimize_function_for_size_p (cfun)")))))
9584 (const_string "*")))
9585 (set_attr "mode" "<MODE>")])
9587 (define_insn "*ashlsi3_cmp_zext"
9588 [(set (reg FLAGS_REG)
9590 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9591 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9593 (set (match_operand:DI 0 "register_operand" "=r")
9594 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9596 && (optimize_function_for_size_p (cfun)
9597 || !TARGET_PARTIAL_FLAG_REG_STALL
9598 || (operands[2] == const1_rtx
9600 || TARGET_DOUBLE_WITH_ADD)))
9601 && ix86_match_ccmode (insn, CCGOCmode)
9602 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9604 switch (get_attr_type (insn))
9607 gcc_assert (operands[2] == const1_rtx);
9608 return "add{l}\t%k0, %k0";
9611 if (operands[2] == const1_rtx
9612 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9613 return "sal{l}\t%k0";
9615 return "sal{l}\t{%2, %k0|%k0, %2}";
9619 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9620 (match_operand 2 "const1_operand"))
9621 (const_string "alu")
9623 (const_string "ishift")))
9624 (set (attr "length_immediate")
9626 (ior (eq_attr "type" "alu")
9627 (and (eq_attr "type" "ishift")
9628 (and (match_operand 2 "const1_operand")
9629 (ior (match_test "TARGET_SHIFT1")
9630 (match_test "optimize_function_for_size_p (cfun)")))))
9632 (const_string "*")))
9633 (set_attr "mode" "SI")])
9635 (define_insn "*ashl<mode>3_cconly"
9636 [(set (reg FLAGS_REG)
9638 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9639 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9641 (clobber (match_scratch:SWI 0 "=<r>"))]
9642 "(optimize_function_for_size_p (cfun)
9643 || !TARGET_PARTIAL_FLAG_REG_STALL
9644 || (operands[2] == const1_rtx
9646 || TARGET_DOUBLE_WITH_ADD)))
9647 && ix86_match_ccmode (insn, CCGOCmode)"
9649 switch (get_attr_type (insn))
9652 gcc_assert (operands[2] == const1_rtx);
9653 return "add{<imodesuffix>}\t%0, %0";
9656 if (operands[2] == const1_rtx
9657 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9658 return "sal{<imodesuffix>}\t%0";
9660 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9664 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9665 (match_operand 0 "register_operand"))
9666 (match_operand 2 "const1_operand"))
9667 (const_string "alu")
9669 (const_string "ishift")))
9670 (set (attr "length_immediate")
9672 (ior (eq_attr "type" "alu")
9673 (and (eq_attr "type" "ishift")
9674 (and (match_operand 2 "const1_operand")
9675 (ior (match_test "TARGET_SHIFT1")
9676 (match_test "optimize_function_for_size_p (cfun)")))))
9678 (const_string "*")))
9679 (set_attr "mode" "<MODE>")])
9681 ;; See comment above `ashl<mode>3' about how this works.
9683 (define_expand "<shift_insn><mode>3"
9684 [(set (match_operand:SDWIM 0 "<shift_operand>")
9685 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9686 (match_operand:QI 2 "nonmemory_operand")))]
9688 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9690 ;; Avoid useless masking of count operand.
9691 (define_insn_and_split "*<shift_insn><mode>3_mask"
9692 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9694 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9697 (match_operand:SI 2 "nonimmediate_operand" "c")
9698 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9699 (clobber (reg:CC FLAGS_REG))]
9700 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9701 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9702 == GET_MODE_BITSIZE (<MODE>mode)-1"
9705 [(parallel [(set (match_dup 0)
9706 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9707 (clobber (reg:CC FLAGS_REG))])]
9709 if (can_create_pseudo_p ())
9710 operands [2] = force_reg (SImode, operands[2]);
9712 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9714 [(set_attr "type" "ishift")
9715 (set_attr "mode" "<MODE>")])
9717 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9718 [(set (match_operand:DWI 0 "register_operand" "=r")
9719 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9720 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9721 (clobber (reg:CC FLAGS_REG))]
9724 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9726 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9727 [(set_attr "type" "multi")])
9729 ;; By default we don't ask for a scratch register, because when DWImode
9730 ;; values are manipulated, registers are already at a premium. But if
9731 ;; we have one handy, we won't turn it away.
9734 [(match_scratch:DWIH 3 "r")
9735 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9737 (match_operand:<DWI> 1 "register_operand")
9738 (match_operand:QI 2 "nonmemory_operand")))
9739 (clobber (reg:CC FLAGS_REG))])
9743 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9745 (define_insn "x86_64_shrd"
9746 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9747 (ior:DI (ashiftrt:DI (match_dup 0)
9748 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9749 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9750 (minus:QI (const_int 64) (match_dup 2)))))
9751 (clobber (reg:CC FLAGS_REG))]
9753 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9754 [(set_attr "type" "ishift")
9755 (set_attr "prefix_0f" "1")
9756 (set_attr "mode" "DI")
9757 (set_attr "athlon_decode" "vector")
9758 (set_attr "amdfam10_decode" "vector")
9759 (set_attr "bdver1_decode" "vector")])
9761 (define_insn "x86_shrd"
9762 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9763 (ior:SI (ashiftrt:SI (match_dup 0)
9764 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9765 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9766 (minus:QI (const_int 32) (match_dup 2)))))
9767 (clobber (reg:CC FLAGS_REG))]
9769 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9770 [(set_attr "type" "ishift")
9771 (set_attr "prefix_0f" "1")
9772 (set_attr "mode" "SI")
9773 (set_attr "pent_pair" "np")
9774 (set_attr "athlon_decode" "vector")
9775 (set_attr "amdfam10_decode" "vector")
9776 (set_attr "bdver1_decode" "vector")])
9778 (define_insn "ashrdi3_cvt"
9779 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9780 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9781 (match_operand:QI 2 "const_int_operand")))
9782 (clobber (reg:CC FLAGS_REG))]
9783 "TARGET_64BIT && INTVAL (operands[2]) == 63
9784 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9785 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9788 sar{q}\t{%2, %0|%0, %2}"
9789 [(set_attr "type" "imovx,ishift")
9790 (set_attr "prefix_0f" "0,*")
9791 (set_attr "length_immediate" "0,*")
9792 (set_attr "modrm" "0,1")
9793 (set_attr "mode" "DI")])
9795 (define_insn "ashrsi3_cvt"
9796 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9797 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9798 (match_operand:QI 2 "const_int_operand")))
9799 (clobber (reg:CC FLAGS_REG))]
9800 "INTVAL (operands[2]) == 31
9801 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9802 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9805 sar{l}\t{%2, %0|%0, %2}"
9806 [(set_attr "type" "imovx,ishift")
9807 (set_attr "prefix_0f" "0,*")
9808 (set_attr "length_immediate" "0,*")
9809 (set_attr "modrm" "0,1")
9810 (set_attr "mode" "SI")])
9812 (define_insn "*ashrsi3_cvt_zext"
9813 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9815 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9816 (match_operand:QI 2 "const_int_operand"))))
9817 (clobber (reg:CC FLAGS_REG))]
9818 "TARGET_64BIT && INTVAL (operands[2]) == 31
9819 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9820 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9823 sar{l}\t{%2, %k0|%k0, %2}"
9824 [(set_attr "type" "imovx,ishift")
9825 (set_attr "prefix_0f" "0,*")
9826 (set_attr "length_immediate" "0,*")
9827 (set_attr "modrm" "0,1")
9828 (set_attr "mode" "SI")])
9830 (define_expand "x86_shift<mode>_adj_3"
9831 [(use (match_operand:SWI48 0 "register_operand"))
9832 (use (match_operand:SWI48 1 "register_operand"))
9833 (use (match_operand:QI 2 "register_operand"))]
9836 rtx label = gen_label_rtx ();
9839 emit_insn (gen_testqi_ccz_1 (operands[2],
9840 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9842 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9843 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9844 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9845 gen_rtx_LABEL_REF (VOIDmode, label),
9847 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9848 JUMP_LABEL (tmp) = label;
9850 emit_move_insn (operands[0], operands[1]);
9851 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9852 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9854 LABEL_NUSES (label) = 1;
9859 (define_insn "*bmi2_<shift_insn><mode>3_1"
9860 [(set (match_operand:SWI48 0 "register_operand" "=r")
9861 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9862 (match_operand:SWI48 2 "register_operand" "r")))]
9864 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9865 [(set_attr "type" "ishiftx")
9866 (set_attr "mode" "<MODE>")])
9868 (define_insn "*<shift_insn><mode>3_1"
9869 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9871 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9872 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9873 (clobber (reg:CC FLAGS_REG))]
9874 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9876 switch (get_attr_type (insn))
9882 if (operands[2] == const1_rtx
9883 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9884 return "<shift>{<imodesuffix>}\t%0";
9886 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9889 [(set_attr "isa" "*,bmi2")
9890 (set_attr "type" "ishift,ishiftx")
9891 (set (attr "length_immediate")
9893 (and (match_operand 2 "const1_operand")
9894 (ior (match_test "TARGET_SHIFT1")
9895 (match_test "optimize_function_for_size_p (cfun)")))
9897 (const_string "*")))
9898 (set_attr "mode" "<MODE>")])
9900 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9902 [(set (match_operand:SWI48 0 "register_operand")
9903 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9904 (match_operand:QI 2 "register_operand")))
9905 (clobber (reg:CC FLAGS_REG))]
9906 "TARGET_BMI2 && reload_completed"
9908 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9909 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9911 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9912 [(set (match_operand:DI 0 "register_operand" "=r")
9914 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9915 (match_operand:SI 2 "register_operand" "r"))))]
9916 "TARGET_64BIT && TARGET_BMI2"
9917 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9918 [(set_attr "type" "ishiftx")
9919 (set_attr "mode" "SI")])
9921 (define_insn "*<shift_insn>si3_1_zext"
9922 [(set (match_operand:DI 0 "register_operand" "=r,r")
9924 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9925 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9926 (clobber (reg:CC FLAGS_REG))]
9927 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9929 switch (get_attr_type (insn))
9935 if (operands[2] == const1_rtx
9936 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9937 return "<shift>{l}\t%k0";
9939 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9942 [(set_attr "isa" "*,bmi2")
9943 (set_attr "type" "ishift,ishiftx")
9944 (set (attr "length_immediate")
9946 (and (match_operand 2 "const1_operand")
9947 (ior (match_test "TARGET_SHIFT1")
9948 (match_test "optimize_function_for_size_p (cfun)")))
9950 (const_string "*")))
9951 (set_attr "mode" "SI")])
9953 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9955 [(set (match_operand:DI 0 "register_operand")
9957 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9958 (match_operand:QI 2 "register_operand"))))
9959 (clobber (reg:CC FLAGS_REG))]
9960 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9962 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9963 "operands[2] = gen_lowpart (SImode, operands[2]);")
9965 (define_insn "*<shift_insn><mode>3_1"
9966 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9968 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9969 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9970 (clobber (reg:CC FLAGS_REG))]
9971 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9973 if (operands[2] == const1_rtx
9974 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9975 return "<shift>{<imodesuffix>}\t%0";
9977 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9979 [(set_attr "type" "ishift")
9980 (set (attr "length_immediate")
9982 (and (match_operand 2 "const1_operand")
9983 (ior (match_test "TARGET_SHIFT1")
9984 (match_test "optimize_function_for_size_p (cfun)")))
9986 (const_string "*")))
9987 (set_attr "mode" "<MODE>")])
9989 (define_insn "*<shift_insn>qi3_1_slp"
9990 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9991 (any_shiftrt:QI (match_dup 0)
9992 (match_operand:QI 1 "nonmemory_operand" "cI")))
9993 (clobber (reg:CC FLAGS_REG))]
9994 "(optimize_function_for_size_p (cfun)
9995 || !TARGET_PARTIAL_REG_STALL
9996 || (operands[1] == const1_rtx
9999 if (operands[1] == const1_rtx
10000 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10001 return "<shift>{b}\t%0";
10003 return "<shift>{b}\t{%1, %0|%0, %1}";
10005 [(set_attr "type" "ishift1")
10006 (set (attr "length_immediate")
10008 (and (match_operand 1 "const1_operand")
10009 (ior (match_test "TARGET_SHIFT1")
10010 (match_test "optimize_function_for_size_p (cfun)")))
10012 (const_string "*")))
10013 (set_attr "mode" "QI")])
10015 ;; This pattern can't accept a variable shift count, since shifts by
10016 ;; zero don't affect the flags. We assume that shifts by constant
10017 ;; zero are optimized away.
10018 (define_insn "*<shift_insn><mode>3_cmp"
10019 [(set (reg FLAGS_REG)
10022 (match_operand:SWI 1 "nonimmediate_operand" "0")
10023 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10025 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10026 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10027 "(optimize_function_for_size_p (cfun)
10028 || !TARGET_PARTIAL_FLAG_REG_STALL
10029 || (operands[2] == const1_rtx
10031 && ix86_match_ccmode (insn, CCGOCmode)
10032 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10034 if (operands[2] == const1_rtx
10035 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10036 return "<shift>{<imodesuffix>}\t%0";
10038 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10040 [(set_attr "type" "ishift")
10041 (set (attr "length_immediate")
10043 (and (match_operand 2 "const1_operand")
10044 (ior (match_test "TARGET_SHIFT1")
10045 (match_test "optimize_function_for_size_p (cfun)")))
10047 (const_string "*")))
10048 (set_attr "mode" "<MODE>")])
10050 (define_insn "*<shift_insn>si3_cmp_zext"
10051 [(set (reg FLAGS_REG)
10053 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10054 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10056 (set (match_operand:DI 0 "register_operand" "=r")
10057 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10059 && (optimize_function_for_size_p (cfun)
10060 || !TARGET_PARTIAL_FLAG_REG_STALL
10061 || (operands[2] == const1_rtx
10063 && ix86_match_ccmode (insn, CCGOCmode)
10064 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10066 if (operands[2] == const1_rtx
10067 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10068 return "<shift>{l}\t%k0";
10070 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10072 [(set_attr "type" "ishift")
10073 (set (attr "length_immediate")
10075 (and (match_operand 2 "const1_operand")
10076 (ior (match_test "TARGET_SHIFT1")
10077 (match_test "optimize_function_for_size_p (cfun)")))
10079 (const_string "*")))
10080 (set_attr "mode" "SI")])
10082 (define_insn "*<shift_insn><mode>3_cconly"
10083 [(set (reg FLAGS_REG)
10086 (match_operand:SWI 1 "register_operand" "0")
10087 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10089 (clobber (match_scratch:SWI 0 "=<r>"))]
10090 "(optimize_function_for_size_p (cfun)
10091 || !TARGET_PARTIAL_FLAG_REG_STALL
10092 || (operands[2] == const1_rtx
10094 && ix86_match_ccmode (insn, CCGOCmode)"
10096 if (operands[2] == const1_rtx
10097 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10098 return "<shift>{<imodesuffix>}\t%0";
10100 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10102 [(set_attr "type" "ishift")
10103 (set (attr "length_immediate")
10105 (and (match_operand 2 "const1_operand")
10106 (ior (match_test "TARGET_SHIFT1")
10107 (match_test "optimize_function_for_size_p (cfun)")))
10109 (const_string "*")))
10110 (set_attr "mode" "<MODE>")])
10112 ;; Rotate instructions
10114 (define_expand "<rotate_insn>ti3"
10115 [(set (match_operand:TI 0 "register_operand")
10116 (any_rotate:TI (match_operand:TI 1 "register_operand")
10117 (match_operand:QI 2 "nonmemory_operand")))]
10120 if (const_1_to_63_operand (operands[2], VOIDmode))
10121 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10122 (operands[0], operands[1], operands[2]));
10129 (define_expand "<rotate_insn>di3"
10130 [(set (match_operand:DI 0 "shiftdi_operand")
10131 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10132 (match_operand:QI 2 "nonmemory_operand")))]
10136 ix86_expand_binary_operator (<CODE>, DImode, operands);
10137 else if (const_1_to_31_operand (operands[2], VOIDmode))
10138 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10139 (operands[0], operands[1], operands[2]));
10146 (define_expand "<rotate_insn><mode>3"
10147 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10148 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10149 (match_operand:QI 2 "nonmemory_operand")))]
10151 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10153 ;; Avoid useless masking of count operand.
10154 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10155 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10157 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10160 (match_operand:SI 2 "nonimmediate_operand" "c")
10161 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10162 (clobber (reg:CC FLAGS_REG))]
10163 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10164 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10165 == GET_MODE_BITSIZE (<MODE>mode)-1"
10168 [(parallel [(set (match_dup 0)
10169 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10170 (clobber (reg:CC FLAGS_REG))])]
10172 if (can_create_pseudo_p ())
10173 operands [2] = force_reg (SImode, operands[2]);
10175 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10177 [(set_attr "type" "rotate")
10178 (set_attr "mode" "<MODE>")])
10180 ;; Implement rotation using two double-precision
10181 ;; shift instructions and a scratch register.
10183 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10184 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10185 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10186 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10187 (clobber (reg:CC FLAGS_REG))
10188 (clobber (match_scratch:DWIH 3 "=&r"))]
10192 [(set (match_dup 3) (match_dup 4))
10194 [(set (match_dup 4)
10195 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10196 (lshiftrt:DWIH (match_dup 5)
10197 (minus:QI (match_dup 6) (match_dup 2)))))
10198 (clobber (reg:CC FLAGS_REG))])
10200 [(set (match_dup 5)
10201 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10202 (lshiftrt:DWIH (match_dup 3)
10203 (minus:QI (match_dup 6) (match_dup 2)))))
10204 (clobber (reg:CC FLAGS_REG))])]
10206 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10208 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10211 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10212 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10213 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10214 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10215 (clobber (reg:CC FLAGS_REG))
10216 (clobber (match_scratch:DWIH 3 "=&r"))]
10220 [(set (match_dup 3) (match_dup 4))
10222 [(set (match_dup 4)
10223 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10224 (ashift:DWIH (match_dup 5)
10225 (minus:QI (match_dup 6) (match_dup 2)))))
10226 (clobber (reg:CC FLAGS_REG))])
10228 [(set (match_dup 5)
10229 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10230 (ashift:DWIH (match_dup 3)
10231 (minus:QI (match_dup 6) (match_dup 2)))))
10232 (clobber (reg:CC FLAGS_REG))])]
10234 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10236 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10239 (define_insn "*bmi2_rorx<mode>3_1"
10240 [(set (match_operand:SWI48 0 "register_operand" "=r")
10241 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10242 (match_operand:QI 2 "immediate_operand" "<S>")))]
10244 "rorx\t{%2, %1, %0|%0, %1, %2}"
10245 [(set_attr "type" "rotatex")
10246 (set_attr "mode" "<MODE>")])
10248 (define_insn "*<rotate_insn><mode>3_1"
10249 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10251 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10252 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10253 (clobber (reg:CC FLAGS_REG))]
10254 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10256 switch (get_attr_type (insn))
10262 if (operands[2] == const1_rtx
10263 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10264 return "<rotate>{<imodesuffix>}\t%0";
10266 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10269 [(set_attr "isa" "*,bmi2")
10270 (set_attr "type" "rotate,rotatex")
10271 (set (attr "length_immediate")
10273 (and (eq_attr "type" "rotate")
10274 (and (match_operand 2 "const1_operand")
10275 (ior (match_test "TARGET_SHIFT1")
10276 (match_test "optimize_function_for_size_p (cfun)"))))
10278 (const_string "*")))
10279 (set_attr "mode" "<MODE>")])
10281 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10283 [(set (match_operand:SWI48 0 "register_operand")
10284 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10285 (match_operand:QI 2 "immediate_operand")))
10286 (clobber (reg:CC FLAGS_REG))]
10287 "TARGET_BMI2 && reload_completed"
10288 [(set (match_dup 0)
10289 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10292 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10296 [(set (match_operand:SWI48 0 "register_operand")
10297 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10298 (match_operand:QI 2 "immediate_operand")))
10299 (clobber (reg:CC FLAGS_REG))]
10300 "TARGET_BMI2 && reload_completed"
10301 [(set (match_dup 0)
10302 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10304 (define_insn "*bmi2_rorxsi3_1_zext"
10305 [(set (match_operand:DI 0 "register_operand" "=r")
10307 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10308 (match_operand:QI 2 "immediate_operand" "I"))))]
10309 "TARGET_64BIT && TARGET_BMI2"
10310 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10311 [(set_attr "type" "rotatex")
10312 (set_attr "mode" "SI")])
10314 (define_insn "*<rotate_insn>si3_1_zext"
10315 [(set (match_operand:DI 0 "register_operand" "=r,r")
10317 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10318 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10319 (clobber (reg:CC FLAGS_REG))]
10320 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10322 switch (get_attr_type (insn))
10328 if (operands[2] == const1_rtx
10329 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10330 return "<rotate>{l}\t%k0";
10332 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10335 [(set_attr "isa" "*,bmi2")
10336 (set_attr "type" "rotate,rotatex")
10337 (set (attr "length_immediate")
10339 (and (eq_attr "type" "rotate")
10340 (and (match_operand 2 "const1_operand")
10341 (ior (match_test "TARGET_SHIFT1")
10342 (match_test "optimize_function_for_size_p (cfun)"))))
10344 (const_string "*")))
10345 (set_attr "mode" "SI")])
10347 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10349 [(set (match_operand:DI 0 "register_operand")
10351 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10352 (match_operand:QI 2 "immediate_operand"))))
10353 (clobber (reg:CC FLAGS_REG))]
10354 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10355 [(set (match_dup 0)
10356 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10359 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10363 [(set (match_operand:DI 0 "register_operand")
10365 (rotatert: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))))])
10372 (define_insn "*<rotate_insn><mode>3_1"
10373 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10374 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10375 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10376 (clobber (reg:CC FLAGS_REG))]
10377 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10379 if (operands[2] == const1_rtx
10380 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10381 return "<rotate>{<imodesuffix>}\t%0";
10383 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10385 [(set_attr "type" "rotate")
10386 (set (attr "length_immediate")
10388 (and (match_operand 2 "const1_operand")
10389 (ior (match_test "TARGET_SHIFT1")
10390 (match_test "optimize_function_for_size_p (cfun)")))
10392 (const_string "*")))
10393 (set_attr "mode" "<MODE>")])
10395 (define_insn "*<rotate_insn>qi3_1_slp"
10396 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10397 (any_rotate:QI (match_dup 0)
10398 (match_operand:QI 1 "nonmemory_operand" "cI")))
10399 (clobber (reg:CC FLAGS_REG))]
10400 "(optimize_function_for_size_p (cfun)
10401 || !TARGET_PARTIAL_REG_STALL
10402 || (operands[1] == const1_rtx
10403 && TARGET_SHIFT1))"
10405 if (operands[1] == const1_rtx
10406 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10407 return "<rotate>{b}\t%0";
10409 return "<rotate>{b}\t{%1, %0|%0, %1}";
10411 [(set_attr "type" "rotate1")
10412 (set (attr "length_immediate")
10414 (and (match_operand 1 "const1_operand")
10415 (ior (match_test "TARGET_SHIFT1")
10416 (match_test "optimize_function_for_size_p (cfun)")))
10418 (const_string "*")))
10419 (set_attr "mode" "QI")])
10422 [(set (match_operand:HI 0 "register_operand")
10423 (any_rotate:HI (match_dup 0) (const_int 8)))
10424 (clobber (reg:CC FLAGS_REG))]
10426 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10427 [(parallel [(set (strict_low_part (match_dup 0))
10428 (bswap:HI (match_dup 0)))
10429 (clobber (reg:CC FLAGS_REG))])])
10431 ;; Bit set / bit test instructions
10433 (define_expand "extv"
10434 [(set (match_operand:SI 0 "register_operand")
10435 (sign_extract:SI (match_operand:SI 1 "register_operand")
10436 (match_operand:SI 2 "const8_operand")
10437 (match_operand:SI 3 "const8_operand")))]
10440 /* Handle extractions from %ah et al. */
10441 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10444 /* From mips.md: extract_bit_field doesn't verify that our source
10445 matches the predicate, so check it again here. */
10446 if (! ext_register_operand (operands[1], VOIDmode))
10450 (define_expand "extzv"
10451 [(set (match_operand:SI 0 "register_operand")
10452 (zero_extract:SI (match_operand 1 "ext_register_operand")
10453 (match_operand:SI 2 "const8_operand")
10454 (match_operand:SI 3 "const8_operand")))]
10457 /* Handle extractions from %ah et al. */
10458 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10461 /* From mips.md: extract_bit_field doesn't verify that our source
10462 matches the predicate, so check it again here. */
10463 if (! ext_register_operand (operands[1], VOIDmode))
10467 (define_expand "insv"
10468 [(set (zero_extract (match_operand 0 "register_operand")
10469 (match_operand 1 "const_int_operand")
10470 (match_operand 2 "const_int_operand"))
10471 (match_operand 3 "register_operand"))]
10474 rtx (*gen_mov_insv_1) (rtx, rtx);
10476 if (ix86_expand_pinsr (operands))
10479 /* Handle insertions to %ah et al. */
10480 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10483 /* From mips.md: insert_bit_field doesn't verify that our source
10484 matches the predicate, so check it again here. */
10485 if (! ext_register_operand (operands[0], VOIDmode))
10488 gen_mov_insv_1 = (TARGET_64BIT
10489 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10491 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10495 ;; %%% bts, btr, btc, bt.
10496 ;; In general these instructions are *slow* when applied to memory,
10497 ;; since they enforce atomic operation. When applied to registers,
10498 ;; it depends on the cpu implementation. They're never faster than
10499 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10500 ;; no point. But in 64-bit, we can't hold the relevant immediates
10501 ;; within the instruction itself, so operating on bits in the high
10502 ;; 32-bits of a register becomes easier.
10504 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10505 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10506 ;; negdf respectively, so they can never be disabled entirely.
10508 (define_insn "*btsq"
10509 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10511 (match_operand:DI 1 "const_0_to_63_operand"))
10513 (clobber (reg:CC FLAGS_REG))]
10514 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10515 "bts{q}\t{%1, %0|%0, %1}"
10516 [(set_attr "type" "alu1")
10517 (set_attr "prefix_0f" "1")
10518 (set_attr "mode" "DI")])
10520 (define_insn "*btrq"
10521 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10523 (match_operand:DI 1 "const_0_to_63_operand"))
10525 (clobber (reg:CC FLAGS_REG))]
10526 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10527 "btr{q}\t{%1, %0|%0, %1}"
10528 [(set_attr "type" "alu1")
10529 (set_attr "prefix_0f" "1")
10530 (set_attr "mode" "DI")])
10532 (define_insn "*btcq"
10533 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10535 (match_operand:DI 1 "const_0_to_63_operand"))
10536 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10537 (clobber (reg:CC FLAGS_REG))]
10538 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10539 "btc{q}\t{%1, %0|%0, %1}"
10540 [(set_attr "type" "alu1")
10541 (set_attr "prefix_0f" "1")
10542 (set_attr "mode" "DI")])
10544 ;; Allow Nocona to avoid these instructions if a register is available.
10547 [(match_scratch:DI 2 "r")
10548 (parallel [(set (zero_extract:DI
10549 (match_operand:DI 0 "register_operand")
10551 (match_operand:DI 1 "const_0_to_63_operand"))
10553 (clobber (reg:CC FLAGS_REG))])]
10554 "TARGET_64BIT && !TARGET_USE_BT"
10557 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10560 if (HOST_BITS_PER_WIDE_INT >= 64)
10561 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10562 else if (i < HOST_BITS_PER_WIDE_INT)
10563 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10565 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10567 op1 = immed_double_const (lo, hi, DImode);
10570 emit_move_insn (operands[2], op1);
10574 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10579 [(match_scratch:DI 2 "r")
10580 (parallel [(set (zero_extract:DI
10581 (match_operand:DI 0 "register_operand")
10583 (match_operand:DI 1 "const_0_to_63_operand"))
10585 (clobber (reg:CC FLAGS_REG))])]
10586 "TARGET_64BIT && !TARGET_USE_BT"
10589 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10592 if (HOST_BITS_PER_WIDE_INT >= 64)
10593 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10594 else if (i < HOST_BITS_PER_WIDE_INT)
10595 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10597 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10599 op1 = immed_double_const (~lo, ~hi, DImode);
10602 emit_move_insn (operands[2], op1);
10606 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10611 [(match_scratch:DI 2 "r")
10612 (parallel [(set (zero_extract:DI
10613 (match_operand:DI 0 "register_operand")
10615 (match_operand:DI 1 "const_0_to_63_operand"))
10616 (not:DI (zero_extract:DI
10617 (match_dup 0) (const_int 1) (match_dup 1))))
10618 (clobber (reg:CC FLAGS_REG))])]
10619 "TARGET_64BIT && !TARGET_USE_BT"
10622 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10625 if (HOST_BITS_PER_WIDE_INT >= 64)
10626 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10627 else if (i < HOST_BITS_PER_WIDE_INT)
10628 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10630 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10632 op1 = immed_double_const (lo, hi, DImode);
10635 emit_move_insn (operands[2], op1);
10639 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10643 (define_insn "*bt<mode>"
10644 [(set (reg:CCC FLAGS_REG)
10646 (zero_extract:SWI48
10647 (match_operand:SWI48 0 "register_operand" "r")
10649 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10651 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10652 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10653 [(set_attr "type" "alu1")
10654 (set_attr "prefix_0f" "1")
10655 (set_attr "mode" "<MODE>")])
10657 ;; Store-flag instructions.
10659 ;; For all sCOND expanders, also expand the compare or test insn that
10660 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10662 (define_insn_and_split "*setcc_di_1"
10663 [(set (match_operand:DI 0 "register_operand" "=q")
10664 (match_operator:DI 1 "ix86_comparison_operator"
10665 [(reg FLAGS_REG) (const_int 0)]))]
10666 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10668 "&& reload_completed"
10669 [(set (match_dup 2) (match_dup 1))
10670 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10672 PUT_MODE (operands[1], QImode);
10673 operands[2] = gen_lowpart (QImode, operands[0]);
10676 (define_insn_and_split "*setcc_si_1_and"
10677 [(set (match_operand:SI 0 "register_operand" "=q")
10678 (match_operator:SI 1 "ix86_comparison_operator"
10679 [(reg FLAGS_REG) (const_int 0)]))
10680 (clobber (reg:CC FLAGS_REG))]
10681 "!TARGET_PARTIAL_REG_STALL
10682 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10684 "&& reload_completed"
10685 [(set (match_dup 2) (match_dup 1))
10686 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10687 (clobber (reg:CC FLAGS_REG))])]
10689 PUT_MODE (operands[1], QImode);
10690 operands[2] = gen_lowpart (QImode, operands[0]);
10693 (define_insn_and_split "*setcc_si_1_movzbl"
10694 [(set (match_operand:SI 0 "register_operand" "=q")
10695 (match_operator:SI 1 "ix86_comparison_operator"
10696 [(reg FLAGS_REG) (const_int 0)]))]
10697 "!TARGET_PARTIAL_REG_STALL
10698 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10700 "&& reload_completed"
10701 [(set (match_dup 2) (match_dup 1))
10702 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10704 PUT_MODE (operands[1], QImode);
10705 operands[2] = gen_lowpart (QImode, operands[0]);
10708 (define_insn "*setcc_qi"
10709 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10710 (match_operator:QI 1 "ix86_comparison_operator"
10711 [(reg FLAGS_REG) (const_int 0)]))]
10714 [(set_attr "type" "setcc")
10715 (set_attr "mode" "QI")])
10717 (define_insn "*setcc_qi_slp"
10718 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10719 (match_operator:QI 1 "ix86_comparison_operator"
10720 [(reg FLAGS_REG) (const_int 0)]))]
10723 [(set_attr "type" "setcc")
10724 (set_attr "mode" "QI")])
10726 ;; In general it is not safe to assume too much about CCmode registers,
10727 ;; so simplify-rtx stops when it sees a second one. Under certain
10728 ;; conditions this is safe on x86, so help combine not create
10735 [(set (match_operand:QI 0 "nonimmediate_operand")
10736 (ne:QI (match_operator 1 "ix86_comparison_operator"
10737 [(reg FLAGS_REG) (const_int 0)])
10740 [(set (match_dup 0) (match_dup 1))]
10741 "PUT_MODE (operands[1], QImode);")
10744 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10745 (ne:QI (match_operator 1 "ix86_comparison_operator"
10746 [(reg FLAGS_REG) (const_int 0)])
10749 [(set (match_dup 0) (match_dup 1))]
10750 "PUT_MODE (operands[1], QImode);")
10753 [(set (match_operand:QI 0 "nonimmediate_operand")
10754 (eq:QI (match_operator 1 "ix86_comparison_operator"
10755 [(reg FLAGS_REG) (const_int 0)])
10758 [(set (match_dup 0) (match_dup 1))]
10760 rtx new_op1 = copy_rtx (operands[1]);
10761 operands[1] = new_op1;
10762 PUT_MODE (new_op1, QImode);
10763 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10764 GET_MODE (XEXP (new_op1, 0))));
10766 /* Make sure that (a) the CCmode we have for the flags is strong
10767 enough for the reversed compare or (b) we have a valid FP compare. */
10768 if (! ix86_comparison_operator (new_op1, VOIDmode))
10773 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10774 (eq:QI (match_operator 1 "ix86_comparison_operator"
10775 [(reg FLAGS_REG) (const_int 0)])
10778 [(set (match_dup 0) (match_dup 1))]
10780 rtx new_op1 = copy_rtx (operands[1]);
10781 operands[1] = new_op1;
10782 PUT_MODE (new_op1, QImode);
10783 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10784 GET_MODE (XEXP (new_op1, 0))));
10786 /* Make sure that (a) the CCmode we have for the flags is strong
10787 enough for the reversed compare or (b) we have a valid FP compare. */
10788 if (! ix86_comparison_operator (new_op1, VOIDmode))
10792 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10793 ;; subsequent logical operations are used to imitate conditional moves.
10794 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10797 (define_insn "setcc_<mode>_sse"
10798 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10799 (match_operator:MODEF 3 "sse_comparison_operator"
10800 [(match_operand:MODEF 1 "register_operand" "0,x")
10801 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10802 "SSE_FLOAT_MODE_P (<MODE>mode)"
10804 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10805 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10806 [(set_attr "isa" "noavx,avx")
10807 (set_attr "type" "ssecmp")
10808 (set_attr "length_immediate" "1")
10809 (set_attr "prefix" "orig,vex")
10810 (set_attr "mode" "<MODE>")])
10812 ;; Basic conditional jump instructions.
10813 ;; We ignore the overflow flag for signed branch instructions.
10815 (define_insn "*jcc_1"
10817 (if_then_else (match_operator 1 "ix86_comparison_operator"
10818 [(reg FLAGS_REG) (const_int 0)])
10819 (label_ref (match_operand 0))
10823 [(set_attr "type" "ibr")
10824 (set_attr "modrm" "0")
10825 (set (attr "length")
10826 (if_then_else (and (ge (minus (match_dup 0) (pc))
10828 (lt (minus (match_dup 0) (pc))
10833 (define_insn "*jcc_2"
10835 (if_then_else (match_operator 1 "ix86_comparison_operator"
10836 [(reg FLAGS_REG) (const_int 0)])
10838 (label_ref (match_operand 0))))]
10841 [(set_attr "type" "ibr")
10842 (set_attr "modrm" "0")
10843 (set (attr "length")
10844 (if_then_else (and (ge (minus (match_dup 0) (pc))
10846 (lt (minus (match_dup 0) (pc))
10851 ;; In general it is not safe to assume too much about CCmode registers,
10852 ;; so simplify-rtx stops when it sees a second one. Under certain
10853 ;; conditions this is safe on x86, so help combine not create
10861 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10862 [(reg FLAGS_REG) (const_int 0)])
10864 (label_ref (match_operand 1))
10868 (if_then_else (match_dup 0)
10869 (label_ref (match_dup 1))
10871 "PUT_MODE (operands[0], VOIDmode);")
10875 (if_then_else (eq (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))
10886 rtx new_op0 = copy_rtx (operands[0]);
10887 operands[0] = new_op0;
10888 PUT_MODE (new_op0, VOIDmode);
10889 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10890 GET_MODE (XEXP (new_op0, 0))));
10892 /* Make sure that (a) the CCmode we have for the flags is strong
10893 enough for the reversed compare or (b) we have a valid FP compare. */
10894 if (! ix86_comparison_operator (new_op0, VOIDmode))
10898 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10899 ;; pass generates from shift insn with QImode operand. Actually, the mode
10900 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10901 ;; appropriate modulo of the bit offset value.
10903 (define_insn_and_split "*jcc_bt<mode>"
10905 (if_then_else (match_operator 0 "bt_comparison_operator"
10906 [(zero_extract:SWI48
10907 (match_operand:SWI48 1 "register_operand" "r")
10910 (match_operand:QI 2 "register_operand" "r")))
10912 (label_ref (match_operand 3))
10914 (clobber (reg:CC FLAGS_REG))]
10915 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10918 [(set (reg:CCC FLAGS_REG)
10920 (zero_extract:SWI48
10926 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10927 (label_ref (match_dup 3))
10930 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10932 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10935 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10936 ;; also for DImode, this is what combine produces.
10937 (define_insn_and_split "*jcc_bt<mode>_mask"
10939 (if_then_else (match_operator 0 "bt_comparison_operator"
10940 [(zero_extract:SWI48
10941 (match_operand:SWI48 1 "register_operand" "r")
10944 (match_operand:SI 2 "register_operand" "r")
10945 (match_operand:SI 3 "const_int_operand" "n")))])
10946 (label_ref (match_operand 4))
10948 (clobber (reg:CC FLAGS_REG))]
10949 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10950 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10951 == GET_MODE_BITSIZE (<MODE>mode)-1"
10954 [(set (reg:CCC FLAGS_REG)
10956 (zero_extract:SWI48
10962 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10963 (label_ref (match_dup 4))
10966 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10968 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10971 (define_insn_and_split "*jcc_btsi_1"
10973 (if_then_else (match_operator 0 "bt_comparison_operator"
10976 (match_operand:SI 1 "register_operand" "r")
10977 (match_operand:QI 2 "register_operand" "r"))
10980 (label_ref (match_operand 3))
10982 (clobber (reg:CC FLAGS_REG))]
10983 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10986 [(set (reg:CCC FLAGS_REG)
10994 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10995 (label_ref (match_dup 3))
10998 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11000 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11003 ;; avoid useless masking of bit offset operand
11004 (define_insn_and_split "*jcc_btsi_mask_1"
11007 (match_operator 0 "bt_comparison_operator"
11010 (match_operand:SI 1 "register_operand" "r")
11013 (match_operand:SI 2 "register_operand" "r")
11014 (match_operand:SI 3 "const_int_operand" "n")) 0))
11017 (label_ref (match_operand 4))
11019 (clobber (reg:CC FLAGS_REG))]
11020 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11021 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11024 [(set (reg:CCC FLAGS_REG)
11032 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11033 (label_ref (match_dup 4))
11035 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11037 ;; Define combination compare-and-branch fp compare instructions to help
11040 (define_insn "*fp_jcc_1_387"
11042 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11043 [(match_operand 1 "register_operand" "f")
11044 (match_operand 2 "nonimmediate_operand" "fm")])
11045 (label_ref (match_operand 3))
11047 (clobber (reg:CCFP FPSR_REG))
11048 (clobber (reg:CCFP FLAGS_REG))
11049 (clobber (match_scratch:HI 4 "=a"))]
11051 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11052 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11053 && SELECT_CC_MODE (GET_CODE (operands[0]),
11054 operands[1], operands[2]) == CCFPmode
11058 (define_insn "*fp_jcc_1r_387"
11060 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11061 [(match_operand 1 "register_operand" "f")
11062 (match_operand 2 "nonimmediate_operand" "fm")])
11064 (label_ref (match_operand 3))))
11065 (clobber (reg:CCFP FPSR_REG))
11066 (clobber (reg:CCFP FLAGS_REG))
11067 (clobber (match_scratch:HI 4 "=a"))]
11069 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11070 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11071 && SELECT_CC_MODE (GET_CODE (operands[0]),
11072 operands[1], operands[2]) == CCFPmode
11076 (define_insn "*fp_jcc_2_387"
11078 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11079 [(match_operand 1 "register_operand" "f")
11080 (match_operand 2 "register_operand" "f")])
11081 (label_ref (match_operand 3))
11083 (clobber (reg:CCFP FPSR_REG))
11084 (clobber (reg:CCFP FLAGS_REG))
11085 (clobber (match_scratch:HI 4 "=a"))]
11086 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11087 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11091 (define_insn "*fp_jcc_2r_387"
11093 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11094 [(match_operand 1 "register_operand" "f")
11095 (match_operand 2 "register_operand" "f")])
11097 (label_ref (match_operand 3))))
11098 (clobber (reg:CCFP FPSR_REG))
11099 (clobber (reg:CCFP FLAGS_REG))
11100 (clobber (match_scratch:HI 4 "=a"))]
11101 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11102 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11106 (define_insn "*fp_jcc_3_387"
11108 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11109 [(match_operand 1 "register_operand" "f")
11110 (match_operand 2 "const0_operand")])
11111 (label_ref (match_operand 3))
11113 (clobber (reg:CCFP FPSR_REG))
11114 (clobber (reg:CCFP FLAGS_REG))
11115 (clobber (match_scratch:HI 4 "=a"))]
11116 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11117 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11118 && SELECT_CC_MODE (GET_CODE (operands[0]),
11119 operands[1], operands[2]) == CCFPmode
11125 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11126 [(match_operand 1 "register_operand")
11127 (match_operand 2 "nonimmediate_operand")])
11129 (match_operand 4)))
11130 (clobber (reg:CCFP FPSR_REG))
11131 (clobber (reg:CCFP FLAGS_REG))]
11135 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11136 operands[3], operands[4], NULL_RTX, NULL_RTX);
11142 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11143 [(match_operand 1 "register_operand")
11144 (match_operand 2 "general_operand")])
11146 (match_operand 4)))
11147 (clobber (reg:CCFP FPSR_REG))
11148 (clobber (reg:CCFP FLAGS_REG))
11149 (clobber (match_scratch:HI 5 "=a"))]
11153 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11154 operands[3], operands[4], operands[5], NULL_RTX);
11158 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11159 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11160 ;; with a precedence over other operators and is always put in the first
11161 ;; place. Swap condition and operands to match ficom instruction.
11163 (define_insn "*fp_jcc_4_<mode>_387"
11166 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11167 [(match_operator 1 "float_operator"
11168 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11169 (match_operand 3 "register_operand" "f,f")])
11170 (label_ref (match_operand 4))
11172 (clobber (reg:CCFP FPSR_REG))
11173 (clobber (reg:CCFP FLAGS_REG))
11174 (clobber (match_scratch:HI 5 "=a,a"))]
11175 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11176 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11177 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11178 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11185 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11186 [(match_operator 1 "float_operator"
11187 [(match_operand:SWI24 2 "memory_operand")])
11188 (match_operand 3 "register_operand")])
11190 (match_operand 5)))
11191 (clobber (reg:CCFP FPSR_REG))
11192 (clobber (reg:CCFP FLAGS_REG))
11193 (clobber (match_scratch:HI 6 "=a"))]
11197 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11199 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11200 operands[3], operands[7],
11201 operands[4], operands[5], operands[6], NULL_RTX);
11205 ;; %%% Kill this when reload knows how to do it.
11209 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11210 [(match_operator 1 "float_operator"
11211 [(match_operand:SWI24 2 "register_operand")])
11212 (match_operand 3 "register_operand")])
11214 (match_operand 5)))
11215 (clobber (reg:CCFP FPSR_REG))
11216 (clobber (reg:CCFP FLAGS_REG))
11217 (clobber (match_scratch:HI 6 "=a"))]
11221 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11222 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11224 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11225 operands[3], operands[7],
11226 operands[4], operands[5], operands[6], operands[2]);
11230 ;; Unconditional and other jump instructions
11232 (define_insn "jump"
11234 (label_ref (match_operand 0)))]
11237 [(set_attr "type" "ibr")
11238 (set (attr "length")
11239 (if_then_else (and (ge (minus (match_dup 0) (pc))
11241 (lt (minus (match_dup 0) (pc))
11245 (set_attr "modrm" "0")])
11247 (define_expand "indirect_jump"
11248 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11252 operands[0] = convert_memory_address (word_mode, operands[0]);
11255 (define_insn "*indirect_jump"
11256 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11259 [(set_attr "type" "ibr")
11260 (set_attr "length_immediate" "0")])
11262 (define_expand "tablejump"
11263 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11264 (use (label_ref (match_operand 1)))])]
11267 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11268 relative. Convert the relative address to an absolute address. */
11272 enum rtx_code code;
11274 /* We can't use @GOTOFF for text labels on VxWorks;
11275 see gotoff_operand. */
11276 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11280 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11282 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11286 op1 = pic_offset_table_rtx;
11291 op0 = pic_offset_table_rtx;
11295 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11300 operands[0] = convert_memory_address (word_mode, operands[0]);
11303 (define_insn "*tablejump_1"
11304 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11305 (use (label_ref (match_operand 1)))]
11308 [(set_attr "type" "ibr")
11309 (set_attr "length_immediate" "0")])
11311 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11314 [(set (reg FLAGS_REG) (match_operand 0))
11315 (set (match_operand:QI 1 "register_operand")
11316 (match_operator:QI 2 "ix86_comparison_operator"
11317 [(reg FLAGS_REG) (const_int 0)]))
11318 (set (match_operand 3 "q_regs_operand")
11319 (zero_extend (match_dup 1)))]
11320 "(peep2_reg_dead_p (3, operands[1])
11321 || operands_match_p (operands[1], operands[3]))
11322 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11323 [(set (match_dup 4) (match_dup 0))
11324 (set (strict_low_part (match_dup 5))
11327 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11328 operands[5] = gen_lowpart (QImode, operands[3]);
11329 ix86_expand_clear (operands[3]);
11333 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11334 (match_operand 4)])
11335 (set (match_operand:QI 1 "register_operand")
11336 (match_operator:QI 2 "ix86_comparison_operator"
11337 [(reg FLAGS_REG) (const_int 0)]))
11338 (set (match_operand 3 "q_regs_operand")
11339 (zero_extend (match_dup 1)))]
11340 "(peep2_reg_dead_p (3, operands[1])
11341 || operands_match_p (operands[1], operands[3]))
11342 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11343 [(parallel [(set (match_dup 5) (match_dup 0))
11345 (set (strict_low_part (match_dup 6))
11348 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11349 operands[6] = gen_lowpart (QImode, operands[3]);
11350 ix86_expand_clear (operands[3]);
11353 ;; Similar, but match zero extend with andsi3.
11356 [(set (reg FLAGS_REG) (match_operand 0))
11357 (set (match_operand:QI 1 "register_operand")
11358 (match_operator:QI 2 "ix86_comparison_operator"
11359 [(reg FLAGS_REG) (const_int 0)]))
11360 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11361 (and:SI (match_dup 3) (const_int 255)))
11362 (clobber (reg:CC FLAGS_REG))])]
11363 "REGNO (operands[1]) == REGNO (operands[3])
11364 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11365 [(set (match_dup 4) (match_dup 0))
11366 (set (strict_low_part (match_dup 5))
11369 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11370 operands[5] = gen_lowpart (QImode, operands[3]);
11371 ix86_expand_clear (operands[3]);
11375 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11376 (match_operand 4)])
11377 (set (match_operand:QI 1 "register_operand")
11378 (match_operator:QI 2 "ix86_comparison_operator"
11379 [(reg FLAGS_REG) (const_int 0)]))
11380 (parallel [(set (match_operand 3 "q_regs_operand")
11381 (zero_extend (match_dup 1)))
11382 (clobber (reg:CC FLAGS_REG))])]
11383 "(peep2_reg_dead_p (3, operands[1])
11384 || operands_match_p (operands[1], operands[3]))
11385 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11386 [(parallel [(set (match_dup 5) (match_dup 0))
11388 (set (strict_low_part (match_dup 6))
11391 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11392 operands[6] = gen_lowpart (QImode, operands[3]);
11393 ix86_expand_clear (operands[3]);
11396 ;; Call instructions.
11398 ;; The predicates normally associated with named expanders are not properly
11399 ;; checked for calls. This is a bug in the generic code, but it isn't that
11400 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11402 ;; P6 processors will jump to the address after the decrement when %esp
11403 ;; is used as a call operand, so they will execute return address as a code.
11404 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11406 ;; Register constraint for call instruction.
11407 (define_mode_attr c [(SI "l") (DI "r")])
11409 ;; Call subroutine returning no value.
11411 (define_expand "call"
11412 [(call (match_operand:QI 0)
11414 (use (match_operand 2))]
11417 ix86_expand_call (NULL, operands[0], operands[1],
11418 operands[2], NULL, false);
11422 (define_expand "sibcall"
11423 [(call (match_operand:QI 0)
11425 (use (match_operand 2))]
11428 ix86_expand_call (NULL, operands[0], operands[1],
11429 operands[2], NULL, true);
11433 (define_insn_and_split "*call_vzeroupper"
11434 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11436 (unspec [(match_operand 2 "const_int_operand")]
11437 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11438 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11440 "&& reload_completed"
11442 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11443 [(set_attr "type" "call")])
11445 (define_insn "*call"
11446 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11447 (match_operand 1))]
11448 "!SIBLING_CALL_P (insn)"
11449 "* return ix86_output_call_insn (insn, operands[0]);"
11450 [(set_attr "type" "call")])
11452 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11453 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11455 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11456 (clobber (reg:TI XMM6_REG))
11457 (clobber (reg:TI XMM7_REG))
11458 (clobber (reg:TI XMM8_REG))
11459 (clobber (reg:TI XMM9_REG))
11460 (clobber (reg:TI XMM10_REG))
11461 (clobber (reg:TI XMM11_REG))
11462 (clobber (reg:TI XMM12_REG))
11463 (clobber (reg:TI XMM13_REG))
11464 (clobber (reg:TI XMM14_REG))
11465 (clobber (reg:TI XMM15_REG))
11466 (clobber (reg:DI SI_REG))
11467 (clobber (reg:DI DI_REG))
11468 (unspec [(match_operand 2 "const_int_operand")]
11469 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11470 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11472 "&& reload_completed"
11474 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11475 [(set_attr "type" "call")])
11477 (define_insn "*call_rex64_ms_sysv"
11478 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11480 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11481 (clobber (reg:TI XMM6_REG))
11482 (clobber (reg:TI XMM7_REG))
11483 (clobber (reg:TI XMM8_REG))
11484 (clobber (reg:TI XMM9_REG))
11485 (clobber (reg:TI XMM10_REG))
11486 (clobber (reg:TI XMM11_REG))
11487 (clobber (reg:TI XMM12_REG))
11488 (clobber (reg:TI XMM13_REG))
11489 (clobber (reg:TI XMM14_REG))
11490 (clobber (reg:TI XMM15_REG))
11491 (clobber (reg:DI SI_REG))
11492 (clobber (reg:DI DI_REG))]
11493 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11494 "* return ix86_output_call_insn (insn, operands[0]);"
11495 [(set_attr "type" "call")])
11497 (define_insn_and_split "*sibcall_vzeroupper"
11498 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11500 (unspec [(match_operand 2 "const_int_operand")]
11501 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11502 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11504 "&& reload_completed"
11506 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11507 [(set_attr "type" "call")])
11509 (define_insn "*sibcall"
11510 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11511 (match_operand 1))]
11512 "SIBLING_CALL_P (insn)"
11513 "* return ix86_output_call_insn (insn, operands[0]);"
11514 [(set_attr "type" "call")])
11516 (define_expand "call_pop"
11517 [(parallel [(call (match_operand:QI 0)
11518 (match_operand:SI 1))
11519 (set (reg:SI SP_REG)
11520 (plus:SI (reg:SI SP_REG)
11521 (match_operand:SI 3)))])]
11524 ix86_expand_call (NULL, operands[0], operands[1],
11525 operands[2], operands[3], false);
11529 (define_insn_and_split "*call_pop_vzeroupper"
11530 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11532 (set (reg:SI SP_REG)
11533 (plus:SI (reg:SI SP_REG)
11534 (match_operand:SI 2 "immediate_operand" "i")))
11535 (unspec [(match_operand 3 "const_int_operand")]
11536 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11537 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11539 "&& reload_completed"
11541 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11542 [(set_attr "type" "call")])
11544 (define_insn "*call_pop"
11545 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11547 (set (reg:SI SP_REG)
11548 (plus:SI (reg:SI SP_REG)
11549 (match_operand:SI 2 "immediate_operand" "i")))]
11550 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11551 "* return ix86_output_call_insn (insn, operands[0]);"
11552 [(set_attr "type" "call")])
11554 (define_insn_and_split "*sibcall_pop_vzeroupper"
11555 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11557 (set (reg:SI SP_REG)
11558 (plus:SI (reg:SI SP_REG)
11559 (match_operand:SI 2 "immediate_operand" "i")))
11560 (unspec [(match_operand 3 "const_int_operand")]
11561 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11562 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11564 "&& reload_completed"
11566 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11567 [(set_attr "type" "call")])
11569 (define_insn "*sibcall_pop"
11570 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11572 (set (reg:SI SP_REG)
11573 (plus:SI (reg:SI SP_REG)
11574 (match_operand:SI 2 "immediate_operand" "i")))]
11575 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11576 "* return ix86_output_call_insn (insn, operands[0]);"
11577 [(set_attr "type" "call")])
11579 ;; Call subroutine, returning value in operand 0
11581 (define_expand "call_value"
11582 [(set (match_operand 0)
11583 (call (match_operand:QI 1)
11584 (match_operand 2)))
11585 (use (match_operand 3))]
11588 ix86_expand_call (operands[0], operands[1], operands[2],
11589 operands[3], NULL, false);
11593 (define_expand "sibcall_value"
11594 [(set (match_operand 0)
11595 (call (match_operand:QI 1)
11596 (match_operand 2)))
11597 (use (match_operand 3))]
11600 ix86_expand_call (operands[0], operands[1], operands[2],
11601 operands[3], NULL, true);
11605 (define_insn_and_split "*call_value_vzeroupper"
11606 [(set (match_operand 0)
11607 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11608 (match_operand 2)))
11609 (unspec [(match_operand 3 "const_int_operand")]
11610 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11611 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11613 "&& reload_completed"
11615 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11616 [(set_attr "type" "callv")])
11618 (define_insn "*call_value"
11619 [(set (match_operand 0)
11620 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11621 (match_operand 2)))]
11622 "!SIBLING_CALL_P (insn)"
11623 "* return ix86_output_call_insn (insn, operands[1]);"
11624 [(set_attr "type" "callv")])
11626 (define_insn_and_split "*sibcall_value_vzeroupper"
11627 [(set (match_operand 0)
11628 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11629 (match_operand 2)))
11630 (unspec [(match_operand 3 "const_int_operand")]
11631 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11632 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11634 "&& reload_completed"
11636 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11637 [(set_attr "type" "callv")])
11639 (define_insn "*sibcall_value"
11640 [(set (match_operand 0)
11641 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11642 (match_operand 2)))]
11643 "SIBLING_CALL_P (insn)"
11644 "* return ix86_output_call_insn (insn, operands[1]);"
11645 [(set_attr "type" "callv")])
11647 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11648 [(set (match_operand 0)
11649 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11650 (match_operand 2)))
11651 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11652 (clobber (reg:TI XMM6_REG))
11653 (clobber (reg:TI XMM7_REG))
11654 (clobber (reg:TI XMM8_REG))
11655 (clobber (reg:TI XMM9_REG))
11656 (clobber (reg:TI XMM10_REG))
11657 (clobber (reg:TI XMM11_REG))
11658 (clobber (reg:TI XMM12_REG))
11659 (clobber (reg:TI XMM13_REG))
11660 (clobber (reg:TI XMM14_REG))
11661 (clobber (reg:TI XMM15_REG))
11662 (clobber (reg:DI SI_REG))
11663 (clobber (reg:DI DI_REG))
11664 (unspec [(match_operand 3 "const_int_operand")]
11665 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11666 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11668 "&& reload_completed"
11670 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11671 [(set_attr "type" "callv")])
11673 (define_insn "*call_value_rex64_ms_sysv"
11674 [(set (match_operand 0)
11675 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11676 (match_operand 2)))
11677 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11678 (clobber (reg:TI XMM6_REG))
11679 (clobber (reg:TI XMM7_REG))
11680 (clobber (reg:TI XMM8_REG))
11681 (clobber (reg:TI XMM9_REG))
11682 (clobber (reg:TI XMM10_REG))
11683 (clobber (reg:TI XMM11_REG))
11684 (clobber (reg:TI XMM12_REG))
11685 (clobber (reg:TI XMM13_REG))
11686 (clobber (reg:TI XMM14_REG))
11687 (clobber (reg:TI XMM15_REG))
11688 (clobber (reg:DI SI_REG))
11689 (clobber (reg:DI DI_REG))]
11690 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11691 "* return ix86_output_call_insn (insn, operands[1]);"
11692 [(set_attr "type" "callv")])
11694 (define_expand "call_value_pop"
11695 [(parallel [(set (match_operand 0)
11696 (call (match_operand:QI 1)
11697 (match_operand:SI 2)))
11698 (set (reg:SI SP_REG)
11699 (plus:SI (reg:SI SP_REG)
11700 (match_operand:SI 4)))])]
11703 ix86_expand_call (operands[0], operands[1], operands[2],
11704 operands[3], operands[4], false);
11708 (define_insn_and_split "*call_value_pop_vzeroupper"
11709 [(set (match_operand 0)
11710 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11711 (match_operand 2)))
11712 (set (reg:SI SP_REG)
11713 (plus:SI (reg:SI SP_REG)
11714 (match_operand:SI 3 "immediate_operand" "i")))
11715 (unspec [(match_operand 4 "const_int_operand")]
11716 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11717 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11719 "&& reload_completed"
11721 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11722 [(set_attr "type" "callv")])
11724 (define_insn "*call_value_pop"
11725 [(set (match_operand 0)
11726 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11727 (match_operand 2)))
11728 (set (reg:SI SP_REG)
11729 (plus:SI (reg:SI SP_REG)
11730 (match_operand:SI 3 "immediate_operand" "i")))]
11731 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11732 "* return ix86_output_call_insn (insn, operands[1]);"
11733 [(set_attr "type" "callv")])
11735 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11736 [(set (match_operand 0)
11737 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11738 (match_operand 2)))
11739 (set (reg:SI SP_REG)
11740 (plus:SI (reg:SI SP_REG)
11741 (match_operand:SI 3 "immediate_operand" "i")))
11742 (unspec [(match_operand 4 "const_int_operand")]
11743 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11744 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11746 "&& reload_completed"
11748 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11749 [(set_attr "type" "callv")])
11751 (define_insn "*sibcall_value_pop"
11752 [(set (match_operand 0)
11753 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11754 (match_operand 2)))
11755 (set (reg:SI SP_REG)
11756 (plus:SI (reg:SI SP_REG)
11757 (match_operand:SI 3 "immediate_operand" "i")))]
11758 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11759 "* return ix86_output_call_insn (insn, operands[1]);"
11760 [(set_attr "type" "callv")])
11762 ;; Call subroutine returning any type.
11764 (define_expand "untyped_call"
11765 [(parallel [(call (match_operand 0)
11768 (match_operand 2)])]
11773 /* In order to give reg-stack an easier job in validating two
11774 coprocessor registers as containing a possible return value,
11775 simply pretend the untyped call returns a complex long double
11778 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11779 and should have the default ABI. */
11781 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11782 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11783 operands[0], const0_rtx,
11784 GEN_INT ((TARGET_64BIT
11785 ? (ix86_abi == SYSV_ABI
11786 ? X86_64_SSE_REGPARM_MAX
11787 : X86_64_MS_SSE_REGPARM_MAX)
11788 : X86_32_SSE_REGPARM_MAX)
11792 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11794 rtx set = XVECEXP (operands[2], 0, i);
11795 emit_move_insn (SET_DEST (set), SET_SRC (set));
11798 /* The optimizer does not know that the call sets the function value
11799 registers we stored in the result block. We avoid problems by
11800 claiming that all hard registers are used and clobbered at this
11802 emit_insn (gen_blockage ());
11807 ;; Prologue and epilogue instructions
11809 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11810 ;; all of memory. This blocks insns from being moved across this point.
11812 (define_insn "blockage"
11813 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11816 [(set_attr "length" "0")])
11818 ;; Do not schedule instructions accessing memory across this point.
11820 (define_expand "memory_blockage"
11821 [(set (match_dup 0)
11822 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11825 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11826 MEM_VOLATILE_P (operands[0]) = 1;
11829 (define_insn "*memory_blockage"
11830 [(set (match_operand:BLK 0)
11831 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11834 [(set_attr "length" "0")])
11836 ;; As USE insns aren't meaningful after reload, this is used instead
11837 ;; to prevent deleting instructions setting registers for PIC code
11838 (define_insn "prologue_use"
11839 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11842 [(set_attr "length" "0")])
11844 ;; Insn emitted into the body of a function to return from a function.
11845 ;; This is only done if the function's epilogue is known to be simple.
11846 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11848 (define_expand "return"
11850 "ix86_can_use_return_insn_p ()"
11852 ix86_maybe_emit_epilogue_vzeroupper ();
11853 if (crtl->args.pops_args)
11855 rtx popc = GEN_INT (crtl->args.pops_args);
11856 emit_jump_insn (gen_simple_return_pop_internal (popc));
11861 ;; We need to disable this for TARGET_SEH, as otherwise
11862 ;; shrink-wrapped prologue gets enabled too. This might exceed
11863 ;; the maximum size of prologue in unwind information.
11865 (define_expand "simple_return"
11869 ix86_maybe_emit_epilogue_vzeroupper ();
11870 if (crtl->args.pops_args)
11872 rtx popc = GEN_INT (crtl->args.pops_args);
11873 emit_jump_insn (gen_simple_return_pop_internal (popc));
11878 (define_insn "simple_return_internal"
11882 [(set_attr "length" "1")
11883 (set_attr "atom_unit" "jeu")
11884 (set_attr "length_immediate" "0")
11885 (set_attr "modrm" "0")])
11887 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11888 ;; instruction Athlon and K8 have.
11890 (define_insn "simple_return_internal_long"
11892 (unspec [(const_int 0)] UNSPEC_REP)]
11895 [(set_attr "length" "2")
11896 (set_attr "atom_unit" "jeu")
11897 (set_attr "length_immediate" "0")
11898 (set_attr "prefix_rep" "1")
11899 (set_attr "modrm" "0")])
11901 (define_insn "simple_return_pop_internal"
11903 (use (match_operand:SI 0 "const_int_operand"))]
11906 [(set_attr "length" "3")
11907 (set_attr "atom_unit" "jeu")
11908 (set_attr "length_immediate" "2")
11909 (set_attr "modrm" "0")])
11911 (define_insn "simple_return_indirect_internal"
11913 (use (match_operand:SI 0 "register_operand" "r"))]
11916 [(set_attr "type" "ibr")
11917 (set_attr "length_immediate" "0")])
11923 [(set_attr "length" "1")
11924 (set_attr "length_immediate" "0")
11925 (set_attr "modrm" "0")])
11927 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11928 (define_insn "nops"
11929 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11933 int num = INTVAL (operands[0]);
11935 gcc_assert (num >= 1 && num <= 8);
11938 fputs ("\tnop\n", asm_out_file);
11942 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11943 (set_attr "length_immediate" "0")
11944 (set_attr "modrm" "0")])
11946 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11947 ;; branch prediction penalty for the third jump in a 16-byte
11951 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11954 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11955 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11957 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11958 The align insn is used to avoid 3 jump instructions in the row to improve
11959 branch prediction and the benefits hardly outweigh the cost of extra 8
11960 nops on the average inserted by full alignment pseudo operation. */
11964 [(set_attr "length" "16")])
11966 (define_expand "prologue"
11969 "ix86_expand_prologue (); DONE;")
11971 (define_insn "set_got"
11972 [(set (match_operand:SI 0 "register_operand" "=r")
11973 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11974 (clobber (reg:CC FLAGS_REG))]
11976 "* return output_set_got (operands[0], NULL_RTX);"
11977 [(set_attr "type" "multi")
11978 (set_attr "length" "12")])
11980 (define_insn "set_got_labelled"
11981 [(set (match_operand:SI 0 "register_operand" "=r")
11982 (unspec:SI [(label_ref (match_operand 1))]
11984 (clobber (reg:CC FLAGS_REG))]
11986 "* return output_set_got (operands[0], operands[1]);"
11987 [(set_attr "type" "multi")
11988 (set_attr "length" "12")])
11990 (define_insn "set_got_rex64"
11991 [(set (match_operand:DI 0 "register_operand" "=r")
11992 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11994 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11995 [(set_attr "type" "lea")
11996 (set_attr "length_address" "4")
11997 (set_attr "mode" "DI")])
11999 (define_insn "set_rip_rex64"
12000 [(set (match_operand:DI 0 "register_operand" "=r")
12001 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12003 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12004 [(set_attr "type" "lea")
12005 (set_attr "length_address" "4")
12006 (set_attr "mode" "DI")])
12008 (define_insn "set_got_offset_rex64"
12009 [(set (match_operand:DI 0 "register_operand" "=r")
12011 [(label_ref (match_operand 1))]
12012 UNSPEC_SET_GOT_OFFSET))]
12014 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12015 [(set_attr "type" "imov")
12016 (set_attr "length_immediate" "0")
12017 (set_attr "length_address" "8")
12018 (set_attr "mode" "DI")])
12020 (define_expand "epilogue"
12023 "ix86_expand_epilogue (1); DONE;")
12025 (define_expand "sibcall_epilogue"
12028 "ix86_expand_epilogue (0); DONE;")
12030 (define_expand "eh_return"
12031 [(use (match_operand 0 "register_operand"))]
12034 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12036 /* Tricky bit: we write the address of the handler to which we will
12037 be returning into someone else's stack frame, one word below the
12038 stack address we wish to restore. */
12039 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12040 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12041 tmp = gen_rtx_MEM (Pmode, tmp);
12042 emit_move_insn (tmp, ra);
12044 emit_jump_insn (gen_eh_return_internal ());
12049 (define_insn_and_split "eh_return_internal"
12053 "epilogue_completed"
12055 "ix86_expand_epilogue (2); DONE;")
12057 (define_insn "leave"
12058 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12059 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12060 (clobber (mem:BLK (scratch)))]
12063 [(set_attr "type" "leave")])
12065 (define_insn "leave_rex64"
12066 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12067 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12068 (clobber (mem:BLK (scratch)))]
12071 [(set_attr "type" "leave")])
12073 ;; Handle -fsplit-stack.
12075 (define_expand "split_stack_prologue"
12079 ix86_expand_split_stack_prologue ();
12083 ;; In order to support the call/return predictor, we use a return
12084 ;; instruction which the middle-end doesn't see.
12085 (define_insn "split_stack_return"
12086 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12087 UNSPECV_SPLIT_STACK_RETURN)]
12090 if (operands[0] == const0_rtx)
12095 [(set_attr "atom_unit" "jeu")
12096 (set_attr "modrm" "0")
12097 (set (attr "length")
12098 (if_then_else (match_operand:SI 0 "const0_operand")
12101 (set (attr "length_immediate")
12102 (if_then_else (match_operand:SI 0 "const0_operand")
12106 ;; If there are operand 0 bytes available on the stack, jump to
12109 (define_expand "split_stack_space_check"
12110 [(set (pc) (if_then_else
12111 (ltu (minus (reg SP_REG)
12112 (match_operand 0 "register_operand"))
12113 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12114 (label_ref (match_operand 1))
12118 rtx reg, size, limit;
12120 reg = gen_reg_rtx (Pmode);
12121 size = force_reg (Pmode, operands[0]);
12122 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12123 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12124 UNSPEC_STACK_CHECK);
12125 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12126 ix86_expand_branch (GEU, reg, limit, operands[1]);
12131 ;; Bit manipulation instructions.
12133 (define_expand "ffs<mode>2"
12134 [(set (match_dup 2) (const_int -1))
12135 (parallel [(set (reg:CCZ FLAGS_REG)
12137 (match_operand:SWI48 1 "nonimmediate_operand")
12139 (set (match_operand:SWI48 0 "register_operand")
12140 (ctz:SWI48 (match_dup 1)))])
12141 (set (match_dup 0) (if_then_else:SWI48
12142 (eq (reg:CCZ FLAGS_REG) (const_int 0))
12145 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12146 (clobber (reg:CC FLAGS_REG))])]
12149 if (<MODE>mode == SImode && !TARGET_CMOVE)
12151 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12154 operands[2] = gen_reg_rtx (<MODE>mode);
12157 (define_insn_and_split "ffssi2_no_cmove"
12158 [(set (match_operand:SI 0 "register_operand" "=r")
12159 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12160 (clobber (match_scratch:SI 2 "=&q"))
12161 (clobber (reg:CC FLAGS_REG))]
12164 "&& reload_completed"
12165 [(parallel [(set (reg:CCZ FLAGS_REG)
12166 (compare:CCZ (match_dup 1) (const_int 0)))
12167 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12168 (set (strict_low_part (match_dup 3))
12169 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12170 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12171 (clobber (reg:CC FLAGS_REG))])
12172 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12173 (clobber (reg:CC FLAGS_REG))])
12174 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12175 (clobber (reg:CC FLAGS_REG))])]
12177 operands[3] = gen_lowpart (QImode, operands[2]);
12178 ix86_expand_clear (operands[2]);
12181 (define_insn "*ffs<mode>_1"
12182 [(set (reg:CCZ FLAGS_REG)
12183 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12185 (set (match_operand:SWI48 0 "register_operand" "=r")
12186 (ctz:SWI48 (match_dup 1)))]
12190 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12191 else if (optimize_function_for_size_p (cfun))
12193 else if (TARGET_GENERIC)
12194 /* tzcnt expands to rep;bsf and we can use it even if !TARGET_BMI. */
12195 return "rep; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12197 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12199 [(set_attr "type" "alu1")
12200 (set_attr "prefix_0f" "1")
12201 (set (attr "prefix_rep")
12203 (ior (match_test "TARGET_BMI")
12204 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12205 (match_test "TARGET_GENERIC")))
12207 (const_string "0")))
12208 (set_attr "mode" "<MODE>")])
12210 (define_insn "ctz<mode>2"
12211 [(set (match_operand:SWI248 0 "register_operand" "=r")
12212 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12213 (clobber (reg:CC FLAGS_REG))]
12217 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12218 else if (optimize_function_for_size_p (cfun))
12220 else if (TARGET_GENERIC)
12221 /* tzcnt expands to rep;bsf and we can use it even if !TARGET_BMI. */
12222 return "rep; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12224 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12226 [(set_attr "type" "alu1")
12227 (set_attr "prefix_0f" "1")
12228 (set (attr "prefix_rep")
12230 (ior (match_test "TARGET_BMI")
12231 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12232 (match_test "TARGET_GENERIC")))
12234 (const_string "0")))
12235 (set_attr "mode" "<MODE>")])
12237 (define_expand "clz<mode>2"
12239 [(set (match_operand:SWI248 0 "register_operand")
12242 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12243 (clobber (reg:CC FLAGS_REG))])
12245 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12246 (clobber (reg:CC FLAGS_REG))])]
12251 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12254 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12257 (define_insn "clz<mode>2_lzcnt"
12258 [(set (match_operand:SWI248 0 "register_operand" "=r")
12259 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12260 (clobber (reg:CC FLAGS_REG))]
12262 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12263 [(set_attr "prefix_rep" "1")
12264 (set_attr "type" "bitmanip")
12265 (set_attr "mode" "<MODE>")])
12267 ;; BMI instructions.
12268 (define_insn "*bmi_andn_<mode>"
12269 [(set (match_operand:SWI48 0 "register_operand" "=r")
12272 (match_operand:SWI48 1 "register_operand" "r"))
12273 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12274 (clobber (reg:CC FLAGS_REG))]
12276 "andn\t{%2, %1, %0|%0, %1, %2}"
12277 [(set_attr "type" "bitmanip")
12278 (set_attr "mode" "<MODE>")])
12280 (define_insn "bmi_bextr_<mode>"
12281 [(set (match_operand:SWI48 0 "register_operand" "=r")
12282 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12283 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12285 (clobber (reg:CC FLAGS_REG))]
12287 "bextr\t{%2, %1, %0|%0, %1, %2}"
12288 [(set_attr "type" "bitmanip")
12289 (set_attr "mode" "<MODE>")])
12291 (define_insn "*bmi_blsi_<mode>"
12292 [(set (match_operand:SWI48 0 "register_operand" "=r")
12295 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12297 (clobber (reg:CC FLAGS_REG))]
12299 "blsi\t{%1, %0|%0, %1}"
12300 [(set_attr "type" "bitmanip")
12301 (set_attr "mode" "<MODE>")])
12303 (define_insn "*bmi_blsmsk_<mode>"
12304 [(set (match_operand:SWI48 0 "register_operand" "=r")
12307 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12310 (clobber (reg:CC FLAGS_REG))]
12312 "blsmsk\t{%1, %0|%0, %1}"
12313 [(set_attr "type" "bitmanip")
12314 (set_attr "mode" "<MODE>")])
12316 (define_insn "*bmi_blsr_<mode>"
12317 [(set (match_operand:SWI48 0 "register_operand" "=r")
12320 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12323 (clobber (reg:CC FLAGS_REG))]
12325 "blsr\t{%1, %0|%0, %1}"
12326 [(set_attr "type" "bitmanip")
12327 (set_attr "mode" "<MODE>")])
12329 ;; BMI2 instructions.
12330 (define_insn "bmi2_bzhi_<mode>3"
12331 [(set (match_operand:SWI48 0 "register_operand" "=r")
12332 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12333 (lshiftrt:SWI48 (const_int -1)
12334 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12335 (clobber (reg:CC FLAGS_REG))]
12337 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12338 [(set_attr "type" "bitmanip")
12339 (set_attr "prefix" "vex")
12340 (set_attr "mode" "<MODE>")])
12342 (define_insn "bmi2_pdep_<mode>3"
12343 [(set (match_operand:SWI48 0 "register_operand" "=r")
12344 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12345 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12348 "pdep\t{%2, %1, %0|%0, %1, %2}"
12349 [(set_attr "type" "bitmanip")
12350 (set_attr "prefix" "vex")
12351 (set_attr "mode" "<MODE>")])
12353 (define_insn "bmi2_pext_<mode>3"
12354 [(set (match_operand:SWI48 0 "register_operand" "=r")
12355 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12356 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12359 "pext\t{%2, %1, %0|%0, %1, %2}"
12360 [(set_attr "type" "bitmanip")
12361 (set_attr "prefix" "vex")
12362 (set_attr "mode" "<MODE>")])
12364 ;; TBM instructions.
12365 (define_insn "tbm_bextri_<mode>"
12366 [(set (match_operand:SWI48 0 "register_operand" "=r")
12367 (zero_extract:SWI48
12368 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12369 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12370 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12371 (clobber (reg:CC FLAGS_REG))]
12374 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12375 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12377 [(set_attr "type" "bitmanip")
12378 (set_attr "mode" "<MODE>")])
12380 (define_insn "*tbm_blcfill_<mode>"
12381 [(set (match_operand:SWI48 0 "register_operand" "=r")
12384 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12387 (clobber (reg:CC FLAGS_REG))]
12389 "blcfill\t{%1, %0|%0, %1}"
12390 [(set_attr "type" "bitmanip")
12391 (set_attr "mode" "<MODE>")])
12393 (define_insn "*tbm_blci_<mode>"
12394 [(set (match_operand:SWI48 0 "register_operand" "=r")
12398 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12401 (clobber (reg:CC FLAGS_REG))]
12403 "blci\t{%1, %0|%0, %1}"
12404 [(set_attr "type" "bitmanip")
12405 (set_attr "mode" "<MODE>")])
12407 (define_insn "*tbm_blcic_<mode>"
12408 [(set (match_operand:SWI48 0 "register_operand" "=r")
12411 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12415 (clobber (reg:CC FLAGS_REG))]
12417 "blcic\t{%1, %0|%0, %1}"
12418 [(set_attr "type" "bitmanip")
12419 (set_attr "mode" "<MODE>")])
12421 (define_insn "*tbm_blcmsk_<mode>"
12422 [(set (match_operand:SWI48 0 "register_operand" "=r")
12425 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12428 (clobber (reg:CC FLAGS_REG))]
12430 "blcmsk\t{%1, %0|%0, %1}"
12431 [(set_attr "type" "bitmanip")
12432 (set_attr "mode" "<MODE>")])
12434 (define_insn "*tbm_blcs_<mode>"
12435 [(set (match_operand:SWI48 0 "register_operand" "=r")
12438 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12441 (clobber (reg:CC FLAGS_REG))]
12443 "blcs\t{%1, %0|%0, %1}"
12444 [(set_attr "type" "bitmanip")
12445 (set_attr "mode" "<MODE>")])
12447 (define_insn "*tbm_blsfill_<mode>"
12448 [(set (match_operand:SWI48 0 "register_operand" "=r")
12451 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12454 (clobber (reg:CC FLAGS_REG))]
12456 "blsfill\t{%1, %0|%0, %1}"
12457 [(set_attr "type" "bitmanip")
12458 (set_attr "mode" "<MODE>")])
12460 (define_insn "*tbm_blsic_<mode>"
12461 [(set (match_operand:SWI48 0 "register_operand" "=r")
12464 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12468 (clobber (reg:CC FLAGS_REG))]
12470 "blsic\t{%1, %0|%0, %1}"
12471 [(set_attr "type" "bitmanip")
12472 (set_attr "mode" "<MODE>")])
12474 (define_insn "*tbm_t1mskc_<mode>"
12475 [(set (match_operand:SWI48 0 "register_operand" "=r")
12478 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12482 (clobber (reg:CC FLAGS_REG))]
12484 "t1mskc\t{%1, %0|%0, %1}"
12485 [(set_attr "type" "bitmanip")
12486 (set_attr "mode" "<MODE>")])
12488 (define_insn "*tbm_tzmsk_<mode>"
12489 [(set (match_operand:SWI48 0 "register_operand" "=r")
12492 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12496 (clobber (reg:CC FLAGS_REG))]
12498 "tzmsk\t{%1, %0|%0, %1}"
12499 [(set_attr "type" "bitmanip")
12500 (set_attr "mode" "<MODE>")])
12502 (define_insn "bsr_rex64"
12503 [(set (match_operand:DI 0 "register_operand" "=r")
12504 (minus:DI (const_int 63)
12505 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12506 (clobber (reg:CC FLAGS_REG))]
12508 "bsr{q}\t{%1, %0|%0, %1}"
12509 [(set_attr "type" "alu1")
12510 (set_attr "prefix_0f" "1")
12511 (set_attr "mode" "DI")])
12514 [(set (match_operand:SI 0 "register_operand" "=r")
12515 (minus:SI (const_int 31)
12516 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12517 (clobber (reg:CC FLAGS_REG))]
12519 "bsr{l}\t{%1, %0|%0, %1}"
12520 [(set_attr "type" "alu1")
12521 (set_attr "prefix_0f" "1")
12522 (set_attr "mode" "SI")])
12524 (define_insn "*bsrhi"
12525 [(set (match_operand:HI 0 "register_operand" "=r")
12526 (minus:HI (const_int 15)
12527 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12528 (clobber (reg:CC FLAGS_REG))]
12530 "bsr{w}\t{%1, %0|%0, %1}"
12531 [(set_attr "type" "alu1")
12532 (set_attr "prefix_0f" "1")
12533 (set_attr "mode" "HI")])
12535 (define_insn "popcount<mode>2"
12536 [(set (match_operand:SWI248 0 "register_operand" "=r")
12538 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12539 (clobber (reg:CC FLAGS_REG))]
12543 return "popcnt\t{%1, %0|%0, %1}";
12545 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12548 [(set_attr "prefix_rep" "1")
12549 (set_attr "type" "bitmanip")
12550 (set_attr "mode" "<MODE>")])
12552 (define_insn "*popcount<mode>2_cmp"
12553 [(set (reg FLAGS_REG)
12556 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12558 (set (match_operand:SWI248 0 "register_operand" "=r")
12559 (popcount:SWI248 (match_dup 1)))]
12560 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12563 return "popcnt\t{%1, %0|%0, %1}";
12565 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12568 [(set_attr "prefix_rep" "1")
12569 (set_attr "type" "bitmanip")
12570 (set_attr "mode" "<MODE>")])
12572 (define_insn "*popcountsi2_cmp_zext"
12573 [(set (reg FLAGS_REG)
12575 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12577 (set (match_operand:DI 0 "register_operand" "=r")
12578 (zero_extend:DI(popcount:SI (match_dup 1))))]
12579 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12582 return "popcnt\t{%1, %0|%0, %1}";
12584 return "popcnt{l}\t{%1, %0|%0, %1}";
12587 [(set_attr "prefix_rep" "1")
12588 (set_attr "type" "bitmanip")
12589 (set_attr "mode" "SI")])
12591 (define_expand "bswapdi2"
12592 [(set (match_operand:DI 0 "register_operand")
12593 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12596 if (TARGET_64BIT && !TARGET_MOVBE)
12597 operands[1] = force_reg (DImode, operands[1]);
12600 (define_insn_and_split "*bswapdi2_doubleword"
12601 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12603 (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12605 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12607 "&& reload_completed"
12608 [(set (match_dup 2)
12609 (bswap:SI (match_dup 1)))
12611 (bswap:SI (match_dup 3)))]
12613 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
12615 if (REG_P (operands[0]) && REG_P (operands[1]))
12617 emit_insn (gen_swapsi (operands[0], operands[2]));
12618 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12619 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12625 if (MEM_P (operands[0]))
12627 emit_insn (gen_bswapsi2 (operands[3], operands[3]));
12628 emit_insn (gen_bswapsi2 (operands[1], operands[1]));
12630 emit_move_insn (operands[0], operands[3]);
12631 emit_move_insn (operands[2], operands[1]);
12633 if (MEM_P (operands[1]))
12635 emit_move_insn (operands[2], operands[1]);
12636 emit_move_insn (operands[0], operands[3]);
12638 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12639 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12645 (define_expand "bswapsi2"
12646 [(set (match_operand:SI 0 "register_operand")
12647 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12652 else if (TARGET_BSWAP)
12653 operands[1] = force_reg (SImode, operands[1]);
12656 rtx x = operands[0];
12658 emit_move_insn (x, operands[1]);
12659 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12660 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12661 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12666 (define_insn "*bswap<mode>2_movbe"
12667 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12668 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12670 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12673 movbe\t{%1, %0|%0, %1}
12674 movbe\t{%1, %0|%0, %1}"
12675 [(set_attr "type" "bitmanip,imov,imov")
12676 (set_attr "modrm" "0,1,1")
12677 (set_attr "prefix_0f" "*,1,1")
12678 (set_attr "prefix_extra" "*,1,1")
12679 (set_attr "mode" "<MODE>")])
12681 (define_insn "*bswap<mode>2"
12682 [(set (match_operand:SWI48 0 "register_operand" "=r")
12683 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12686 [(set_attr "type" "bitmanip")
12687 (set_attr "modrm" "0")
12688 (set_attr "mode" "<MODE>")])
12690 (define_insn "*bswaphi_lowpart_1"
12691 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12692 (bswap:HI (match_dup 0)))
12693 (clobber (reg:CC FLAGS_REG))]
12694 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12696 xchg{b}\t{%h0, %b0|%b0, %h0}
12697 rol{w}\t{$8, %0|%0, 8}"
12698 [(set_attr "length" "2,4")
12699 (set_attr "mode" "QI,HI")])
12701 (define_insn "bswaphi_lowpart"
12702 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12703 (bswap:HI (match_dup 0)))
12704 (clobber (reg:CC FLAGS_REG))]
12706 "rol{w}\t{$8, %0|%0, 8}"
12707 [(set_attr "length" "4")
12708 (set_attr "mode" "HI")])
12710 (define_expand "paritydi2"
12711 [(set (match_operand:DI 0 "register_operand")
12712 (parity:DI (match_operand:DI 1 "register_operand")))]
12715 rtx scratch = gen_reg_rtx (QImode);
12718 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12719 NULL_RTX, operands[1]));
12721 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12722 gen_rtx_REG (CCmode, FLAGS_REG),
12724 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12727 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12730 rtx tmp = gen_reg_rtx (SImode);
12732 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12733 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12738 (define_expand "paritysi2"
12739 [(set (match_operand:SI 0 "register_operand")
12740 (parity:SI (match_operand:SI 1 "register_operand")))]
12743 rtx scratch = gen_reg_rtx (QImode);
12746 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12748 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12749 gen_rtx_REG (CCmode, FLAGS_REG),
12751 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12753 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12757 (define_insn_and_split "paritydi2_cmp"
12758 [(set (reg:CC FLAGS_REG)
12759 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12761 (clobber (match_scratch:DI 0 "=r"))
12762 (clobber (match_scratch:SI 1 "=&r"))
12763 (clobber (match_scratch:HI 2 "=Q"))]
12766 "&& reload_completed"
12768 [(set (match_dup 1)
12769 (xor:SI (match_dup 1) (match_dup 4)))
12770 (clobber (reg:CC FLAGS_REG))])
12772 [(set (reg:CC FLAGS_REG)
12773 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12774 (clobber (match_dup 1))
12775 (clobber (match_dup 2))])]
12777 operands[4] = gen_lowpart (SImode, operands[3]);
12781 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12782 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12785 operands[1] = gen_highpart (SImode, operands[3]);
12788 (define_insn_and_split "paritysi2_cmp"
12789 [(set (reg:CC FLAGS_REG)
12790 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12792 (clobber (match_scratch:SI 0 "=r"))
12793 (clobber (match_scratch:HI 1 "=&Q"))]
12796 "&& reload_completed"
12798 [(set (match_dup 1)
12799 (xor:HI (match_dup 1) (match_dup 3)))
12800 (clobber (reg:CC FLAGS_REG))])
12802 [(set (reg:CC FLAGS_REG)
12803 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12804 (clobber (match_dup 1))])]
12806 operands[3] = gen_lowpart (HImode, operands[2]);
12808 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12809 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12812 (define_insn "*parityhi2_cmp"
12813 [(set (reg:CC FLAGS_REG)
12814 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12816 (clobber (match_scratch:HI 0 "=Q"))]
12818 "xor{b}\t{%h0, %b0|%b0, %h0}"
12819 [(set_attr "length" "2")
12820 (set_attr "mode" "HI")])
12823 ;; Thread-local storage patterns for ELF.
12825 ;; Note that these code sequences must appear exactly as shown
12826 ;; in order to allow linker relaxation.
12828 (define_insn "*tls_global_dynamic_32_gnu"
12829 [(set (match_operand:SI 0 "register_operand" "=a")
12831 [(match_operand:SI 1 "register_operand" "b")
12832 (match_operand 2 "tls_symbolic_operand")
12833 (match_operand 3 "constant_call_address_operand" "z")]
12835 (clobber (match_scratch:SI 4 "=d"))
12836 (clobber (match_scratch:SI 5 "=c"))
12837 (clobber (reg:CC FLAGS_REG))]
12838 "!TARGET_64BIT && TARGET_GNU_TLS"
12841 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12842 if (TARGET_SUN_TLS)
12843 #ifdef HAVE_AS_IX86_TLSGDPLT
12844 return "call\t%a2@tlsgdplt";
12846 return "call\t%p3@plt";
12848 return "call\t%P3";
12850 [(set_attr "type" "multi")
12851 (set_attr "length" "12")])
12853 (define_expand "tls_global_dynamic_32"
12855 [(set (match_operand:SI 0 "register_operand")
12856 (unspec:SI [(match_operand:SI 2 "register_operand")
12857 (match_operand 1 "tls_symbolic_operand")
12858 (match_operand 3 "constant_call_address_operand")]
12860 (clobber (match_scratch:SI 4))
12861 (clobber (match_scratch:SI 5))
12862 (clobber (reg:CC FLAGS_REG))])])
12864 (define_insn "*tls_global_dynamic_64_<mode>"
12865 [(set (match_operand:P 0 "register_operand" "=a")
12867 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12868 (match_operand 3)))
12869 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12874 fputs (ASM_BYTE "0x66\n", asm_out_file);
12876 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12877 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12878 fputs ("\trex64\n", asm_out_file);
12879 if (TARGET_SUN_TLS)
12880 return "call\t%p2@plt";
12881 return "call\t%P2";
12883 [(set_attr "type" "multi")
12884 (set (attr "length")
12885 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12887 (define_expand "tls_global_dynamic_64_<mode>"
12889 [(set (match_operand:P 0 "register_operand")
12891 (mem:QI (match_operand 2 "constant_call_address_operand"))
12893 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12897 (define_insn "*tls_local_dynamic_base_32_gnu"
12898 [(set (match_operand:SI 0 "register_operand" "=a")
12900 [(match_operand:SI 1 "register_operand" "b")
12901 (match_operand 2 "constant_call_address_operand" "z")]
12902 UNSPEC_TLS_LD_BASE))
12903 (clobber (match_scratch:SI 3 "=d"))
12904 (clobber (match_scratch:SI 4 "=c"))
12905 (clobber (reg:CC FLAGS_REG))]
12906 "!TARGET_64BIT && TARGET_GNU_TLS"
12909 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12910 if (TARGET_SUN_TLS)
12911 #ifdef HAVE_AS_IX86_TLSLDMPLT
12912 return "call\t%&@tlsldmplt";
12914 return "call\t%p2@plt";
12916 return "call\t%P2";
12918 [(set_attr "type" "multi")
12919 (set_attr "length" "11")])
12921 (define_expand "tls_local_dynamic_base_32"
12923 [(set (match_operand:SI 0 "register_operand")
12925 [(match_operand:SI 1 "register_operand")
12926 (match_operand 2 "constant_call_address_operand")]
12927 UNSPEC_TLS_LD_BASE))
12928 (clobber (match_scratch:SI 3))
12929 (clobber (match_scratch:SI 4))
12930 (clobber (reg:CC FLAGS_REG))])])
12932 (define_insn "*tls_local_dynamic_base_64_<mode>"
12933 [(set (match_operand:P 0 "register_operand" "=a")
12935 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12936 (match_operand 2)))
12937 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12941 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12942 if (TARGET_SUN_TLS)
12943 return "call\t%p1@plt";
12944 return "call\t%P1";
12946 [(set_attr "type" "multi")
12947 (set_attr "length" "12")])
12949 (define_expand "tls_local_dynamic_base_64_<mode>"
12951 [(set (match_operand:P 0 "register_operand")
12953 (mem:QI (match_operand 1 "constant_call_address_operand"))
12955 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12958 ;; Local dynamic of a single variable is a lose. Show combine how
12959 ;; to convert that back to global dynamic.
12961 (define_insn_and_split "*tls_local_dynamic_32_once"
12962 [(set (match_operand:SI 0 "register_operand" "=a")
12964 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12965 (match_operand 2 "constant_call_address_operand" "z")]
12966 UNSPEC_TLS_LD_BASE)
12967 (const:SI (unspec:SI
12968 [(match_operand 3 "tls_symbolic_operand")]
12970 (clobber (match_scratch:SI 4 "=d"))
12971 (clobber (match_scratch:SI 5 "=c"))
12972 (clobber (reg:CC FLAGS_REG))]
12977 [(set (match_dup 0)
12978 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12980 (clobber (match_dup 4))
12981 (clobber (match_dup 5))
12982 (clobber (reg:CC FLAGS_REG))])])
12984 ;; Segment register for the thread base ptr load
12985 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12987 ;; Load and add the thread base pointer from %<tp_seg>:0.
12988 (define_insn "*load_tp_x32"
12989 [(set (match_operand:SI 0 "register_operand" "=r")
12990 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12992 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12993 [(set_attr "type" "imov")
12994 (set_attr "modrm" "0")
12995 (set_attr "length" "7")
12996 (set_attr "memory" "load")
12997 (set_attr "imm_disp" "false")])
12999 (define_insn "*load_tp_x32_zext"
13000 [(set (match_operand:DI 0 "register_operand" "=r")
13001 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13003 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13004 [(set_attr "type" "imov")
13005 (set_attr "modrm" "0")
13006 (set_attr "length" "7")
13007 (set_attr "memory" "load")
13008 (set_attr "imm_disp" "false")])
13010 (define_insn "*load_tp_<mode>"
13011 [(set (match_operand:P 0 "register_operand" "=r")
13012 (unspec:P [(const_int 0)] UNSPEC_TP))]
13014 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13015 [(set_attr "type" "imov")
13016 (set_attr "modrm" "0")
13017 (set_attr "length" "7")
13018 (set_attr "memory" "load")
13019 (set_attr "imm_disp" "false")])
13021 (define_insn "*add_tp_x32"
13022 [(set (match_operand:SI 0 "register_operand" "=r")
13023 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13024 (match_operand:SI 1 "register_operand" "0")))
13025 (clobber (reg:CC FLAGS_REG))]
13027 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13028 [(set_attr "type" "alu")
13029 (set_attr "modrm" "0")
13030 (set_attr "length" "7")
13031 (set_attr "memory" "load")
13032 (set_attr "imm_disp" "false")])
13034 (define_insn "*add_tp_x32_zext"
13035 [(set (match_operand:DI 0 "register_operand" "=r")
13037 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13038 (match_operand:SI 1 "register_operand" "0"))))
13039 (clobber (reg:CC FLAGS_REG))]
13041 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13042 [(set_attr "type" "alu")
13043 (set_attr "modrm" "0")
13044 (set_attr "length" "7")
13045 (set_attr "memory" "load")
13046 (set_attr "imm_disp" "false")])
13048 (define_insn "*add_tp_<mode>"
13049 [(set (match_operand:P 0 "register_operand" "=r")
13050 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13051 (match_operand:P 1 "register_operand" "0")))
13052 (clobber (reg:CC FLAGS_REG))]
13054 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13055 [(set_attr "type" "alu")
13056 (set_attr "modrm" "0")
13057 (set_attr "length" "7")
13058 (set_attr "memory" "load")
13059 (set_attr "imm_disp" "false")])
13061 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13062 ;; %rax as destination of the initial executable code sequence.
13063 (define_insn "tls_initial_exec_64_sun"
13064 [(set (match_operand:DI 0 "register_operand" "=a")
13066 [(match_operand 1 "tls_symbolic_operand")]
13067 UNSPEC_TLS_IE_SUN))
13068 (clobber (reg:CC FLAGS_REG))]
13069 "TARGET_64BIT && TARGET_SUN_TLS"
13072 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13073 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13075 [(set_attr "type" "multi")])
13077 ;; GNU2 TLS patterns can be split.
13079 (define_expand "tls_dynamic_gnu2_32"
13080 [(set (match_dup 3)
13081 (plus:SI (match_operand:SI 2 "register_operand")
13083 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13086 [(set (match_operand:SI 0 "register_operand")
13087 (unspec:SI [(match_dup 1) (match_dup 3)
13088 (match_dup 2) (reg:SI SP_REG)]
13090 (clobber (reg:CC FLAGS_REG))])]
13091 "!TARGET_64BIT && TARGET_GNU2_TLS"
13093 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13094 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13097 (define_insn "*tls_dynamic_gnu2_lea_32"
13098 [(set (match_operand:SI 0 "register_operand" "=r")
13099 (plus:SI (match_operand:SI 1 "register_operand" "b")
13101 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13102 UNSPEC_TLSDESC))))]
13103 "!TARGET_64BIT && TARGET_GNU2_TLS"
13104 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13105 [(set_attr "type" "lea")
13106 (set_attr "mode" "SI")
13107 (set_attr "length" "6")
13108 (set_attr "length_address" "4")])
13110 (define_insn "*tls_dynamic_gnu2_call_32"
13111 [(set (match_operand:SI 0 "register_operand" "=a")
13112 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13113 (match_operand:SI 2 "register_operand" "0")
13114 ;; we have to make sure %ebx still points to the GOT
13115 (match_operand:SI 3 "register_operand" "b")
13118 (clobber (reg:CC FLAGS_REG))]
13119 "!TARGET_64BIT && TARGET_GNU2_TLS"
13120 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13121 [(set_attr "type" "call")
13122 (set_attr "length" "2")
13123 (set_attr "length_address" "0")])
13125 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13126 [(set (match_operand:SI 0 "register_operand" "=&a")
13128 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13129 (match_operand:SI 4)
13130 (match_operand:SI 2 "register_operand" "b")
13133 (const:SI (unspec:SI
13134 [(match_operand 1 "tls_symbolic_operand")]
13136 (clobber (reg:CC FLAGS_REG))]
13137 "!TARGET_64BIT && TARGET_GNU2_TLS"
13140 [(set (match_dup 0) (match_dup 5))]
13142 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13143 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13146 (define_expand "tls_dynamic_gnu2_64"
13147 [(set (match_dup 2)
13148 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13151 [(set (match_operand:DI 0 "register_operand")
13152 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13154 (clobber (reg:CC FLAGS_REG))])]
13155 "TARGET_64BIT && TARGET_GNU2_TLS"
13157 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13158 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13161 (define_insn "*tls_dynamic_gnu2_lea_64"
13162 [(set (match_operand:DI 0 "register_operand" "=r")
13163 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13165 "TARGET_64BIT && TARGET_GNU2_TLS"
13166 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13167 [(set_attr "type" "lea")
13168 (set_attr "mode" "DI")
13169 (set_attr "length" "7")
13170 (set_attr "length_address" "4")])
13172 (define_insn "*tls_dynamic_gnu2_call_64"
13173 [(set (match_operand:DI 0 "register_operand" "=a")
13174 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13175 (match_operand:DI 2 "register_operand" "0")
13178 (clobber (reg:CC FLAGS_REG))]
13179 "TARGET_64BIT && TARGET_GNU2_TLS"
13180 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13181 [(set_attr "type" "call")
13182 (set_attr "length" "2")
13183 (set_attr "length_address" "0")])
13185 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13186 [(set (match_operand:DI 0 "register_operand" "=&a")
13188 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13189 (match_operand:DI 3)
13192 (const:DI (unspec:DI
13193 [(match_operand 1 "tls_symbolic_operand")]
13195 (clobber (reg:CC FLAGS_REG))]
13196 "TARGET_64BIT && TARGET_GNU2_TLS"
13199 [(set (match_dup 0) (match_dup 4))]
13201 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13202 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13205 ;; These patterns match the binary 387 instructions for addM3, subM3,
13206 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13207 ;; SFmode. The first is the normal insn, the second the same insn but
13208 ;; with one operand a conversion, and the third the same insn but with
13209 ;; the other operand a conversion. The conversion may be SFmode or
13210 ;; SImode if the target mode DFmode, but only SImode if the target mode
13213 ;; Gcc is slightly more smart about handling normal two address instructions
13214 ;; so use special patterns for add and mull.
13216 (define_insn "*fop_<mode>_comm_mixed"
13217 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13218 (match_operator:MODEF 3 "binary_fp_operator"
13219 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13220 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13221 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13222 && COMMUTATIVE_ARITH_P (operands[3])
13223 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13224 "* return output_387_binary_op (insn, operands);"
13225 [(set (attr "type")
13226 (if_then_else (eq_attr "alternative" "1,2")
13227 (if_then_else (match_operand:MODEF 3 "mult_operator")
13228 (const_string "ssemul")
13229 (const_string "sseadd"))
13230 (if_then_else (match_operand:MODEF 3 "mult_operator")
13231 (const_string "fmul")
13232 (const_string "fop"))))
13233 (set_attr "isa" "*,noavx,avx")
13234 (set_attr "prefix" "orig,orig,vex")
13235 (set_attr "mode" "<MODE>")])
13237 (define_insn "*fop_<mode>_comm_sse"
13238 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13239 (match_operator:MODEF 3 "binary_fp_operator"
13240 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13241 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13242 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13243 && COMMUTATIVE_ARITH_P (operands[3])
13244 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13245 "* return output_387_binary_op (insn, operands);"
13246 [(set (attr "type")
13247 (if_then_else (match_operand:MODEF 3 "mult_operator")
13248 (const_string "ssemul")
13249 (const_string "sseadd")))
13250 (set_attr "isa" "noavx,avx")
13251 (set_attr "prefix" "orig,vex")
13252 (set_attr "mode" "<MODE>")])
13254 (define_insn "*fop_<mode>_comm_i387"
13255 [(set (match_operand:MODEF 0 "register_operand" "=f")
13256 (match_operator:MODEF 3 "binary_fp_operator"
13257 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13258 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13259 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13260 && COMMUTATIVE_ARITH_P (operands[3])
13261 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13262 "* return output_387_binary_op (insn, operands);"
13263 [(set (attr "type")
13264 (if_then_else (match_operand:MODEF 3 "mult_operator")
13265 (const_string "fmul")
13266 (const_string "fop")))
13267 (set_attr "mode" "<MODE>")])
13269 (define_insn "*fop_<mode>_1_mixed"
13270 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13271 (match_operator:MODEF 3 "binary_fp_operator"
13272 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13273 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13274 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13275 && !COMMUTATIVE_ARITH_P (operands[3])
13276 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13277 "* return output_387_binary_op (insn, operands);"
13278 [(set (attr "type")
13279 (cond [(and (eq_attr "alternative" "2,3")
13280 (match_operand:MODEF 3 "mult_operator"))
13281 (const_string "ssemul")
13282 (and (eq_attr "alternative" "2,3")
13283 (match_operand:MODEF 3 "div_operator"))
13284 (const_string "ssediv")
13285 (eq_attr "alternative" "2,3")
13286 (const_string "sseadd")
13287 (match_operand:MODEF 3 "mult_operator")
13288 (const_string "fmul")
13289 (match_operand:MODEF 3 "div_operator")
13290 (const_string "fdiv")
13292 (const_string "fop")))
13293 (set_attr "isa" "*,*,noavx,avx")
13294 (set_attr "prefix" "orig,orig,orig,vex")
13295 (set_attr "mode" "<MODE>")])
13297 (define_insn "*rcpsf2_sse"
13298 [(set (match_operand:SF 0 "register_operand" "=x")
13299 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13302 "%vrcpss\t{%1, %d0|%d0, %1}"
13303 [(set_attr "type" "sse")
13304 (set_attr "atom_sse_attr" "rcp")
13305 (set_attr "prefix" "maybe_vex")
13306 (set_attr "mode" "SF")])
13308 (define_insn "*fop_<mode>_1_sse"
13309 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13310 (match_operator:MODEF 3 "binary_fp_operator"
13311 [(match_operand:MODEF 1 "register_operand" "0,x")
13312 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13313 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13314 && !COMMUTATIVE_ARITH_P (operands[3])"
13315 "* return output_387_binary_op (insn, operands);"
13316 [(set (attr "type")
13317 (cond [(match_operand:MODEF 3 "mult_operator")
13318 (const_string "ssemul")
13319 (match_operand:MODEF 3 "div_operator")
13320 (const_string "ssediv")
13322 (const_string "sseadd")))
13323 (set_attr "isa" "noavx,avx")
13324 (set_attr "prefix" "orig,vex")
13325 (set_attr "mode" "<MODE>")])
13327 ;; This pattern is not fully shadowed by the pattern above.
13328 (define_insn "*fop_<mode>_1_i387"
13329 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13330 (match_operator:MODEF 3 "binary_fp_operator"
13331 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13332 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13333 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13334 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13335 && !COMMUTATIVE_ARITH_P (operands[3])
13336 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13337 "* return output_387_binary_op (insn, operands);"
13338 [(set (attr "type")
13339 (cond [(match_operand:MODEF 3 "mult_operator")
13340 (const_string "fmul")
13341 (match_operand:MODEF 3 "div_operator")
13342 (const_string "fdiv")
13344 (const_string "fop")))
13345 (set_attr "mode" "<MODE>")])
13347 ;; ??? Add SSE splitters for these!
13348 (define_insn "*fop_<MODEF:mode>_2_i387"
13349 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13350 (match_operator:MODEF 3 "binary_fp_operator"
13352 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13353 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13354 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13355 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13356 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13357 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13358 [(set (attr "type")
13359 (cond [(match_operand:MODEF 3 "mult_operator")
13360 (const_string "fmul")
13361 (match_operand:MODEF 3 "div_operator")
13362 (const_string "fdiv")
13364 (const_string "fop")))
13365 (set_attr "fp_int_src" "true")
13366 (set_attr "mode" "<SWI24:MODE>")])
13368 (define_insn "*fop_<MODEF:mode>_3_i387"
13369 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13370 (match_operator:MODEF 3 "binary_fp_operator"
13371 [(match_operand:MODEF 1 "register_operand" "0,0")
13373 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13374 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13375 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13376 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13377 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13378 [(set (attr "type")
13379 (cond [(match_operand:MODEF 3 "mult_operator")
13380 (const_string "fmul")
13381 (match_operand:MODEF 3 "div_operator")
13382 (const_string "fdiv")
13384 (const_string "fop")))
13385 (set_attr "fp_int_src" "true")
13386 (set_attr "mode" "<MODE>")])
13388 (define_insn "*fop_df_4_i387"
13389 [(set (match_operand:DF 0 "register_operand" "=f,f")
13390 (match_operator:DF 3 "binary_fp_operator"
13392 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13393 (match_operand:DF 2 "register_operand" "0,f")]))]
13394 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13395 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13396 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13397 "* return output_387_binary_op (insn, operands);"
13398 [(set (attr "type")
13399 (cond [(match_operand:DF 3 "mult_operator")
13400 (const_string "fmul")
13401 (match_operand:DF 3 "div_operator")
13402 (const_string "fdiv")
13404 (const_string "fop")))
13405 (set_attr "mode" "SF")])
13407 (define_insn "*fop_df_5_i387"
13408 [(set (match_operand:DF 0 "register_operand" "=f,f")
13409 (match_operator:DF 3 "binary_fp_operator"
13410 [(match_operand:DF 1 "register_operand" "0,f")
13412 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13413 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13414 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13415 "* return output_387_binary_op (insn, operands);"
13416 [(set (attr "type")
13417 (cond [(match_operand:DF 3 "mult_operator")
13418 (const_string "fmul")
13419 (match_operand:DF 3 "div_operator")
13420 (const_string "fdiv")
13422 (const_string "fop")))
13423 (set_attr "mode" "SF")])
13425 (define_insn "*fop_df_6_i387"
13426 [(set (match_operand:DF 0 "register_operand" "=f,f")
13427 (match_operator:DF 3 "binary_fp_operator"
13429 (match_operand:SF 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_xf_comm_i387"
13445 [(set (match_operand:XF 0 "register_operand" "=f")
13446 (match_operator:XF 3 "binary_fp_operator"
13447 [(match_operand:XF 1 "register_operand" "%0")
13448 (match_operand:XF 2 "register_operand" "f")]))]
13450 && COMMUTATIVE_ARITH_P (operands[3])"
13451 "* return output_387_binary_op (insn, operands);"
13452 [(set (attr "type")
13453 (if_then_else (match_operand:XF 3 "mult_operator")
13454 (const_string "fmul")
13455 (const_string "fop")))
13456 (set_attr "mode" "XF")])
13458 (define_insn "*fop_xf_1_i387"
13459 [(set (match_operand:XF 0 "register_operand" "=f,f")
13460 (match_operator:XF 3 "binary_fp_operator"
13461 [(match_operand:XF 1 "register_operand" "0,f")
13462 (match_operand:XF 2 "register_operand" "f,0")]))]
13464 && !COMMUTATIVE_ARITH_P (operands[3])"
13465 "* return output_387_binary_op (insn, operands);"
13466 [(set (attr "type")
13467 (cond [(match_operand:XF 3 "mult_operator")
13468 (const_string "fmul")
13469 (match_operand:XF 3 "div_operator")
13470 (const_string "fdiv")
13472 (const_string "fop")))
13473 (set_attr "mode" "XF")])
13475 (define_insn "*fop_xf_2_i387"
13476 [(set (match_operand:XF 0 "register_operand" "=f,f")
13477 (match_operator:XF 3 "binary_fp_operator"
13479 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13480 (match_operand:XF 2 "register_operand" "0,0")]))]
13481 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13482 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13483 [(set (attr "type")
13484 (cond [(match_operand:XF 3 "mult_operator")
13485 (const_string "fmul")
13486 (match_operand:XF 3 "div_operator")
13487 (const_string "fdiv")
13489 (const_string "fop")))
13490 (set_attr "fp_int_src" "true")
13491 (set_attr "mode" "<MODE>")])
13493 (define_insn "*fop_xf_3_i387"
13494 [(set (match_operand:XF 0 "register_operand" "=f,f")
13495 (match_operator:XF 3 "binary_fp_operator"
13496 [(match_operand:XF 1 "register_operand" "0,0")
13498 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13499 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13500 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13501 [(set (attr "type")
13502 (cond [(match_operand:XF 3 "mult_operator")
13503 (const_string "fmul")
13504 (match_operand:XF 3 "div_operator")
13505 (const_string "fdiv")
13507 (const_string "fop")))
13508 (set_attr "fp_int_src" "true")
13509 (set_attr "mode" "<MODE>")])
13511 (define_insn "*fop_xf_4_i387"
13512 [(set (match_operand:XF 0 "register_operand" "=f,f")
13513 (match_operator:XF 3 "binary_fp_operator"
13515 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13516 (match_operand:XF 2 "register_operand" "0,f")]))]
13518 "* return output_387_binary_op (insn, operands);"
13519 [(set (attr "type")
13520 (cond [(match_operand:XF 3 "mult_operator")
13521 (const_string "fmul")
13522 (match_operand:XF 3 "div_operator")
13523 (const_string "fdiv")
13525 (const_string "fop")))
13526 (set_attr "mode" "<MODE>")])
13528 (define_insn "*fop_xf_5_i387"
13529 [(set (match_operand:XF 0 "register_operand" "=f,f")
13530 (match_operator:XF 3 "binary_fp_operator"
13531 [(match_operand:XF 1 "register_operand" "0,f")
13533 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13535 "* return output_387_binary_op (insn, operands);"
13536 [(set (attr "type")
13537 (cond [(match_operand:XF 3 "mult_operator")
13538 (const_string "fmul")
13539 (match_operand:XF 3 "div_operator")
13540 (const_string "fdiv")
13542 (const_string "fop")))
13543 (set_attr "mode" "<MODE>")])
13545 (define_insn "*fop_xf_6_i387"
13546 [(set (match_operand:XF 0 "register_operand" "=f,f")
13547 (match_operator:XF 3 "binary_fp_operator"
13549 (match_operand:MODEF 1 "register_operand" "0,f"))
13551 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13553 "* return output_387_binary_op (insn, operands);"
13554 [(set (attr "type")
13555 (cond [(match_operand:XF 3 "mult_operator")
13556 (const_string "fmul")
13557 (match_operand:XF 3 "div_operator")
13558 (const_string "fdiv")
13560 (const_string "fop")))
13561 (set_attr "mode" "<MODE>")])
13564 [(set (match_operand 0 "register_operand")
13565 (match_operator 3 "binary_fp_operator"
13566 [(float (match_operand:SWI24 1 "register_operand"))
13567 (match_operand 2 "register_operand")]))]
13569 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13570 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13573 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13574 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13575 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13576 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13577 GET_MODE (operands[3]),
13580 ix86_free_from_memory (GET_MODE (operands[1]));
13585 [(set (match_operand 0 "register_operand")
13586 (match_operator 3 "binary_fp_operator"
13587 [(match_operand 1 "register_operand")
13588 (float (match_operand:SWI24 2 "register_operand"))]))]
13590 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13591 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13594 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13595 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13596 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13597 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13598 GET_MODE (operands[3]),
13601 ix86_free_from_memory (GET_MODE (operands[2]));
13605 ;; FPU special functions.
13607 ;; This pattern implements a no-op XFmode truncation for
13608 ;; all fancy i386 XFmode math functions.
13610 (define_insn "truncxf<mode>2_i387_noop_unspec"
13611 [(set (match_operand:MODEF 0 "register_operand" "=f")
13612 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13613 UNSPEC_TRUNC_NOOP))]
13614 "TARGET_USE_FANCY_MATH_387"
13615 "* return output_387_reg_move (insn, operands);"
13616 [(set_attr "type" "fmov")
13617 (set_attr "mode" "<MODE>")])
13619 (define_insn "sqrtxf2"
13620 [(set (match_operand:XF 0 "register_operand" "=f")
13621 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13622 "TARGET_USE_FANCY_MATH_387"
13624 [(set_attr "type" "fpspc")
13625 (set_attr "mode" "XF")
13626 (set_attr "athlon_decode" "direct")
13627 (set_attr "amdfam10_decode" "direct")
13628 (set_attr "bdver1_decode" "direct")])
13630 (define_insn "sqrt_extend<mode>xf2_i387"
13631 [(set (match_operand:XF 0 "register_operand" "=f")
13634 (match_operand:MODEF 1 "register_operand" "0"))))]
13635 "TARGET_USE_FANCY_MATH_387"
13637 [(set_attr "type" "fpspc")
13638 (set_attr "mode" "XF")
13639 (set_attr "athlon_decode" "direct")
13640 (set_attr "amdfam10_decode" "direct")
13641 (set_attr "bdver1_decode" "direct")])
13643 (define_insn "*rsqrtsf2_sse"
13644 [(set (match_operand:SF 0 "register_operand" "=x")
13645 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13648 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13649 [(set_attr "type" "sse")
13650 (set_attr "atom_sse_attr" "rcp")
13651 (set_attr "prefix" "maybe_vex")
13652 (set_attr "mode" "SF")])
13654 (define_expand "rsqrtsf2"
13655 [(set (match_operand:SF 0 "register_operand")
13656 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13660 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13664 (define_insn "*sqrt<mode>2_sse"
13665 [(set (match_operand:MODEF 0 "register_operand" "=x")
13667 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13668 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13669 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13670 [(set_attr "type" "sse")
13671 (set_attr "atom_sse_attr" "sqrt")
13672 (set_attr "prefix" "maybe_vex")
13673 (set_attr "mode" "<MODE>")
13674 (set_attr "athlon_decode" "*")
13675 (set_attr "amdfam10_decode" "*")
13676 (set_attr "bdver1_decode" "*")])
13678 (define_expand "sqrt<mode>2"
13679 [(set (match_operand:MODEF 0 "register_operand")
13681 (match_operand:MODEF 1 "nonimmediate_operand")))]
13682 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13683 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13685 if (<MODE>mode == SFmode
13687 && TARGET_RECIP_SQRT
13688 && !optimize_function_for_size_p (cfun)
13689 && flag_finite_math_only && !flag_trapping_math
13690 && flag_unsafe_math_optimizations)
13692 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13696 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13698 rtx op0 = gen_reg_rtx (XFmode);
13699 rtx op1 = force_reg (<MODE>mode, operands[1]);
13701 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13702 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13707 (define_insn "fpremxf4_i387"
13708 [(set (match_operand:XF 0 "register_operand" "=f")
13709 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13710 (match_operand:XF 3 "register_operand" "1")]
13712 (set (match_operand:XF 1 "register_operand" "=u")
13713 (unspec:XF [(match_dup 2) (match_dup 3)]
13715 (set (reg:CCFP FPSR_REG)
13716 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13718 "TARGET_USE_FANCY_MATH_387"
13720 [(set_attr "type" "fpspc")
13721 (set_attr "mode" "XF")])
13723 (define_expand "fmodxf3"
13724 [(use (match_operand:XF 0 "register_operand"))
13725 (use (match_operand:XF 1 "general_operand"))
13726 (use (match_operand:XF 2 "general_operand"))]
13727 "TARGET_USE_FANCY_MATH_387"
13729 rtx label = gen_label_rtx ();
13731 rtx op1 = gen_reg_rtx (XFmode);
13732 rtx op2 = gen_reg_rtx (XFmode);
13734 emit_move_insn (op2, operands[2]);
13735 emit_move_insn (op1, operands[1]);
13737 emit_label (label);
13738 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13739 ix86_emit_fp_unordered_jump (label);
13740 LABEL_NUSES (label) = 1;
13742 emit_move_insn (operands[0], op1);
13746 (define_expand "fmod<mode>3"
13747 [(use (match_operand:MODEF 0 "register_operand"))
13748 (use (match_operand:MODEF 1 "general_operand"))
13749 (use (match_operand:MODEF 2 "general_operand"))]
13750 "TARGET_USE_FANCY_MATH_387"
13752 rtx (*gen_truncxf) (rtx, rtx);
13754 rtx label = gen_label_rtx ();
13756 rtx op1 = gen_reg_rtx (XFmode);
13757 rtx op2 = gen_reg_rtx (XFmode);
13759 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13760 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13762 emit_label (label);
13763 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13764 ix86_emit_fp_unordered_jump (label);
13765 LABEL_NUSES (label) = 1;
13767 /* Truncate the result properly for strict SSE math. */
13768 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13769 && !TARGET_MIX_SSE_I387)
13770 gen_truncxf = gen_truncxf<mode>2;
13772 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13774 emit_insn (gen_truncxf (operands[0], op1));
13778 (define_insn "fprem1xf4_i387"
13779 [(set (match_operand:XF 0 "register_operand" "=f")
13780 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13781 (match_operand:XF 3 "register_operand" "1")]
13783 (set (match_operand:XF 1 "register_operand" "=u")
13784 (unspec:XF [(match_dup 2) (match_dup 3)]
13786 (set (reg:CCFP FPSR_REG)
13787 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13789 "TARGET_USE_FANCY_MATH_387"
13791 [(set_attr "type" "fpspc")
13792 (set_attr "mode" "XF")])
13794 (define_expand "remainderxf3"
13795 [(use (match_operand:XF 0 "register_operand"))
13796 (use (match_operand:XF 1 "general_operand"))
13797 (use (match_operand:XF 2 "general_operand"))]
13798 "TARGET_USE_FANCY_MATH_387"
13800 rtx label = gen_label_rtx ();
13802 rtx op1 = gen_reg_rtx (XFmode);
13803 rtx op2 = gen_reg_rtx (XFmode);
13805 emit_move_insn (op2, operands[2]);
13806 emit_move_insn (op1, operands[1]);
13808 emit_label (label);
13809 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13810 ix86_emit_fp_unordered_jump (label);
13811 LABEL_NUSES (label) = 1;
13813 emit_move_insn (operands[0], op1);
13817 (define_expand "remainder<mode>3"
13818 [(use (match_operand:MODEF 0 "register_operand"))
13819 (use (match_operand:MODEF 1 "general_operand"))
13820 (use (match_operand:MODEF 2 "general_operand"))]
13821 "TARGET_USE_FANCY_MATH_387"
13823 rtx (*gen_truncxf) (rtx, rtx);
13825 rtx label = gen_label_rtx ();
13827 rtx op1 = gen_reg_rtx (XFmode);
13828 rtx op2 = gen_reg_rtx (XFmode);
13830 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13831 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13833 emit_label (label);
13835 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13836 ix86_emit_fp_unordered_jump (label);
13837 LABEL_NUSES (label) = 1;
13839 /* Truncate the result properly for strict SSE math. */
13840 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13841 && !TARGET_MIX_SSE_I387)
13842 gen_truncxf = gen_truncxf<mode>2;
13844 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13846 emit_insn (gen_truncxf (operands[0], op1));
13850 (define_insn "*sinxf2_i387"
13851 [(set (match_operand:XF 0 "register_operand" "=f")
13852 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13853 "TARGET_USE_FANCY_MATH_387
13854 && flag_unsafe_math_optimizations"
13856 [(set_attr "type" "fpspc")
13857 (set_attr "mode" "XF")])
13859 (define_insn "*sin_extend<mode>xf2_i387"
13860 [(set (match_operand:XF 0 "register_operand" "=f")
13861 (unspec:XF [(float_extend:XF
13862 (match_operand:MODEF 1 "register_operand" "0"))]
13864 "TARGET_USE_FANCY_MATH_387
13865 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13866 || TARGET_MIX_SSE_I387)
13867 && flag_unsafe_math_optimizations"
13869 [(set_attr "type" "fpspc")
13870 (set_attr "mode" "XF")])
13872 (define_insn "*cosxf2_i387"
13873 [(set (match_operand:XF 0 "register_operand" "=f")
13874 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13875 "TARGET_USE_FANCY_MATH_387
13876 && flag_unsafe_math_optimizations"
13878 [(set_attr "type" "fpspc")
13879 (set_attr "mode" "XF")])
13881 (define_insn "*cos_extend<mode>xf2_i387"
13882 [(set (match_operand:XF 0 "register_operand" "=f")
13883 (unspec:XF [(float_extend:XF
13884 (match_operand:MODEF 1 "register_operand" "0"))]
13886 "TARGET_USE_FANCY_MATH_387
13887 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13888 || TARGET_MIX_SSE_I387)
13889 && flag_unsafe_math_optimizations"
13891 [(set_attr "type" "fpspc")
13892 (set_attr "mode" "XF")])
13894 ;; When sincos pattern is defined, sin and cos builtin functions will be
13895 ;; expanded to sincos pattern with one of its outputs left unused.
13896 ;; CSE pass will figure out if two sincos patterns can be combined,
13897 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13898 ;; depending on the unused output.
13900 (define_insn "sincosxf3"
13901 [(set (match_operand:XF 0 "register_operand" "=f")
13902 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13903 UNSPEC_SINCOS_COS))
13904 (set (match_operand:XF 1 "register_operand" "=u")
13905 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13906 "TARGET_USE_FANCY_MATH_387
13907 && flag_unsafe_math_optimizations"
13909 [(set_attr "type" "fpspc")
13910 (set_attr "mode" "XF")])
13913 [(set (match_operand:XF 0 "register_operand")
13914 (unspec:XF [(match_operand:XF 2 "register_operand")]
13915 UNSPEC_SINCOS_COS))
13916 (set (match_operand:XF 1 "register_operand")
13917 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13918 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13919 && can_create_pseudo_p ()"
13920 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13923 [(set (match_operand:XF 0 "register_operand")
13924 (unspec:XF [(match_operand:XF 2 "register_operand")]
13925 UNSPEC_SINCOS_COS))
13926 (set (match_operand:XF 1 "register_operand")
13927 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13928 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13929 && can_create_pseudo_p ()"
13930 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13932 (define_insn "sincos_extend<mode>xf3_i387"
13933 [(set (match_operand:XF 0 "register_operand" "=f")
13934 (unspec:XF [(float_extend:XF
13935 (match_operand:MODEF 2 "register_operand" "0"))]
13936 UNSPEC_SINCOS_COS))
13937 (set (match_operand:XF 1 "register_operand" "=u")
13938 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13939 "TARGET_USE_FANCY_MATH_387
13940 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13941 || TARGET_MIX_SSE_I387)
13942 && flag_unsafe_math_optimizations"
13944 [(set_attr "type" "fpspc")
13945 (set_attr "mode" "XF")])
13948 [(set (match_operand:XF 0 "register_operand")
13949 (unspec:XF [(float_extend:XF
13950 (match_operand:MODEF 2 "register_operand"))]
13951 UNSPEC_SINCOS_COS))
13952 (set (match_operand:XF 1 "register_operand")
13953 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13954 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13955 && can_create_pseudo_p ()"
13956 [(set (match_dup 1)
13957 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13960 [(set (match_operand:XF 0 "register_operand")
13961 (unspec:XF [(float_extend:XF
13962 (match_operand:MODEF 2 "register_operand"))]
13963 UNSPEC_SINCOS_COS))
13964 (set (match_operand:XF 1 "register_operand")
13965 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13966 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13967 && can_create_pseudo_p ()"
13968 [(set (match_dup 0)
13969 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13971 (define_expand "sincos<mode>3"
13972 [(use (match_operand:MODEF 0 "register_operand"))
13973 (use (match_operand:MODEF 1 "register_operand"))
13974 (use (match_operand:MODEF 2 "register_operand"))]
13975 "TARGET_USE_FANCY_MATH_387
13976 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13977 || TARGET_MIX_SSE_I387)
13978 && flag_unsafe_math_optimizations"
13980 rtx op0 = gen_reg_rtx (XFmode);
13981 rtx op1 = gen_reg_rtx (XFmode);
13983 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13984 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13985 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13989 (define_insn "fptanxf4_i387"
13990 [(set (match_operand:XF 0 "register_operand" "=f")
13991 (match_operand:XF 3 "const_double_operand" "F"))
13992 (set (match_operand:XF 1 "register_operand" "=u")
13993 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13995 "TARGET_USE_FANCY_MATH_387
13996 && flag_unsafe_math_optimizations
13997 && standard_80387_constant_p (operands[3]) == 2"
13999 [(set_attr "type" "fpspc")
14000 (set_attr "mode" "XF")])
14002 (define_insn "fptan_extend<mode>xf4_i387"
14003 [(set (match_operand:MODEF 0 "register_operand" "=f")
14004 (match_operand:MODEF 3 "const_double_operand" "F"))
14005 (set (match_operand:XF 1 "register_operand" "=u")
14006 (unspec:XF [(float_extend:XF
14007 (match_operand:MODEF 2 "register_operand" "0"))]
14009 "TARGET_USE_FANCY_MATH_387
14010 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14011 || TARGET_MIX_SSE_I387)
14012 && flag_unsafe_math_optimizations
14013 && standard_80387_constant_p (operands[3]) == 2"
14015 [(set_attr "type" "fpspc")
14016 (set_attr "mode" "XF")])
14018 (define_expand "tanxf2"
14019 [(use (match_operand:XF 0 "register_operand"))
14020 (use (match_operand:XF 1 "register_operand"))]
14021 "TARGET_USE_FANCY_MATH_387
14022 && flag_unsafe_math_optimizations"
14024 rtx one = gen_reg_rtx (XFmode);
14025 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14027 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14031 (define_expand "tan<mode>2"
14032 [(use (match_operand:MODEF 0 "register_operand"))
14033 (use (match_operand:MODEF 1 "register_operand"))]
14034 "TARGET_USE_FANCY_MATH_387
14035 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14036 || TARGET_MIX_SSE_I387)
14037 && flag_unsafe_math_optimizations"
14039 rtx op0 = gen_reg_rtx (XFmode);
14041 rtx one = gen_reg_rtx (<MODE>mode);
14042 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14044 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14045 operands[1], op2));
14046 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14050 (define_insn "*fpatanxf3_i387"
14051 [(set (match_operand:XF 0 "register_operand" "=f")
14052 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14053 (match_operand:XF 2 "register_operand" "u")]
14055 (clobber (match_scratch:XF 3 "=2"))]
14056 "TARGET_USE_FANCY_MATH_387
14057 && flag_unsafe_math_optimizations"
14059 [(set_attr "type" "fpspc")
14060 (set_attr "mode" "XF")])
14062 (define_insn "fpatan_extend<mode>xf3_i387"
14063 [(set (match_operand:XF 0 "register_operand" "=f")
14064 (unspec:XF [(float_extend:XF
14065 (match_operand:MODEF 1 "register_operand" "0"))
14067 (match_operand:MODEF 2 "register_operand" "u"))]
14069 (clobber (match_scratch:XF 3 "=2"))]
14070 "TARGET_USE_FANCY_MATH_387
14071 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14072 || TARGET_MIX_SSE_I387)
14073 && flag_unsafe_math_optimizations"
14075 [(set_attr "type" "fpspc")
14076 (set_attr "mode" "XF")])
14078 (define_expand "atan2xf3"
14079 [(parallel [(set (match_operand:XF 0 "register_operand")
14080 (unspec:XF [(match_operand:XF 2 "register_operand")
14081 (match_operand:XF 1 "register_operand")]
14083 (clobber (match_scratch:XF 3))])]
14084 "TARGET_USE_FANCY_MATH_387
14085 && flag_unsafe_math_optimizations")
14087 (define_expand "atan2<mode>3"
14088 [(use (match_operand:MODEF 0 "register_operand"))
14089 (use (match_operand:MODEF 1 "register_operand"))
14090 (use (match_operand:MODEF 2 "register_operand"))]
14091 "TARGET_USE_FANCY_MATH_387
14092 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14093 || TARGET_MIX_SSE_I387)
14094 && flag_unsafe_math_optimizations"
14096 rtx op0 = gen_reg_rtx (XFmode);
14098 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14099 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14103 (define_expand "atanxf2"
14104 [(parallel [(set (match_operand:XF 0 "register_operand")
14105 (unspec:XF [(match_dup 2)
14106 (match_operand:XF 1 "register_operand")]
14108 (clobber (match_scratch:XF 3))])]
14109 "TARGET_USE_FANCY_MATH_387
14110 && flag_unsafe_math_optimizations"
14112 operands[2] = gen_reg_rtx (XFmode);
14113 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14116 (define_expand "atan<mode>2"
14117 [(use (match_operand:MODEF 0 "register_operand"))
14118 (use (match_operand:MODEF 1 "register_operand"))]
14119 "TARGET_USE_FANCY_MATH_387
14120 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14121 || TARGET_MIX_SSE_I387)
14122 && flag_unsafe_math_optimizations"
14124 rtx op0 = gen_reg_rtx (XFmode);
14126 rtx op2 = gen_reg_rtx (<MODE>mode);
14127 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14129 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14130 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14134 (define_expand "asinxf2"
14135 [(set (match_dup 2)
14136 (mult:XF (match_operand:XF 1 "register_operand")
14138 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14139 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14140 (parallel [(set (match_operand:XF 0 "register_operand")
14141 (unspec:XF [(match_dup 5) (match_dup 1)]
14143 (clobber (match_scratch:XF 6))])]
14144 "TARGET_USE_FANCY_MATH_387
14145 && flag_unsafe_math_optimizations"
14149 if (optimize_insn_for_size_p ())
14152 for (i = 2; i < 6; i++)
14153 operands[i] = gen_reg_rtx (XFmode);
14155 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14158 (define_expand "asin<mode>2"
14159 [(use (match_operand:MODEF 0 "register_operand"))
14160 (use (match_operand:MODEF 1 "general_operand"))]
14161 "TARGET_USE_FANCY_MATH_387
14162 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14163 || TARGET_MIX_SSE_I387)
14164 && flag_unsafe_math_optimizations"
14166 rtx op0 = gen_reg_rtx (XFmode);
14167 rtx op1 = gen_reg_rtx (XFmode);
14169 if (optimize_insn_for_size_p ())
14172 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14173 emit_insn (gen_asinxf2 (op0, op1));
14174 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14178 (define_expand "acosxf2"
14179 [(set (match_dup 2)
14180 (mult:XF (match_operand:XF 1 "register_operand")
14182 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14183 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14184 (parallel [(set (match_operand:XF 0 "register_operand")
14185 (unspec:XF [(match_dup 1) (match_dup 5)]
14187 (clobber (match_scratch:XF 6))])]
14188 "TARGET_USE_FANCY_MATH_387
14189 && flag_unsafe_math_optimizations"
14193 if (optimize_insn_for_size_p ())
14196 for (i = 2; i < 6; i++)
14197 operands[i] = gen_reg_rtx (XFmode);
14199 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14202 (define_expand "acos<mode>2"
14203 [(use (match_operand:MODEF 0 "register_operand"))
14204 (use (match_operand:MODEF 1 "general_operand"))]
14205 "TARGET_USE_FANCY_MATH_387
14206 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14207 || TARGET_MIX_SSE_I387)
14208 && flag_unsafe_math_optimizations"
14210 rtx op0 = gen_reg_rtx (XFmode);
14211 rtx op1 = gen_reg_rtx (XFmode);
14213 if (optimize_insn_for_size_p ())
14216 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14217 emit_insn (gen_acosxf2 (op0, op1));
14218 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14222 (define_insn "fyl2xxf3_i387"
14223 [(set (match_operand:XF 0 "register_operand" "=f")
14224 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14225 (match_operand:XF 2 "register_operand" "u")]
14227 (clobber (match_scratch:XF 3 "=2"))]
14228 "TARGET_USE_FANCY_MATH_387
14229 && flag_unsafe_math_optimizations"
14231 [(set_attr "type" "fpspc")
14232 (set_attr "mode" "XF")])
14234 (define_insn "fyl2x_extend<mode>xf3_i387"
14235 [(set (match_operand:XF 0 "register_operand" "=f")
14236 (unspec:XF [(float_extend:XF
14237 (match_operand:MODEF 1 "register_operand" "0"))
14238 (match_operand:XF 2 "register_operand" "u")]
14240 (clobber (match_scratch:XF 3 "=2"))]
14241 "TARGET_USE_FANCY_MATH_387
14242 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14243 || TARGET_MIX_SSE_I387)
14244 && flag_unsafe_math_optimizations"
14246 [(set_attr "type" "fpspc")
14247 (set_attr "mode" "XF")])
14249 (define_expand "logxf2"
14250 [(parallel [(set (match_operand:XF 0 "register_operand")
14251 (unspec:XF [(match_operand:XF 1 "register_operand")
14252 (match_dup 2)] UNSPEC_FYL2X))
14253 (clobber (match_scratch:XF 3))])]
14254 "TARGET_USE_FANCY_MATH_387
14255 && flag_unsafe_math_optimizations"
14257 operands[2] = gen_reg_rtx (XFmode);
14258 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14261 (define_expand "log<mode>2"
14262 [(use (match_operand:MODEF 0 "register_operand"))
14263 (use (match_operand:MODEF 1 "register_operand"))]
14264 "TARGET_USE_FANCY_MATH_387
14265 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14266 || TARGET_MIX_SSE_I387)
14267 && flag_unsafe_math_optimizations"
14269 rtx op0 = gen_reg_rtx (XFmode);
14271 rtx op2 = gen_reg_rtx (XFmode);
14272 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14274 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14275 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14279 (define_expand "log10xf2"
14280 [(parallel [(set (match_operand:XF 0 "register_operand")
14281 (unspec:XF [(match_operand:XF 1 "register_operand")
14282 (match_dup 2)] UNSPEC_FYL2X))
14283 (clobber (match_scratch:XF 3))])]
14284 "TARGET_USE_FANCY_MATH_387
14285 && flag_unsafe_math_optimizations"
14287 operands[2] = gen_reg_rtx (XFmode);
14288 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14291 (define_expand "log10<mode>2"
14292 [(use (match_operand:MODEF 0 "register_operand"))
14293 (use (match_operand:MODEF 1 "register_operand"))]
14294 "TARGET_USE_FANCY_MATH_387
14295 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14296 || TARGET_MIX_SSE_I387)
14297 && flag_unsafe_math_optimizations"
14299 rtx op0 = gen_reg_rtx (XFmode);
14301 rtx op2 = gen_reg_rtx (XFmode);
14302 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14304 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14305 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14309 (define_expand "log2xf2"
14310 [(parallel [(set (match_operand:XF 0 "register_operand")
14311 (unspec:XF [(match_operand:XF 1 "register_operand")
14312 (match_dup 2)] UNSPEC_FYL2X))
14313 (clobber (match_scratch:XF 3))])]
14314 "TARGET_USE_FANCY_MATH_387
14315 && flag_unsafe_math_optimizations"
14317 operands[2] = gen_reg_rtx (XFmode);
14318 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14321 (define_expand "log2<mode>2"
14322 [(use (match_operand:MODEF 0 "register_operand"))
14323 (use (match_operand:MODEF 1 "register_operand"))]
14324 "TARGET_USE_FANCY_MATH_387
14325 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14326 || TARGET_MIX_SSE_I387)
14327 && flag_unsafe_math_optimizations"
14329 rtx op0 = gen_reg_rtx (XFmode);
14331 rtx op2 = gen_reg_rtx (XFmode);
14332 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14334 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14335 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14339 (define_insn "fyl2xp1xf3_i387"
14340 [(set (match_operand:XF 0 "register_operand" "=f")
14341 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14342 (match_operand:XF 2 "register_operand" "u")]
14344 (clobber (match_scratch:XF 3 "=2"))]
14345 "TARGET_USE_FANCY_MATH_387
14346 && flag_unsafe_math_optimizations"
14348 [(set_attr "type" "fpspc")
14349 (set_attr "mode" "XF")])
14351 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14352 [(set (match_operand:XF 0 "register_operand" "=f")
14353 (unspec:XF [(float_extend:XF
14354 (match_operand:MODEF 1 "register_operand" "0"))
14355 (match_operand:XF 2 "register_operand" "u")]
14357 (clobber (match_scratch:XF 3 "=2"))]
14358 "TARGET_USE_FANCY_MATH_387
14359 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14360 || TARGET_MIX_SSE_I387)
14361 && flag_unsafe_math_optimizations"
14363 [(set_attr "type" "fpspc")
14364 (set_attr "mode" "XF")])
14366 (define_expand "log1pxf2"
14367 [(use (match_operand:XF 0 "register_operand"))
14368 (use (match_operand:XF 1 "register_operand"))]
14369 "TARGET_USE_FANCY_MATH_387
14370 && flag_unsafe_math_optimizations"
14372 if (optimize_insn_for_size_p ())
14375 ix86_emit_i387_log1p (operands[0], operands[1]);
14379 (define_expand "log1p<mode>2"
14380 [(use (match_operand:MODEF 0 "register_operand"))
14381 (use (match_operand:MODEF 1 "register_operand"))]
14382 "TARGET_USE_FANCY_MATH_387
14383 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14384 || TARGET_MIX_SSE_I387)
14385 && flag_unsafe_math_optimizations"
14389 if (optimize_insn_for_size_p ())
14392 op0 = gen_reg_rtx (XFmode);
14394 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14396 ix86_emit_i387_log1p (op0, operands[1]);
14397 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14401 (define_insn "fxtractxf3_i387"
14402 [(set (match_operand:XF 0 "register_operand" "=f")
14403 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14404 UNSPEC_XTRACT_FRACT))
14405 (set (match_operand:XF 1 "register_operand" "=u")
14406 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14407 "TARGET_USE_FANCY_MATH_387
14408 && flag_unsafe_math_optimizations"
14410 [(set_attr "type" "fpspc")
14411 (set_attr "mode" "XF")])
14413 (define_insn "fxtract_extend<mode>xf3_i387"
14414 [(set (match_operand:XF 0 "register_operand" "=f")
14415 (unspec:XF [(float_extend:XF
14416 (match_operand:MODEF 2 "register_operand" "0"))]
14417 UNSPEC_XTRACT_FRACT))
14418 (set (match_operand:XF 1 "register_operand" "=u")
14419 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14420 "TARGET_USE_FANCY_MATH_387
14421 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14422 || TARGET_MIX_SSE_I387)
14423 && flag_unsafe_math_optimizations"
14425 [(set_attr "type" "fpspc")
14426 (set_attr "mode" "XF")])
14428 (define_expand "logbxf2"
14429 [(parallel [(set (match_dup 2)
14430 (unspec:XF [(match_operand:XF 1 "register_operand")]
14431 UNSPEC_XTRACT_FRACT))
14432 (set (match_operand:XF 0 "register_operand")
14433 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14434 "TARGET_USE_FANCY_MATH_387
14435 && flag_unsafe_math_optimizations"
14436 "operands[2] = gen_reg_rtx (XFmode);")
14438 (define_expand "logb<mode>2"
14439 [(use (match_operand:MODEF 0 "register_operand"))
14440 (use (match_operand:MODEF 1 "register_operand"))]
14441 "TARGET_USE_FANCY_MATH_387
14442 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14443 || TARGET_MIX_SSE_I387)
14444 && flag_unsafe_math_optimizations"
14446 rtx op0 = gen_reg_rtx (XFmode);
14447 rtx op1 = gen_reg_rtx (XFmode);
14449 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14450 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14454 (define_expand "ilogbxf2"
14455 [(use (match_operand:SI 0 "register_operand"))
14456 (use (match_operand:XF 1 "register_operand"))]
14457 "TARGET_USE_FANCY_MATH_387
14458 && flag_unsafe_math_optimizations"
14462 if (optimize_insn_for_size_p ())
14465 op0 = gen_reg_rtx (XFmode);
14466 op1 = gen_reg_rtx (XFmode);
14468 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14469 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14473 (define_expand "ilogb<mode>2"
14474 [(use (match_operand:SI 0 "register_operand"))
14475 (use (match_operand:MODEF 1 "register_operand"))]
14476 "TARGET_USE_FANCY_MATH_387
14477 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14478 || TARGET_MIX_SSE_I387)
14479 && flag_unsafe_math_optimizations"
14483 if (optimize_insn_for_size_p ())
14486 op0 = gen_reg_rtx (XFmode);
14487 op1 = gen_reg_rtx (XFmode);
14489 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14490 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14494 (define_insn "*f2xm1xf2_i387"
14495 [(set (match_operand:XF 0 "register_operand" "=f")
14496 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14498 "TARGET_USE_FANCY_MATH_387
14499 && flag_unsafe_math_optimizations"
14501 [(set_attr "type" "fpspc")
14502 (set_attr "mode" "XF")])
14504 (define_insn "*fscalexf4_i387"
14505 [(set (match_operand:XF 0 "register_operand" "=f")
14506 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14507 (match_operand:XF 3 "register_operand" "1")]
14508 UNSPEC_FSCALE_FRACT))
14509 (set (match_operand:XF 1 "register_operand" "=u")
14510 (unspec:XF [(match_dup 2) (match_dup 3)]
14511 UNSPEC_FSCALE_EXP))]
14512 "TARGET_USE_FANCY_MATH_387
14513 && flag_unsafe_math_optimizations"
14515 [(set_attr "type" "fpspc")
14516 (set_attr "mode" "XF")])
14518 (define_expand "expNcorexf3"
14519 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14520 (match_operand:XF 2 "register_operand")))
14521 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14522 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14523 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14524 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14525 (parallel [(set (match_operand:XF 0 "register_operand")
14526 (unspec:XF [(match_dup 8) (match_dup 4)]
14527 UNSPEC_FSCALE_FRACT))
14529 (unspec:XF [(match_dup 8) (match_dup 4)]
14530 UNSPEC_FSCALE_EXP))])]
14531 "TARGET_USE_FANCY_MATH_387
14532 && flag_unsafe_math_optimizations"
14536 if (optimize_insn_for_size_p ())
14539 for (i = 3; i < 10; i++)
14540 operands[i] = gen_reg_rtx (XFmode);
14542 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14545 (define_expand "expxf2"
14546 [(use (match_operand:XF 0 "register_operand"))
14547 (use (match_operand:XF 1 "register_operand"))]
14548 "TARGET_USE_FANCY_MATH_387
14549 && flag_unsafe_math_optimizations"
14553 if (optimize_insn_for_size_p ())
14556 op2 = gen_reg_rtx (XFmode);
14557 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14559 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14563 (define_expand "exp<mode>2"
14564 [(use (match_operand:MODEF 0 "register_operand"))
14565 (use (match_operand:MODEF 1 "general_operand"))]
14566 "TARGET_USE_FANCY_MATH_387
14567 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14568 || TARGET_MIX_SSE_I387)
14569 && flag_unsafe_math_optimizations"
14573 if (optimize_insn_for_size_p ())
14576 op0 = gen_reg_rtx (XFmode);
14577 op1 = gen_reg_rtx (XFmode);
14579 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14580 emit_insn (gen_expxf2 (op0, op1));
14581 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14585 (define_expand "exp10xf2"
14586 [(use (match_operand:XF 0 "register_operand"))
14587 (use (match_operand:XF 1 "register_operand"))]
14588 "TARGET_USE_FANCY_MATH_387
14589 && flag_unsafe_math_optimizations"
14593 if (optimize_insn_for_size_p ())
14596 op2 = gen_reg_rtx (XFmode);
14597 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14599 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14603 (define_expand "exp10<mode>2"
14604 [(use (match_operand:MODEF 0 "register_operand"))
14605 (use (match_operand:MODEF 1 "general_operand"))]
14606 "TARGET_USE_FANCY_MATH_387
14607 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14608 || TARGET_MIX_SSE_I387)
14609 && flag_unsafe_math_optimizations"
14613 if (optimize_insn_for_size_p ())
14616 op0 = gen_reg_rtx (XFmode);
14617 op1 = gen_reg_rtx (XFmode);
14619 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14620 emit_insn (gen_exp10xf2 (op0, op1));
14621 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14625 (define_expand "exp2xf2"
14626 [(use (match_operand:XF 0 "register_operand"))
14627 (use (match_operand:XF 1 "register_operand"))]
14628 "TARGET_USE_FANCY_MATH_387
14629 && flag_unsafe_math_optimizations"
14633 if (optimize_insn_for_size_p ())
14636 op2 = gen_reg_rtx (XFmode);
14637 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14639 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14643 (define_expand "exp2<mode>2"
14644 [(use (match_operand:MODEF 0 "register_operand"))
14645 (use (match_operand:MODEF 1 "general_operand"))]
14646 "TARGET_USE_FANCY_MATH_387
14647 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14648 || TARGET_MIX_SSE_I387)
14649 && flag_unsafe_math_optimizations"
14653 if (optimize_insn_for_size_p ())
14656 op0 = gen_reg_rtx (XFmode);
14657 op1 = gen_reg_rtx (XFmode);
14659 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14660 emit_insn (gen_exp2xf2 (op0, op1));
14661 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14665 (define_expand "expm1xf2"
14666 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14668 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14669 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14670 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14671 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14672 (parallel [(set (match_dup 7)
14673 (unspec:XF [(match_dup 6) (match_dup 4)]
14674 UNSPEC_FSCALE_FRACT))
14676 (unspec:XF [(match_dup 6) (match_dup 4)]
14677 UNSPEC_FSCALE_EXP))])
14678 (parallel [(set (match_dup 10)
14679 (unspec:XF [(match_dup 9) (match_dup 8)]
14680 UNSPEC_FSCALE_FRACT))
14681 (set (match_dup 11)
14682 (unspec:XF [(match_dup 9) (match_dup 8)]
14683 UNSPEC_FSCALE_EXP))])
14684 (set (match_dup 12) (minus:XF (match_dup 10)
14685 (float_extend:XF (match_dup 13))))
14686 (set (match_operand:XF 0 "register_operand")
14687 (plus:XF (match_dup 12) (match_dup 7)))]
14688 "TARGET_USE_FANCY_MATH_387
14689 && flag_unsafe_math_optimizations"
14693 if (optimize_insn_for_size_p ())
14696 for (i = 2; i < 13; i++)
14697 operands[i] = gen_reg_rtx (XFmode);
14700 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14702 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14705 (define_expand "expm1<mode>2"
14706 [(use (match_operand:MODEF 0 "register_operand"))
14707 (use (match_operand:MODEF 1 "general_operand"))]
14708 "TARGET_USE_FANCY_MATH_387
14709 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14710 || TARGET_MIX_SSE_I387)
14711 && flag_unsafe_math_optimizations"
14715 if (optimize_insn_for_size_p ())
14718 op0 = gen_reg_rtx (XFmode);
14719 op1 = gen_reg_rtx (XFmode);
14721 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14722 emit_insn (gen_expm1xf2 (op0, op1));
14723 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14727 (define_expand "ldexpxf3"
14728 [(set (match_dup 3)
14729 (float:XF (match_operand:SI 2 "register_operand")))
14730 (parallel [(set (match_operand:XF 0 " register_operand")
14731 (unspec:XF [(match_operand:XF 1 "register_operand")
14733 UNSPEC_FSCALE_FRACT))
14735 (unspec:XF [(match_dup 1) (match_dup 3)]
14736 UNSPEC_FSCALE_EXP))])]
14737 "TARGET_USE_FANCY_MATH_387
14738 && flag_unsafe_math_optimizations"
14740 if (optimize_insn_for_size_p ())
14743 operands[3] = gen_reg_rtx (XFmode);
14744 operands[4] = gen_reg_rtx (XFmode);
14747 (define_expand "ldexp<mode>3"
14748 [(use (match_operand:MODEF 0 "register_operand"))
14749 (use (match_operand:MODEF 1 "general_operand"))
14750 (use (match_operand:SI 2 "register_operand"))]
14751 "TARGET_USE_FANCY_MATH_387
14752 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14753 || TARGET_MIX_SSE_I387)
14754 && flag_unsafe_math_optimizations"
14758 if (optimize_insn_for_size_p ())
14761 op0 = gen_reg_rtx (XFmode);
14762 op1 = gen_reg_rtx (XFmode);
14764 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14765 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14766 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14770 (define_expand "scalbxf3"
14771 [(parallel [(set (match_operand:XF 0 " register_operand")
14772 (unspec:XF [(match_operand:XF 1 "register_operand")
14773 (match_operand:XF 2 "register_operand")]
14774 UNSPEC_FSCALE_FRACT))
14776 (unspec:XF [(match_dup 1) (match_dup 2)]
14777 UNSPEC_FSCALE_EXP))])]
14778 "TARGET_USE_FANCY_MATH_387
14779 && flag_unsafe_math_optimizations"
14781 if (optimize_insn_for_size_p ())
14784 operands[3] = gen_reg_rtx (XFmode);
14787 (define_expand "scalb<mode>3"
14788 [(use (match_operand:MODEF 0 "register_operand"))
14789 (use (match_operand:MODEF 1 "general_operand"))
14790 (use (match_operand:MODEF 2 "general_operand"))]
14791 "TARGET_USE_FANCY_MATH_387
14792 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14793 || TARGET_MIX_SSE_I387)
14794 && flag_unsafe_math_optimizations"
14798 if (optimize_insn_for_size_p ())
14801 op0 = gen_reg_rtx (XFmode);
14802 op1 = gen_reg_rtx (XFmode);
14803 op2 = gen_reg_rtx (XFmode);
14805 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14806 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14807 emit_insn (gen_scalbxf3 (op0, op1, op2));
14808 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14812 (define_expand "significandxf2"
14813 [(parallel [(set (match_operand:XF 0 "register_operand")
14814 (unspec:XF [(match_operand:XF 1 "register_operand")]
14815 UNSPEC_XTRACT_FRACT))
14817 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14818 "TARGET_USE_FANCY_MATH_387
14819 && flag_unsafe_math_optimizations"
14820 "operands[2] = gen_reg_rtx (XFmode);")
14822 (define_expand "significand<mode>2"
14823 [(use (match_operand:MODEF 0 "register_operand"))
14824 (use (match_operand:MODEF 1 "register_operand"))]
14825 "TARGET_USE_FANCY_MATH_387
14826 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14827 || TARGET_MIX_SSE_I387)
14828 && flag_unsafe_math_optimizations"
14830 rtx op0 = gen_reg_rtx (XFmode);
14831 rtx op1 = gen_reg_rtx (XFmode);
14833 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14834 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14839 (define_insn "sse4_1_round<mode>2"
14840 [(set (match_operand:MODEF 0 "register_operand" "=x")
14841 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14842 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14845 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14846 [(set_attr "type" "ssecvt")
14847 (set_attr "prefix_extra" "1")
14848 (set_attr "prefix" "maybe_vex")
14849 (set_attr "mode" "<MODE>")])
14851 (define_insn "rintxf2"
14852 [(set (match_operand:XF 0 "register_operand" "=f")
14853 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14855 "TARGET_USE_FANCY_MATH_387
14856 && flag_unsafe_math_optimizations"
14858 [(set_attr "type" "fpspc")
14859 (set_attr "mode" "XF")])
14861 (define_expand "rint<mode>2"
14862 [(use (match_operand:MODEF 0 "register_operand"))
14863 (use (match_operand:MODEF 1 "register_operand"))]
14864 "(TARGET_USE_FANCY_MATH_387
14865 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14866 || TARGET_MIX_SSE_I387)
14867 && flag_unsafe_math_optimizations)
14868 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14869 && !flag_trapping_math)"
14871 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14872 && !flag_trapping_math)
14875 emit_insn (gen_sse4_1_round<mode>2
14876 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14877 else if (optimize_insn_for_size_p ())
14880 ix86_expand_rint (operands[0], operands[1]);
14884 rtx op0 = gen_reg_rtx (XFmode);
14885 rtx op1 = gen_reg_rtx (XFmode);
14887 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14888 emit_insn (gen_rintxf2 (op0, op1));
14890 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14895 (define_expand "round<mode>2"
14896 [(match_operand:X87MODEF 0 "register_operand")
14897 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14898 "(TARGET_USE_FANCY_MATH_387
14899 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14900 || TARGET_MIX_SSE_I387)
14901 && flag_unsafe_math_optimizations)
14902 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14903 && !flag_trapping_math && !flag_rounding_math)"
14905 if (optimize_insn_for_size_p ())
14908 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14909 && !flag_trapping_math && !flag_rounding_math)
14913 operands[1] = force_reg (<MODE>mode, operands[1]);
14914 ix86_expand_round_sse4 (operands[0], operands[1]);
14916 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14917 ix86_expand_round (operands[0], operands[1]);
14919 ix86_expand_rounddf_32 (operands[0], operands[1]);
14923 operands[1] = force_reg (<MODE>mode, operands[1]);
14924 ix86_emit_i387_round (operands[0], operands[1]);
14929 (define_insn_and_split "*fistdi2_1"
14930 [(set (match_operand:DI 0 "nonimmediate_operand")
14931 (unspec:DI [(match_operand:XF 1 "register_operand")]
14933 "TARGET_USE_FANCY_MATH_387
14934 && can_create_pseudo_p ()"
14939 if (memory_operand (operands[0], VOIDmode))
14940 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14943 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14944 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14949 [(set_attr "type" "fpspc")
14950 (set_attr "mode" "DI")])
14952 (define_insn "fistdi2"
14953 [(set (match_operand:DI 0 "memory_operand" "=m")
14954 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14956 (clobber (match_scratch:XF 2 "=&1f"))]
14957 "TARGET_USE_FANCY_MATH_387"
14958 "* return output_fix_trunc (insn, operands, false);"
14959 [(set_attr "type" "fpspc")
14960 (set_attr "mode" "DI")])
14962 (define_insn "fistdi2_with_temp"
14963 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14964 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14966 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14967 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14968 "TARGET_USE_FANCY_MATH_387"
14970 [(set_attr "type" "fpspc")
14971 (set_attr "mode" "DI")])
14974 [(set (match_operand:DI 0 "register_operand")
14975 (unspec:DI [(match_operand:XF 1 "register_operand")]
14977 (clobber (match_operand:DI 2 "memory_operand"))
14978 (clobber (match_scratch 3))]
14980 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14981 (clobber (match_dup 3))])
14982 (set (match_dup 0) (match_dup 2))])
14985 [(set (match_operand:DI 0 "memory_operand")
14986 (unspec:DI [(match_operand:XF 1 "register_operand")]
14988 (clobber (match_operand:DI 2 "memory_operand"))
14989 (clobber (match_scratch 3))]
14991 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14992 (clobber (match_dup 3))])])
14994 (define_insn_and_split "*fist<mode>2_1"
14995 [(set (match_operand:SWI24 0 "register_operand")
14996 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14998 "TARGET_USE_FANCY_MATH_387
14999 && can_create_pseudo_p ()"
15004 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15005 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15009 [(set_attr "type" "fpspc")
15010 (set_attr "mode" "<MODE>")])
15012 (define_insn "fist<mode>2"
15013 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15014 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15016 "TARGET_USE_FANCY_MATH_387"
15017 "* return output_fix_trunc (insn, operands, false);"
15018 [(set_attr "type" "fpspc")
15019 (set_attr "mode" "<MODE>")])
15021 (define_insn "fist<mode>2_with_temp"
15022 [(set (match_operand:SWI24 0 "register_operand" "=r")
15023 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15025 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15026 "TARGET_USE_FANCY_MATH_387"
15028 [(set_attr "type" "fpspc")
15029 (set_attr "mode" "<MODE>")])
15032 [(set (match_operand:SWI24 0 "register_operand")
15033 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15035 (clobber (match_operand:SWI24 2 "memory_operand"))]
15037 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15038 (set (match_dup 0) (match_dup 2))])
15041 [(set (match_operand:SWI24 0 "memory_operand")
15042 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15044 (clobber (match_operand:SWI24 2 "memory_operand"))]
15046 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15048 (define_expand "lrintxf<mode>2"
15049 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15050 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15052 "TARGET_USE_FANCY_MATH_387")
15054 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
15055 [(set (match_operand:SWI48x 0 "nonimmediate_operand")
15056 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand")]
15057 UNSPEC_FIX_NOTRUNC))]
15058 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15059 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
15061 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15062 [(match_operand:SWI248x 0 "nonimmediate_operand")
15063 (match_operand:X87MODEF 1 "register_operand")]
15064 "(TARGET_USE_FANCY_MATH_387
15065 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15066 || TARGET_MIX_SSE_I387)
15067 && flag_unsafe_math_optimizations)
15068 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15069 && <SWI248x:MODE>mode != HImode
15070 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15071 && !flag_trapping_math && !flag_rounding_math)"
15073 if (optimize_insn_for_size_p ())
15076 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15077 && <SWI248x:MODE>mode != HImode
15078 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15079 && !flag_trapping_math && !flag_rounding_math)
15080 ix86_expand_lround (operands[0], operands[1]);
15082 ix86_emit_i387_round (operands[0], operands[1]);
15086 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15087 (define_insn_and_split "frndintxf2_floor"
15088 [(set (match_operand:XF 0 "register_operand")
15089 (unspec:XF [(match_operand:XF 1 "register_operand")]
15090 UNSPEC_FRNDINT_FLOOR))
15091 (clobber (reg:CC FLAGS_REG))]
15092 "TARGET_USE_FANCY_MATH_387
15093 && flag_unsafe_math_optimizations
15094 && can_create_pseudo_p ()"
15099 ix86_optimize_mode_switching[I387_FLOOR] = 1;
15101 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15102 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
15104 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
15105 operands[2], operands[3]));
15108 [(set_attr "type" "frndint")
15109 (set_attr "i387_cw" "floor")
15110 (set_attr "mode" "XF")])
15112 (define_insn "frndintxf2_floor_i387"
15113 [(set (match_operand:XF 0 "register_operand" "=f")
15114 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15115 UNSPEC_FRNDINT_FLOOR))
15116 (use (match_operand:HI 2 "memory_operand" "m"))
15117 (use (match_operand:HI 3 "memory_operand" "m"))]
15118 "TARGET_USE_FANCY_MATH_387
15119 && flag_unsafe_math_optimizations"
15120 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15121 [(set_attr "type" "frndint")
15122 (set_attr "i387_cw" "floor")
15123 (set_attr "mode" "XF")])
15125 (define_expand "floorxf2"
15126 [(use (match_operand:XF 0 "register_operand"))
15127 (use (match_operand:XF 1 "register_operand"))]
15128 "TARGET_USE_FANCY_MATH_387
15129 && flag_unsafe_math_optimizations"
15131 if (optimize_insn_for_size_p ())
15133 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
15137 (define_expand "floor<mode>2"
15138 [(use (match_operand:MODEF 0 "register_operand"))
15139 (use (match_operand:MODEF 1 "register_operand"))]
15140 "(TARGET_USE_FANCY_MATH_387
15141 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15142 || TARGET_MIX_SSE_I387)
15143 && flag_unsafe_math_optimizations)
15144 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15145 && !flag_trapping_math)"
15147 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15148 && !flag_trapping_math)
15151 emit_insn (gen_sse4_1_round<mode>2
15152 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
15153 else if (optimize_insn_for_size_p ())
15155 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15156 ix86_expand_floorceil (operands[0], operands[1], true);
15158 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15164 if (optimize_insn_for_size_p ())
15167 op0 = gen_reg_rtx (XFmode);
15168 op1 = gen_reg_rtx (XFmode);
15169 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15170 emit_insn (gen_frndintxf2_floor (op0, op1));
15172 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15177 (define_insn_and_split "*fist<mode>2_floor_1"
15178 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15179 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15180 UNSPEC_FIST_FLOOR))
15181 (clobber (reg:CC FLAGS_REG))]
15182 "TARGET_USE_FANCY_MATH_387
15183 && flag_unsafe_math_optimizations
15184 && can_create_pseudo_p ()"
15189 ix86_optimize_mode_switching[I387_FLOOR] = 1;
15191 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15192 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
15193 if (memory_operand (operands[0], VOIDmode))
15194 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
15195 operands[2], operands[3]));
15198 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15199 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
15200 operands[2], operands[3],
15205 [(set_attr "type" "fistp")
15206 (set_attr "i387_cw" "floor")
15207 (set_attr "mode" "<MODE>")])
15209 (define_insn "fistdi2_floor"
15210 [(set (match_operand:DI 0 "memory_operand" "=m")
15211 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15212 UNSPEC_FIST_FLOOR))
15213 (use (match_operand:HI 2 "memory_operand" "m"))
15214 (use (match_operand:HI 3 "memory_operand" "m"))
15215 (clobber (match_scratch:XF 4 "=&1f"))]
15216 "TARGET_USE_FANCY_MATH_387
15217 && flag_unsafe_math_optimizations"
15218 "* return output_fix_trunc (insn, operands, false);"
15219 [(set_attr "type" "fistp")
15220 (set_attr "i387_cw" "floor")
15221 (set_attr "mode" "DI")])
15223 (define_insn "fistdi2_floor_with_temp"
15224 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15225 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15226 UNSPEC_FIST_FLOOR))
15227 (use (match_operand:HI 2 "memory_operand" "m,m"))
15228 (use (match_operand:HI 3 "memory_operand" "m,m"))
15229 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15230 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15231 "TARGET_USE_FANCY_MATH_387
15232 && flag_unsafe_math_optimizations"
15234 [(set_attr "type" "fistp")
15235 (set_attr "i387_cw" "floor")
15236 (set_attr "mode" "DI")])
15239 [(set (match_operand:DI 0 "register_operand")
15240 (unspec:DI [(match_operand:XF 1 "register_operand")]
15241 UNSPEC_FIST_FLOOR))
15242 (use (match_operand:HI 2 "memory_operand"))
15243 (use (match_operand:HI 3 "memory_operand"))
15244 (clobber (match_operand:DI 4 "memory_operand"))
15245 (clobber (match_scratch 5))]
15247 [(parallel [(set (match_dup 4)
15248 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15249 (use (match_dup 2))
15250 (use (match_dup 3))
15251 (clobber (match_dup 5))])
15252 (set (match_dup 0) (match_dup 4))])
15255 [(set (match_operand:DI 0 "memory_operand")
15256 (unspec:DI [(match_operand:XF 1 "register_operand")]
15257 UNSPEC_FIST_FLOOR))
15258 (use (match_operand:HI 2 "memory_operand"))
15259 (use (match_operand:HI 3 "memory_operand"))
15260 (clobber (match_operand:DI 4 "memory_operand"))
15261 (clobber (match_scratch 5))]
15263 [(parallel [(set (match_dup 0)
15264 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15265 (use (match_dup 2))
15266 (use (match_dup 3))
15267 (clobber (match_dup 5))])])
15269 (define_insn "fist<mode>2_floor"
15270 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15271 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15272 UNSPEC_FIST_FLOOR))
15273 (use (match_operand:HI 2 "memory_operand" "m"))
15274 (use (match_operand:HI 3 "memory_operand" "m"))]
15275 "TARGET_USE_FANCY_MATH_387
15276 && flag_unsafe_math_optimizations"
15277 "* return output_fix_trunc (insn, operands, false);"
15278 [(set_attr "type" "fistp")
15279 (set_attr "i387_cw" "floor")
15280 (set_attr "mode" "<MODE>")])
15282 (define_insn "fist<mode>2_floor_with_temp"
15283 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15284 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15285 UNSPEC_FIST_FLOOR))
15286 (use (match_operand:HI 2 "memory_operand" "m,m"))
15287 (use (match_operand:HI 3 "memory_operand" "m,m"))
15288 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15289 "TARGET_USE_FANCY_MATH_387
15290 && flag_unsafe_math_optimizations"
15292 [(set_attr "type" "fistp")
15293 (set_attr "i387_cw" "floor")
15294 (set_attr "mode" "<MODE>")])
15297 [(set (match_operand:SWI24 0 "register_operand")
15298 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15299 UNSPEC_FIST_FLOOR))
15300 (use (match_operand:HI 2 "memory_operand"))
15301 (use (match_operand:HI 3 "memory_operand"))
15302 (clobber (match_operand:SWI24 4 "memory_operand"))]
15304 [(parallel [(set (match_dup 4)
15305 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15306 (use (match_dup 2))
15307 (use (match_dup 3))])
15308 (set (match_dup 0) (match_dup 4))])
15311 [(set (match_operand:SWI24 0 "memory_operand")
15312 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15313 UNSPEC_FIST_FLOOR))
15314 (use (match_operand:HI 2 "memory_operand"))
15315 (use (match_operand:HI 3 "memory_operand"))
15316 (clobber (match_operand:SWI24 4 "memory_operand"))]
15318 [(parallel [(set (match_dup 0)
15319 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15320 (use (match_dup 2))
15321 (use (match_dup 3))])])
15323 (define_expand "lfloorxf<mode>2"
15324 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15325 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15326 UNSPEC_FIST_FLOOR))
15327 (clobber (reg:CC FLAGS_REG))])]
15328 "TARGET_USE_FANCY_MATH_387
15329 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15330 && flag_unsafe_math_optimizations")
15332 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15333 [(match_operand:SWI48 0 "nonimmediate_operand")
15334 (match_operand:MODEF 1 "register_operand")]
15335 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15336 && !flag_trapping_math"
15338 if (TARGET_64BIT && optimize_insn_for_size_p ())
15340 ix86_expand_lfloorceil (operands[0], operands[1], true);
15344 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15345 (define_insn_and_split "frndintxf2_ceil"
15346 [(set (match_operand:XF 0 "register_operand")
15347 (unspec:XF [(match_operand:XF 1 "register_operand")]
15348 UNSPEC_FRNDINT_CEIL))
15349 (clobber (reg:CC FLAGS_REG))]
15350 "TARGET_USE_FANCY_MATH_387
15351 && flag_unsafe_math_optimizations
15352 && can_create_pseudo_p ()"
15357 ix86_optimize_mode_switching[I387_CEIL] = 1;
15359 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15360 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15362 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15363 operands[2], operands[3]));
15366 [(set_attr "type" "frndint")
15367 (set_attr "i387_cw" "ceil")
15368 (set_attr "mode" "XF")])
15370 (define_insn "frndintxf2_ceil_i387"
15371 [(set (match_operand:XF 0 "register_operand" "=f")
15372 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15373 UNSPEC_FRNDINT_CEIL))
15374 (use (match_operand:HI 2 "memory_operand" "m"))
15375 (use (match_operand:HI 3 "memory_operand" "m"))]
15376 "TARGET_USE_FANCY_MATH_387
15377 && flag_unsafe_math_optimizations"
15378 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15379 [(set_attr "type" "frndint")
15380 (set_attr "i387_cw" "ceil")
15381 (set_attr "mode" "XF")])
15383 (define_expand "ceilxf2"
15384 [(use (match_operand:XF 0 "register_operand"))
15385 (use (match_operand:XF 1 "register_operand"))]
15386 "TARGET_USE_FANCY_MATH_387
15387 && flag_unsafe_math_optimizations"
15389 if (optimize_insn_for_size_p ())
15391 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15395 (define_expand "ceil<mode>2"
15396 [(use (match_operand:MODEF 0 "register_operand"))
15397 (use (match_operand:MODEF 1 "register_operand"))]
15398 "(TARGET_USE_FANCY_MATH_387
15399 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15400 || TARGET_MIX_SSE_I387)
15401 && flag_unsafe_math_optimizations)
15402 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15403 && !flag_trapping_math)"
15405 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15406 && !flag_trapping_math)
15409 emit_insn (gen_sse4_1_round<mode>2
15410 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15411 else if (optimize_insn_for_size_p ())
15413 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15414 ix86_expand_floorceil (operands[0], operands[1], false);
15416 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15422 if (optimize_insn_for_size_p ())
15425 op0 = gen_reg_rtx (XFmode);
15426 op1 = gen_reg_rtx (XFmode);
15427 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15428 emit_insn (gen_frndintxf2_ceil (op0, op1));
15430 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15435 (define_insn_and_split "*fist<mode>2_ceil_1"
15436 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15437 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15439 (clobber (reg:CC FLAGS_REG))]
15440 "TARGET_USE_FANCY_MATH_387
15441 && flag_unsafe_math_optimizations
15442 && can_create_pseudo_p ()"
15447 ix86_optimize_mode_switching[I387_CEIL] = 1;
15449 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15450 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15451 if (memory_operand (operands[0], VOIDmode))
15452 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15453 operands[2], operands[3]));
15456 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15457 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15458 operands[2], operands[3],
15463 [(set_attr "type" "fistp")
15464 (set_attr "i387_cw" "ceil")
15465 (set_attr "mode" "<MODE>")])
15467 (define_insn "fistdi2_ceil"
15468 [(set (match_operand:DI 0 "memory_operand" "=m")
15469 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15471 (use (match_operand:HI 2 "memory_operand" "m"))
15472 (use (match_operand:HI 3 "memory_operand" "m"))
15473 (clobber (match_scratch:XF 4 "=&1f"))]
15474 "TARGET_USE_FANCY_MATH_387
15475 && flag_unsafe_math_optimizations"
15476 "* return output_fix_trunc (insn, operands, false);"
15477 [(set_attr "type" "fistp")
15478 (set_attr "i387_cw" "ceil")
15479 (set_attr "mode" "DI")])
15481 (define_insn "fistdi2_ceil_with_temp"
15482 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15483 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15485 (use (match_operand:HI 2 "memory_operand" "m,m"))
15486 (use (match_operand:HI 3 "memory_operand" "m,m"))
15487 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15488 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15489 "TARGET_USE_FANCY_MATH_387
15490 && flag_unsafe_math_optimizations"
15492 [(set_attr "type" "fistp")
15493 (set_attr "i387_cw" "ceil")
15494 (set_attr "mode" "DI")])
15497 [(set (match_operand:DI 0 "register_operand")
15498 (unspec:DI [(match_operand:XF 1 "register_operand")]
15500 (use (match_operand:HI 2 "memory_operand"))
15501 (use (match_operand:HI 3 "memory_operand"))
15502 (clobber (match_operand:DI 4 "memory_operand"))
15503 (clobber (match_scratch 5))]
15505 [(parallel [(set (match_dup 4)
15506 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15507 (use (match_dup 2))
15508 (use (match_dup 3))
15509 (clobber (match_dup 5))])
15510 (set (match_dup 0) (match_dup 4))])
15513 [(set (match_operand:DI 0 "memory_operand")
15514 (unspec:DI [(match_operand:XF 1 "register_operand")]
15516 (use (match_operand:HI 2 "memory_operand"))
15517 (use (match_operand:HI 3 "memory_operand"))
15518 (clobber (match_operand:DI 4 "memory_operand"))
15519 (clobber (match_scratch 5))]
15521 [(parallel [(set (match_dup 0)
15522 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15523 (use (match_dup 2))
15524 (use (match_dup 3))
15525 (clobber (match_dup 5))])])
15527 (define_insn "fist<mode>2_ceil"
15528 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15529 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15531 (use (match_operand:HI 2 "memory_operand" "m"))
15532 (use (match_operand:HI 3 "memory_operand" "m"))]
15533 "TARGET_USE_FANCY_MATH_387
15534 && flag_unsafe_math_optimizations"
15535 "* return output_fix_trunc (insn, operands, false);"
15536 [(set_attr "type" "fistp")
15537 (set_attr "i387_cw" "ceil")
15538 (set_attr "mode" "<MODE>")])
15540 (define_insn "fist<mode>2_ceil_with_temp"
15541 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15542 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15544 (use (match_operand:HI 2 "memory_operand" "m,m"))
15545 (use (match_operand:HI 3 "memory_operand" "m,m"))
15546 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15547 "TARGET_USE_FANCY_MATH_387
15548 && flag_unsafe_math_optimizations"
15550 [(set_attr "type" "fistp")
15551 (set_attr "i387_cw" "ceil")
15552 (set_attr "mode" "<MODE>")])
15555 [(set (match_operand:SWI24 0 "register_operand")
15556 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15558 (use (match_operand:HI 2 "memory_operand"))
15559 (use (match_operand:HI 3 "memory_operand"))
15560 (clobber (match_operand:SWI24 4 "memory_operand"))]
15562 [(parallel [(set (match_dup 4)
15563 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15564 (use (match_dup 2))
15565 (use (match_dup 3))])
15566 (set (match_dup 0) (match_dup 4))])
15569 [(set (match_operand:SWI24 0 "memory_operand")
15570 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15572 (use (match_operand:HI 2 "memory_operand"))
15573 (use (match_operand:HI 3 "memory_operand"))
15574 (clobber (match_operand:SWI24 4 "memory_operand"))]
15576 [(parallel [(set (match_dup 0)
15577 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15578 (use (match_dup 2))
15579 (use (match_dup 3))])])
15581 (define_expand "lceilxf<mode>2"
15582 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15583 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15585 (clobber (reg:CC FLAGS_REG))])]
15586 "TARGET_USE_FANCY_MATH_387
15587 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15588 && flag_unsafe_math_optimizations")
15590 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15591 [(match_operand:SWI48 0 "nonimmediate_operand")
15592 (match_operand:MODEF 1 "register_operand")]
15593 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15594 && !flag_trapping_math"
15596 ix86_expand_lfloorceil (operands[0], operands[1], false);
15600 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15601 (define_insn_and_split "frndintxf2_trunc"
15602 [(set (match_operand:XF 0 "register_operand")
15603 (unspec:XF [(match_operand:XF 1 "register_operand")]
15604 UNSPEC_FRNDINT_TRUNC))
15605 (clobber (reg:CC FLAGS_REG))]
15606 "TARGET_USE_FANCY_MATH_387
15607 && flag_unsafe_math_optimizations
15608 && can_create_pseudo_p ()"
15613 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15615 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15616 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15618 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15619 operands[2], operands[3]));
15622 [(set_attr "type" "frndint")
15623 (set_attr "i387_cw" "trunc")
15624 (set_attr "mode" "XF")])
15626 (define_insn "frndintxf2_trunc_i387"
15627 [(set (match_operand:XF 0 "register_operand" "=f")
15628 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15629 UNSPEC_FRNDINT_TRUNC))
15630 (use (match_operand:HI 2 "memory_operand" "m"))
15631 (use (match_operand:HI 3 "memory_operand" "m"))]
15632 "TARGET_USE_FANCY_MATH_387
15633 && flag_unsafe_math_optimizations"
15634 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15635 [(set_attr "type" "frndint")
15636 (set_attr "i387_cw" "trunc")
15637 (set_attr "mode" "XF")])
15639 (define_expand "btruncxf2"
15640 [(use (match_operand:XF 0 "register_operand"))
15641 (use (match_operand:XF 1 "register_operand"))]
15642 "TARGET_USE_FANCY_MATH_387
15643 && flag_unsafe_math_optimizations"
15645 if (optimize_insn_for_size_p ())
15647 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15651 (define_expand "btrunc<mode>2"
15652 [(use (match_operand:MODEF 0 "register_operand"))
15653 (use (match_operand:MODEF 1 "register_operand"))]
15654 "(TARGET_USE_FANCY_MATH_387
15655 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15656 || TARGET_MIX_SSE_I387)
15657 && flag_unsafe_math_optimizations)
15658 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15659 && !flag_trapping_math)"
15661 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15662 && !flag_trapping_math)
15665 emit_insn (gen_sse4_1_round<mode>2
15666 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15667 else if (optimize_insn_for_size_p ())
15669 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15670 ix86_expand_trunc (operands[0], operands[1]);
15672 ix86_expand_truncdf_32 (operands[0], operands[1]);
15678 if (optimize_insn_for_size_p ())
15681 op0 = gen_reg_rtx (XFmode);
15682 op1 = gen_reg_rtx (XFmode);
15683 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15684 emit_insn (gen_frndintxf2_trunc (op0, op1));
15686 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15691 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15692 (define_insn_and_split "frndintxf2_mask_pm"
15693 [(set (match_operand:XF 0 "register_operand")
15694 (unspec:XF [(match_operand:XF 1 "register_operand")]
15695 UNSPEC_FRNDINT_MASK_PM))
15696 (clobber (reg:CC FLAGS_REG))]
15697 "TARGET_USE_FANCY_MATH_387
15698 && flag_unsafe_math_optimizations
15699 && can_create_pseudo_p ()"
15704 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15706 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15707 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15709 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15710 operands[2], operands[3]));
15713 [(set_attr "type" "frndint")
15714 (set_attr "i387_cw" "mask_pm")
15715 (set_attr "mode" "XF")])
15717 (define_insn "frndintxf2_mask_pm_i387"
15718 [(set (match_operand:XF 0 "register_operand" "=f")
15719 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15720 UNSPEC_FRNDINT_MASK_PM))
15721 (use (match_operand:HI 2 "memory_operand" "m"))
15722 (use (match_operand:HI 3 "memory_operand" "m"))]
15723 "TARGET_USE_FANCY_MATH_387
15724 && flag_unsafe_math_optimizations"
15725 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15726 [(set_attr "type" "frndint")
15727 (set_attr "i387_cw" "mask_pm")
15728 (set_attr "mode" "XF")])
15730 (define_expand "nearbyintxf2"
15731 [(use (match_operand:XF 0 "register_operand"))
15732 (use (match_operand:XF 1 "register_operand"))]
15733 "TARGET_USE_FANCY_MATH_387
15734 && flag_unsafe_math_optimizations"
15736 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15740 (define_expand "nearbyint<mode>2"
15741 [(use (match_operand:MODEF 0 "register_operand"))
15742 (use (match_operand:MODEF 1 "register_operand"))]
15743 "TARGET_USE_FANCY_MATH_387
15744 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15745 || TARGET_MIX_SSE_I387)
15746 && flag_unsafe_math_optimizations"
15748 rtx op0 = gen_reg_rtx (XFmode);
15749 rtx op1 = gen_reg_rtx (XFmode);
15751 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15752 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15754 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15758 (define_insn "fxam<mode>2_i387"
15759 [(set (match_operand:HI 0 "register_operand" "=a")
15761 [(match_operand:X87MODEF 1 "register_operand" "f")]
15763 "TARGET_USE_FANCY_MATH_387"
15764 "fxam\n\tfnstsw\t%0"
15765 [(set_attr "type" "multi")
15766 (set_attr "length" "4")
15767 (set_attr "unit" "i387")
15768 (set_attr "mode" "<MODE>")])
15770 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15771 [(set (match_operand:HI 0 "register_operand")
15773 [(match_operand:MODEF 1 "memory_operand")]
15775 "TARGET_USE_FANCY_MATH_387
15776 && can_create_pseudo_p ()"
15779 [(set (match_dup 2)(match_dup 1))
15781 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15783 operands[2] = gen_reg_rtx (<MODE>mode);
15785 MEM_VOLATILE_P (operands[1]) = 1;
15787 [(set_attr "type" "multi")
15788 (set_attr "unit" "i387")
15789 (set_attr "mode" "<MODE>")])
15791 (define_expand "isinfxf2"
15792 [(use (match_operand:SI 0 "register_operand"))
15793 (use (match_operand:XF 1 "register_operand"))]
15794 "TARGET_USE_FANCY_MATH_387
15795 && TARGET_C99_FUNCTIONS"
15797 rtx mask = GEN_INT (0x45);
15798 rtx val = GEN_INT (0x05);
15802 rtx scratch = gen_reg_rtx (HImode);
15803 rtx res = gen_reg_rtx (QImode);
15805 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15807 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15808 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15809 cond = gen_rtx_fmt_ee (EQ, QImode,
15810 gen_rtx_REG (CCmode, FLAGS_REG),
15812 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15813 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15817 (define_expand "isinf<mode>2"
15818 [(use (match_operand:SI 0 "register_operand"))
15819 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15820 "TARGET_USE_FANCY_MATH_387
15821 && TARGET_C99_FUNCTIONS
15822 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15824 rtx mask = GEN_INT (0x45);
15825 rtx val = GEN_INT (0x05);
15829 rtx scratch = gen_reg_rtx (HImode);
15830 rtx res = gen_reg_rtx (QImode);
15832 /* Remove excess precision by forcing value through memory. */
15833 if (memory_operand (operands[1], VOIDmode))
15834 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15837 enum ix86_stack_slot slot = (virtuals_instantiated
15840 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15842 emit_move_insn (temp, operands[1]);
15843 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15846 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15847 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15848 cond = gen_rtx_fmt_ee (EQ, QImode,
15849 gen_rtx_REG (CCmode, FLAGS_REG),
15851 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15852 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15856 (define_expand "signbitxf2"
15857 [(use (match_operand:SI 0 "register_operand"))
15858 (use (match_operand:XF 1 "register_operand"))]
15859 "TARGET_USE_FANCY_MATH_387"
15861 rtx scratch = gen_reg_rtx (HImode);
15863 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15864 emit_insn (gen_andsi3 (operands[0],
15865 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15869 (define_insn "movmsk_df"
15870 [(set (match_operand:SI 0 "register_operand" "=r")
15872 [(match_operand:DF 1 "register_operand" "x")]
15874 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15875 "%vmovmskpd\t{%1, %0|%0, %1}"
15876 [(set_attr "type" "ssemov")
15877 (set_attr "prefix" "maybe_vex")
15878 (set_attr "mode" "DF")])
15880 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15881 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15882 (define_expand "signbitdf2"
15883 [(use (match_operand:SI 0 "register_operand"))
15884 (use (match_operand:DF 1 "register_operand"))]
15885 "TARGET_USE_FANCY_MATH_387
15886 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15888 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15890 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15891 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15895 rtx scratch = gen_reg_rtx (HImode);
15897 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15898 emit_insn (gen_andsi3 (operands[0],
15899 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15904 (define_expand "signbitsf2"
15905 [(use (match_operand:SI 0 "register_operand"))
15906 (use (match_operand:SF 1 "register_operand"))]
15907 "TARGET_USE_FANCY_MATH_387
15908 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15910 rtx scratch = gen_reg_rtx (HImode);
15912 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15913 emit_insn (gen_andsi3 (operands[0],
15914 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15918 ;; Block operation instructions
15921 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15924 [(set_attr "length" "1")
15925 (set_attr "length_immediate" "0")
15926 (set_attr "modrm" "0")])
15928 (define_expand "movmem<mode>"
15929 [(use (match_operand:BLK 0 "memory_operand"))
15930 (use (match_operand:BLK 1 "memory_operand"))
15931 (use (match_operand:SWI48 2 "nonmemory_operand"))
15932 (use (match_operand:SWI48 3 "const_int_operand"))
15933 (use (match_operand:SI 4 "const_int_operand"))
15934 (use (match_operand:SI 5 "const_int_operand"))]
15937 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15938 operands[4], operands[5]))
15944 ;; Most CPUs don't like single string operations
15945 ;; Handle this case here to simplify previous expander.
15947 (define_expand "strmov"
15948 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15949 (set (match_operand 1 "memory_operand") (match_dup 4))
15950 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15951 (clobber (reg:CC FLAGS_REG))])
15952 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15953 (clobber (reg:CC FLAGS_REG))])]
15956 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15958 /* If .md ever supports :P for Pmode, these can be directly
15959 in the pattern above. */
15960 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15961 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15963 /* Can't use this if the user has appropriated esi or edi. */
15964 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15965 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15967 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15968 operands[2], operands[3],
15969 operands[5], operands[6]));
15973 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15976 (define_expand "strmov_singleop"
15977 [(parallel [(set (match_operand 1 "memory_operand")
15978 (match_operand 3 "memory_operand"))
15979 (set (match_operand 0 "register_operand")
15981 (set (match_operand 2 "register_operand")
15982 (match_operand 5))])]
15984 "ix86_current_function_needs_cld = 1;")
15986 (define_insn "*strmovdi_rex_1"
15987 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15988 (mem:DI (match_operand:P 3 "register_operand" "1")))
15989 (set (match_operand:P 0 "register_operand" "=D")
15990 (plus:P (match_dup 2)
15992 (set (match_operand:P 1 "register_operand" "=S")
15993 (plus:P (match_dup 3)
15996 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15998 [(set_attr "type" "str")
15999 (set_attr "memory" "both")
16000 (set_attr "mode" "DI")])
16002 (define_insn "*strmovsi_1"
16003 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16004 (mem:SI (match_operand:P 3 "register_operand" "1")))
16005 (set (match_operand:P 0 "register_operand" "=D")
16006 (plus:P (match_dup 2)
16008 (set (match_operand:P 1 "register_operand" "=S")
16009 (plus:P (match_dup 3)
16011 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16013 [(set_attr "type" "str")
16014 (set_attr "memory" "both")
16015 (set_attr "mode" "SI")])
16017 (define_insn "*strmovhi_1"
16018 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16019 (mem:HI (match_operand:P 3 "register_operand" "1")))
16020 (set (match_operand:P 0 "register_operand" "=D")
16021 (plus:P (match_dup 2)
16023 (set (match_operand:P 1 "register_operand" "=S")
16024 (plus:P (match_dup 3)
16026 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16028 [(set_attr "type" "str")
16029 (set_attr "memory" "both")
16030 (set_attr "mode" "HI")])
16032 (define_insn "*strmovqi_1"
16033 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16034 (mem:QI (match_operand:P 3 "register_operand" "1")))
16035 (set (match_operand:P 0 "register_operand" "=D")
16036 (plus:P (match_dup 2)
16038 (set (match_operand:P 1 "register_operand" "=S")
16039 (plus:P (match_dup 3)
16041 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16043 [(set_attr "type" "str")
16044 (set_attr "memory" "both")
16045 (set (attr "prefix_rex")
16047 (match_test "<P:MODE>mode == DImode")
16049 (const_string "*")))
16050 (set_attr "mode" "QI")])
16052 (define_expand "rep_mov"
16053 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16054 (set (match_operand 0 "register_operand")
16056 (set (match_operand 2 "register_operand")
16058 (set (match_operand 1 "memory_operand")
16059 (match_operand 3 "memory_operand"))
16060 (use (match_dup 4))])]
16062 "ix86_current_function_needs_cld = 1;")
16064 (define_insn "*rep_movdi_rex64"
16065 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16066 (set (match_operand:P 0 "register_operand" "=D")
16067 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16069 (match_operand:P 3 "register_operand" "0")))
16070 (set (match_operand:P 1 "register_operand" "=S")
16071 (plus:P (ashift:P (match_dup 5) (const_int 3))
16072 (match_operand:P 4 "register_operand" "1")))
16073 (set (mem:BLK (match_dup 3))
16074 (mem:BLK (match_dup 4)))
16075 (use (match_dup 5))]
16077 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16079 [(set_attr "type" "str")
16080 (set_attr "prefix_rep" "1")
16081 (set_attr "memory" "both")
16082 (set_attr "mode" "DI")])
16084 (define_insn "*rep_movsi"
16085 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16086 (set (match_operand:P 0 "register_operand" "=D")
16087 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16089 (match_operand:P 3 "register_operand" "0")))
16090 (set (match_operand:P 1 "register_operand" "=S")
16091 (plus:P (ashift:P (match_dup 5) (const_int 2))
16092 (match_operand:P 4 "register_operand" "1")))
16093 (set (mem:BLK (match_dup 3))
16094 (mem:BLK (match_dup 4)))
16095 (use (match_dup 5))]
16096 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16097 "%^rep{%;} movs{l|d}"
16098 [(set_attr "type" "str")
16099 (set_attr "prefix_rep" "1")
16100 (set_attr "memory" "both")
16101 (set_attr "mode" "SI")])
16103 (define_insn "*rep_movqi"
16104 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16105 (set (match_operand:P 0 "register_operand" "=D")
16106 (plus:P (match_operand:P 3 "register_operand" "0")
16107 (match_operand:P 5 "register_operand" "2")))
16108 (set (match_operand:P 1 "register_operand" "=S")
16109 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16110 (set (mem:BLK (match_dup 3))
16111 (mem:BLK (match_dup 4)))
16112 (use (match_dup 5))]
16113 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16115 [(set_attr "type" "str")
16116 (set_attr "prefix_rep" "1")
16117 (set_attr "memory" "both")
16118 (set_attr "mode" "QI")])
16120 (define_expand "setmem<mode>"
16121 [(use (match_operand:BLK 0 "memory_operand"))
16122 (use (match_operand:SWI48 1 "nonmemory_operand"))
16123 (use (match_operand:QI 2 "nonmemory_operand"))
16124 (use (match_operand 3 "const_int_operand"))
16125 (use (match_operand:SI 4 "const_int_operand"))
16126 (use (match_operand:SI 5 "const_int_operand"))]
16129 if (ix86_expand_setmem (operands[0], operands[1],
16130 operands[2], operands[3],
16131 operands[4], operands[5]))
16137 ;; Most CPUs don't like single string operations
16138 ;; Handle this case here to simplify previous expander.
16140 (define_expand "strset"
16141 [(set (match_operand 1 "memory_operand")
16142 (match_operand 2 "register_operand"))
16143 (parallel [(set (match_operand 0 "register_operand")
16145 (clobber (reg:CC FLAGS_REG))])]
16148 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16149 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16151 /* If .md ever supports :P for Pmode, this can be directly
16152 in the pattern above. */
16153 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16154 GEN_INT (GET_MODE_SIZE (GET_MODE
16156 /* Can't use this if the user has appropriated eax or edi. */
16157 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16158 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16160 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16166 (define_expand "strset_singleop"
16167 [(parallel [(set (match_operand 1 "memory_operand")
16168 (match_operand 2 "register_operand"))
16169 (set (match_operand 0 "register_operand")
16170 (match_operand 3))])]
16172 "ix86_current_function_needs_cld = 1;")
16174 (define_insn "*strsetdi_rex_1"
16175 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16176 (match_operand:DI 2 "register_operand" "a"))
16177 (set (match_operand:P 0 "register_operand" "=D")
16178 (plus:P (match_dup 1)
16181 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16183 [(set_attr "type" "str")
16184 (set_attr "memory" "store")
16185 (set_attr "mode" "DI")])
16187 (define_insn "*strsetsi_1"
16188 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16189 (match_operand:SI 2 "register_operand" "a"))
16190 (set (match_operand:P 0 "register_operand" "=D")
16191 (plus:P (match_dup 1)
16193 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16195 [(set_attr "type" "str")
16196 (set_attr "memory" "store")
16197 (set_attr "mode" "SI")])
16199 (define_insn "*strsethi_1"
16200 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16201 (match_operand:HI 2 "register_operand" "a"))
16202 (set (match_operand:P 0 "register_operand" "=D")
16203 (plus:P (match_dup 1)
16205 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16207 [(set_attr "type" "str")
16208 (set_attr "memory" "store")
16209 (set_attr "mode" "HI")])
16211 (define_insn "*strsetqi_1"
16212 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16213 (match_operand:QI 2 "register_operand" "a"))
16214 (set (match_operand:P 0 "register_operand" "=D")
16215 (plus:P (match_dup 1)
16217 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16219 [(set_attr "type" "str")
16220 (set_attr "memory" "store")
16221 (set (attr "prefix_rex")
16223 (match_test "<P:MODE>mode == DImode")
16225 (const_string "*")))
16226 (set_attr "mode" "QI")])
16228 (define_expand "rep_stos"
16229 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16230 (set (match_operand 0 "register_operand")
16232 (set (match_operand 2 "memory_operand") (const_int 0))
16233 (use (match_operand 3 "register_operand"))
16234 (use (match_dup 1))])]
16236 "ix86_current_function_needs_cld = 1;")
16238 (define_insn "*rep_stosdi_rex64"
16239 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16240 (set (match_operand:P 0 "register_operand" "=D")
16241 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16243 (match_operand:P 3 "register_operand" "0")))
16244 (set (mem:BLK (match_dup 3))
16246 (use (match_operand:DI 2 "register_operand" "a"))
16247 (use (match_dup 4))]
16249 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16251 [(set_attr "type" "str")
16252 (set_attr "prefix_rep" "1")
16253 (set_attr "memory" "store")
16254 (set_attr "mode" "DI")])
16256 (define_insn "*rep_stossi"
16257 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16258 (set (match_operand:P 0 "register_operand" "=D")
16259 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16261 (match_operand:P 3 "register_operand" "0")))
16262 (set (mem:BLK (match_dup 3))
16264 (use (match_operand:SI 2 "register_operand" "a"))
16265 (use (match_dup 4))]
16266 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16267 "%^rep{%;} stos{l|d}"
16268 [(set_attr "type" "str")
16269 (set_attr "prefix_rep" "1")
16270 (set_attr "memory" "store")
16271 (set_attr "mode" "SI")])
16273 (define_insn "*rep_stosqi"
16274 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16275 (set (match_operand:P 0 "register_operand" "=D")
16276 (plus:P (match_operand:P 3 "register_operand" "0")
16277 (match_operand:P 4 "register_operand" "1")))
16278 (set (mem:BLK (match_dup 3))
16280 (use (match_operand:QI 2 "register_operand" "a"))
16281 (use (match_dup 4))]
16282 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16284 [(set_attr "type" "str")
16285 (set_attr "prefix_rep" "1")
16286 (set_attr "memory" "store")
16287 (set (attr "prefix_rex")
16289 (match_test "<P:MODE>mode == DImode")
16291 (const_string "*")))
16292 (set_attr "mode" "QI")])
16294 (define_expand "cmpstrnsi"
16295 [(set (match_operand:SI 0 "register_operand")
16296 (compare:SI (match_operand:BLK 1 "general_operand")
16297 (match_operand:BLK 2 "general_operand")))
16298 (use (match_operand 3 "general_operand"))
16299 (use (match_operand 4 "immediate_operand"))]
16302 rtx addr1, addr2, out, outlow, count, countreg, align;
16304 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16307 /* Can't use this if the user has appropriated ecx, esi or edi. */
16308 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16313 out = gen_reg_rtx (SImode);
16315 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16316 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16317 if (addr1 != XEXP (operands[1], 0))
16318 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16319 if (addr2 != XEXP (operands[2], 0))
16320 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16322 count = operands[3];
16323 countreg = ix86_zero_extend_to_Pmode (count);
16325 /* %%% Iff we are testing strict equality, we can use known alignment
16326 to good advantage. This may be possible with combine, particularly
16327 once cc0 is dead. */
16328 align = operands[4];
16330 if (CONST_INT_P (count))
16332 if (INTVAL (count) == 0)
16334 emit_move_insn (operands[0], const0_rtx);
16337 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16338 operands[1], operands[2]));
16342 rtx (*gen_cmp) (rtx, rtx);
16344 gen_cmp = (TARGET_64BIT
16345 ? gen_cmpdi_1 : gen_cmpsi_1);
16347 emit_insn (gen_cmp (countreg, countreg));
16348 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16349 operands[1], operands[2]));
16352 outlow = gen_lowpart (QImode, out);
16353 emit_insn (gen_cmpintqi (outlow));
16354 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16356 if (operands[0] != out)
16357 emit_move_insn (operands[0], out);
16362 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16364 (define_expand "cmpintqi"
16365 [(set (match_dup 1)
16366 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16368 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16369 (parallel [(set (match_operand:QI 0 "register_operand")
16370 (minus:QI (match_dup 1)
16372 (clobber (reg:CC FLAGS_REG))])]
16375 operands[1] = gen_reg_rtx (QImode);
16376 operands[2] = gen_reg_rtx (QImode);
16379 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16380 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16382 (define_expand "cmpstrnqi_nz_1"
16383 [(parallel [(set (reg:CC FLAGS_REG)
16384 (compare:CC (match_operand 4 "memory_operand")
16385 (match_operand 5 "memory_operand")))
16386 (use (match_operand 2 "register_operand"))
16387 (use (match_operand:SI 3 "immediate_operand"))
16388 (clobber (match_operand 0 "register_operand"))
16389 (clobber (match_operand 1 "register_operand"))
16390 (clobber (match_dup 2))])]
16392 "ix86_current_function_needs_cld = 1;")
16394 (define_insn "*cmpstrnqi_nz_1"
16395 [(set (reg:CC FLAGS_REG)
16396 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16397 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16398 (use (match_operand:P 6 "register_operand" "2"))
16399 (use (match_operand:SI 3 "immediate_operand" "i"))
16400 (clobber (match_operand:P 0 "register_operand" "=S"))
16401 (clobber (match_operand:P 1 "register_operand" "=D"))
16402 (clobber (match_operand:P 2 "register_operand" "=c"))]
16403 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16405 [(set_attr "type" "str")
16406 (set_attr "mode" "QI")
16407 (set (attr "prefix_rex")
16409 (match_test "<P:MODE>mode == DImode")
16411 (const_string "*")))
16412 (set_attr "prefix_rep" "1")])
16414 ;; The same, but the count is not known to not be zero.
16416 (define_expand "cmpstrnqi_1"
16417 [(parallel [(set (reg:CC FLAGS_REG)
16418 (if_then_else:CC (ne (match_operand 2 "register_operand")
16420 (compare:CC (match_operand 4 "memory_operand")
16421 (match_operand 5 "memory_operand"))
16423 (use (match_operand:SI 3 "immediate_operand"))
16424 (use (reg:CC FLAGS_REG))
16425 (clobber (match_operand 0 "register_operand"))
16426 (clobber (match_operand 1 "register_operand"))
16427 (clobber (match_dup 2))])]
16429 "ix86_current_function_needs_cld = 1;")
16431 (define_insn "*cmpstrnqi_1"
16432 [(set (reg:CC FLAGS_REG)
16433 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16435 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16436 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16438 (use (match_operand:SI 3 "immediate_operand" "i"))
16439 (use (reg:CC FLAGS_REG))
16440 (clobber (match_operand:P 0 "register_operand" "=S"))
16441 (clobber (match_operand:P 1 "register_operand" "=D"))
16442 (clobber (match_operand:P 2 "register_operand" "=c"))]
16443 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16445 [(set_attr "type" "str")
16446 (set_attr "mode" "QI")
16447 (set (attr "prefix_rex")
16449 (match_test "<P:MODE>mode == DImode")
16451 (const_string "*")))
16452 (set_attr "prefix_rep" "1")])
16454 (define_expand "strlen<mode>"
16455 [(set (match_operand:P 0 "register_operand")
16456 (unspec:P [(match_operand:BLK 1 "general_operand")
16457 (match_operand:QI 2 "immediate_operand")
16458 (match_operand 3 "immediate_operand")]
16462 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16468 (define_expand "strlenqi_1"
16469 [(parallel [(set (match_operand 0 "register_operand")
16471 (clobber (match_operand 1 "register_operand"))
16472 (clobber (reg:CC FLAGS_REG))])]
16474 "ix86_current_function_needs_cld = 1;")
16476 (define_insn "*strlenqi_1"
16477 [(set (match_operand:P 0 "register_operand" "=&c")
16478 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16479 (match_operand:QI 2 "register_operand" "a")
16480 (match_operand:P 3 "immediate_operand" "i")
16481 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16482 (clobber (match_operand:P 1 "register_operand" "=D"))
16483 (clobber (reg:CC FLAGS_REG))]
16484 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16485 "%^repnz{%;} scasb"
16486 [(set_attr "type" "str")
16487 (set_attr "mode" "QI")
16488 (set (attr "prefix_rex")
16490 (match_test "<P:MODE>mode == DImode")
16492 (const_string "*")))
16493 (set_attr "prefix_rep" "1")])
16495 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16496 ;; handled in combine, but it is not currently up to the task.
16497 ;; When used for their truth value, the cmpstrn* expanders generate
16506 ;; The intermediate three instructions are unnecessary.
16508 ;; This one handles cmpstrn*_nz_1...
16511 (set (reg:CC FLAGS_REG)
16512 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16513 (mem:BLK (match_operand 5 "register_operand"))))
16514 (use (match_operand 6 "register_operand"))
16515 (use (match_operand:SI 3 "immediate_operand"))
16516 (clobber (match_operand 0 "register_operand"))
16517 (clobber (match_operand 1 "register_operand"))
16518 (clobber (match_operand 2 "register_operand"))])
16519 (set (match_operand:QI 7 "register_operand")
16520 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16521 (set (match_operand:QI 8 "register_operand")
16522 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16523 (set (reg FLAGS_REG)
16524 (compare (match_dup 7) (match_dup 8)))
16526 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16528 (set (reg:CC FLAGS_REG)
16529 (compare:CC (mem:BLK (match_dup 4))
16530 (mem:BLK (match_dup 5))))
16531 (use (match_dup 6))
16532 (use (match_dup 3))
16533 (clobber (match_dup 0))
16534 (clobber (match_dup 1))
16535 (clobber (match_dup 2))])])
16537 ;; ...and this one handles cmpstrn*_1.
16540 (set (reg:CC FLAGS_REG)
16541 (if_then_else:CC (ne (match_operand 6 "register_operand")
16543 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16544 (mem:BLK (match_operand 5 "register_operand")))
16546 (use (match_operand:SI 3 "immediate_operand"))
16547 (use (reg:CC FLAGS_REG))
16548 (clobber (match_operand 0 "register_operand"))
16549 (clobber (match_operand 1 "register_operand"))
16550 (clobber (match_operand 2 "register_operand"))])
16551 (set (match_operand:QI 7 "register_operand")
16552 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16553 (set (match_operand:QI 8 "register_operand")
16554 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16555 (set (reg FLAGS_REG)
16556 (compare (match_dup 7) (match_dup 8)))
16558 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16560 (set (reg:CC FLAGS_REG)
16561 (if_then_else:CC (ne (match_dup 6)
16563 (compare:CC (mem:BLK (match_dup 4))
16564 (mem:BLK (match_dup 5)))
16566 (use (match_dup 3))
16567 (use (reg:CC FLAGS_REG))
16568 (clobber (match_dup 0))
16569 (clobber (match_dup 1))
16570 (clobber (match_dup 2))])])
16572 ;; Conditional move instructions.
16574 (define_expand "mov<mode>cc"
16575 [(set (match_operand:SWIM 0 "register_operand")
16576 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator")
16577 (match_operand:SWIM 2 "<general_operand>")
16578 (match_operand:SWIM 3 "<general_operand>")))]
16580 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16582 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16583 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16584 ;; So just document what we're doing explicitly.
16586 (define_expand "x86_mov<mode>cc_0_m1"
16588 [(set (match_operand:SWI48 0 "register_operand")
16589 (if_then_else:SWI48
16590 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16591 [(match_operand 1 "flags_reg_operand")
16595 (clobber (reg:CC FLAGS_REG))])])
16597 (define_insn "*x86_mov<mode>cc_0_m1"
16598 [(set (match_operand:SWI48 0 "register_operand" "=r")
16599 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16600 [(reg FLAGS_REG) (const_int 0)])
16603 (clobber (reg:CC FLAGS_REG))]
16605 "sbb{<imodesuffix>}\t%0, %0"
16606 ; Since we don't have the proper number of operands for an alu insn,
16607 ; fill in all the blanks.
16608 [(set_attr "type" "alu")
16609 (set_attr "use_carry" "1")
16610 (set_attr "pent_pair" "pu")
16611 (set_attr "memory" "none")
16612 (set_attr "imm_disp" "false")
16613 (set_attr "mode" "<MODE>")
16614 (set_attr "length_immediate" "0")])
16616 (define_insn "*x86_mov<mode>cc_0_m1_se"
16617 [(set (match_operand:SWI48 0 "register_operand" "=r")
16618 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16619 [(reg FLAGS_REG) (const_int 0)])
16622 (clobber (reg:CC FLAGS_REG))]
16624 "sbb{<imodesuffix>}\t%0, %0"
16625 [(set_attr "type" "alu")
16626 (set_attr "use_carry" "1")
16627 (set_attr "pent_pair" "pu")
16628 (set_attr "memory" "none")
16629 (set_attr "imm_disp" "false")
16630 (set_attr "mode" "<MODE>")
16631 (set_attr "length_immediate" "0")])
16633 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16634 [(set (match_operand:SWI48 0 "register_operand" "=r")
16635 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16636 [(reg FLAGS_REG) (const_int 0)])))
16637 (clobber (reg:CC FLAGS_REG))]
16639 "sbb{<imodesuffix>}\t%0, %0"
16640 [(set_attr "type" "alu")
16641 (set_attr "use_carry" "1")
16642 (set_attr "pent_pair" "pu")
16643 (set_attr "memory" "none")
16644 (set_attr "imm_disp" "false")
16645 (set_attr "mode" "<MODE>")
16646 (set_attr "length_immediate" "0")])
16648 (define_insn "*mov<mode>cc_noc"
16649 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16650 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16651 [(reg FLAGS_REG) (const_int 0)])
16652 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16653 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16654 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16656 cmov%O2%C1\t{%2, %0|%0, %2}
16657 cmov%O2%c1\t{%3, %0|%0, %3}"
16658 [(set_attr "type" "icmov")
16659 (set_attr "mode" "<MODE>")])
16661 (define_insn_and_split "*movqicc_noc"
16662 [(set (match_operand:QI 0 "register_operand" "=r,r")
16663 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16664 [(match_operand 4 "flags_reg_operand")
16666 (match_operand:QI 2 "register_operand" "r,0")
16667 (match_operand:QI 3 "register_operand" "0,r")))]
16668 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16670 "&& reload_completed"
16671 [(set (match_dup 0)
16672 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16675 "operands[0] = gen_lowpart (SImode, operands[0]);
16676 operands[2] = gen_lowpart (SImode, operands[2]);
16677 operands[3] = gen_lowpart (SImode, operands[3]);"
16678 [(set_attr "type" "icmov")
16679 (set_attr "mode" "SI")])
16681 (define_expand "mov<mode>cc"
16682 [(set (match_operand:X87MODEF 0 "register_operand")
16683 (if_then_else:X87MODEF
16684 (match_operand 1 "ix86_fp_comparison_operator")
16685 (match_operand:X87MODEF 2 "register_operand")
16686 (match_operand:X87MODEF 3 "register_operand")))]
16687 "(TARGET_80387 && TARGET_CMOVE)
16688 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16689 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16691 (define_insn "*movxfcc_1"
16692 [(set (match_operand:XF 0 "register_operand" "=f,f")
16693 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16694 [(reg FLAGS_REG) (const_int 0)])
16695 (match_operand:XF 2 "register_operand" "f,0")
16696 (match_operand:XF 3 "register_operand" "0,f")))]
16697 "TARGET_80387 && TARGET_CMOVE"
16699 fcmov%F1\t{%2, %0|%0, %2}
16700 fcmov%f1\t{%3, %0|%0, %3}"
16701 [(set_attr "type" "fcmov")
16702 (set_attr "mode" "XF")])
16704 (define_insn "*movdfcc_1_rex64"
16705 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16706 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16707 [(reg FLAGS_REG) (const_int 0)])
16708 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16709 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16710 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16711 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16713 fcmov%F1\t{%2, %0|%0, %2}
16714 fcmov%f1\t{%3, %0|%0, %3}
16715 cmov%O2%C1\t{%2, %0|%0, %2}
16716 cmov%O2%c1\t{%3, %0|%0, %3}"
16717 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16718 (set_attr "mode" "DF,DF,DI,DI")])
16720 (define_insn "*movdfcc_1"
16721 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16722 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16723 [(reg FLAGS_REG) (const_int 0)])
16724 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16725 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16726 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16727 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16729 fcmov%F1\t{%2, %0|%0, %2}
16730 fcmov%f1\t{%3, %0|%0, %3}
16733 [(set_attr "type" "fcmov,fcmov,multi,multi")
16734 (set_attr "mode" "DF,DF,DI,DI")])
16737 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16738 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16739 [(match_operand 4 "flags_reg_operand")
16741 (match_operand:DF 2 "nonimmediate_operand")
16742 (match_operand:DF 3 "nonimmediate_operand")))]
16743 "!TARGET_64BIT && reload_completed"
16744 [(set (match_dup 2)
16745 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16749 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16753 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16754 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16757 (define_insn "*movsfcc_1_387"
16758 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16759 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16760 [(reg FLAGS_REG) (const_int 0)])
16761 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16762 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16763 "TARGET_80387 && TARGET_CMOVE
16764 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16766 fcmov%F1\t{%2, %0|%0, %2}
16767 fcmov%f1\t{%3, %0|%0, %3}
16768 cmov%O2%C1\t{%2, %0|%0, %2}
16769 cmov%O2%c1\t{%3, %0|%0, %3}"
16770 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16771 (set_attr "mode" "SF,SF,SI,SI")])
16773 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16774 ;; the scalar versions to have only XMM registers as operands.
16776 ;; XOP conditional move
16777 (define_insn "*xop_pcmov_<mode>"
16778 [(set (match_operand:MODEF 0 "register_operand" "=x")
16779 (if_then_else:MODEF
16780 (match_operand:MODEF 1 "register_operand" "x")
16781 (match_operand:MODEF 2 "register_operand" "x")
16782 (match_operand:MODEF 3 "register_operand" "x")))]
16784 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16785 [(set_attr "type" "sse4arg")])
16787 ;; These versions of the min/max patterns are intentionally ignorant of
16788 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16789 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16790 ;; are undefined in this condition, we're certain this is correct.
16792 (define_insn "<code><mode>3"
16793 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16795 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16796 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16797 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16799 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16800 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16801 [(set_attr "isa" "noavx,avx")
16802 (set_attr "prefix" "orig,vex")
16803 (set_attr "type" "sseadd")
16804 (set_attr "mode" "<MODE>")])
16806 ;; These versions of the min/max patterns implement exactly the operations
16807 ;; min = (op1 < op2 ? op1 : op2)
16808 ;; max = (!(op1 < op2) ? op1 : op2)
16809 ;; Their operands are not commutative, and thus they may be used in the
16810 ;; presence of -0.0 and NaN.
16812 (define_insn "*ieee_smin<mode>3"
16813 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16815 [(match_operand:MODEF 1 "register_operand" "0,x")
16816 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16818 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16820 min<ssemodesuffix>\t{%2, %0|%0, %2}
16821 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16822 [(set_attr "isa" "noavx,avx")
16823 (set_attr "prefix" "orig,vex")
16824 (set_attr "type" "sseadd")
16825 (set_attr "mode" "<MODE>")])
16827 (define_insn "*ieee_smax<mode>3"
16828 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16830 [(match_operand:MODEF 1 "register_operand" "0,x")
16831 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16833 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16835 max<ssemodesuffix>\t{%2, %0|%0, %2}
16836 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16837 [(set_attr "isa" "noavx,avx")
16838 (set_attr "prefix" "orig,vex")
16839 (set_attr "type" "sseadd")
16840 (set_attr "mode" "<MODE>")])
16842 ;; Make two stack loads independent:
16844 ;; fld %st(0) -> fld bb
16845 ;; fmul bb fmul %st(1), %st
16847 ;; Actually we only match the last two instructions for simplicity.
16849 [(set (match_operand 0 "fp_register_operand")
16850 (match_operand 1 "fp_register_operand"))
16852 (match_operator 2 "binary_fp_operator"
16854 (match_operand 3 "memory_operand")]))]
16855 "REGNO (operands[0]) != REGNO (operands[1])"
16856 [(set (match_dup 0) (match_dup 3))
16857 (set (match_dup 0) (match_dup 4))]
16859 ;; The % modifier is not operational anymore in peephole2's, so we have to
16860 ;; swap the operands manually in the case of addition and multiplication.
16864 if (COMMUTATIVE_ARITH_P (operands[2]))
16865 op0 = operands[0], op1 = operands[1];
16867 op0 = operands[1], op1 = operands[0];
16869 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16870 GET_MODE (operands[2]),
16874 ;; Conditional addition patterns
16875 (define_expand "add<mode>cc"
16876 [(match_operand:SWI 0 "register_operand")
16877 (match_operand 1 "ordered_comparison_operator")
16878 (match_operand:SWI 2 "register_operand")
16879 (match_operand:SWI 3 "const_int_operand")]
16881 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16883 ;; Misc patterns (?)
16885 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16886 ;; Otherwise there will be nothing to keep
16888 ;; [(set (reg ebp) (reg esp))]
16889 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16890 ;; (clobber (eflags)]
16891 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16893 ;; in proper program order.
16895 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16896 [(set (match_operand:P 0 "register_operand" "=r,r")
16897 (plus:P (match_operand:P 1 "register_operand" "0,r")
16898 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16899 (clobber (reg:CC FLAGS_REG))
16900 (clobber (mem:BLK (scratch)))]
16903 switch (get_attr_type (insn))
16906 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16909 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16910 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16911 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16913 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16916 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16917 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16920 [(set (attr "type")
16921 (cond [(and (eq_attr "alternative" "0")
16922 (not (match_test "TARGET_OPT_AGU")))
16923 (const_string "alu")
16924 (match_operand:<MODE> 2 "const0_operand")
16925 (const_string "imov")
16927 (const_string "lea")))
16928 (set (attr "length_immediate")
16929 (cond [(eq_attr "type" "imov")
16931 (and (eq_attr "type" "alu")
16932 (match_operand 2 "const128_operand"))
16935 (const_string "*")))
16936 (set_attr "mode" "<MODE>")])
16938 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16939 [(set (match_operand:P 0 "register_operand" "=r")
16940 (minus:P (match_operand:P 1 "register_operand" "0")
16941 (match_operand:P 2 "register_operand" "r")))
16942 (clobber (reg:CC FLAGS_REG))
16943 (clobber (mem:BLK (scratch)))]
16945 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16946 [(set_attr "type" "alu")
16947 (set_attr "mode" "<MODE>")])
16949 (define_insn "allocate_stack_worker_probe_<mode>"
16950 [(set (match_operand:P 0 "register_operand" "=a")
16951 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16952 UNSPECV_STACK_PROBE))
16953 (clobber (reg:CC FLAGS_REG))]
16954 "ix86_target_stack_probe ()"
16955 "call\t___chkstk_ms"
16956 [(set_attr "type" "multi")
16957 (set_attr "length" "5")])
16959 (define_expand "allocate_stack"
16960 [(match_operand 0 "register_operand")
16961 (match_operand 1 "general_operand")]
16962 "ix86_target_stack_probe ()"
16966 #ifndef CHECK_STACK_LIMIT
16967 #define CHECK_STACK_LIMIT 0
16970 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16971 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16975 rtx (*insn) (rtx, rtx);
16977 x = copy_to_mode_reg (Pmode, operands[1]);
16979 insn = (TARGET_64BIT
16980 ? gen_allocate_stack_worker_probe_di
16981 : gen_allocate_stack_worker_probe_si);
16983 emit_insn (insn (x, x));
16986 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16987 stack_pointer_rtx, 0, OPTAB_DIRECT);
16989 if (x != stack_pointer_rtx)
16990 emit_move_insn (stack_pointer_rtx, x);
16992 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16996 ;; Use IOR for stack probes, this is shorter.
16997 (define_expand "probe_stack"
16998 [(match_operand 0 "memory_operand")]
17001 rtx (*gen_ior3) (rtx, rtx, rtx);
17003 gen_ior3 = (GET_MODE (operands[0]) == DImode
17004 ? gen_iordi3 : gen_iorsi3);
17006 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17010 (define_insn "adjust_stack_and_probe<mode>"
17011 [(set (match_operand:P 0 "register_operand" "=r")
17012 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17013 UNSPECV_PROBE_STACK_RANGE))
17014 (set (reg:P SP_REG)
17015 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17016 (clobber (reg:CC FLAGS_REG))
17017 (clobber (mem:BLK (scratch)))]
17019 "* return output_adjust_stack_and_probe (operands[0]);"
17020 [(set_attr "type" "multi")])
17022 (define_insn "probe_stack_range<mode>"
17023 [(set (match_operand:P 0 "register_operand" "=r")
17024 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17025 (match_operand:P 2 "const_int_operand" "n")]
17026 UNSPECV_PROBE_STACK_RANGE))
17027 (clobber (reg:CC FLAGS_REG))]
17029 "* return output_probe_stack_range (operands[0], operands[2]);"
17030 [(set_attr "type" "multi")])
17032 (define_expand "builtin_setjmp_receiver"
17033 [(label_ref (match_operand 0))]
17034 "!TARGET_64BIT && flag_pic"
17040 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
17041 rtx label_rtx = gen_label_rtx ();
17042 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17043 xops[0] = xops[1] = picreg;
17044 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17045 ix86_expand_binary_operator (MINUS, SImode, xops);
17049 emit_insn (gen_set_got (pic_offset_table_rtx));
17053 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17056 [(set (match_operand 0 "register_operand")
17057 (match_operator 3 "promotable_binary_operator"
17058 [(match_operand 1 "register_operand")
17059 (match_operand 2 "aligned_operand")]))
17060 (clobber (reg:CC FLAGS_REG))]
17061 "! TARGET_PARTIAL_REG_STALL && reload_completed
17062 && ((GET_MODE (operands[0]) == HImode
17063 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17064 /* ??? next two lines just !satisfies_constraint_K (...) */
17065 || !CONST_INT_P (operands[2])
17066 || satisfies_constraint_K (operands[2])))
17067 || (GET_MODE (operands[0]) == QImode
17068 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17069 [(parallel [(set (match_dup 0)
17070 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17071 (clobber (reg:CC FLAGS_REG))])]
17073 operands[0] = gen_lowpart (SImode, operands[0]);
17074 operands[1] = gen_lowpart (SImode, operands[1]);
17075 if (GET_CODE (operands[3]) != ASHIFT)
17076 operands[2] = gen_lowpart (SImode, operands[2]);
17077 PUT_MODE (operands[3], SImode);
17080 ; Promote the QImode tests, as i386 has encoding of the AND
17081 ; instruction with 32-bit sign-extended immediate and thus the
17082 ; instruction size is unchanged, except in the %eax case for
17083 ; which it is increased by one byte, hence the ! optimize_size.
17085 [(set (match_operand 0 "flags_reg_operand")
17086 (match_operator 2 "compare_operator"
17087 [(and (match_operand 3 "aligned_operand")
17088 (match_operand 4 "const_int_operand"))
17090 (set (match_operand 1 "register_operand")
17091 (and (match_dup 3) (match_dup 4)))]
17092 "! TARGET_PARTIAL_REG_STALL && reload_completed
17093 && optimize_insn_for_speed_p ()
17094 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17095 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17096 /* Ensure that the operand will remain sign-extended immediate. */
17097 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17098 [(parallel [(set (match_dup 0)
17099 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17102 (and:SI (match_dup 3) (match_dup 4)))])]
17105 = gen_int_mode (INTVAL (operands[4])
17106 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17107 operands[1] = gen_lowpart (SImode, operands[1]);
17108 operands[3] = gen_lowpart (SImode, operands[3]);
17111 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17112 ; the TEST instruction with 32-bit sign-extended immediate and thus
17113 ; the instruction size would at least double, which is not what we
17114 ; want even with ! optimize_size.
17116 [(set (match_operand 0 "flags_reg_operand")
17117 (match_operator 1 "compare_operator"
17118 [(and (match_operand:HI 2 "aligned_operand")
17119 (match_operand:HI 3 "const_int_operand"))
17121 "! TARGET_PARTIAL_REG_STALL && reload_completed
17122 && ! TARGET_FAST_PREFIX
17123 && optimize_insn_for_speed_p ()
17124 /* Ensure that the operand will remain sign-extended immediate. */
17125 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17126 [(set (match_dup 0)
17127 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17131 = gen_int_mode (INTVAL (operands[3])
17132 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17133 operands[2] = gen_lowpart (SImode, operands[2]);
17137 [(set (match_operand 0 "register_operand")
17138 (neg (match_operand 1 "register_operand")))
17139 (clobber (reg:CC FLAGS_REG))]
17140 "! TARGET_PARTIAL_REG_STALL && reload_completed
17141 && (GET_MODE (operands[0]) == HImode
17142 || (GET_MODE (operands[0]) == QImode
17143 && (TARGET_PROMOTE_QImode
17144 || optimize_insn_for_size_p ())))"
17145 [(parallel [(set (match_dup 0)
17146 (neg:SI (match_dup 1)))
17147 (clobber (reg:CC FLAGS_REG))])]
17149 operands[0] = gen_lowpart (SImode, operands[0]);
17150 operands[1] = gen_lowpart (SImode, operands[1]);
17154 [(set (match_operand 0 "register_operand")
17155 (not (match_operand 1 "register_operand")))]
17156 "! TARGET_PARTIAL_REG_STALL && reload_completed
17157 && (GET_MODE (operands[0]) == HImode
17158 || (GET_MODE (operands[0]) == QImode
17159 && (TARGET_PROMOTE_QImode
17160 || optimize_insn_for_size_p ())))"
17161 [(set (match_dup 0)
17162 (not:SI (match_dup 1)))]
17164 operands[0] = gen_lowpart (SImode, operands[0]);
17165 operands[1] = gen_lowpart (SImode, operands[1]);
17169 [(set (match_operand 0 "register_operand")
17170 (if_then_else (match_operator 1 "ordered_comparison_operator"
17171 [(reg FLAGS_REG) (const_int 0)])
17172 (match_operand 2 "register_operand")
17173 (match_operand 3 "register_operand")))]
17174 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17175 && (GET_MODE (operands[0]) == HImode
17176 || (GET_MODE (operands[0]) == QImode
17177 && (TARGET_PROMOTE_QImode
17178 || optimize_insn_for_size_p ())))"
17179 [(set (match_dup 0)
17180 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17182 operands[0] = gen_lowpart (SImode, operands[0]);
17183 operands[2] = gen_lowpart (SImode, operands[2]);
17184 operands[3] = gen_lowpart (SImode, operands[3]);
17187 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17188 ;; transform a complex memory operation into two memory to register operations.
17190 ;; Don't push memory operands
17192 [(set (match_operand:SWI 0 "push_operand")
17193 (match_operand:SWI 1 "memory_operand"))
17194 (match_scratch:SWI 2 "<r>")]
17195 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17196 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17197 [(set (match_dup 2) (match_dup 1))
17198 (set (match_dup 0) (match_dup 2))])
17200 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17203 [(set (match_operand:SF 0 "push_operand")
17204 (match_operand:SF 1 "memory_operand"))
17205 (match_scratch:SF 2 "r")]
17206 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17207 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17208 [(set (match_dup 2) (match_dup 1))
17209 (set (match_dup 0) (match_dup 2))])
17211 ;; Don't move an immediate directly to memory when the instruction
17212 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17214 [(match_scratch:SWI124 1 "<r>")
17215 (set (match_operand:SWI124 0 "memory_operand")
17217 "optimize_insn_for_speed_p ()
17218 && ((<MODE>mode == HImode
17219 && TARGET_LCP_STALL)
17220 || (!TARGET_USE_MOV0
17221 && TARGET_SPLIT_LONG_MOVES
17222 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17223 && peep2_regno_dead_p (0, FLAGS_REG)"
17224 [(parallel [(set (match_dup 2) (const_int 0))
17225 (clobber (reg:CC FLAGS_REG))])
17226 (set (match_dup 0) (match_dup 1))]
17227 "operands[2] = gen_lowpart (SImode, operands[1]);")
17230 [(match_scratch:SWI124 2 "<r>")
17231 (set (match_operand:SWI124 0 "memory_operand")
17232 (match_operand:SWI124 1 "immediate_operand"))]
17233 "optimize_insn_for_speed_p ()
17234 && ((<MODE>mode == HImode
17235 && TARGET_LCP_STALL)
17236 || (TARGET_SPLIT_LONG_MOVES
17237 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17238 [(set (match_dup 2) (match_dup 1))
17239 (set (match_dup 0) (match_dup 2))])
17241 ;; Don't compare memory with zero, load and use a test instead.
17243 [(set (match_operand 0 "flags_reg_operand")
17244 (match_operator 1 "compare_operator"
17245 [(match_operand:SI 2 "memory_operand")
17247 (match_scratch:SI 3 "r")]
17248 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17249 [(set (match_dup 3) (match_dup 2))
17250 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17252 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17253 ;; Don't split NOTs with a displacement operand, because resulting XOR
17254 ;; will not be pairable anyway.
17256 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17257 ;; represented using a modRM byte. The XOR replacement is long decoded,
17258 ;; so this split helps here as well.
17260 ;; Note: Can't do this as a regular split because we can't get proper
17261 ;; lifetime information then.
17264 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17265 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17266 "optimize_insn_for_speed_p ()
17267 && ((TARGET_NOT_UNPAIRABLE
17268 && (!MEM_P (operands[0])
17269 || !memory_displacement_operand (operands[0], <MODE>mode)))
17270 || (TARGET_NOT_VECTORMODE
17271 && long_memory_operand (operands[0], <MODE>mode)))
17272 && peep2_regno_dead_p (0, FLAGS_REG)"
17273 [(parallel [(set (match_dup 0)
17274 (xor:SWI124 (match_dup 1) (const_int -1)))
17275 (clobber (reg:CC FLAGS_REG))])])
17277 ;; Non pairable "test imm, reg" instructions can be translated to
17278 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17279 ;; byte opcode instead of two, have a short form for byte operands),
17280 ;; so do it for other CPUs as well. Given that the value was dead,
17281 ;; this should not create any new dependencies. Pass on the sub-word
17282 ;; versions if we're concerned about partial register stalls.
17285 [(set (match_operand 0 "flags_reg_operand")
17286 (match_operator 1 "compare_operator"
17287 [(and:SI (match_operand:SI 2 "register_operand")
17288 (match_operand:SI 3 "immediate_operand"))
17290 "ix86_match_ccmode (insn, CCNOmode)
17291 && (true_regnum (operands[2]) != AX_REG
17292 || satisfies_constraint_K (operands[3]))
17293 && peep2_reg_dead_p (1, operands[2])"
17295 [(set (match_dup 0)
17296 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17299 (and:SI (match_dup 2) (match_dup 3)))])])
17301 ;; We don't need to handle HImode case, because it will be promoted to SImode
17302 ;; on ! TARGET_PARTIAL_REG_STALL
17305 [(set (match_operand 0 "flags_reg_operand")
17306 (match_operator 1 "compare_operator"
17307 [(and:QI (match_operand:QI 2 "register_operand")
17308 (match_operand:QI 3 "immediate_operand"))
17310 "! TARGET_PARTIAL_REG_STALL
17311 && ix86_match_ccmode (insn, CCNOmode)
17312 && true_regnum (operands[2]) != AX_REG
17313 && peep2_reg_dead_p (1, operands[2])"
17315 [(set (match_dup 0)
17316 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17319 (and:QI (match_dup 2) (match_dup 3)))])])
17322 [(set (match_operand 0 "flags_reg_operand")
17323 (match_operator 1 "compare_operator"
17326 (match_operand 2 "ext_register_operand")
17329 (match_operand 3 "const_int_operand"))
17331 "! TARGET_PARTIAL_REG_STALL
17332 && ix86_match_ccmode (insn, CCNOmode)
17333 && true_regnum (operands[2]) != AX_REG
17334 && peep2_reg_dead_p (1, operands[2])"
17335 [(parallel [(set (match_dup 0)
17344 (set (zero_extract:SI (match_dup 2)
17352 (match_dup 3)))])])
17354 ;; Don't do logical operations with memory inputs.
17356 [(match_scratch:SI 2 "r")
17357 (parallel [(set (match_operand:SI 0 "register_operand")
17358 (match_operator:SI 3 "arith_or_logical_operator"
17360 (match_operand:SI 1 "memory_operand")]))
17361 (clobber (reg:CC FLAGS_REG))])]
17362 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17363 [(set (match_dup 2) (match_dup 1))
17364 (parallel [(set (match_dup 0)
17365 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17366 (clobber (reg:CC FLAGS_REG))])])
17369 [(match_scratch:SI 2 "r")
17370 (parallel [(set (match_operand:SI 0 "register_operand")
17371 (match_operator:SI 3 "arith_or_logical_operator"
17372 [(match_operand:SI 1 "memory_operand")
17374 (clobber (reg:CC FLAGS_REG))])]
17375 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17376 [(set (match_dup 2) (match_dup 1))
17377 (parallel [(set (match_dup 0)
17378 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17379 (clobber (reg:CC FLAGS_REG))])])
17381 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17382 ;; refers to the destination of the load!
17385 [(set (match_operand:SI 0 "register_operand")
17386 (match_operand:SI 1 "register_operand"))
17387 (parallel [(set (match_dup 0)
17388 (match_operator:SI 3 "commutative_operator"
17390 (match_operand:SI 2 "memory_operand")]))
17391 (clobber (reg:CC FLAGS_REG))])]
17392 "REGNO (operands[0]) != REGNO (operands[1])
17393 && GENERAL_REGNO_P (REGNO (operands[0]))
17394 && GENERAL_REGNO_P (REGNO (operands[1]))"
17395 [(set (match_dup 0) (match_dup 4))
17396 (parallel [(set (match_dup 0)
17397 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17398 (clobber (reg:CC FLAGS_REG))])]
17399 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17402 [(set (match_operand 0 "register_operand")
17403 (match_operand 1 "register_operand"))
17405 (match_operator 3 "commutative_operator"
17407 (match_operand 2 "memory_operand")]))]
17408 "REGNO (operands[0]) != REGNO (operands[1])
17409 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17410 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17411 [(set (match_dup 0) (match_dup 2))
17413 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17415 ; Don't do logical operations with memory outputs
17417 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17418 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17419 ; the same decoder scheduling characteristics as the original.
17422 [(match_scratch:SI 2 "r")
17423 (parallel [(set (match_operand:SI 0 "memory_operand")
17424 (match_operator:SI 3 "arith_or_logical_operator"
17426 (match_operand:SI 1 "nonmemory_operand")]))
17427 (clobber (reg:CC FLAGS_REG))])]
17428 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17429 /* Do not split stack checking probes. */
17430 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17431 [(set (match_dup 2) (match_dup 0))
17432 (parallel [(set (match_dup 2)
17433 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17434 (clobber (reg:CC FLAGS_REG))])
17435 (set (match_dup 0) (match_dup 2))])
17438 [(match_scratch:SI 2 "r")
17439 (parallel [(set (match_operand:SI 0 "memory_operand")
17440 (match_operator:SI 3 "arith_or_logical_operator"
17441 [(match_operand:SI 1 "nonmemory_operand")
17443 (clobber (reg:CC FLAGS_REG))])]
17444 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17445 /* Do not split stack checking probes. */
17446 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17447 [(set (match_dup 2) (match_dup 0))
17448 (parallel [(set (match_dup 2)
17449 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17450 (clobber (reg:CC FLAGS_REG))])
17451 (set (match_dup 0) (match_dup 2))])
17453 ;; Attempt to use arith or logical operations with memory outputs with
17454 ;; setting of flags.
17456 [(set (match_operand:SWI 0 "register_operand")
17457 (match_operand:SWI 1 "memory_operand"))
17458 (parallel [(set (match_dup 0)
17459 (match_operator:SWI 3 "plusminuslogic_operator"
17461 (match_operand:SWI 2 "<nonmemory_operand>")]))
17462 (clobber (reg:CC FLAGS_REG))])
17463 (set (match_dup 1) (match_dup 0))
17464 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17465 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17466 && peep2_reg_dead_p (4, operands[0])
17467 && !reg_overlap_mentioned_p (operands[0], operands[1])
17468 && ix86_match_ccmode (peep2_next_insn (3),
17469 (GET_CODE (operands[3]) == PLUS
17470 || GET_CODE (operands[3]) == MINUS)
17471 ? CCGOCmode : CCNOmode)"
17472 [(parallel [(set (match_dup 4) (match_dup 5))
17473 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17474 (match_dup 2)]))])]
17476 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17477 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17478 copy_rtx (operands[1]),
17479 copy_rtx (operands[2]));
17480 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17481 operands[5], const0_rtx);
17485 [(parallel [(set (match_operand:SWI 0 "register_operand")
17486 (match_operator:SWI 2 "plusminuslogic_operator"
17488 (match_operand:SWI 1 "memory_operand")]))
17489 (clobber (reg:CC FLAGS_REG))])
17490 (set (match_dup 1) (match_dup 0))
17491 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17492 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17493 && GET_CODE (operands[2]) != MINUS
17494 && peep2_reg_dead_p (3, operands[0])
17495 && !reg_overlap_mentioned_p (operands[0], operands[1])
17496 && ix86_match_ccmode (peep2_next_insn (2),
17497 GET_CODE (operands[2]) == PLUS
17498 ? CCGOCmode : CCNOmode)"
17499 [(parallel [(set (match_dup 3) (match_dup 4))
17500 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17501 (match_dup 0)]))])]
17503 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17504 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17505 copy_rtx (operands[1]),
17506 copy_rtx (operands[0]));
17507 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17508 operands[4], const0_rtx);
17512 [(set (match_operand:SWI12 0 "register_operand")
17513 (match_operand:SWI12 1 "memory_operand"))
17514 (parallel [(set (match_operand:SI 4 "register_operand")
17515 (match_operator:SI 3 "plusminuslogic_operator"
17517 (match_operand:SI 2 "nonmemory_operand")]))
17518 (clobber (reg:CC FLAGS_REG))])
17519 (set (match_dup 1) (match_dup 0))
17520 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17521 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17522 && REG_P (operands[0]) && REG_P (operands[4])
17523 && REGNO (operands[0]) == REGNO (operands[4])
17524 && peep2_reg_dead_p (4, operands[0])
17525 && (<MODE>mode != QImode
17526 || immediate_operand (operands[2], SImode)
17527 || q_regs_operand (operands[2], SImode))
17528 && !reg_overlap_mentioned_p (operands[0], operands[1])
17529 && ix86_match_ccmode (peep2_next_insn (3),
17530 (GET_CODE (operands[3]) == PLUS
17531 || GET_CODE (operands[3]) == MINUS)
17532 ? CCGOCmode : CCNOmode)"
17533 [(parallel [(set (match_dup 4) (match_dup 5))
17534 (set (match_dup 1) (match_dup 6))])]
17536 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17537 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17538 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17539 copy_rtx (operands[1]), operands[2]);
17540 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17541 operands[5], const0_rtx);
17542 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17543 copy_rtx (operands[1]),
17544 copy_rtx (operands[2]));
17547 ;; Attempt to always use XOR for zeroing registers.
17549 [(set (match_operand 0 "register_operand")
17550 (match_operand 1 "const0_operand"))]
17551 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17552 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17553 && GENERAL_REG_P (operands[0])
17554 && peep2_regno_dead_p (0, FLAGS_REG)"
17555 [(parallel [(set (match_dup 0) (const_int 0))
17556 (clobber (reg:CC FLAGS_REG))])]
17557 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17560 [(set (strict_low_part (match_operand 0 "register_operand"))
17562 "(GET_MODE (operands[0]) == QImode
17563 || GET_MODE (operands[0]) == HImode)
17564 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17565 && peep2_regno_dead_p (0, FLAGS_REG)"
17566 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17567 (clobber (reg:CC FLAGS_REG))])])
17569 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17571 [(set (match_operand:SWI248 0 "register_operand")
17573 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17574 && peep2_regno_dead_p (0, FLAGS_REG)"
17575 [(parallel [(set (match_dup 0) (const_int -1))
17576 (clobber (reg:CC FLAGS_REG))])]
17578 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17579 operands[0] = gen_lowpart (SImode, operands[0]);
17582 ;; Attempt to convert simple lea to add/shift.
17583 ;; These can be created by move expanders.
17586 [(set (match_operand:SWI48 0 "register_operand")
17587 (plus:SWI48 (match_dup 0)
17588 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17589 "peep2_regno_dead_p (0, FLAGS_REG)"
17590 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17591 (clobber (reg:CC FLAGS_REG))])])
17594 [(set (match_operand:SI 0 "register_operand")
17595 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand")
17596 (match_operand:DI 2 "nonmemory_operand")) 0))]
17598 && peep2_regno_dead_p (0, FLAGS_REG)
17599 && REGNO (operands[0]) == REGNO (operands[1])"
17600 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17601 (clobber (reg:CC FLAGS_REG))])]
17602 "operands[2] = gen_lowpart (SImode, operands[2]);")
17605 [(set (match_operand:SWI48 0 "register_operand")
17606 (mult:SWI48 (match_dup 0)
17607 (match_operand:SWI48 1 "const_int_operand")))]
17608 "exact_log2 (INTVAL (operands[1])) >= 0
17609 && peep2_regno_dead_p (0, FLAGS_REG)"
17610 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17611 (clobber (reg:CC FLAGS_REG))])]
17612 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17615 [(set (match_operand:SI 0 "register_operand")
17616 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand")
17617 (match_operand:DI 2 "const_int_operand")) 0))]
17619 && exact_log2 (INTVAL (operands[2])) >= 0
17620 && REGNO (operands[0]) == REGNO (operands[1])
17621 && peep2_regno_dead_p (0, FLAGS_REG)"
17622 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17623 (clobber (reg:CC FLAGS_REG))])]
17624 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17626 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17627 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17628 ;; On many CPUs it is also faster, since special hardware to avoid esp
17629 ;; dependencies is present.
17631 ;; While some of these conversions may be done using splitters, we use
17632 ;; peepholes in order to allow combine_stack_adjustments pass to see
17633 ;; nonobfuscated RTL.
17635 ;; Convert prologue esp subtractions to push.
17636 ;; We need register to push. In order to keep verify_flow_info happy we have
17638 ;; - use scratch and clobber it in order to avoid dependencies
17639 ;; - use already live register
17640 ;; We can't use the second way right now, since there is no reliable way how to
17641 ;; verify that given register is live. First choice will also most likely in
17642 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17643 ;; call clobbered registers are dead. We may want to use base pointer as an
17644 ;; alternative when no register is available later.
17647 [(match_scratch:W 1 "r")
17648 (parallel [(set (reg:P SP_REG)
17649 (plus:P (reg:P SP_REG)
17650 (match_operand:P 0 "const_int_operand")))
17651 (clobber (reg:CC FLAGS_REG))
17652 (clobber (mem:BLK (scratch)))])]
17653 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17654 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17655 [(clobber (match_dup 1))
17656 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17657 (clobber (mem:BLK (scratch)))])])
17660 [(match_scratch:W 1 "r")
17661 (parallel [(set (reg:P SP_REG)
17662 (plus:P (reg:P SP_REG)
17663 (match_operand:P 0 "const_int_operand")))
17664 (clobber (reg:CC FLAGS_REG))
17665 (clobber (mem:BLK (scratch)))])]
17666 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17667 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17668 [(clobber (match_dup 1))
17669 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17670 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17671 (clobber (mem:BLK (scratch)))])])
17673 ;; Convert esp subtractions to push.
17675 [(match_scratch:W 1 "r")
17676 (parallel [(set (reg:P SP_REG)
17677 (plus:P (reg:P SP_REG)
17678 (match_operand:P 0 "const_int_operand")))
17679 (clobber (reg:CC FLAGS_REG))])]
17680 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17681 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17682 [(clobber (match_dup 1))
17683 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17686 [(match_scratch:W 1 "r")
17687 (parallel [(set (reg:P SP_REG)
17688 (plus:P (reg:P SP_REG)
17689 (match_operand:P 0 "const_int_operand")))
17690 (clobber (reg:CC FLAGS_REG))])]
17691 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17692 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17693 [(clobber (match_dup 1))
17694 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17695 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17697 ;; Convert epilogue deallocator to pop.
17699 [(match_scratch:W 1 "r")
17700 (parallel [(set (reg:P SP_REG)
17701 (plus:P (reg:P SP_REG)
17702 (match_operand:P 0 "const_int_operand")))
17703 (clobber (reg:CC FLAGS_REG))
17704 (clobber (mem:BLK (scratch)))])]
17705 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17706 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17707 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17708 (clobber (mem:BLK (scratch)))])])
17710 ;; Two pops case is tricky, since pop causes dependency
17711 ;; on destination register. We use two registers if available.
17713 [(match_scratch:W 1 "r")
17714 (match_scratch:W 2 "r")
17715 (parallel [(set (reg:P SP_REG)
17716 (plus:P (reg:P SP_REG)
17717 (match_operand:P 0 "const_int_operand")))
17718 (clobber (reg:CC FLAGS_REG))
17719 (clobber (mem:BLK (scratch)))])]
17720 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17721 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17722 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17723 (clobber (mem:BLK (scratch)))])
17724 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17727 [(match_scratch:W 1 "r")
17728 (parallel [(set (reg:P SP_REG)
17729 (plus:P (reg:P SP_REG)
17730 (match_operand:P 0 "const_int_operand")))
17731 (clobber (reg:CC FLAGS_REG))
17732 (clobber (mem:BLK (scratch)))])]
17733 "optimize_insn_for_size_p ()
17734 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17735 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17736 (clobber (mem:BLK (scratch)))])
17737 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17739 ;; Convert esp additions to pop.
17741 [(match_scratch:W 1 "r")
17742 (parallel [(set (reg:P SP_REG)
17743 (plus:P (reg:P SP_REG)
17744 (match_operand:P 0 "const_int_operand")))
17745 (clobber (reg:CC FLAGS_REG))])]
17746 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17747 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17749 ;; Two pops case is tricky, since pop causes dependency
17750 ;; on destination register. We use two registers if available.
17752 [(match_scratch:W 1 "r")
17753 (match_scratch:W 2 "r")
17754 (parallel [(set (reg:P SP_REG)
17755 (plus:P (reg:P SP_REG)
17756 (match_operand:P 0 "const_int_operand")))
17757 (clobber (reg:CC FLAGS_REG))])]
17758 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17759 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17760 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17763 [(match_scratch:W 1 "r")
17764 (parallel [(set (reg:P SP_REG)
17765 (plus:P (reg:P SP_REG)
17766 (match_operand:P 0 "const_int_operand")))
17767 (clobber (reg:CC FLAGS_REG))])]
17768 "optimize_insn_for_size_p ()
17769 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17770 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17771 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17773 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17774 ;; required and register dies. Similarly for 128 to -128.
17776 [(set (match_operand 0 "flags_reg_operand")
17777 (match_operator 1 "compare_operator"
17778 [(match_operand 2 "register_operand")
17779 (match_operand 3 "const_int_operand")]))]
17780 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17781 && incdec_operand (operands[3], GET_MODE (operands[3])))
17782 || (!TARGET_FUSE_CMP_AND_BRANCH
17783 && INTVAL (operands[3]) == 128))
17784 && ix86_match_ccmode (insn, CCGCmode)
17785 && peep2_reg_dead_p (1, operands[2])"
17786 [(parallel [(set (match_dup 0)
17787 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17788 (clobber (match_dup 2))])])
17790 ;; Convert imul by three, five and nine into lea
17793 [(set (match_operand:SWI48 0 "register_operand")
17794 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17795 (match_operand:SWI48 2 "const359_operand")))
17796 (clobber (reg:CC FLAGS_REG))])]
17797 "!TARGET_PARTIAL_REG_STALL
17798 || <MODE>mode == SImode
17799 || optimize_function_for_size_p (cfun)"
17800 [(set (match_dup 0)
17801 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17803 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17807 [(set (match_operand:SWI48 0 "register_operand")
17808 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17809 (match_operand:SWI48 2 "const359_operand")))
17810 (clobber (reg:CC FLAGS_REG))])]
17811 "optimize_insn_for_speed_p ()
17812 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17813 [(set (match_dup 0) (match_dup 1))
17815 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17817 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17819 ;; imul $32bit_imm, mem, reg is vector decoded, while
17820 ;; imul $32bit_imm, reg, reg is direct decoded.
17822 [(match_scratch:SWI48 3 "r")
17823 (parallel [(set (match_operand:SWI48 0 "register_operand")
17824 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17825 (match_operand:SWI48 2 "immediate_operand")))
17826 (clobber (reg:CC FLAGS_REG))])]
17827 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17828 && !satisfies_constraint_K (operands[2])"
17829 [(set (match_dup 3) (match_dup 1))
17830 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17831 (clobber (reg:CC FLAGS_REG))])])
17834 [(match_scratch:SI 3 "r")
17835 (parallel [(set (match_operand:DI 0 "register_operand")
17837 (mult:SI (match_operand:SI 1 "memory_operand")
17838 (match_operand:SI 2 "immediate_operand"))))
17839 (clobber (reg:CC FLAGS_REG))])]
17841 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17842 && !satisfies_constraint_K (operands[2])"
17843 [(set (match_dup 3) (match_dup 1))
17844 (parallel [(set (match_dup 0)
17845 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17846 (clobber (reg:CC FLAGS_REG))])])
17848 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17849 ;; Convert it into imul reg, reg
17850 ;; It would be better to force assembler to encode instruction using long
17851 ;; immediate, but there is apparently no way to do so.
17853 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17855 (match_operand:SWI248 1 "nonimmediate_operand")
17856 (match_operand:SWI248 2 "const_int_operand")))
17857 (clobber (reg:CC FLAGS_REG))])
17858 (match_scratch:SWI248 3 "r")]
17859 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17860 && satisfies_constraint_K (operands[2])"
17861 [(set (match_dup 3) (match_dup 2))
17862 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17863 (clobber (reg:CC FLAGS_REG))])]
17865 if (!rtx_equal_p (operands[0], operands[1]))
17866 emit_move_insn (operands[0], operands[1]);
17869 ;; After splitting up read-modify operations, array accesses with memory
17870 ;; operands might end up in form:
17872 ;; movl 4(%esp), %edx
17874 ;; instead of pre-splitting:
17876 ;; addl 4(%esp), %eax
17878 ;; movl 4(%esp), %edx
17879 ;; leal (%edx,%eax,4), %eax
17882 [(match_scratch:W 5 "r")
17883 (parallel [(set (match_operand 0 "register_operand")
17884 (ashift (match_operand 1 "register_operand")
17885 (match_operand 2 "const_int_operand")))
17886 (clobber (reg:CC FLAGS_REG))])
17887 (parallel [(set (match_operand 3 "register_operand")
17888 (plus (match_dup 0)
17889 (match_operand 4 "x86_64_general_operand")))
17890 (clobber (reg:CC FLAGS_REG))])]
17891 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17892 /* Validate MODE for lea. */
17893 && ((!TARGET_PARTIAL_REG_STALL
17894 && (GET_MODE (operands[0]) == QImode
17895 || GET_MODE (operands[0]) == HImode))
17896 || GET_MODE (operands[0]) == SImode
17897 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17898 && (rtx_equal_p (operands[0], operands[3])
17899 || peep2_reg_dead_p (2, operands[0]))
17900 /* We reorder load and the shift. */
17901 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17902 [(set (match_dup 5) (match_dup 4))
17903 (set (match_dup 0) (match_dup 1))]
17905 enum machine_mode op1mode = GET_MODE (operands[1]);
17906 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17907 int scale = 1 << INTVAL (operands[2]);
17908 rtx index = gen_lowpart (word_mode, operands[1]);
17909 rtx base = gen_lowpart (word_mode, operands[5]);
17910 rtx dest = gen_lowpart (mode, operands[3]);
17912 operands[1] = gen_rtx_PLUS (word_mode, base,
17913 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17914 operands[5] = base;
17915 if (mode != word_mode)
17916 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17917 if (op1mode != word_mode)
17918 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17919 operands[0] = dest;
17922 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17923 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17924 ;; caught for use by garbage collectors and the like. Using an insn that
17925 ;; maps to SIGILL makes it more likely the program will rightfully die.
17926 ;; Keeping with tradition, "6" is in honor of #UD.
17927 (define_insn "trap"
17928 [(trap_if (const_int 1) (const_int 6))]
17930 { return ASM_SHORT "0x0b0f"; }
17931 [(set_attr "length" "2")])
17933 (define_expand "prefetch"
17934 [(prefetch (match_operand 0 "address_operand")
17935 (match_operand:SI 1 "const_int_operand")
17936 (match_operand:SI 2 "const_int_operand"))]
17937 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17939 int rw = INTVAL (operands[1]);
17940 int locality = INTVAL (operands[2]);
17942 gcc_assert (rw == 0 || rw == 1);
17943 gcc_assert (locality >= 0 && locality <= 3);
17944 gcc_assert (GET_MODE (operands[0]) == Pmode
17945 || GET_MODE (operands[0]) == VOIDmode);
17947 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17948 supported by SSE counterpart or the SSE prefetch is not available
17949 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17951 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17952 operands[2] = GEN_INT (3);
17954 operands[1] = const0_rtx;
17957 (define_insn "*prefetch_sse_<mode>"
17958 [(prefetch (match_operand:P 0 "address_operand" "p")
17960 (match_operand:SI 1 "const_int_operand"))]
17961 "TARGET_PREFETCH_SSE"
17963 static const char * const patterns[4] = {
17964 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17967 int locality = INTVAL (operands[1]);
17968 gcc_assert (locality >= 0 && locality <= 3);
17970 return patterns[locality];
17972 [(set_attr "type" "sse")
17973 (set_attr "atom_sse_attr" "prefetch")
17974 (set (attr "length_address")
17975 (symbol_ref "memory_address_length (operands[0])"))
17976 (set_attr "memory" "none")])
17978 (define_insn "*prefetch_3dnow_<mode>"
17979 [(prefetch (match_operand:P 0 "address_operand" "p")
17980 (match_operand:SI 1 "const_int_operand" "n")
17984 if (INTVAL (operands[1]) == 0)
17985 return "prefetch\t%a0";
17987 return "prefetchw\t%a0";
17989 [(set_attr "type" "mmx")
17990 (set (attr "length_address")
17991 (symbol_ref "memory_address_length (operands[0])"))
17992 (set_attr "memory" "none")])
17994 (define_expand "stack_protect_set"
17995 [(match_operand 0 "memory_operand")
17996 (match_operand 1 "memory_operand")]
17999 rtx (*insn)(rtx, rtx);
18001 #ifdef TARGET_THREAD_SSP_OFFSET
18002 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18003 insn = (TARGET_LP64
18004 ? gen_stack_tls_protect_set_di
18005 : gen_stack_tls_protect_set_si);
18007 insn = (TARGET_LP64
18008 ? gen_stack_protect_set_di
18009 : gen_stack_protect_set_si);
18012 emit_insn (insn (operands[0], operands[1]));
18016 (define_insn "stack_protect_set_<mode>"
18017 [(set (match_operand:PTR 0 "memory_operand" "=m")
18018 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18020 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18021 (clobber (reg:CC FLAGS_REG))]
18023 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18024 [(set_attr "type" "multi")])
18026 (define_insn "stack_tls_protect_set_<mode>"
18027 [(set (match_operand:PTR 0 "memory_operand" "=m")
18028 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18029 UNSPEC_SP_TLS_SET))
18030 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18031 (clobber (reg:CC FLAGS_REG))]
18033 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18034 [(set_attr "type" "multi")])
18036 (define_expand "stack_protect_test"
18037 [(match_operand 0 "memory_operand")
18038 (match_operand 1 "memory_operand")
18042 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18044 rtx (*insn)(rtx, rtx, rtx);
18046 #ifdef TARGET_THREAD_SSP_OFFSET
18047 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18048 insn = (TARGET_LP64
18049 ? gen_stack_tls_protect_test_di
18050 : gen_stack_tls_protect_test_si);
18052 insn = (TARGET_LP64
18053 ? gen_stack_protect_test_di
18054 : gen_stack_protect_test_si);
18057 emit_insn (insn (flags, operands[0], operands[1]));
18059 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18060 flags, const0_rtx, operands[2]));
18064 (define_insn "stack_protect_test_<mode>"
18065 [(set (match_operand:CCZ 0 "flags_reg_operand")
18066 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18067 (match_operand:PTR 2 "memory_operand" "m")]
18069 (clobber (match_scratch:PTR 3 "=&r"))]
18071 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18072 [(set_attr "type" "multi")])
18074 (define_insn "stack_tls_protect_test_<mode>"
18075 [(set (match_operand:CCZ 0 "flags_reg_operand")
18076 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18077 (match_operand:PTR 2 "const_int_operand" "i")]
18078 UNSPEC_SP_TLS_TEST))
18079 (clobber (match_scratch:PTR 3 "=r"))]
18081 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18082 [(set_attr "type" "multi")])
18084 (define_insn "sse4_2_crc32<mode>"
18085 [(set (match_operand:SI 0 "register_operand" "=r")
18087 [(match_operand:SI 1 "register_operand" "0")
18088 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18090 "TARGET_SSE4_2 || TARGET_CRC32"
18091 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18092 [(set_attr "type" "sselog1")
18093 (set_attr "prefix_rep" "1")
18094 (set_attr "prefix_extra" "1")
18095 (set (attr "prefix_data16")
18096 (if_then_else (match_operand:HI 2)
18098 (const_string "*")))
18099 (set (attr "prefix_rex")
18100 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18102 (const_string "*")))
18103 (set_attr "mode" "SI")])
18105 (define_insn "sse4_2_crc32di"
18106 [(set (match_operand:DI 0 "register_operand" "=r")
18108 [(match_operand:DI 1 "register_operand" "0")
18109 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18111 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18112 "crc32{q}\t{%2, %0|%0, %2}"
18113 [(set_attr "type" "sselog1")
18114 (set_attr "prefix_rep" "1")
18115 (set_attr "prefix_extra" "1")
18116 (set_attr "mode" "DI")])
18118 (define_expand "rdpmc"
18119 [(match_operand:DI 0 "register_operand")
18120 (match_operand:SI 1 "register_operand")]
18123 rtx reg = gen_reg_rtx (DImode);
18126 /* Force operand 1 into ECX. */
18127 rtx ecx = gen_rtx_REG (SImode, CX_REG);
18128 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18129 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18134 rtvec vec = rtvec_alloc (2);
18135 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18136 rtx upper = gen_reg_rtx (DImode);
18137 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18138 gen_rtvec (1, const0_rtx),
18140 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18141 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18143 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18144 NULL, 1, OPTAB_DIRECT);
18145 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18149 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18150 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18154 (define_insn "*rdpmc"
18155 [(set (match_operand:DI 0 "register_operand" "=A")
18156 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18160 [(set_attr "type" "other")
18161 (set_attr "length" "2")])
18163 (define_insn "*rdpmc_rex64"
18164 [(set (match_operand:DI 0 "register_operand" "=a")
18165 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18167 (set (match_operand:DI 1 "register_operand" "=d")
18168 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18171 [(set_attr "type" "other")
18172 (set_attr "length" "2")])
18174 (define_expand "rdtsc"
18175 [(set (match_operand:DI 0 "register_operand")
18176 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18181 rtvec vec = rtvec_alloc (2);
18182 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18183 rtx upper = gen_reg_rtx (DImode);
18184 rtx lower = gen_reg_rtx (DImode);
18185 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18186 gen_rtvec (1, const0_rtx),
18188 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18189 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18191 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18192 NULL, 1, OPTAB_DIRECT);
18193 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18195 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18200 (define_insn "*rdtsc"
18201 [(set (match_operand:DI 0 "register_operand" "=A")
18202 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18205 [(set_attr "type" "other")
18206 (set_attr "length" "2")])
18208 (define_insn "*rdtsc_rex64"
18209 [(set (match_operand:DI 0 "register_operand" "=a")
18210 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18211 (set (match_operand:DI 1 "register_operand" "=d")
18212 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18215 [(set_attr "type" "other")
18216 (set_attr "length" "2")])
18218 (define_expand "rdtscp"
18219 [(match_operand:DI 0 "register_operand")
18220 (match_operand:SI 1 "memory_operand")]
18223 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18224 gen_rtvec (1, const0_rtx),
18226 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18227 gen_rtvec (1, const0_rtx),
18229 rtx reg = gen_reg_rtx (DImode);
18230 rtx tmp = gen_reg_rtx (SImode);
18234 rtvec vec = rtvec_alloc (3);
18235 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18236 rtx upper = gen_reg_rtx (DImode);
18237 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18238 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18239 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18241 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18242 NULL, 1, OPTAB_DIRECT);
18243 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18248 rtvec vec = rtvec_alloc (2);
18249 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18250 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18251 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18254 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18255 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18259 (define_insn "*rdtscp"
18260 [(set (match_operand:DI 0 "register_operand" "=A")
18261 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18262 (set (match_operand:SI 1 "register_operand" "=c")
18263 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18266 [(set_attr "type" "other")
18267 (set_attr "length" "3")])
18269 (define_insn "*rdtscp_rex64"
18270 [(set (match_operand:DI 0 "register_operand" "=a")
18271 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18272 (set (match_operand:DI 1 "register_operand" "=d")
18273 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18274 (set (match_operand:SI 2 "register_operand" "=c")
18275 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18278 [(set_attr "type" "other")
18279 (set_attr "length" "3")])
18281 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18283 ;; LWP instructions
18285 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18287 (define_expand "lwp_llwpcb"
18288 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18289 UNSPECV_LLWP_INTRINSIC)]
18292 (define_insn "*lwp_llwpcb<mode>1"
18293 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18294 UNSPECV_LLWP_INTRINSIC)]
18297 [(set_attr "type" "lwp")
18298 (set_attr "mode" "<MODE>")
18299 (set_attr "length" "5")])
18301 (define_expand "lwp_slwpcb"
18302 [(set (match_operand 0 "register_operand" "=r")
18303 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18308 insn = (Pmode == DImode
18310 : gen_lwp_slwpcbsi);
18312 emit_insn (insn (operands[0]));
18316 (define_insn "lwp_slwpcb<mode>"
18317 [(set (match_operand:P 0 "register_operand" "=r")
18318 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18321 [(set_attr "type" "lwp")
18322 (set_attr "mode" "<MODE>")
18323 (set_attr "length" "5")])
18325 (define_expand "lwp_lwpval<mode>3"
18326 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18327 (match_operand:SI 2 "nonimmediate_operand" "rm")
18328 (match_operand:SI 3 "const_int_operand" "i")]
18329 UNSPECV_LWPVAL_INTRINSIC)]
18331 ;; Avoid unused variable warning.
18332 "(void) operands[0];")
18334 (define_insn "*lwp_lwpval<mode>3_1"
18335 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18336 (match_operand:SI 1 "nonimmediate_operand" "rm")
18337 (match_operand:SI 2 "const_int_operand" "i")]
18338 UNSPECV_LWPVAL_INTRINSIC)]
18340 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18341 [(set_attr "type" "lwp")
18342 (set_attr "mode" "<MODE>")
18343 (set (attr "length")
18344 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18346 (define_expand "lwp_lwpins<mode>3"
18347 [(set (reg:CCC FLAGS_REG)
18348 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18349 (match_operand:SI 2 "nonimmediate_operand" "rm")
18350 (match_operand:SI 3 "const_int_operand" "i")]
18351 UNSPECV_LWPINS_INTRINSIC))
18352 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18353 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18356 (define_insn "*lwp_lwpins<mode>3_1"
18357 [(set (reg:CCC FLAGS_REG)
18358 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18359 (match_operand:SI 1 "nonimmediate_operand" "rm")
18360 (match_operand:SI 2 "const_int_operand" "i")]
18361 UNSPECV_LWPINS_INTRINSIC))]
18363 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18364 [(set_attr "type" "lwp")
18365 (set_attr "mode" "<MODE>")
18366 (set (attr "length")
18367 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18369 (define_insn "rdfsbase<mode>"
18370 [(set (match_operand:SWI48 0 "register_operand" "=r")
18371 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18372 "TARGET_64BIT && TARGET_FSGSBASE"
18374 [(set_attr "type" "other")
18375 (set_attr "prefix_extra" "2")])
18377 (define_insn "rdgsbase<mode>"
18378 [(set (match_operand:SWI48 0 "register_operand" "=r")
18379 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18380 "TARGET_64BIT && TARGET_FSGSBASE"
18382 [(set_attr "type" "other")
18383 (set_attr "prefix_extra" "2")])
18385 (define_insn "wrfsbase<mode>"
18386 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18388 "TARGET_64BIT && TARGET_FSGSBASE"
18390 [(set_attr "type" "other")
18391 (set_attr "prefix_extra" "2")])
18393 (define_insn "wrgsbase<mode>"
18394 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18396 "TARGET_64BIT && TARGET_FSGSBASE"
18398 [(set_attr "type" "other")
18399 (set_attr "prefix_extra" "2")])
18401 (define_insn "rdrand<mode>_1"
18402 [(set (match_operand:SWI248 0 "register_operand" "=r")
18403 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18404 (set (reg:CCC FLAGS_REG)
18405 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18408 [(set_attr "type" "other")
18409 (set_attr "prefix_extra" "1")])
18411 (define_expand "pause"
18412 [(set (match_dup 0)
18413 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18416 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18417 MEM_VOLATILE_P (operands[0]) = 1;
18420 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18421 ;; They have the same encoding.
18422 (define_insn "*pause"
18423 [(set (match_operand:BLK 0)
18424 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18427 [(set_attr "length" "2")
18428 (set_attr "memory" "unknown")])
18430 (define_expand "xbegin"
18431 [(set (match_operand:SI 0 "register_operand")
18432 (unspec_volatile:SI [(match_dup 1)] UNSPECV_XBEGIN))]
18435 rtx label = gen_label_rtx ();
18437 operands[1] = force_reg (SImode, constm1_rtx);
18439 emit_jump_insn (gen_xbegin_1 (operands[0], operands[1], label));
18441 emit_label (label);
18442 LABEL_NUSES (label) = 1;
18447 (define_insn "xbegin_1"
18449 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18451 (label_ref (match_operand 2))
18453 (set (match_operand:SI 0 "register_operand" "=a")
18454 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
18458 [(set_attr "type" "other")
18459 (set_attr "length" "6")])
18461 (define_insn "xend"
18462 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18465 [(set_attr "type" "other")
18466 (set_attr "length" "3")])
18468 (define_insn "xabort"
18469 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18473 [(set_attr "type" "other")
18474 (set_attr "length" "3")])
18476 (define_expand "xtest"
18477 [(set (match_operand:QI 0 "register_operand")
18478 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18481 emit_insn (gen_xtest_1 ());
18483 ix86_expand_setcc (operands[0], NE,
18484 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18488 (define_insn "xtest_1"
18489 [(set (reg:CCZ FLAGS_REG)
18490 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18493 [(set_attr "type" "other")
18494 (set_attr "length" "3")])
18498 (include "sync.md")