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
89 UNSPEC_MEMORY_BLOCKAGE
99 ;; Other random patterns
108 UNSPEC_LD_MPIC ; load_macho_picbase
110 UNSPEC_DIV_ALREADY_SPLIT
111 UNSPEC_MS_TO_SYSV_CALL
112 UNSPEC_CALL_NEEDS_VZEROUPPER
117 ;; For SSE/MMX support:
125 ;; Generic math support
127 UNSPEC_IEEE_MIN ; not commutative
128 UNSPEC_IEEE_MAX ; not commutative
130 ;; x87 Floating point
146 UNSPEC_FRNDINT_MASK_PM
150 ;; x87 Double output FP
185 (define_c_enum "unspecv" [
188 UNSPECV_PROBE_STACK_RANGE
191 UNSPECV_SPLIT_STACK_RETURN
197 UNSPECV_LLWP_INTRINSIC
198 UNSPECV_SLWP_INTRINSIC
199 UNSPECV_LWPVAL_INTRINSIC
200 UNSPECV_LWPINS_INTRINSIC
216 ;; For RDRAND support
219 ;; For RDSEED support
229 ;; Constants to represent rounding modes in the ROUND instruction
238 ;; Constants to represent pcomtrue/pcomfalse variants
248 ;; Constants used in the XOP pperm instruction
250 [(PPERM_SRC 0x00) /* copy source */
251 (PPERM_INVERT 0x20) /* invert source */
252 (PPERM_REVERSE 0x40) /* bit reverse source */
253 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
254 (PPERM_ZERO 0x80) /* all 0's */
255 (PPERM_ONES 0xa0) /* all 1's */
256 (PPERM_SIGN 0xc0) /* propagate sign bit */
257 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
258 (PPERM_SRC1 0x00) /* use first source byte */
259 (PPERM_SRC2 0x10) /* use second source byte */
262 ;; Registers by name.
315 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
318 ;; In C guard expressions, put expressions which may be compile-time
319 ;; constants first. This allows for better optimization. For
320 ;; example, write "TARGET_64BIT && reload_completed", not
321 ;; "reload_completed && TARGET_64BIT".
325 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
326 atom,generic64,amdfam10,bdver1,bdver2,btver1,btver2"
327 (const (symbol_ref "ix86_schedule")))
329 ;; A basic instruction type. Refinements due to arguments to be
330 ;; provided in other attributes.
333 alu,alu1,negnot,imov,imovx,lea,
334 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
335 icmp,test,ibr,setcc,icmov,
336 push,pop,call,callv,leave,
338 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
339 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
340 sse,ssemov,sseadd,sseadd1,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
341 ssediv,sseins,ssemuladd,sse4arg,lwp,
342 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
343 (const_string "other"))
345 ;; Main data type used by the insn
347 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
348 (const_string "unknown"))
350 ;; The CPU unit operations uses.
351 (define_attr "unit" "integer,i387,sse,mmx,unknown"
352 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
353 (const_string "i387")
354 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
355 sse,ssemov,sseadd,sseadd1,ssemul,ssecmp,ssecomi,ssecvt,
356 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
358 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
360 (eq_attr "type" "other")
361 (const_string "unknown")]
362 (const_string "integer")))
364 ;; The (bounding maximum) length of an instruction immediate.
365 (define_attr "length_immediate" ""
366 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
369 (eq_attr "unit" "i387,sse,mmx")
371 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
372 rotate,rotatex,rotate1,imul,icmp,push,pop")
373 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
374 (eq_attr "type" "imov,test")
375 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
376 (eq_attr "type" "call")
377 (if_then_else (match_operand 0 "constant_call_address_operand")
380 (eq_attr "type" "callv")
381 (if_then_else (match_operand 1 "constant_call_address_operand")
384 ;; We don't know the size before shorten_branches. Expect
385 ;; the instruction to fit for better scheduling.
386 (eq_attr "type" "ibr")
389 (symbol_ref "/* Update immediate_length and other attributes! */
390 gcc_unreachable (),1")))
392 ;; The (bounding maximum) length of an instruction address.
393 (define_attr "length_address" ""
394 (cond [(eq_attr "type" "str,other,multi,fxch")
396 (and (eq_attr "type" "call")
397 (match_operand 0 "constant_call_address_operand"))
399 (and (eq_attr "type" "callv")
400 (match_operand 1 "constant_call_address_operand"))
403 (symbol_ref "ix86_attr_length_address_default (insn)")))
405 ;; Set when length prefix is used.
406 (define_attr "prefix_data16" ""
407 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
409 (eq_attr "mode" "HI")
411 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
416 ;; Set when string REP prefix is used.
417 (define_attr "prefix_rep" ""
418 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
420 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
425 ;; Set when 0f opcode prefix is used.
426 (define_attr "prefix_0f" ""
428 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
429 (eq_attr "unit" "sse,mmx"))
433 ;; Set when REX opcode prefix is used.
434 (define_attr "prefix_rex" ""
435 (cond [(not (match_test "TARGET_64BIT"))
437 (and (eq_attr "mode" "DI")
438 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
439 (eq_attr "unit" "!mmx")))
441 (and (eq_attr "mode" "QI")
442 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
444 (match_test "x86_extended_reg_mentioned_p (insn)")
446 (and (eq_attr "type" "imovx")
447 (match_operand:QI 1 "ext_QIreg_operand"))
452 ;; There are also additional prefixes in 3DNOW, SSSE3.
453 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
454 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
455 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
456 (define_attr "prefix_extra" ""
457 (cond [(eq_attr "type" "ssemuladd,sse4arg")
459 (eq_attr "type" "sseiadd1,ssecvt1")
464 ;; Prefix used: original, VEX or maybe VEX.
465 (define_attr "prefix" "orig,vex,maybe_vex"
466 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
468 (const_string "orig")))
470 ;; VEX W bit is used.
471 (define_attr "prefix_vex_w" "" (const_int 0))
473 ;; The length of VEX prefix
474 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
475 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
476 ;; still prefix_0f 1, with prefix_extra 1.
477 (define_attr "length_vex" ""
478 (if_then_else (and (eq_attr "prefix_0f" "1")
479 (eq_attr "prefix_extra" "0"))
480 (if_then_else (eq_attr "prefix_vex_w" "1")
481 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
482 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
483 (if_then_else (eq_attr "prefix_vex_w" "1")
484 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
485 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
487 ;; Set when modrm byte is used.
488 (define_attr "modrm" ""
489 (cond [(eq_attr "type" "str,leave")
491 (eq_attr "unit" "i387")
493 (and (eq_attr "type" "incdec")
494 (and (not (match_test "TARGET_64BIT"))
495 (ior (match_operand:SI 1 "register_operand")
496 (match_operand:HI 1 "register_operand"))))
498 (and (eq_attr "type" "push")
499 (not (match_operand 1 "memory_operand")))
501 (and (eq_attr "type" "pop")
502 (not (match_operand 0 "memory_operand")))
504 (and (eq_attr "type" "imov")
505 (and (not (eq_attr "mode" "DI"))
506 (ior (and (match_operand 0 "register_operand")
507 (match_operand 1 "immediate_operand"))
508 (ior (and (match_operand 0 "ax_reg_operand")
509 (match_operand 1 "memory_displacement_only_operand"))
510 (and (match_operand 0 "memory_displacement_only_operand")
511 (match_operand 1 "ax_reg_operand"))))))
513 (and (eq_attr "type" "call")
514 (match_operand 0 "constant_call_address_operand"))
516 (and (eq_attr "type" "callv")
517 (match_operand 1 "constant_call_address_operand"))
519 (and (eq_attr "type" "alu,alu1,icmp,test")
520 (match_operand 0 "ax_reg_operand"))
521 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
525 ;; The (bounding maximum) length of an instruction in bytes.
526 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
527 ;; Later we may want to split them and compute proper length as for
529 (define_attr "length" ""
530 (cond [(eq_attr "type" "other,multi,fistp,frndint")
532 (eq_attr "type" "fcmp")
534 (eq_attr "unit" "i387")
536 (plus (attr "prefix_data16")
537 (attr "length_address")))
538 (ior (eq_attr "prefix" "vex")
539 (and (eq_attr "prefix" "maybe_vex")
540 (match_test "TARGET_AVX")))
541 (plus (attr "length_vex")
542 (plus (attr "length_immediate")
544 (attr "length_address"))))]
545 (plus (plus (attr "modrm")
546 (plus (attr "prefix_0f")
547 (plus (attr "prefix_rex")
548 (plus (attr "prefix_extra")
550 (plus (attr "prefix_rep")
551 (plus (attr "prefix_data16")
552 (plus (attr "length_immediate")
553 (attr "length_address")))))))
555 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
556 ;; `store' if there is a simple memory reference therein, or `unknown'
557 ;; if the instruction is complex.
559 (define_attr "memory" "none,load,store,both,unknown"
560 (cond [(eq_attr "type" "other,multi,str,lwp")
561 (const_string "unknown")
562 (eq_attr "type" "lea,fcmov,fpspc")
563 (const_string "none")
564 (eq_attr "type" "fistp,leave")
565 (const_string "both")
566 (eq_attr "type" "frndint")
567 (const_string "load")
568 (eq_attr "type" "push")
569 (if_then_else (match_operand 1 "memory_operand")
570 (const_string "both")
571 (const_string "store"))
572 (eq_attr "type" "pop")
573 (if_then_else (match_operand 0 "memory_operand")
574 (const_string "both")
575 (const_string "load"))
576 (eq_attr "type" "setcc")
577 (if_then_else (match_operand 0 "memory_operand")
578 (const_string "store")
579 (const_string "none"))
580 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
581 (if_then_else (ior (match_operand 0 "memory_operand")
582 (match_operand 1 "memory_operand"))
583 (const_string "load")
584 (const_string "none"))
585 (eq_attr "type" "ibr")
586 (if_then_else (match_operand 0 "memory_operand")
587 (const_string "load")
588 (const_string "none"))
589 (eq_attr "type" "call")
590 (if_then_else (match_operand 0 "constant_call_address_operand")
591 (const_string "none")
592 (const_string "load"))
593 (eq_attr "type" "callv")
594 (if_then_else (match_operand 1 "constant_call_address_operand")
595 (const_string "none")
596 (const_string "load"))
597 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
598 (match_operand 1 "memory_operand"))
599 (const_string "both")
600 (and (match_operand 0 "memory_operand")
601 (match_operand 1 "memory_operand"))
602 (const_string "both")
603 (match_operand 0 "memory_operand")
604 (const_string "store")
605 (match_operand 1 "memory_operand")
606 (const_string "load")
608 "!alu1,negnot,ishift1,
609 imov,imovx,icmp,test,bitmanip,
611 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
612 sseadd1,sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
613 (match_operand 2 "memory_operand"))
614 (const_string "load")
615 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
616 (match_operand 3 "memory_operand"))
617 (const_string "load")
619 (const_string "none")))
621 ;; Indicates if an instruction has both an immediate and a displacement.
623 (define_attr "imm_disp" "false,true,unknown"
624 (cond [(eq_attr "type" "other,multi")
625 (const_string "unknown")
626 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
627 (and (match_operand 0 "memory_displacement_operand")
628 (match_operand 1 "immediate_operand")))
629 (const_string "true")
630 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
631 (and (match_operand 0 "memory_displacement_operand")
632 (match_operand 2 "immediate_operand")))
633 (const_string "true")
635 (const_string "false")))
637 ;; Indicates if an FP operation has an integer source.
639 (define_attr "fp_int_src" "false,true"
640 (const_string "false"))
642 ;; Defines rounding mode of an FP operation.
644 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
645 (const_string "any"))
647 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
648 (define_attr "use_carry" "0,1" (const_string "0"))
650 ;; Define attribute to indicate unaligned ssemov insns
651 (define_attr "movu" "0,1" (const_string "0"))
653 ;; Used to control the "enabled" attribute on a per-instruction basis.
654 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,
655 avx2,noavx2,bmi2,fma,fma4"
656 (const_string "base"))
658 (define_attr "enabled" ""
659 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
660 (eq_attr "isa" "sse2_noavx")
661 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
662 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
663 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
664 (eq_attr "isa" "sse4_noavx")
665 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
666 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
667 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
668 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
669 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
670 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
671 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
672 ;; Fma instruction selection has to be done based on
673 ;; register pressure. For generating fma4, a cost model
674 ;; based on register pressure is required. Till then,
675 ;; fma4 instruction is disabled for targets that implement
676 ;; both fma and fma4 instruction sets.
677 (eq_attr "isa" "fma4")
678 (symbol_ref "TARGET_FMA4 && !TARGET_FMA")
682 ;; Describe a user's asm statement.
683 (define_asm_attributes
684 [(set_attr "length" "128")
685 (set_attr "type" "multi")])
687 (define_code_iterator plusminus [plus minus])
689 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
691 ;; Base name for define_insn
692 (define_code_attr plusminus_insn
693 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
694 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
696 ;; Base name for insn mnemonic.
697 (define_code_attr plusminus_mnemonic
698 [(plus "add") (ss_plus "adds") (us_plus "addus")
699 (minus "sub") (ss_minus "subs") (us_minus "subus")])
700 (define_code_attr plusminus_carry_mnemonic
701 [(plus "adc") (minus "sbb")])
703 ;; Mark commutative operators as such in constraints.
704 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
705 (minus "") (ss_minus "") (us_minus "")])
707 ;; Mapping of max and min
708 (define_code_iterator maxmin [smax smin umax umin])
710 ;; Mapping of signed max and min
711 (define_code_iterator smaxmin [smax smin])
713 ;; Mapping of unsigned max and min
714 (define_code_iterator umaxmin [umax umin])
716 ;; Base name for integer and FP insn mnemonic
717 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
718 (umax "maxu") (umin "minu")])
719 (define_code_attr maxmin_float [(smax "max") (smin "min")])
721 ;; Mapping of logic operators
722 (define_code_iterator any_logic [and ior xor])
723 (define_code_iterator any_or [ior xor])
725 ;; Base name for insn mnemonic.
726 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
728 ;; Mapping of logic-shift operators
729 (define_code_iterator any_lshift [ashift lshiftrt])
731 ;; Mapping of shift-right operators
732 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
734 ;; Mapping of all shift operators
735 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
737 ;; Base name for define_insn
738 (define_code_attr shift_insn
739 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
741 ;; Base name for insn mnemonic.
742 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
743 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
745 ;; Mapping of rotate operators
746 (define_code_iterator any_rotate [rotate rotatert])
748 ;; Base name for define_insn
749 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
751 ;; Base name for insn mnemonic.
752 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
754 ;; Mapping of abs neg operators
755 (define_code_iterator absneg [abs neg])
757 ;; Base name for x87 insn mnemonic.
758 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
760 ;; Used in signed and unsigned widening multiplications.
761 (define_code_iterator any_extend [sign_extend zero_extend])
763 ;; Prefix for insn menmonic.
764 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
766 ;; Prefix for define_insn
767 (define_code_attr u [(sign_extend "") (zero_extend "u")])
768 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
769 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
771 ;; All integer modes.
772 (define_mode_iterator SWI1248x [QI HI SI DI])
774 ;; All integer modes without QImode.
775 (define_mode_iterator SWI248x [HI SI DI])
777 ;; All integer modes without QImode and HImode.
778 (define_mode_iterator SWI48x [SI DI])
780 ;; All integer modes without SImode and DImode.
781 (define_mode_iterator SWI12 [QI HI])
783 ;; All integer modes without DImode.
784 (define_mode_iterator SWI124 [QI HI SI])
786 ;; All integer modes without QImode and DImode.
787 (define_mode_iterator SWI24 [HI SI])
789 ;; Single word integer modes.
790 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
792 ;; Single word integer modes without QImode.
793 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
795 ;; Single word integer modes without QImode and HImode.
796 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
798 ;; All math-dependant single and double word integer modes.
799 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
800 (HI "TARGET_HIMODE_MATH")
801 SI DI (TI "TARGET_64BIT")])
803 ;; Math-dependant single word integer modes.
804 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
805 (HI "TARGET_HIMODE_MATH")
806 SI (DI "TARGET_64BIT")])
808 ;; Math-dependant integer modes without DImode.
809 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
810 (HI "TARGET_HIMODE_MATH")
813 ;; Math-dependant single word integer modes without QImode.
814 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
815 SI (DI "TARGET_64BIT")])
817 ;; Double word integer modes.
818 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
819 (TI "TARGET_64BIT")])
821 ;; Double word integer modes as mode attribute.
822 (define_mode_attr DWI [(SI "DI") (DI "TI")])
823 (define_mode_attr dwi [(SI "di") (DI "ti")])
825 ;; Half mode for double word integer modes.
826 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
827 (DI "TARGET_64BIT")])
829 ;; Instruction suffix for integer modes.
830 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
832 ;; Pointer size prefix for integer modes (Intel asm dialect)
833 (define_mode_attr iptrsize [(QI "BYTE")
838 ;; Register class for integer modes.
839 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
841 ;; Immediate operand constraint for integer modes.
842 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
844 ;; General operand constraint for word modes.
845 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
847 ;; Immediate operand constraint for double integer modes.
848 (define_mode_attr di [(SI "nF") (DI "e")])
850 ;; Immediate operand constraint for shifts.
851 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
853 ;; General operand predicate for integer modes.
854 (define_mode_attr general_operand
855 [(QI "general_operand")
856 (HI "general_operand")
857 (SI "x86_64_general_operand")
858 (DI "x86_64_general_operand")
859 (TI "x86_64_general_operand")])
861 ;; General sign/zero extend operand predicate for integer modes.
862 (define_mode_attr general_szext_operand
863 [(QI "general_operand")
864 (HI "general_operand")
865 (SI "x86_64_szext_general_operand")
866 (DI "x86_64_szext_general_operand")])
868 ;; Immediate operand predicate for integer modes.
869 (define_mode_attr immediate_operand
870 [(QI "immediate_operand")
871 (HI "immediate_operand")
872 (SI "x86_64_immediate_operand")
873 (DI "x86_64_immediate_operand")])
875 ;; Nonmemory operand predicate for integer modes.
876 (define_mode_attr nonmemory_operand
877 [(QI "nonmemory_operand")
878 (HI "nonmemory_operand")
879 (SI "x86_64_nonmemory_operand")
880 (DI "x86_64_nonmemory_operand")])
882 ;; Operand predicate for shifts.
883 (define_mode_attr shift_operand
884 [(QI "nonimmediate_operand")
885 (HI "nonimmediate_operand")
886 (SI "nonimmediate_operand")
887 (DI "shiftdi_operand")
888 (TI "register_operand")])
890 ;; Operand predicate for shift argument.
891 (define_mode_attr shift_immediate_operand
892 [(QI "const_1_to_31_operand")
893 (HI "const_1_to_31_operand")
894 (SI "const_1_to_31_operand")
895 (DI "const_1_to_63_operand")])
897 ;; Input operand predicate for arithmetic left shifts.
898 (define_mode_attr ashl_input_operand
899 [(QI "nonimmediate_operand")
900 (HI "nonimmediate_operand")
901 (SI "nonimmediate_operand")
902 (DI "ashldi_input_operand")
903 (TI "reg_or_pm1_operand")])
905 ;; SSE and x87 SFmode and DFmode floating point modes
906 (define_mode_iterator MODEF [SF DF])
908 ;; All x87 floating point modes
909 (define_mode_iterator X87MODEF [SF DF XF])
911 ;; SSE instruction suffix for various modes
912 (define_mode_attr ssemodesuffix
914 (V8SF "ps") (V4DF "pd")
915 (V4SF "ps") (V2DF "pd")
916 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
917 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
919 ;; SSE vector suffix for floating point modes
920 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
922 ;; SSE vector mode corresponding to a scalar mode
923 (define_mode_attr ssevecmode
924 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
926 ;; Instruction suffix for REX 64bit operators.
927 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
929 ;; This mode iterator allows :P to be used for patterns that operate on
930 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
931 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
933 ;; This mode iterator allows :W to be used for patterns that operate on
934 ;; word_mode sized quantities.
935 (define_mode_iterator W
936 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
938 ;; This mode iterator allows :PTR to be used for patterns that operate on
939 ;; ptr_mode sized quantities.
940 (define_mode_iterator PTR
941 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
943 ;; Scheduling descriptions
945 (include "pentium.md")
948 (include "athlon.md")
949 (include "bdver1.md")
955 ;; Operand and operator predicates and constraints
957 (include "predicates.md")
958 (include "constraints.md")
961 ;; Compare and branch/compare and store instructions.
963 (define_expand "cbranch<mode>4"
964 [(set (reg:CC FLAGS_REG)
965 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
966 (match_operand:SDWIM 2 "<general_operand>")))
967 (set (pc) (if_then_else
968 (match_operator 0 "ordered_comparison_operator"
969 [(reg:CC FLAGS_REG) (const_int 0)])
970 (label_ref (match_operand 3))
974 if (MEM_P (operands[1]) && MEM_P (operands[2]))
975 operands[1] = force_reg (<MODE>mode, operands[1]);
976 ix86_expand_branch (GET_CODE (operands[0]),
977 operands[1], operands[2], operands[3]);
981 (define_expand "cstore<mode>4"
982 [(set (reg:CC FLAGS_REG)
983 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
984 (match_operand:SWIM 3 "<general_operand>")))
985 (set (match_operand:QI 0 "register_operand")
986 (match_operator 1 "ordered_comparison_operator"
987 [(reg:CC FLAGS_REG) (const_int 0)]))]
990 if (MEM_P (operands[2]) && MEM_P (operands[3]))
991 operands[2] = force_reg (<MODE>mode, operands[2]);
992 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
993 operands[2], operands[3]);
997 (define_expand "cmp<mode>_1"
998 [(set (reg:CC FLAGS_REG)
999 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1000 (match_operand:SWI48 1 "<general_operand>")))])
1002 (define_insn "*cmp<mode>_ccno_1"
1003 [(set (reg FLAGS_REG)
1004 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1005 (match_operand:SWI 1 "const0_operand")))]
1006 "ix86_match_ccmode (insn, CCNOmode)"
1008 test{<imodesuffix>}\t%0, %0
1009 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1010 [(set_attr "type" "test,icmp")
1011 (set_attr "length_immediate" "0,1")
1012 (set_attr "mode" "<MODE>")])
1014 (define_insn "*cmp<mode>_1"
1015 [(set (reg FLAGS_REG)
1016 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1017 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1018 "ix86_match_ccmode (insn, CCmode)"
1019 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1020 [(set_attr "type" "icmp")
1021 (set_attr "mode" "<MODE>")])
1023 (define_insn "*cmp<mode>_minus_1"
1024 [(set (reg FLAGS_REG)
1026 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1027 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1029 "ix86_match_ccmode (insn, CCGOCmode)"
1030 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1031 [(set_attr "type" "icmp")
1032 (set_attr "mode" "<MODE>")])
1034 (define_insn "*cmpqi_ext_1"
1035 [(set (reg FLAGS_REG)
1037 (match_operand:QI 0 "general_operand" "Qm")
1040 (match_operand 1 "ext_register_operand" "Q")
1042 (const_int 8)) 0)))]
1043 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1044 "cmp{b}\t{%h1, %0|%0, %h1}"
1045 [(set_attr "type" "icmp")
1046 (set_attr "mode" "QI")])
1048 (define_insn "*cmpqi_ext_1_rex64"
1049 [(set (reg FLAGS_REG)
1051 (match_operand:QI 0 "register_operand" "Q")
1054 (match_operand 1 "ext_register_operand" "Q")
1056 (const_int 8)) 0)))]
1057 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1058 "cmp{b}\t{%h1, %0|%0, %h1}"
1059 [(set_attr "type" "icmp")
1060 (set_attr "mode" "QI")])
1062 (define_insn "*cmpqi_ext_2"
1063 [(set (reg FLAGS_REG)
1067 (match_operand 0 "ext_register_operand" "Q")
1070 (match_operand:QI 1 "const0_operand")))]
1071 "ix86_match_ccmode (insn, CCNOmode)"
1073 [(set_attr "type" "test")
1074 (set_attr "length_immediate" "0")
1075 (set_attr "mode" "QI")])
1077 (define_expand "cmpqi_ext_3"
1078 [(set (reg:CC FLAGS_REG)
1082 (match_operand 0 "ext_register_operand")
1085 (match_operand:QI 1 "immediate_operand")))])
1087 (define_insn "*cmpqi_ext_3_insn"
1088 [(set (reg FLAGS_REG)
1092 (match_operand 0 "ext_register_operand" "Q")
1095 (match_operand:QI 1 "general_operand" "Qmn")))]
1096 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1097 "cmp{b}\t{%1, %h0|%h0, %1}"
1098 [(set_attr "type" "icmp")
1099 (set_attr "modrm" "1")
1100 (set_attr "mode" "QI")])
1102 (define_insn "*cmpqi_ext_3_insn_rex64"
1103 [(set (reg FLAGS_REG)
1107 (match_operand 0 "ext_register_operand" "Q")
1110 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1111 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1112 "cmp{b}\t{%1, %h0|%h0, %1}"
1113 [(set_attr "type" "icmp")
1114 (set_attr "modrm" "1")
1115 (set_attr "mode" "QI")])
1117 (define_insn "*cmpqi_ext_4"
1118 [(set (reg FLAGS_REG)
1122 (match_operand 0 "ext_register_operand" "Q")
1127 (match_operand 1 "ext_register_operand" "Q")
1129 (const_int 8)) 0)))]
1130 "ix86_match_ccmode (insn, CCmode)"
1131 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1132 [(set_attr "type" "icmp")
1133 (set_attr "mode" "QI")])
1135 ;; These implement float point compares.
1136 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1137 ;; which would allow mix and match FP modes on the compares. Which is what
1138 ;; the old patterns did, but with many more of them.
1140 (define_expand "cbranchxf4"
1141 [(set (reg:CC FLAGS_REG)
1142 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1143 (match_operand:XF 2 "nonmemory_operand")))
1144 (set (pc) (if_then_else
1145 (match_operator 0 "ix86_fp_comparison_operator"
1148 (label_ref (match_operand 3))
1152 ix86_expand_branch (GET_CODE (operands[0]),
1153 operands[1], operands[2], operands[3]);
1157 (define_expand "cstorexf4"
1158 [(set (reg:CC FLAGS_REG)
1159 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1160 (match_operand:XF 3 "nonmemory_operand")))
1161 (set (match_operand:QI 0 "register_operand")
1162 (match_operator 1 "ix86_fp_comparison_operator"
1167 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1168 operands[2], operands[3]);
1172 (define_expand "cbranch<mode>4"
1173 [(set (reg:CC FLAGS_REG)
1174 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1175 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1176 (set (pc) (if_then_else
1177 (match_operator 0 "ix86_fp_comparison_operator"
1180 (label_ref (match_operand 3))
1182 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1184 ix86_expand_branch (GET_CODE (operands[0]),
1185 operands[1], operands[2], operands[3]);
1189 (define_expand "cstore<mode>4"
1190 [(set (reg:CC FLAGS_REG)
1191 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1192 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1193 (set (match_operand:QI 0 "register_operand")
1194 (match_operator 1 "ix86_fp_comparison_operator"
1197 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1199 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1200 operands[2], operands[3]);
1204 (define_expand "cbranchcc4"
1205 [(set (pc) (if_then_else
1206 (match_operator 0 "comparison_operator"
1207 [(match_operand 1 "flags_reg_operand")
1208 (match_operand 2 "const0_operand")])
1209 (label_ref (match_operand 3))
1213 ix86_expand_branch (GET_CODE (operands[0]),
1214 operands[1], operands[2], operands[3]);
1218 (define_expand "cstorecc4"
1219 [(set (match_operand:QI 0 "register_operand")
1220 (match_operator 1 "comparison_operator"
1221 [(match_operand 2 "flags_reg_operand")
1222 (match_operand 3 "const0_operand")]))]
1225 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1226 operands[2], operands[3]);
1231 ;; FP compares, step 1:
1232 ;; Set the FP condition codes.
1234 ;; CCFPmode compare with exceptions
1235 ;; CCFPUmode compare with no exceptions
1237 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1238 ;; used to manage the reg stack popping would not be preserved.
1240 (define_insn "*cmpfp_0"
1241 [(set (match_operand:HI 0 "register_operand" "=a")
1244 (match_operand 1 "register_operand" "f")
1245 (match_operand 2 "const0_operand"))]
1247 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1248 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1249 "* return output_fp_compare (insn, operands, false, false);"
1250 [(set_attr "type" "multi")
1251 (set_attr "unit" "i387")
1253 (cond [(match_operand:SF 1)
1255 (match_operand:DF 1)
1258 (const_string "XF")))])
1260 (define_insn_and_split "*cmpfp_0_cc"
1261 [(set (reg:CCFP FLAGS_REG)
1263 (match_operand 1 "register_operand" "f")
1264 (match_operand 2 "const0_operand")))
1265 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1266 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1267 && TARGET_SAHF && !TARGET_CMOVE
1268 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1270 "&& reload_completed"
1273 [(compare:CCFP (match_dup 1)(match_dup 2))]
1275 (set (reg:CC FLAGS_REG)
1276 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1278 [(set_attr "type" "multi")
1279 (set_attr "unit" "i387")
1281 (cond [(match_operand:SF 1)
1283 (match_operand:DF 1)
1286 (const_string "XF")))])
1288 (define_insn "*cmpfp_xf"
1289 [(set (match_operand:HI 0 "register_operand" "=a")
1292 (match_operand:XF 1 "register_operand" "f")
1293 (match_operand:XF 2 "register_operand" "f"))]
1296 "* return output_fp_compare (insn, operands, false, false);"
1297 [(set_attr "type" "multi")
1298 (set_attr "unit" "i387")
1299 (set_attr "mode" "XF")])
1301 (define_insn_and_split "*cmpfp_xf_cc"
1302 [(set (reg:CCFP FLAGS_REG)
1304 (match_operand:XF 1 "register_operand" "f")
1305 (match_operand:XF 2 "register_operand" "f")))
1306 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1308 && TARGET_SAHF && !TARGET_CMOVE"
1310 "&& reload_completed"
1313 [(compare:CCFP (match_dup 1)(match_dup 2))]
1315 (set (reg:CC FLAGS_REG)
1316 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1318 [(set_attr "type" "multi")
1319 (set_attr "unit" "i387")
1320 (set_attr "mode" "XF")])
1322 (define_insn "*cmpfp_<mode>"
1323 [(set (match_operand:HI 0 "register_operand" "=a")
1326 (match_operand:MODEF 1 "register_operand" "f")
1327 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1330 "* return output_fp_compare (insn, operands, false, false);"
1331 [(set_attr "type" "multi")
1332 (set_attr "unit" "i387")
1333 (set_attr "mode" "<MODE>")])
1335 (define_insn_and_split "*cmpfp_<mode>_cc"
1336 [(set (reg:CCFP FLAGS_REG)
1338 (match_operand:MODEF 1 "register_operand" "f")
1339 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1340 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1342 && TARGET_SAHF && !TARGET_CMOVE"
1344 "&& reload_completed"
1347 [(compare:CCFP (match_dup 1)(match_dup 2))]
1349 (set (reg:CC FLAGS_REG)
1350 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1352 [(set_attr "type" "multi")
1353 (set_attr "unit" "i387")
1354 (set_attr "mode" "<MODE>")])
1356 (define_insn "*cmpfp_u"
1357 [(set (match_operand:HI 0 "register_operand" "=a")
1360 (match_operand 1 "register_operand" "f")
1361 (match_operand 2 "register_operand" "f"))]
1363 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1364 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1365 "* return output_fp_compare (insn, operands, false, true);"
1366 [(set_attr "type" "multi")
1367 (set_attr "unit" "i387")
1369 (cond [(match_operand:SF 1)
1371 (match_operand:DF 1)
1374 (const_string "XF")))])
1376 (define_insn_and_split "*cmpfp_u_cc"
1377 [(set (reg:CCFPU FLAGS_REG)
1379 (match_operand 1 "register_operand" "f")
1380 (match_operand 2 "register_operand" "f")))
1381 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1382 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1383 && TARGET_SAHF && !TARGET_CMOVE
1384 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1386 "&& reload_completed"
1389 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1391 (set (reg:CC FLAGS_REG)
1392 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1394 [(set_attr "type" "multi")
1395 (set_attr "unit" "i387")
1397 (cond [(match_operand:SF 1)
1399 (match_operand:DF 1)
1402 (const_string "XF")))])
1404 (define_insn "*cmpfp_<mode>"
1405 [(set (match_operand:HI 0 "register_operand" "=a")
1408 (match_operand 1 "register_operand" "f")
1409 (match_operator 3 "float_operator"
1410 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1412 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1413 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1414 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1415 "* return output_fp_compare (insn, operands, false, false);"
1416 [(set_attr "type" "multi")
1417 (set_attr "unit" "i387")
1418 (set_attr "fp_int_src" "true")
1419 (set_attr "mode" "<MODE>")])
1421 (define_insn_and_split "*cmpfp_<mode>_cc"
1422 [(set (reg:CCFP FLAGS_REG)
1424 (match_operand 1 "register_operand" "f")
1425 (match_operator 3 "float_operator"
1426 [(match_operand:SWI24 2 "memory_operand" "m")])))
1427 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1428 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1429 && TARGET_SAHF && !TARGET_CMOVE
1430 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1431 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1433 "&& reload_completed"
1438 (match_op_dup 3 [(match_dup 2)]))]
1440 (set (reg:CC FLAGS_REG)
1441 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1443 [(set_attr "type" "multi")
1444 (set_attr "unit" "i387")
1445 (set_attr "fp_int_src" "true")
1446 (set_attr "mode" "<MODE>")])
1448 ;; FP compares, step 2
1449 ;; Move the fpsw to ax.
1451 (define_insn "x86_fnstsw_1"
1452 [(set (match_operand:HI 0 "register_operand" "=a")
1453 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1456 [(set (attr "length")
1457 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1458 (set_attr "mode" "SI")
1459 (set_attr "unit" "i387")])
1461 ;; FP compares, step 3
1462 ;; Get ax into flags, general case.
1464 (define_insn "x86_sahf_1"
1465 [(set (reg:CC FLAGS_REG)
1466 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1470 #ifndef HAVE_AS_IX86_SAHF
1472 return ASM_BYTE "0x9e";
1477 [(set_attr "length" "1")
1478 (set_attr "athlon_decode" "vector")
1479 (set_attr "amdfam10_decode" "direct")
1480 (set_attr "bdver1_decode" "direct")
1481 (set_attr "mode" "SI")])
1483 ;; Pentium Pro can do steps 1 through 3 in one go.
1484 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1485 ;; (these i387 instructions set flags directly)
1486 (define_insn "*cmpfp_i_mixed"
1487 [(set (reg:CCFP FLAGS_REG)
1488 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1489 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1490 "TARGET_MIX_SSE_I387
1491 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1492 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1493 "* return output_fp_compare (insn, operands, true, false);"
1494 [(set_attr "type" "fcmp,ssecomi")
1495 (set_attr "prefix" "orig,maybe_vex")
1497 (if_then_else (match_operand:SF 1)
1499 (const_string "DF")))
1500 (set (attr "prefix_rep")
1501 (if_then_else (eq_attr "type" "ssecomi")
1503 (const_string "*")))
1504 (set (attr "prefix_data16")
1505 (cond [(eq_attr "type" "fcmp")
1507 (eq_attr "mode" "DF")
1510 (const_string "0")))
1511 (set_attr "athlon_decode" "vector")
1512 (set_attr "amdfam10_decode" "direct")
1513 (set_attr "bdver1_decode" "double")])
1515 (define_insn "*cmpfp_i_sse"
1516 [(set (reg:CCFP FLAGS_REG)
1517 (compare:CCFP (match_operand 0 "register_operand" "x")
1518 (match_operand 1 "nonimmediate_operand" "xm")))]
1520 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1521 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1522 "* return output_fp_compare (insn, operands, true, false);"
1523 [(set_attr "type" "ssecomi")
1524 (set_attr "prefix" "maybe_vex")
1526 (if_then_else (match_operand:SF 1)
1528 (const_string "DF")))
1529 (set_attr "prefix_rep" "0")
1530 (set (attr "prefix_data16")
1531 (if_then_else (eq_attr "mode" "DF")
1533 (const_string "0")))
1534 (set_attr "athlon_decode" "vector")
1535 (set_attr "amdfam10_decode" "direct")
1536 (set_attr "bdver1_decode" "double")])
1538 (define_insn "*cmpfp_i_i387"
1539 [(set (reg:CCFP FLAGS_REG)
1540 (compare:CCFP (match_operand 0 "register_operand" "f")
1541 (match_operand 1 "register_operand" "f")))]
1542 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1544 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1545 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1546 "* return output_fp_compare (insn, operands, true, false);"
1547 [(set_attr "type" "fcmp")
1549 (cond [(match_operand:SF 1)
1551 (match_operand:DF 1)
1554 (const_string "XF")))
1555 (set_attr "athlon_decode" "vector")
1556 (set_attr "amdfam10_decode" "direct")
1557 (set_attr "bdver1_decode" "double")])
1559 (define_insn "*cmpfp_iu_mixed"
1560 [(set (reg:CCFPU FLAGS_REG)
1561 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1562 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1563 "TARGET_MIX_SSE_I387
1564 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1565 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1566 "* return output_fp_compare (insn, operands, true, true);"
1567 [(set_attr "type" "fcmp,ssecomi")
1568 (set_attr "prefix" "orig,maybe_vex")
1570 (if_then_else (match_operand:SF 1)
1572 (const_string "DF")))
1573 (set (attr "prefix_rep")
1574 (if_then_else (eq_attr "type" "ssecomi")
1576 (const_string "*")))
1577 (set (attr "prefix_data16")
1578 (cond [(eq_attr "type" "fcmp")
1580 (eq_attr "mode" "DF")
1583 (const_string "0")))
1584 (set_attr "athlon_decode" "vector")
1585 (set_attr "amdfam10_decode" "direct")
1586 (set_attr "bdver1_decode" "double")])
1588 (define_insn "*cmpfp_iu_sse"
1589 [(set (reg:CCFPU FLAGS_REG)
1590 (compare:CCFPU (match_operand 0 "register_operand" "x")
1591 (match_operand 1 "nonimmediate_operand" "xm")))]
1593 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1594 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1595 "* return output_fp_compare (insn, operands, true, true);"
1596 [(set_attr "type" "ssecomi")
1597 (set_attr "prefix" "maybe_vex")
1599 (if_then_else (match_operand:SF 1)
1601 (const_string "DF")))
1602 (set_attr "prefix_rep" "0")
1603 (set (attr "prefix_data16")
1604 (if_then_else (eq_attr "mode" "DF")
1606 (const_string "0")))
1607 (set_attr "athlon_decode" "vector")
1608 (set_attr "amdfam10_decode" "direct")
1609 (set_attr "bdver1_decode" "double")])
1611 (define_insn "*cmpfp_iu_387"
1612 [(set (reg:CCFPU FLAGS_REG)
1613 (compare:CCFPU (match_operand 0 "register_operand" "f")
1614 (match_operand 1 "register_operand" "f")))]
1615 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1617 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1618 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1619 "* return output_fp_compare (insn, operands, true, true);"
1620 [(set_attr "type" "fcmp")
1622 (cond [(match_operand:SF 1)
1624 (match_operand:DF 1)
1627 (const_string "XF")))
1628 (set_attr "athlon_decode" "vector")
1629 (set_attr "amdfam10_decode" "direct")
1630 (set_attr "bdver1_decode" "direct")])
1632 ;; Push/pop instructions.
1634 (define_insn "*push<mode>2"
1635 [(set (match_operand:DWI 0 "push_operand" "=<")
1636 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1639 [(set_attr "type" "multi")
1640 (set_attr "mode" "<MODE>")])
1643 [(set (match_operand:TI 0 "push_operand")
1644 (match_operand:TI 1 "general_operand"))]
1645 "TARGET_64BIT && reload_completed
1646 && !SSE_REG_P (operands[1])"
1648 "ix86_split_long_move (operands); DONE;")
1650 (define_insn "*pushdi2_rex64"
1651 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1652 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1657 [(set_attr "type" "push,multi")
1658 (set_attr "mode" "DI")])
1660 ;; Convert impossible pushes of immediate to existing instructions.
1661 ;; First try to get scratch register and go through it. In case this
1662 ;; fails, push sign extended lower part first and then overwrite
1663 ;; upper part by 32bit move.
1665 [(match_scratch:DI 2 "r")
1666 (set (match_operand:DI 0 "push_operand")
1667 (match_operand:DI 1 "immediate_operand"))]
1668 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1669 && !x86_64_immediate_operand (operands[1], DImode)"
1670 [(set (match_dup 2) (match_dup 1))
1671 (set (match_dup 0) (match_dup 2))])
1673 ;; We need to define this as both peepholer and splitter for case
1674 ;; peephole2 pass is not run.
1675 ;; "&& 1" is needed to keep it from matching the previous pattern.
1677 [(set (match_operand:DI 0 "push_operand")
1678 (match_operand:DI 1 "immediate_operand"))]
1679 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1680 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1681 [(set (match_dup 0) (match_dup 1))
1682 (set (match_dup 2) (match_dup 3))]
1684 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1686 operands[1] = gen_lowpart (DImode, operands[2]);
1687 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1692 [(set (match_operand:DI 0 "push_operand")
1693 (match_operand:DI 1 "immediate_operand"))]
1694 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1695 ? epilogue_completed : reload_completed)
1696 && !symbolic_operand (operands[1], DImode)
1697 && !x86_64_immediate_operand (operands[1], DImode)"
1698 [(set (match_dup 0) (match_dup 1))
1699 (set (match_dup 2) (match_dup 3))]
1701 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1703 operands[1] = gen_lowpart (DImode, operands[2]);
1704 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1709 [(set (match_operand:DI 0 "push_operand")
1710 (match_operand:DI 1 "general_operand"))]
1711 "!TARGET_64BIT && reload_completed
1712 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1714 "ix86_split_long_move (operands); DONE;")
1716 (define_insn "*pushsi2"
1717 [(set (match_operand:SI 0 "push_operand" "=<")
1718 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1721 [(set_attr "type" "push")
1722 (set_attr "mode" "SI")])
1724 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1725 ;; "push a byte/word". But actually we use pushl, which has the effect
1726 ;; of rounding the amount pushed up to a word.
1728 ;; For TARGET_64BIT we always round up to 8 bytes.
1729 (define_insn "*push<mode>2_rex64"
1730 [(set (match_operand:SWI124 0 "push_operand" "=X")
1731 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1734 [(set_attr "type" "push")
1735 (set_attr "mode" "DI")])
1737 (define_insn "*push<mode>2"
1738 [(set (match_operand:SWI12 0 "push_operand" "=X")
1739 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1742 [(set_attr "type" "push")
1743 (set_attr "mode" "SI")])
1745 (define_insn "*push<mode>2_prologue"
1746 [(set (match_operand:W 0 "push_operand" "=<")
1747 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1748 (clobber (mem:BLK (scratch)))]
1750 "push{<imodesuffix>}\t%1"
1751 [(set_attr "type" "push")
1752 (set_attr "mode" "<MODE>")])
1754 (define_insn "*pop<mode>1"
1755 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1756 (match_operand:W 1 "pop_operand" ">"))]
1758 "pop{<imodesuffix>}\t%0"
1759 [(set_attr "type" "pop")
1760 (set_attr "mode" "<MODE>")])
1762 (define_insn "*pop<mode>1_epilogue"
1763 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1764 (match_operand:W 1 "pop_operand" ">"))
1765 (clobber (mem:BLK (scratch)))]
1767 "pop{<imodesuffix>}\t%0"
1768 [(set_attr "type" "pop")
1769 (set_attr "mode" "<MODE>")])
1771 ;; Move instructions.
1773 (define_expand "movoi"
1774 [(set (match_operand:OI 0 "nonimmediate_operand")
1775 (match_operand:OI 1 "general_operand"))]
1777 "ix86_expand_move (OImode, operands); DONE;")
1779 (define_expand "movti"
1780 [(set (match_operand:TI 0 "nonimmediate_operand")
1781 (match_operand:TI 1 "nonimmediate_operand"))]
1782 "TARGET_64BIT || TARGET_SSE"
1785 ix86_expand_move (TImode, operands);
1786 else if (push_operand (operands[0], TImode))
1787 ix86_expand_push (TImode, operands[1]);
1789 ix86_expand_vector_move (TImode, operands);
1793 ;; This expands to what emit_move_complex would generate if we didn't
1794 ;; have a movti pattern. Having this avoids problems with reload on
1795 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1796 ;; to have around all the time.
1797 (define_expand "movcdi"
1798 [(set (match_operand:CDI 0 "nonimmediate_operand")
1799 (match_operand:CDI 1 "general_operand"))]
1802 if (push_operand (operands[0], CDImode))
1803 emit_move_complex_push (CDImode, operands[0], operands[1]);
1805 emit_move_complex_parts (operands[0], operands[1]);
1809 (define_expand "mov<mode>"
1810 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1811 (match_operand:SWI1248x 1 "general_operand"))]
1813 "ix86_expand_move (<MODE>mode, operands); DONE;")
1815 (define_insn "*mov<mode>_xor"
1816 [(set (match_operand:SWI48 0 "register_operand" "=r")
1817 (match_operand:SWI48 1 "const0_operand"))
1818 (clobber (reg:CC FLAGS_REG))]
1821 [(set_attr "type" "alu1")
1822 (set_attr "mode" "SI")
1823 (set_attr "length_immediate" "0")])
1825 (define_insn "*mov<mode>_or"
1826 [(set (match_operand:SWI48 0 "register_operand" "=r")
1827 (match_operand:SWI48 1 "const_int_operand"))
1828 (clobber (reg:CC FLAGS_REG))]
1830 && operands[1] == constm1_rtx"
1831 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1832 [(set_attr "type" "alu1")
1833 (set_attr "mode" "<MODE>")
1834 (set_attr "length_immediate" "1")])
1836 (define_insn "*movoi_internal_avx"
1837 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1838 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1839 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1841 switch (which_alternative)
1844 return standard_sse_constant_opcode (insn, operands[1]);
1847 if (misaligned_operand (operands[0], OImode)
1848 || misaligned_operand (operands[1], OImode))
1850 if (get_attr_mode (insn) == MODE_V8SF)
1851 return "vmovups\t{%1, %0|%0, %1}";
1853 return "vmovdqu\t{%1, %0|%0, %1}";
1857 if (get_attr_mode (insn) == MODE_V8SF)
1858 return "vmovaps\t{%1, %0|%0, %1}";
1860 return "vmovdqa\t{%1, %0|%0, %1}";
1866 [(set_attr "type" "sselog1,ssemov,ssemov")
1867 (set_attr "prefix" "vex")
1869 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1870 (const_string "V8SF")
1871 (and (eq_attr "alternative" "2")
1872 (match_test "TARGET_SSE_TYPELESS_STORES"))
1873 (const_string "V8SF")
1875 (const_string "OI")))])
1877 (define_insn "*movti_internal_rex64"
1878 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1879 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1880 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1882 switch (which_alternative)
1888 return standard_sse_constant_opcode (insn, operands[1]);
1891 /* TDmode values are passed as TImode on the stack. Moving them
1892 to stack may result in unaligned memory access. */
1893 if (misaligned_operand (operands[0], TImode)
1894 || misaligned_operand (operands[1], TImode))
1896 if (get_attr_mode (insn) == MODE_V4SF)
1897 return "%vmovups\t{%1, %0|%0, %1}";
1899 return "%vmovdqu\t{%1, %0|%0, %1}";
1903 if (get_attr_mode (insn) == MODE_V4SF)
1904 return "%vmovaps\t{%1, %0|%0, %1}";
1906 return "%vmovdqa\t{%1, %0|%0, %1}";
1912 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1913 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1915 (cond [(eq_attr "alternative" "0,1")
1917 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1918 (const_string "V4SF")
1919 (and (eq_attr "alternative" "4")
1920 (match_test "TARGET_SSE_TYPELESS_STORES"))
1921 (const_string "V4SF")
1922 (match_test "TARGET_AVX")
1924 (match_test "optimize_function_for_size_p (cfun)")
1925 (const_string "V4SF")
1927 (const_string "TI")))])
1930 [(set (match_operand:TI 0 "nonimmediate_operand")
1931 (match_operand:TI 1 "general_operand"))]
1933 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1935 "ix86_split_long_move (operands); DONE;")
1937 (define_insn "*movti_internal_sse"
1938 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x ,m")
1939 (match_operand:TI 1 "vector_move_operand" "C ,xm,x"))]
1940 "TARGET_SSE && !TARGET_64BIT
1941 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1943 switch (which_alternative)
1946 return standard_sse_constant_opcode (insn, operands[1]);
1949 /* TDmode values are passed as TImode on the stack. Moving them
1950 to stack may result in unaligned memory access. */
1951 if (misaligned_operand (operands[0], TImode)
1952 || misaligned_operand (operands[1], TImode))
1954 if (get_attr_mode (insn) == MODE_V4SF)
1955 return "%vmovups\t{%1, %0|%0, %1}";
1957 return "%vmovdqu\t{%1, %0|%0, %1}";
1961 if (get_attr_mode (insn) == MODE_V4SF)
1962 return "%vmovaps\t{%1, %0|%0, %1}";
1964 return "%vmovdqa\t{%1, %0|%0, %1}";
1970 [(set_attr "type" "sselog1,ssemov,ssemov")
1971 (set_attr "prefix" "maybe_vex")
1973 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1974 (const_string "V4SF")
1975 (and (eq_attr "alternative" "2")
1976 (match_test "TARGET_SSE_TYPELESS_STORES"))
1977 (const_string "V4SF")
1978 (match_test "TARGET_AVX")
1980 (ior (not (match_test "TARGET_SSE2"))
1981 (match_test "optimize_function_for_size_p (cfun)"))
1982 (const_string "V4SF")
1984 (const_string "TI")))])
1986 (define_insn "*movdi_internal_rex64"
1987 [(set (match_operand:DI 0 "nonimmediate_operand"
1988 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1989 (match_operand:DI 1 "general_operand"
1990 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1991 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1993 switch (get_attr_type (insn))
1996 if (SSE_REG_P (operands[0]))
1997 return "movq2dq\t{%1, %0|%0, %1}";
1999 return "movdq2q\t{%1, %0|%0, %1}";
2002 if (get_attr_mode (insn) == MODE_V4SF)
2003 return "%vmovaps\t{%1, %0|%0, %1}";
2004 else if (get_attr_mode (insn) == MODE_TI)
2005 return "%vmovdqa\t{%1, %0|%0, %1}";
2007 /* Handle broken assemblers that require movd instead of movq. */
2008 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2009 return "%vmovd\t{%1, %0|%0, %1}";
2011 return "%vmovq\t{%1, %0|%0, %1}";
2014 /* Handle broken assemblers that require movd instead of movq. */
2015 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2016 return "movd\t{%1, %0|%0, %1}";
2018 return "movq\t{%1, %0|%0, %1}";
2021 return standard_sse_constant_opcode (insn, operands[1]);
2024 return "pxor\t%0, %0";
2030 return "lea{q}\t{%E1, %0|%0, %E1}";
2033 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2034 if (get_attr_mode (insn) == MODE_SI)
2035 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2036 else if (which_alternative == 2)
2037 return "movabs{q}\t{%1, %0|%0, %1}";
2038 else if (ix86_use_lea_for_mov (insn, operands))
2039 return "lea{q}\t{%E1, %0|%0, %E1}";
2041 return "mov{q}\t{%1, %0|%0, %1}";
2045 (cond [(eq_attr "alternative" "4")
2046 (const_string "multi")
2047 (eq_attr "alternative" "5")
2048 (const_string "mmx")
2049 (eq_attr "alternative" "6,7,8,9")
2050 (const_string "mmxmov")
2051 (eq_attr "alternative" "10")
2052 (const_string "sselog1")
2053 (eq_attr "alternative" "11,12,13,14,15")
2054 (const_string "ssemov")
2055 (eq_attr "alternative" "16,17")
2056 (const_string "ssecvt")
2057 (match_operand 1 "pic_32bit_operand")
2058 (const_string "lea")
2060 (const_string "imov")))
2063 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2065 (const_string "*")))
2066 (set (attr "length_immediate")
2068 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2070 (const_string "*")))
2071 (set (attr "prefix_rex")
2072 (if_then_else (eq_attr "alternative" "8,9")
2074 (const_string "*")))
2075 (set (attr "prefix_data16")
2076 (if_then_else (eq_attr "alternative" "11")
2078 (const_string "*")))
2079 (set (attr "prefix")
2080 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2081 (const_string "maybe_vex")
2082 (const_string "orig")))
2084 (cond [(eq_attr "alternative" "0,4")
2086 (eq_attr "alternative" "10,12")
2087 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2088 (const_string "V4SF")
2089 (match_test "TARGET_AVX")
2091 (match_test "optimize_function_for_size_p (cfun)")
2092 (const_string "V4SF")
2094 (const_string "TI"))
2096 (const_string "DI")))])
2098 ;; Reload patterns to support multi-word load/store
2099 ;; with non-offsetable address.
2100 (define_expand "reload_noff_store"
2101 [(parallel [(match_operand 0 "memory_operand" "=m")
2102 (match_operand 1 "register_operand" "r")
2103 (match_operand:DI 2 "register_operand" "=&r")])]
2106 rtx mem = operands[0];
2107 rtx addr = XEXP (mem, 0);
2109 emit_move_insn (operands[2], addr);
2110 mem = replace_equiv_address_nv (mem, operands[2]);
2112 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2116 (define_expand "reload_noff_load"
2117 [(parallel [(match_operand 0 "register_operand" "=r")
2118 (match_operand 1 "memory_operand" "m")
2119 (match_operand:DI 2 "register_operand" "=r")])]
2122 rtx mem = operands[1];
2123 rtx addr = XEXP (mem, 0);
2125 emit_move_insn (operands[2], addr);
2126 mem = replace_equiv_address_nv (mem, operands[2]);
2128 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2132 ;; Convert impossible stores of immediate to existing instructions.
2133 ;; First try to get scratch register and go through it. In case this
2134 ;; fails, move by 32bit parts.
2136 [(match_scratch:DI 2 "r")
2137 (set (match_operand:DI 0 "memory_operand")
2138 (match_operand:DI 1 "immediate_operand"))]
2139 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2140 && !x86_64_immediate_operand (operands[1], DImode)"
2141 [(set (match_dup 2) (match_dup 1))
2142 (set (match_dup 0) (match_dup 2))])
2144 ;; We need to define this as both peepholer and splitter for case
2145 ;; peephole2 pass is not run.
2146 ;; "&& 1" is needed to keep it from matching the previous pattern.
2148 [(set (match_operand:DI 0 "memory_operand")
2149 (match_operand:DI 1 "immediate_operand"))]
2150 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2151 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2152 [(set (match_dup 2) (match_dup 3))
2153 (set (match_dup 4) (match_dup 5))]
2154 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2157 [(set (match_operand:DI 0 "memory_operand")
2158 (match_operand:DI 1 "immediate_operand"))]
2159 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2160 ? epilogue_completed : reload_completed)
2161 && !symbolic_operand (operands[1], DImode)
2162 && !x86_64_immediate_operand (operands[1], DImode)"
2163 [(set (match_dup 2) (match_dup 3))
2164 (set (match_dup 4) (match_dup 5))]
2165 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2167 (define_insn "*movdi_internal"
2168 [(set (match_operand:DI 0 "nonimmediate_operand"
2169 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2170 (match_operand:DI 1 "general_operand"
2171 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2172 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2174 switch (get_attr_type (insn))
2177 if (SSE_REG_P (operands[0]))
2178 return "movq2dq\t{%1, %0|%0, %1}";
2180 return "movdq2q\t{%1, %0|%0, %1}";
2183 switch (get_attr_mode (insn))
2186 return "%vmovdqa\t{%1, %0|%0, %1}";
2188 return "%vmovq\t{%1, %0|%0, %1}";
2190 return "%vmovaps\t{%1, %0|%0, %1}";
2192 return "movlps\t{%1, %0|%0, %1}";
2198 return "movq\t{%1, %0|%0, %1}";
2201 return standard_sse_constant_opcode (insn, operands[1]);
2204 return "pxor\t%0, %0";
2214 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2215 (const_string "sse2")
2216 (eq_attr "alternative" "9,10,11,12")
2217 (const_string "noavx")
2219 (const_string "*")))
2221 (cond [(eq_attr "alternative" "0,1")
2222 (const_string "multi")
2223 (eq_attr "alternative" "2")
2224 (const_string "mmx")
2225 (eq_attr "alternative" "3,4")
2226 (const_string "mmxmov")
2227 (eq_attr "alternative" "5,9")
2228 (const_string "sselog1")
2229 (eq_attr "alternative" "13,14")
2230 (const_string "ssecvt")
2232 (const_string "ssemov")))
2233 (set (attr "prefix")
2234 (if_then_else (eq_attr "alternative" "5,6,7,8")
2235 (const_string "maybe_vex")
2236 (const_string "orig")))
2238 (cond [(eq_attr "alternative" "9,11")
2239 (const_string "V4SF")
2240 (eq_attr "alternative" "10,12")
2241 (const_string "V2SF")
2242 (eq_attr "alternative" "5,7")
2243 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2244 (const_string "V4SF")
2245 (match_test "TARGET_AVX")
2247 (match_test "optimize_function_for_size_p (cfun)")
2248 (const_string "V4SF")
2250 (const_string "TI"))
2252 (const_string "DI")))])
2255 [(set (match_operand:DI 0 "nonimmediate_operand")
2256 (match_operand:DI 1 "general_operand"))]
2257 "!TARGET_64BIT && reload_completed
2258 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2259 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2261 "ix86_split_long_move (operands); DONE;")
2263 (define_insn "*movsi_internal"
2264 [(set (match_operand:SI 0 "nonimmediate_operand"
2265 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2266 (match_operand:SI 1 "general_operand"
2267 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2268 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2270 switch (get_attr_type (insn))
2273 return standard_sse_constant_opcode (insn, operands[1]);
2276 switch (get_attr_mode (insn))
2279 return "%vmovdqa\t{%1, %0|%0, %1}";
2281 return "%vmovaps\t{%1, %0|%0, %1}";
2283 return "%vmovd\t{%1, %0|%0, %1}";
2285 return "%vmovss\t{%1, %0|%0, %1}";
2291 return "pxor\t%0, %0";
2294 if (get_attr_mode (insn) == MODE_DI)
2295 return "movq\t{%1, %0|%0, %1}";
2296 return "movd\t{%1, %0|%0, %1}";
2299 return "lea{l}\t{%E1, %0|%0, %E1}";
2302 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2303 if (ix86_use_lea_for_mov (insn, operands))
2304 return "lea{l}\t{%E1, %0|%0, %E1}";
2306 return "mov{l}\t{%1, %0|%0, %1}";
2310 (cond [(eq_attr "alternative" "2")
2311 (const_string "mmx")
2312 (eq_attr "alternative" "3,4,5")
2313 (const_string "mmxmov")
2314 (eq_attr "alternative" "6")
2315 (const_string "sselog1")
2316 (eq_attr "alternative" "7,8,9,10,11")
2317 (const_string "ssemov")
2318 (match_operand 1 "pic_32bit_operand")
2319 (const_string "lea")
2321 (const_string "imov")))
2322 (set (attr "prefix")
2323 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2324 (const_string "orig")
2325 (const_string "maybe_vex")))
2326 (set (attr "prefix_data16")
2327 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2329 (const_string "*")))
2331 (cond [(eq_attr "alternative" "2,3")
2333 (eq_attr "alternative" "6,7")
2334 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2335 (const_string "V4SF")
2336 (match_test "TARGET_AVX")
2338 (ior (not (match_test "TARGET_SSE2"))
2339 (match_test "optimize_function_for_size_p (cfun)"))
2340 (const_string "V4SF")
2342 (const_string "TI"))
2343 (and (eq_attr "alternative" "8,9,10,11")
2344 (not (match_test "TARGET_SSE2")))
2347 (const_string "SI")))])
2349 (define_insn "*movhi_internal"
2350 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2351 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2352 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2354 switch (get_attr_type (insn))
2357 /* movzwl is faster than movw on p2 due to partial word stalls,
2358 though not as fast as an aligned movl. */
2359 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2361 if (get_attr_mode (insn) == MODE_SI)
2362 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2364 return "mov{w}\t{%1, %0|%0, %1}";
2368 (cond [(match_test "optimize_function_for_size_p (cfun)")
2369 (const_string "imov")
2370 (and (eq_attr "alternative" "0")
2371 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2372 (not (match_test "TARGET_HIMODE_MATH"))))
2373 (const_string "imov")
2374 (and (eq_attr "alternative" "1,2")
2375 (match_operand:HI 1 "aligned_operand"))
2376 (const_string "imov")
2377 (and (match_test "TARGET_MOVX")
2378 (eq_attr "alternative" "0,2"))
2379 (const_string "imovx")
2381 (const_string "imov")))
2383 (cond [(eq_attr "type" "imovx")
2385 (and (eq_attr "alternative" "1,2")
2386 (match_operand:HI 1 "aligned_operand"))
2388 (and (eq_attr "alternative" "0")
2389 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2390 (not (match_test "TARGET_HIMODE_MATH"))))
2393 (const_string "HI")))])
2395 ;; Situation is quite tricky about when to choose full sized (SImode) move
2396 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2397 ;; partial register dependency machines (such as AMD Athlon), where QImode
2398 ;; moves issue extra dependency and for partial register stalls machines
2399 ;; that don't use QImode patterns (and QImode move cause stall on the next
2402 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2403 ;; register stall machines with, where we use QImode instructions, since
2404 ;; partial register stall can be caused there. Then we use movzx.
2405 (define_insn "*movqi_internal"
2406 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2407 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2408 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2410 switch (get_attr_type (insn))
2413 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2414 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2416 if (get_attr_mode (insn) == MODE_SI)
2417 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2419 return "mov{b}\t{%1, %0|%0, %1}";
2423 (cond [(and (eq_attr "alternative" "5")
2424 (not (match_operand:QI 1 "aligned_operand")))
2425 (const_string "imovx")
2426 (match_test "optimize_function_for_size_p (cfun)")
2427 (const_string "imov")
2428 (and (eq_attr "alternative" "3")
2429 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2430 (not (match_test "TARGET_QIMODE_MATH"))))
2431 (const_string "imov")
2432 (eq_attr "alternative" "3,5")
2433 (const_string "imovx")
2434 (and (match_test "TARGET_MOVX")
2435 (eq_attr "alternative" "2"))
2436 (const_string "imovx")
2438 (const_string "imov")))
2440 (cond [(eq_attr "alternative" "3,4,5")
2442 (eq_attr "alternative" "6")
2444 (eq_attr "type" "imovx")
2446 (and (eq_attr "type" "imov")
2447 (and (eq_attr "alternative" "0,1")
2448 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2449 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2450 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2452 ;; Avoid partial register stalls when not using QImode arithmetic
2453 (and (eq_attr "type" "imov")
2454 (and (eq_attr "alternative" "0,1")
2455 (and (match_test "TARGET_PARTIAL_REG_STALL")
2456 (not (match_test "TARGET_QIMODE_MATH")))))
2459 (const_string "QI")))])
2461 ;; Stores and loads of ax to arbitrary constant address.
2462 ;; We fake an second form of instruction to force reload to load address
2463 ;; into register when rax is not available
2464 (define_insn "*movabs<mode>_1"
2465 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2466 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2467 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2469 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2470 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2471 [(set_attr "type" "imov")
2472 (set_attr "modrm" "0,*")
2473 (set_attr "length_address" "8,0")
2474 (set_attr "length_immediate" "0,*")
2475 (set_attr "memory" "store")
2476 (set_attr "mode" "<MODE>")])
2478 (define_insn "*movabs<mode>_2"
2479 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2480 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2481 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2483 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2484 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2485 [(set_attr "type" "imov")
2486 (set_attr "modrm" "0,*")
2487 (set_attr "length_address" "8,0")
2488 (set_attr "length_immediate" "0")
2489 (set_attr "memory" "load")
2490 (set_attr "mode" "<MODE>")])
2492 (define_insn "swap<mode>"
2493 [(set (match_operand:SWI48 0 "register_operand" "+r")
2494 (match_operand:SWI48 1 "register_operand" "+r"))
2498 "xchg{<imodesuffix>}\t%1, %0"
2499 [(set_attr "type" "imov")
2500 (set_attr "mode" "<MODE>")
2501 (set_attr "pent_pair" "np")
2502 (set_attr "athlon_decode" "vector")
2503 (set_attr "amdfam10_decode" "double")
2504 (set_attr "bdver1_decode" "double")])
2506 (define_insn "*swap<mode>_1"
2507 [(set (match_operand:SWI12 0 "register_operand" "+r")
2508 (match_operand:SWI12 1 "register_operand" "+r"))
2511 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2513 [(set_attr "type" "imov")
2514 (set_attr "mode" "SI")
2515 (set_attr "pent_pair" "np")
2516 (set_attr "athlon_decode" "vector")
2517 (set_attr "amdfam10_decode" "double")
2518 (set_attr "bdver1_decode" "double")])
2520 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2521 ;; is disabled for AMDFAM10
2522 (define_insn "*swap<mode>_2"
2523 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2524 (match_operand:SWI12 1 "register_operand" "+<r>"))
2527 "TARGET_PARTIAL_REG_STALL"
2528 "xchg{<imodesuffix>}\t%1, %0"
2529 [(set_attr "type" "imov")
2530 (set_attr "mode" "<MODE>")
2531 (set_attr "pent_pair" "np")
2532 (set_attr "athlon_decode" "vector")])
2534 (define_expand "movstrict<mode>"
2535 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2536 (match_operand:SWI12 1 "general_operand"))]
2539 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2541 if (GET_CODE (operands[0]) == SUBREG
2542 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2544 /* Don't generate memory->memory moves, go through a register */
2545 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2546 operands[1] = force_reg (<MODE>mode, operands[1]);
2549 (define_insn "*movstrict<mode>_1"
2550 [(set (strict_low_part
2551 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2552 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2553 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2554 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2555 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2556 [(set_attr "type" "imov")
2557 (set_attr "mode" "<MODE>")])
2559 (define_insn "*movstrict<mode>_xor"
2560 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2561 (match_operand:SWI12 1 "const0_operand"))
2562 (clobber (reg:CC FLAGS_REG))]
2564 "xor{<imodesuffix>}\t%0, %0"
2565 [(set_attr "type" "alu1")
2566 (set_attr "mode" "<MODE>")
2567 (set_attr "length_immediate" "0")])
2569 (define_insn "*mov<mode>_extv_1"
2570 [(set (match_operand:SWI24 0 "register_operand" "=R")
2571 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2575 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2576 [(set_attr "type" "imovx")
2577 (set_attr "mode" "SI")])
2579 (define_insn "*movqi_extv_1_rex64"
2580 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2581 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2586 switch (get_attr_type (insn))
2589 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2591 return "mov{b}\t{%h1, %0|%0, %h1}";
2595 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2596 (match_test "TARGET_MOVX"))
2597 (const_string "imovx")
2598 (const_string "imov")))
2600 (if_then_else (eq_attr "type" "imovx")
2602 (const_string "QI")))])
2604 (define_insn "*movqi_extv_1"
2605 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2606 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2611 switch (get_attr_type (insn))
2614 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2616 return "mov{b}\t{%h1, %0|%0, %h1}";
2620 (if_then_else (and (match_operand:QI 0 "register_operand")
2621 (ior (not (match_operand:QI 0 "QIreg_operand"))
2622 (match_test "TARGET_MOVX")))
2623 (const_string "imovx")
2624 (const_string "imov")))
2626 (if_then_else (eq_attr "type" "imovx")
2628 (const_string "QI")))])
2630 (define_insn "*mov<mode>_extzv_1"
2631 [(set (match_operand:SWI48 0 "register_operand" "=R")
2632 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2636 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2637 [(set_attr "type" "imovx")
2638 (set_attr "mode" "SI")])
2640 (define_insn "*movqi_extzv_2_rex64"
2641 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2643 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2648 switch (get_attr_type (insn))
2651 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2653 return "mov{b}\t{%h1, %0|%0, %h1}";
2657 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2658 (match_test "TARGET_MOVX"))
2659 (const_string "imovx")
2660 (const_string "imov")))
2662 (if_then_else (eq_attr "type" "imovx")
2664 (const_string "QI")))])
2666 (define_insn "*movqi_extzv_2"
2667 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2669 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2674 switch (get_attr_type (insn))
2677 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2679 return "mov{b}\t{%h1, %0|%0, %h1}";
2683 (if_then_else (and (match_operand:QI 0 "register_operand")
2684 (ior (not (match_operand:QI 0 "QIreg_operand"))
2685 (match_test "TARGET_MOVX")))
2686 (const_string "imovx")
2687 (const_string "imov")))
2689 (if_then_else (eq_attr "type" "imovx")
2691 (const_string "QI")))])
2693 (define_expand "mov<mode>_insv_1"
2694 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2697 (match_operand:SWI48 1 "nonmemory_operand"))])
2699 (define_insn "*mov<mode>_insv_1_rex64"
2700 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2703 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2706 if (CONST_INT_P (operands[1]))
2707 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2708 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2710 [(set_attr "type" "imov")
2711 (set_attr "mode" "QI")])
2713 (define_insn "*movsi_insv_1"
2714 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2717 (match_operand:SI 1 "general_operand" "Qmn"))]
2720 if (CONST_INT_P (operands[1]))
2721 operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2722 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2724 [(set_attr "type" "imov")
2725 (set_attr "mode" "QI")])
2727 (define_insn "*movqi_insv_2"
2728 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2731 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2734 "mov{b}\t{%h1, %h0|%h0, %h1}"
2735 [(set_attr "type" "imov")
2736 (set_attr "mode" "QI")])
2738 ;; Floating point push instructions.
2740 (define_insn "*pushtf"
2741 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2742 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2745 /* This insn should be already split before reg-stack. */
2748 [(set_attr "type" "multi")
2749 (set_attr "unit" "sse,*,*")
2750 (set_attr "mode" "TF,SI,SI")])
2752 ;; %%% Kill this when call knows how to work this out.
2754 [(set (match_operand:TF 0 "push_operand")
2755 (match_operand:TF 1 "sse_reg_operand"))]
2756 "TARGET_SSE && reload_completed"
2757 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2758 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2760 (define_insn "*pushxf"
2761 [(set (match_operand:XF 0 "push_operand" "=<,<")
2762 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2763 "optimize_function_for_speed_p (cfun)"
2765 /* This insn should be already split before reg-stack. */
2768 [(set_attr "type" "multi")
2769 (set_attr "unit" "i387,*")
2770 (set_attr "mode" "XF,SI")])
2772 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2773 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2774 ;; Pushing using integer instructions is longer except for constants
2775 ;; and direct memory references (assuming that any given constant is pushed
2776 ;; only once, but this ought to be handled elsewhere).
2778 (define_insn "*pushxf_nointeger"
2779 [(set (match_operand:XF 0 "push_operand" "=<,<")
2780 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2781 "optimize_function_for_size_p (cfun)"
2783 /* This insn should be already split before reg-stack. */
2786 [(set_attr "type" "multi")
2787 (set_attr "unit" "i387,*")
2788 (set_attr "mode" "XF,SI")])
2790 ;; %%% Kill this when call knows how to work this out.
2792 [(set (match_operand:XF 0 "push_operand")
2793 (match_operand:XF 1 "fp_register_operand"))]
2795 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2796 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2797 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2799 (define_insn "*pushdf_rex64"
2800 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2801 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2804 /* This insn should be already split before reg-stack. */
2807 [(set_attr "type" "multi")
2808 (set_attr "unit" "i387,*,*")
2809 (set_attr "mode" "DF,DI,DF")])
2811 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2812 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2813 ;; On the average, pushdf using integers can be still shorter.
2815 (define_insn "*pushdf"
2816 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2817 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2820 /* This insn should be already split before reg-stack. */
2823 [(set_attr "isa" "*,*,sse2")
2824 (set_attr "type" "multi")
2825 (set_attr "unit" "i387,*,*")
2826 (set_attr "mode" "DF,DI,DF")])
2828 ;; %%% Kill this when call knows how to work this out.
2830 [(set (match_operand:DF 0 "push_operand")
2831 (match_operand:DF 1 "any_fp_register_operand"))]
2833 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2834 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2836 (define_insn "*pushsf_rex64"
2837 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2838 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2841 /* Anything else should be already split before reg-stack. */
2842 gcc_assert (which_alternative == 1);
2843 return "push{q}\t%q1";
2845 [(set_attr "type" "multi,push,multi")
2846 (set_attr "unit" "i387,*,*")
2847 (set_attr "mode" "SF,DI,SF")])
2849 (define_insn "*pushsf"
2850 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2851 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2854 /* Anything else should be already split before reg-stack. */
2855 gcc_assert (which_alternative == 1);
2856 return "push{l}\t%1";
2858 [(set_attr "type" "multi,push,multi")
2859 (set_attr "unit" "i387,*,*")
2860 (set_attr "mode" "SF,SI,SF")])
2862 ;; %%% Kill this when call knows how to work this out.
2864 [(set (match_operand:SF 0 "push_operand")
2865 (match_operand:SF 1 "any_fp_register_operand"))]
2867 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2868 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2869 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2872 [(set (match_operand:SF 0 "push_operand")
2873 (match_operand:SF 1 "memory_operand"))]
2875 && (operands[2] = find_constant_src (insn))"
2876 [(set (match_dup 0) (match_dup 2))])
2879 [(set (match_operand 0 "push_operand")
2880 (match_operand 1 "general_operand"))]
2882 && (GET_MODE (operands[0]) == TFmode
2883 || GET_MODE (operands[0]) == XFmode
2884 || GET_MODE (operands[0]) == DFmode)
2885 && !ANY_FP_REG_P (operands[1])"
2887 "ix86_split_long_move (operands); DONE;")
2889 ;; Floating point move instructions.
2891 (define_expand "movtf"
2892 [(set (match_operand:TF 0 "nonimmediate_operand")
2893 (match_operand:TF 1 "nonimmediate_operand"))]
2896 ix86_expand_move (TFmode, operands);
2900 (define_expand "mov<mode>"
2901 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2902 (match_operand:X87MODEF 1 "general_operand"))]
2904 "ix86_expand_move (<MODE>mode, operands); DONE;")
2906 (define_insn "*movtf_internal"
2907 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2908 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,F*r"))]
2910 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2911 && (!can_create_pseudo_p ()
2912 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2913 || GET_CODE (operands[1]) != CONST_DOUBLE
2914 || (optimize_function_for_size_p (cfun)
2915 && standard_sse_constant_p (operands[1])
2916 && !memory_operand (operands[0], TFmode))
2917 || (!TARGET_MEMORY_MISMATCH_STALL
2918 && memory_operand (operands[0], TFmode)))"
2920 switch (which_alternative)
2923 return standard_sse_constant_opcode (insn, operands[1]);
2926 /* Handle misaligned load/store since we
2927 don't have movmisaligntf pattern. */
2928 if (misaligned_operand (operands[0], TFmode)
2929 || misaligned_operand (operands[1], TFmode))
2931 if (get_attr_mode (insn) == MODE_V4SF)
2932 return "%vmovups\t{%1, %0|%0, %1}";
2934 return "%vmovdqu\t{%1, %0|%0, %1}";
2938 if (get_attr_mode (insn) == MODE_V4SF)
2939 return "%vmovaps\t{%1, %0|%0, %1}";
2941 return "%vmovdqa\t{%1, %0|%0, %1}";
2952 [(set_attr "type" "sselog1,ssemov,ssemov,*,*")
2953 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2955 (cond [(eq_attr "alternative" "3,4")
2957 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2958 (const_string "V4SF")
2959 (and (eq_attr "alternative" "2")
2960 (match_test "TARGET_SSE_TYPELESS_STORES"))
2961 (const_string "V4SF")
2962 (match_test "TARGET_AVX")
2964 (ior (not (match_test "TARGET_SSE2"))
2965 (match_test "optimize_function_for_size_p (cfun)"))
2966 (const_string "V4SF")
2968 (const_string "TI")))])
2970 ;; Possible store forwarding (partial memory) stall in alternative 4.
2971 (define_insn "*movxf_internal"
2972 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2973 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2974 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2975 && (!can_create_pseudo_p ()
2976 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2977 || GET_CODE (operands[1]) != CONST_DOUBLE
2978 || (optimize_function_for_size_p (cfun)
2979 && standard_80387_constant_p (operands[1]) > 0
2980 && !memory_operand (operands[0], XFmode))
2981 || (!TARGET_MEMORY_MISMATCH_STALL
2982 && memory_operand (operands[0], XFmode)))"
2984 switch (which_alternative)
2988 return output_387_reg_move (insn, operands);
2991 return standard_80387_constant_opcode (operands[1]);
3001 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3002 (set_attr "mode" "XF,XF,XF,SI,SI")])
3004 (define_insn "*movdf_internal_rex64"
3005 [(set (match_operand:DF 0 "nonimmediate_operand"
3006 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
3007 (match_operand:DF 1 "general_operand"
3008 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
3009 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3010 && (!can_create_pseudo_p ()
3011 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3012 || GET_CODE (operands[1]) != CONST_DOUBLE
3013 || (optimize_function_for_size_p (cfun)
3014 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3015 && standard_80387_constant_p (operands[1]) > 0)
3016 || (TARGET_SSE2 && TARGET_SSE_MATH
3017 && standard_sse_constant_p (operands[1]))))
3018 || memory_operand (operands[0], DFmode))"
3020 switch (which_alternative)
3024 return output_387_reg_move (insn, operands);
3027 return standard_80387_constant_opcode (operands[1]);
3031 return "mov{q}\t{%1, %0|%0, %1}";
3034 return "movabs{q}\t{%1, %0|%0, %1}";
3040 return standard_sse_constant_opcode (insn, operands[1]);
3045 switch (get_attr_mode (insn))
3048 return "%vmovapd\t{%1, %0|%0, %1}";
3050 return "%vmovaps\t{%1, %0|%0, %1}";
3053 return "%vmovq\t{%1, %0|%0, %1}";
3055 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3056 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3057 return "%vmovsd\t{%1, %0|%0, %1}";
3059 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3061 return "%vmovlps\t{%1, %d0|%d0, %1}";
3068 /* Handle broken assemblers that require movd instead of movq. */
3069 return "%vmovd\t{%1, %0|%0, %1}";
3076 (cond [(eq_attr "alternative" "0,1,2")
3077 (const_string "fmov")
3078 (eq_attr "alternative" "3,4,5")
3079 (const_string "imov")
3080 (eq_attr "alternative" "6")
3081 (const_string "multi")
3082 (eq_attr "alternative" "7")
3083 (const_string "sselog1")
3085 (const_string "ssemov")))
3088 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3090 (const_string "*")))
3091 (set (attr "length_immediate")
3093 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3095 (const_string "*")))
3096 (set (attr "prefix")
3097 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3098 (const_string "orig")
3099 (const_string "maybe_vex")))
3100 (set (attr "prefix_data16")
3101 (if_then_else (eq_attr "mode" "V1DF")
3103 (const_string "*")))
3105 (cond [(eq_attr "alternative" "0,1,2")
3107 (eq_attr "alternative" "3,4,5,6,11,12")
3110 /* xorps is one byte shorter for !TARGET_AVX. */
3111 (eq_attr "alternative" "7")
3112 (cond [(match_test "TARGET_AVX")
3113 (const_string "V2DF")
3114 (match_test "optimize_function_for_size_p (cfun)")
3115 (const_string "V4SF")
3116 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3119 (const_string "V2DF"))
3121 /* For architectures resolving dependencies on
3122 whole SSE registers use APD move to break dependency
3123 chains, otherwise use short move to avoid extra work.
3125 movaps encodes one byte shorter for !TARGET_AVX. */
3126 (eq_attr "alternative" "8")
3127 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3128 (const_string "V4SF")
3129 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3130 (const_string "V2DF")
3131 (match_test "TARGET_AVX")
3133 (match_test "optimize_function_for_size_p (cfun)")
3134 (const_string "V4SF")
3136 (const_string "DF"))
3137 /* For architectures resolving dependencies on register
3138 parts we may avoid extra work to zero out upper part
3140 (eq_attr "alternative" "9")
3142 (match_test "TARGET_SSE_SPLIT_REGS")
3143 (const_string "V1DF")
3144 (const_string "DF"))
3146 (const_string "DF")))])
3148 ;; Possible store forwarding (partial memory) stall in alternative 4.
3149 (define_insn "*movdf_internal"
3150 [(set (match_operand:DF 0 "nonimmediate_operand"
3151 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3152 (match_operand:DF 1 "general_operand"
3153 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3154 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3155 && (!can_create_pseudo_p ()
3156 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3157 || GET_CODE (operands[1]) != CONST_DOUBLE
3158 || (optimize_function_for_size_p (cfun)
3159 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3160 && standard_80387_constant_p (operands[1]) > 0)
3161 || (TARGET_SSE2 && TARGET_SSE_MATH
3162 && standard_sse_constant_p (operands[1])))
3163 && !memory_operand (operands[0], DFmode))
3164 || (!TARGET_MEMORY_MISMATCH_STALL
3165 && memory_operand (operands[0], DFmode)))"
3167 switch (which_alternative)
3171 return output_387_reg_move (insn, operands);
3174 return standard_80387_constant_opcode (operands[1]);
3182 return standard_sse_constant_opcode (insn, operands[1]);
3190 switch (get_attr_mode (insn))
3193 return "%vmovapd\t{%1, %0|%0, %1}";
3195 return "%vmovaps\t{%1, %0|%0, %1}";
3198 return "%vmovq\t{%1, %0|%0, %1}";
3200 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3201 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3202 return "%vmovsd\t{%1, %0|%0, %1}";
3204 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3206 return "%vmovlps\t{%1, %d0|%d0, %1}";
3216 (if_then_else (eq_attr "alternative" "5,6,7,8")
3217 (const_string "sse2")
3218 (const_string "*")))
3220 (cond [(eq_attr "alternative" "0,1,2")
3221 (const_string "fmov")
3222 (eq_attr "alternative" "3,4")
3223 (const_string "multi")
3224 (eq_attr "alternative" "5,9")
3225 (const_string "sselog1")
3227 (const_string "ssemov")))
3228 (set (attr "prefix")
3229 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3230 (const_string "orig")
3231 (const_string "maybe_vex")))
3232 (set (attr "prefix_data16")
3233 (if_then_else (eq_attr "mode" "V1DF")
3235 (const_string "*")))
3237 (cond [(eq_attr "alternative" "0,1,2")
3239 (eq_attr "alternative" "3,4")
3242 /* For SSE1, we have many fewer alternatives. */
3243 (not (match_test "TARGET_SSE2"))
3245 (eq_attr "alternative" "5,6,9,10")
3246 (const_string "V4SF")
3247 (const_string "V2SF"))
3249 /* xorps is one byte shorter for !TARGET_AVX. */
3250 (eq_attr "alternative" "5,9")
3251 (cond [(match_test "TARGET_AVX")
3252 (const_string "V2DF")
3253 (match_test "optimize_function_for_size_p (cfun)")
3254 (const_string "V4SF")
3255 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3258 (const_string "V2DF"))
3260 /* For architectures resolving dependencies on
3261 whole SSE registers use APD move to break dependency
3262 chains, otherwise use short move to avoid extra work.
3264 movaps encodes one byte shorter for !TARGET_AVX. */
3265 (eq_attr "alternative" "6,10")
3266 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3267 (const_string "V4SF")
3268 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3269 (const_string "V2DF")
3270 (match_test "TARGET_AVX")
3272 (match_test "optimize_function_for_size_p (cfun)")
3273 (const_string "V4SF")
3275 (const_string "DF"))
3277 /* For architectures resolving dependencies on register
3278 parts we may avoid extra work to zero out upper part
3280 (eq_attr "alternative" "7,11")
3282 (match_test "TARGET_SSE_SPLIT_REGS")
3283 (const_string "V1DF")
3284 (const_string "DF"))
3286 (const_string "DF")))])
3288 (define_insn "*movsf_internal"
3289 [(set (match_operand:SF 0 "nonimmediate_operand"
3290 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3291 (match_operand:SF 1 "general_operand"
3292 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3293 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3294 && (!can_create_pseudo_p ()
3295 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3296 || GET_CODE (operands[1]) != CONST_DOUBLE
3297 || (optimize_function_for_size_p (cfun)
3298 && ((!TARGET_SSE_MATH
3299 && standard_80387_constant_p (operands[1]) > 0)
3301 && standard_sse_constant_p (operands[1]))))
3302 || memory_operand (operands[0], SFmode))"
3304 switch (which_alternative)
3308 return output_387_reg_move (insn, operands);
3311 return standard_80387_constant_opcode (operands[1]);
3315 return "mov{l}\t{%1, %0|%0, %1}";
3318 return standard_sse_constant_opcode (insn, operands[1]);
3321 if (get_attr_mode (insn) == MODE_V4SF)
3322 return "%vmovaps\t{%1, %0|%0, %1}";
3324 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3328 return "%vmovss\t{%1, %0|%0, %1}";
3334 return "movd\t{%1, %0|%0, %1}";
3337 return "movq\t{%1, %0|%0, %1}";
3341 return "%vmovd\t{%1, %0|%0, %1}";
3348 (cond [(eq_attr "alternative" "0,1,2")
3349 (const_string "fmov")
3350 (eq_attr "alternative" "3,4")
3351 (const_string "multi")
3352 (eq_attr "alternative" "5")
3353 (const_string "sselog1")
3354 (eq_attr "alternative" "9,10,11,14,15")
3355 (const_string "mmxmov")
3357 (const_string "ssemov")))
3358 (set (attr "prefix")
3359 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3360 (const_string "maybe_vex")
3361 (const_string "orig")))
3363 (cond [(eq_attr "alternative" "3,4,9,10")
3365 (eq_attr "alternative" "5")
3366 (cond [(match_test "TARGET_AVX")
3367 (const_string "V4SF")
3368 (ior (not (match_test "TARGET_SSE2"))
3369 (match_test "optimize_function_for_size_p (cfun)"))
3370 (const_string "V4SF")
3371 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3374 (const_string "V4SF"))
3376 /* For architectures resolving dependencies on
3377 whole SSE registers use APS move to break dependency
3378 chains, otherwise use short move to avoid extra work.
3380 Do the same for architectures resolving dependencies on
3381 the parts. While in DF mode it is better to always handle
3382 just register parts, the SF mode is different due to lack
3383 of instructions to load just part of the register. It is
3384 better to maintain the whole registers in single format
3385 to avoid problems on using packed logical operations. */
3386 (eq_attr "alternative" "6")
3388 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3389 (match_test "TARGET_SSE_SPLIT_REGS"))
3390 (const_string "V4SF")
3391 (const_string "SF"))
3392 (eq_attr "alternative" "11")
3393 (const_string "DI")]
3394 (const_string "SF")))])
3397 [(set (match_operand 0 "any_fp_register_operand")
3398 (match_operand 1 "memory_operand"))]
3400 && (GET_MODE (operands[0]) == TFmode
3401 || GET_MODE (operands[0]) == XFmode
3402 || GET_MODE (operands[0]) == DFmode
3403 || GET_MODE (operands[0]) == SFmode)
3404 && (operands[2] = find_constant_src (insn))"
3405 [(set (match_dup 0) (match_dup 2))]
3407 rtx c = operands[2];
3408 int r = REGNO (operands[0]);
3410 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3411 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3416 [(set (match_operand 0 "any_fp_register_operand")
3417 (float_extend (match_operand 1 "memory_operand")))]
3419 && (GET_MODE (operands[0]) == TFmode
3420 || GET_MODE (operands[0]) == XFmode
3421 || GET_MODE (operands[0]) == DFmode)
3422 && (operands[2] = find_constant_src (insn))"
3423 [(set (match_dup 0) (match_dup 2))]
3425 rtx c = operands[2];
3426 int r = REGNO (operands[0]);
3428 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3429 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3433 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3435 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3436 (match_operand:X87MODEF 1 "immediate_operand"))]
3438 && (standard_80387_constant_p (operands[1]) == 8
3439 || standard_80387_constant_p (operands[1]) == 9)"
3440 [(set (match_dup 0)(match_dup 1))
3442 (neg:X87MODEF (match_dup 0)))]
3446 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3447 if (real_isnegzero (&r))
3448 operands[1] = CONST0_RTX (<MODE>mode);
3450 operands[1] = CONST1_RTX (<MODE>mode);
3454 [(set (match_operand 0 "nonimmediate_operand")
3455 (match_operand 1 "general_operand"))]
3457 && (GET_MODE (operands[0]) == TFmode
3458 || GET_MODE (operands[0]) == XFmode
3459 || GET_MODE (operands[0]) == DFmode)
3460 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3462 "ix86_split_long_move (operands); DONE;")
3464 (define_insn "swapxf"
3465 [(set (match_operand:XF 0 "register_operand" "+f")
3466 (match_operand:XF 1 "register_operand" "+f"))
3471 if (STACK_TOP_P (operands[0]))
3476 [(set_attr "type" "fxch")
3477 (set_attr "mode" "XF")])
3479 (define_insn "*swap<mode>"
3480 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3481 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3484 "TARGET_80387 || reload_completed"
3486 if (STACK_TOP_P (operands[0]))
3491 [(set_attr "type" "fxch")
3492 (set_attr "mode" "<MODE>")])
3494 ;; Zero extension instructions
3496 (define_expand "zero_extendsidi2"
3497 [(set (match_operand:DI 0 "nonimmediate_operand")
3498 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3500 (define_insn "*zero_extendsidi2_rex64"
3501 [(set (match_operand:DI 0 "nonimmediate_operand"
3502 "=r ,o,?*Ym,?*y,?*Yi,?*x")
3504 (match_operand:SI 1 "x86_64_zext_general_operand"
3505 "rmWz,0,r ,m ,r ,m")))]
3508 switch (get_attr_type (insn))
3511 if (ix86_use_lea_for_mov (insn, operands))
3512 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3514 return "mov{l}\t{%1, %k0|%k0, %1}";
3520 return "movd\t{%1, %0|%0, %1}";
3523 return "%vmovd\t{%1, %0|%0, %1}";
3529 [(set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3530 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3531 (set_attr "prefix_0f" "0,*,*,*,*,*")
3532 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3534 (define_insn "*zero_extendsidi2"
3535 [(set (match_operand:DI 0 "nonimmediate_operand"
3536 "=ro,?r,?o,?*Ym,?*y,?*Yi,?*x")
3537 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3538 "0 ,rm,r ,r ,m ,r ,m")))]
3544 movd\t{%1, %0|%0, %1}
3545 movd\t{%1, %0|%0, %1}
3546 %vmovd\t{%1, %0|%0, %1}
3547 %vmovd\t{%1, %0|%0, %1}"
3548 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3549 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3550 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3551 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3554 [(set (match_operand:DI 0 "memory_operand")
3555 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3557 [(set (match_dup 4) (const_int 0))]
3558 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3561 [(set (match_operand:DI 0 "register_operand")
3562 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3563 "!TARGET_64BIT && reload_completed
3564 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3565 && true_regnum (operands[0]) == true_regnum (operands[1])"
3566 [(set (match_dup 4) (const_int 0))]
3567 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3570 [(set (match_operand:DI 0 "nonimmediate_operand")
3571 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3572 "!TARGET_64BIT && reload_completed
3573 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3574 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3575 [(set (match_dup 3) (match_dup 1))
3576 (set (match_dup 4) (const_int 0))]
3577 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3579 (define_insn "zero_extend<mode>di2"
3580 [(set (match_operand:DI 0 "register_operand" "=r")
3582 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3584 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3585 [(set_attr "type" "imovx")
3586 (set_attr "mode" "SI")])
3588 (define_expand "zero_extend<mode>si2"
3589 [(set (match_operand:SI 0 "register_operand")
3590 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3593 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3595 operands[1] = force_reg (<MODE>mode, operands[1]);
3596 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3601 (define_insn_and_split "zero_extend<mode>si2_and"
3602 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3604 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3605 (clobber (reg:CC FLAGS_REG))]
3606 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3608 "&& reload_completed"
3609 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3610 (clobber (reg:CC FLAGS_REG))])]
3612 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3614 ix86_expand_clear (operands[0]);
3616 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3617 emit_insn (gen_movstrict<mode>
3618 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3622 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3624 [(set_attr "type" "alu1")
3625 (set_attr "mode" "SI")])
3627 (define_insn "*zero_extend<mode>si2"
3628 [(set (match_operand:SI 0 "register_operand" "=r")
3630 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3631 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3632 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3633 [(set_attr "type" "imovx")
3634 (set_attr "mode" "SI")])
3636 (define_expand "zero_extendqihi2"
3637 [(set (match_operand:HI 0 "register_operand")
3638 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3641 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3643 operands[1] = force_reg (QImode, operands[1]);
3644 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3649 (define_insn_and_split "zero_extendqihi2_and"
3650 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3651 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3652 (clobber (reg:CC FLAGS_REG))]
3653 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3655 "&& reload_completed"
3656 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3657 (clobber (reg:CC FLAGS_REG))])]
3659 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3661 ix86_expand_clear (operands[0]);
3663 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3664 emit_insn (gen_movstrictqi
3665 (gen_lowpart (QImode, operands[0]), operands[1]));
3669 operands[0] = gen_lowpart (SImode, operands[0]);
3671 [(set_attr "type" "alu1")
3672 (set_attr "mode" "SI")])
3674 ; zero extend to SImode to avoid partial register stalls
3675 (define_insn "*zero_extendqihi2"
3676 [(set (match_operand:HI 0 "register_operand" "=r")
3677 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3678 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3679 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3680 [(set_attr "type" "imovx")
3681 (set_attr "mode" "SI")])
3683 ;; Sign extension instructions
3685 (define_expand "extendsidi2"
3686 [(set (match_operand:DI 0 "register_operand")
3687 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3692 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3697 (define_insn "*extendsidi2_rex64"
3698 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3699 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3703 movs{lq|x}\t{%1, %0|%0, %1}"
3704 [(set_attr "type" "imovx")
3705 (set_attr "mode" "DI")
3706 (set_attr "prefix_0f" "0")
3707 (set_attr "modrm" "0,1")])
3709 (define_insn "extendsidi2_1"
3710 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3711 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3712 (clobber (reg:CC FLAGS_REG))
3713 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3717 ;; Extend to memory case when source register does die.
3719 [(set (match_operand:DI 0 "memory_operand")
3720 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3721 (clobber (reg:CC FLAGS_REG))
3722 (clobber (match_operand:SI 2 "register_operand"))]
3724 && dead_or_set_p (insn, operands[1])
3725 && !reg_mentioned_p (operands[1], operands[0]))"
3726 [(set (match_dup 3) (match_dup 1))
3727 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3728 (clobber (reg:CC FLAGS_REG))])
3729 (set (match_dup 4) (match_dup 1))]
3730 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3732 ;; Extend to memory case when source register does not die.
3734 [(set (match_operand:DI 0 "memory_operand")
3735 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3736 (clobber (reg:CC FLAGS_REG))
3737 (clobber (match_operand:SI 2 "register_operand"))]
3741 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3743 emit_move_insn (operands[3], operands[1]);
3745 /* Generate a cltd if possible and doing so it profitable. */
3746 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3747 && true_regnum (operands[1]) == AX_REG
3748 && true_regnum (operands[2]) == DX_REG)
3750 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3754 emit_move_insn (operands[2], operands[1]);
3755 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3757 emit_move_insn (operands[4], operands[2]);
3761 ;; Extend to register case. Optimize case where source and destination
3762 ;; registers match and cases where we can use cltd.
3764 [(set (match_operand:DI 0 "register_operand")
3765 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3766 (clobber (reg:CC FLAGS_REG))
3767 (clobber (match_scratch:SI 2))]
3771 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3773 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3774 emit_move_insn (operands[3], operands[1]);
3776 /* Generate a cltd if possible and doing so it profitable. */
3777 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3778 && true_regnum (operands[3]) == AX_REG
3779 && true_regnum (operands[4]) == DX_REG)
3781 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3785 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3786 emit_move_insn (operands[4], operands[1]);
3788 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3792 (define_insn "extend<mode>di2"
3793 [(set (match_operand:DI 0 "register_operand" "=r")
3795 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3797 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3798 [(set_attr "type" "imovx")
3799 (set_attr "mode" "DI")])
3801 (define_insn "extendhisi2"
3802 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3803 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3806 switch (get_attr_prefix_0f (insn))
3809 return "{cwtl|cwde}";
3811 return "movs{wl|x}\t{%1, %0|%0, %1}";
3814 [(set_attr "type" "imovx")
3815 (set_attr "mode" "SI")
3816 (set (attr "prefix_0f")
3817 ;; movsx is short decodable while cwtl is vector decoded.
3818 (if_then_else (and (eq_attr "cpu" "!k6")
3819 (eq_attr "alternative" "0"))
3821 (const_string "1")))
3823 (if_then_else (eq_attr "prefix_0f" "0")
3825 (const_string "1")))])
3827 (define_insn "*extendhisi2_zext"
3828 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3831 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3834 switch (get_attr_prefix_0f (insn))
3837 return "{cwtl|cwde}";
3839 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3842 [(set_attr "type" "imovx")
3843 (set_attr "mode" "SI")
3844 (set (attr "prefix_0f")
3845 ;; movsx is short decodable while cwtl is vector decoded.
3846 (if_then_else (and (eq_attr "cpu" "!k6")
3847 (eq_attr "alternative" "0"))
3849 (const_string "1")))
3851 (if_then_else (eq_attr "prefix_0f" "0")
3853 (const_string "1")))])
3855 (define_insn "extendqisi2"
3856 [(set (match_operand:SI 0 "register_operand" "=r")
3857 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3859 "movs{bl|x}\t{%1, %0|%0, %1}"
3860 [(set_attr "type" "imovx")
3861 (set_attr "mode" "SI")])
3863 (define_insn "*extendqisi2_zext"
3864 [(set (match_operand:DI 0 "register_operand" "=r")
3866 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3868 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3869 [(set_attr "type" "imovx")
3870 (set_attr "mode" "SI")])
3872 (define_insn "extendqihi2"
3873 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3874 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3877 switch (get_attr_prefix_0f (insn))
3880 return "{cbtw|cbw}";
3882 return "movs{bw|x}\t{%1, %0|%0, %1}";
3885 [(set_attr "type" "imovx")
3886 (set_attr "mode" "HI")
3887 (set (attr "prefix_0f")
3888 ;; movsx is short decodable while cwtl is vector decoded.
3889 (if_then_else (and (eq_attr "cpu" "!k6")
3890 (eq_attr "alternative" "0"))
3892 (const_string "1")))
3894 (if_then_else (eq_attr "prefix_0f" "0")
3896 (const_string "1")))])
3898 ;; Conversions between float and double.
3900 ;; These are all no-ops in the model used for the 80387.
3901 ;; So just emit moves.
3903 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3905 [(set (match_operand:DF 0 "push_operand")
3906 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3908 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3909 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3912 [(set (match_operand:XF 0 "push_operand")
3913 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3915 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3916 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3917 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3919 (define_expand "extendsfdf2"
3920 [(set (match_operand:DF 0 "nonimmediate_operand")
3921 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3922 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3924 /* ??? Needed for compress_float_constant since all fp constants
3925 are TARGET_LEGITIMATE_CONSTANT_P. */
3926 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3928 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3929 && standard_80387_constant_p (operands[1]) > 0)
3931 operands[1] = simplify_const_unary_operation
3932 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3933 emit_move_insn_1 (operands[0], operands[1]);
3936 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3940 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3942 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3944 We do the conversion post reload to avoid producing of 128bit spills
3945 that might lead to ICE on 32bit target. The sequence unlikely combine
3948 [(set (match_operand:DF 0 "register_operand")
3950 (match_operand:SF 1 "nonimmediate_operand")))]
3951 "TARGET_USE_VECTOR_FP_CONVERTS
3952 && optimize_insn_for_speed_p ()
3953 && reload_completed && SSE_REG_P (operands[0])"
3958 (parallel [(const_int 0) (const_int 1)]))))]
3960 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3961 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3962 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3963 Try to avoid move when unpacking can be done in source. */
3964 if (REG_P (operands[1]))
3966 /* If it is unsafe to overwrite upper half of source, we need
3967 to move to destination and unpack there. */
3968 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3969 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3970 && true_regnum (operands[0]) != true_regnum (operands[1]))
3972 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3973 emit_move_insn (tmp, operands[1]);
3976 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3977 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3981 emit_insn (gen_vec_setv4sf_0 (operands[3],
3982 CONST0_RTX (V4SFmode), operands[1]));
3985 (define_insn "*extendsfdf2_mixed"
3986 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3988 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3989 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3991 switch (which_alternative)
3995 return output_387_reg_move (insn, operands);
3998 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4004 [(set_attr "type" "fmov,fmov,ssecvt")
4005 (set_attr "prefix" "orig,orig,maybe_vex")
4006 (set_attr "mode" "SF,XF,DF")])
4008 (define_insn "*extendsfdf2_sse"
4009 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4010 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4011 "TARGET_SSE2 && TARGET_SSE_MATH"
4012 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4013 [(set_attr "type" "ssecvt")
4014 (set_attr "prefix" "maybe_vex")
4015 (set_attr "mode" "DF")])
4017 (define_insn "*extendsfdf2_i387"
4018 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4019 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4021 "* return output_387_reg_move (insn, operands);"
4022 [(set_attr "type" "fmov")
4023 (set_attr "mode" "SF,XF")])
4025 (define_expand "extend<mode>xf2"
4026 [(set (match_operand:XF 0 "nonimmediate_operand")
4027 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4030 /* ??? Needed for compress_float_constant since all fp constants
4031 are TARGET_LEGITIMATE_CONSTANT_P. */
4032 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4034 if (standard_80387_constant_p (operands[1]) > 0)
4036 operands[1] = simplify_const_unary_operation
4037 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4038 emit_move_insn_1 (operands[0], operands[1]);
4041 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4045 (define_insn "*extend<mode>xf2_i387"
4046 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4048 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4050 "* return output_387_reg_move (insn, operands);"
4051 [(set_attr "type" "fmov")
4052 (set_attr "mode" "<MODE>,XF")])
4054 ;; %%% This seems bad bad news.
4055 ;; This cannot output into an f-reg because there is no way to be sure
4056 ;; of truncating in that case. Otherwise this is just like a simple move
4057 ;; insn. So we pretend we can output to a reg in order to get better
4058 ;; register preferencing, but we really use a stack slot.
4060 ;; Conversion from DFmode to SFmode.
4062 (define_expand "truncdfsf2"
4063 [(set (match_operand:SF 0 "nonimmediate_operand")
4065 (match_operand:DF 1 "nonimmediate_operand")))]
4066 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4068 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4070 else if (flag_unsafe_math_optimizations)
4074 enum ix86_stack_slot slot = (virtuals_instantiated
4077 rtx temp = assign_386_stack_local (SFmode, slot);
4078 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4083 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4085 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4087 We do the conversion post reload to avoid producing of 128bit spills
4088 that might lead to ICE on 32bit target. The sequence unlikely combine
4091 [(set (match_operand:SF 0 "register_operand")
4093 (match_operand:DF 1 "nonimmediate_operand")))]
4094 "TARGET_USE_VECTOR_FP_CONVERTS
4095 && optimize_insn_for_speed_p ()
4096 && reload_completed && SSE_REG_P (operands[0])"
4099 (float_truncate:V2SF
4103 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4104 operands[3] = CONST0_RTX (V2SFmode);
4105 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4106 /* Use movsd for loading from memory, unpcklpd for registers.
4107 Try to avoid move when unpacking can be done in source, or SSE3
4108 movddup is available. */
4109 if (REG_P (operands[1]))
4112 && true_regnum (operands[0]) != true_regnum (operands[1])
4113 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4114 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4116 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4117 emit_move_insn (tmp, operands[1]);
4120 else if (!TARGET_SSE3)
4121 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4122 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4125 emit_insn (gen_sse2_loadlpd (operands[4],
4126 CONST0_RTX (V2DFmode), operands[1]));
4129 (define_expand "truncdfsf2_with_temp"
4130 [(parallel [(set (match_operand:SF 0)
4131 (float_truncate:SF (match_operand:DF 1)))
4132 (clobber (match_operand:SF 2))])])
4134 (define_insn "*truncdfsf_fast_mixed"
4135 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4137 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4138 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4140 switch (which_alternative)
4143 return output_387_reg_move (insn, operands);
4145 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4150 [(set_attr "type" "fmov,ssecvt")
4151 (set_attr "prefix" "orig,maybe_vex")
4152 (set_attr "mode" "SF")])
4154 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4155 ;; because nothing we do here is unsafe.
4156 (define_insn "*truncdfsf_fast_sse"
4157 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4159 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4160 "TARGET_SSE2 && TARGET_SSE_MATH"
4161 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4162 [(set_attr "type" "ssecvt")
4163 (set_attr "prefix" "maybe_vex")
4164 (set_attr "mode" "SF")])
4166 (define_insn "*truncdfsf_fast_i387"
4167 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4169 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4170 "TARGET_80387 && flag_unsafe_math_optimizations"
4171 "* return output_387_reg_move (insn, operands);"
4172 [(set_attr "type" "fmov")
4173 (set_attr "mode" "SF")])
4175 (define_insn "*truncdfsf_mixed"
4176 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4178 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4179 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4180 "TARGET_MIX_SSE_I387"
4182 switch (which_alternative)
4185 return output_387_reg_move (insn, operands);
4187 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4193 [(set_attr "isa" "*,sse2,*,*,*")
4194 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4195 (set_attr "unit" "*,*,i387,i387,i387")
4196 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4197 (set_attr "mode" "SF")])
4199 (define_insn "*truncdfsf_i387"
4200 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4202 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4203 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4206 switch (which_alternative)
4209 return output_387_reg_move (insn, operands);
4215 [(set_attr "type" "fmov,multi,multi,multi")
4216 (set_attr "unit" "*,i387,i387,i387")
4217 (set_attr "mode" "SF")])
4219 (define_insn "*truncdfsf2_i387_1"
4220 [(set (match_operand:SF 0 "memory_operand" "=m")
4222 (match_operand:DF 1 "register_operand" "f")))]
4224 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4225 && !TARGET_MIX_SSE_I387"
4226 "* return output_387_reg_move (insn, operands);"
4227 [(set_attr "type" "fmov")
4228 (set_attr "mode" "SF")])
4231 [(set (match_operand:SF 0 "register_operand")
4233 (match_operand:DF 1 "fp_register_operand")))
4234 (clobber (match_operand 2))]
4236 [(set (match_dup 2) (match_dup 1))
4237 (set (match_dup 0) (match_dup 2))]
4238 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4240 ;; Conversion from XFmode to {SF,DF}mode
4242 (define_expand "truncxf<mode>2"
4243 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4244 (float_truncate:MODEF
4245 (match_operand:XF 1 "register_operand")))
4246 (clobber (match_dup 2))])]
4249 if (flag_unsafe_math_optimizations)
4251 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4252 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4253 if (reg != operands[0])
4254 emit_move_insn (operands[0], reg);
4259 enum ix86_stack_slot slot = (virtuals_instantiated
4262 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4266 (define_insn "*truncxfsf2_mixed"
4267 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4269 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4270 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4273 gcc_assert (!which_alternative);
4274 return output_387_reg_move (insn, operands);
4276 [(set_attr "type" "fmov,multi,multi,multi")
4277 (set_attr "unit" "*,i387,i387,i387")
4278 (set_attr "mode" "SF")])
4280 (define_insn "*truncxfdf2_mixed"
4281 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4283 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4284 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4287 gcc_assert (!which_alternative);
4288 return output_387_reg_move (insn, operands);
4290 [(set_attr "isa" "*,*,sse2,*")
4291 (set_attr "type" "fmov,multi,multi,multi")
4292 (set_attr "unit" "*,i387,i387,i387")
4293 (set_attr "mode" "DF")])
4295 (define_insn "truncxf<mode>2_i387_noop"
4296 [(set (match_operand:MODEF 0 "register_operand" "=f")
4297 (float_truncate:MODEF
4298 (match_operand:XF 1 "register_operand" "f")))]
4299 "TARGET_80387 && flag_unsafe_math_optimizations"
4300 "* return output_387_reg_move (insn, operands);"
4301 [(set_attr "type" "fmov")
4302 (set_attr "mode" "<MODE>")])
4304 (define_insn "*truncxf<mode>2_i387"
4305 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4306 (float_truncate:MODEF
4307 (match_operand:XF 1 "register_operand" "f")))]
4309 "* return output_387_reg_move (insn, operands);"
4310 [(set_attr "type" "fmov")
4311 (set_attr "mode" "<MODE>")])
4314 [(set (match_operand:MODEF 0 "register_operand")
4315 (float_truncate:MODEF
4316 (match_operand:XF 1 "register_operand")))
4317 (clobber (match_operand:MODEF 2 "memory_operand"))]
4318 "TARGET_80387 && reload_completed"
4319 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4320 (set (match_dup 0) (match_dup 2))])
4323 [(set (match_operand:MODEF 0 "memory_operand")
4324 (float_truncate:MODEF
4325 (match_operand:XF 1 "register_operand")))
4326 (clobber (match_operand:MODEF 2 "memory_operand"))]
4328 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4330 ;; Signed conversion to DImode.
4332 (define_expand "fix_truncxfdi2"
4333 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4334 (fix:DI (match_operand:XF 1 "register_operand")))
4335 (clobber (reg:CC FLAGS_REG))])]
4340 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4345 (define_expand "fix_trunc<mode>di2"
4346 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4347 (fix:DI (match_operand:MODEF 1 "register_operand")))
4348 (clobber (reg:CC FLAGS_REG))])]
4349 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4352 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4354 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4357 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4359 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4360 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4361 if (out != operands[0])
4362 emit_move_insn (operands[0], out);
4367 ;; Signed conversion to SImode.
4369 (define_expand "fix_truncxfsi2"
4370 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4371 (fix:SI (match_operand:XF 1 "register_operand")))
4372 (clobber (reg:CC FLAGS_REG))])]
4377 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4382 (define_expand "fix_trunc<mode>si2"
4383 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4384 (fix:SI (match_operand:MODEF 1 "register_operand")))
4385 (clobber (reg:CC FLAGS_REG))])]
4386 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4389 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4391 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4394 if (SSE_FLOAT_MODE_P (<MODE>mode))
4396 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4397 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4398 if (out != operands[0])
4399 emit_move_insn (operands[0], out);
4404 ;; Signed conversion to HImode.
4406 (define_expand "fix_trunc<mode>hi2"
4407 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4408 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4409 (clobber (reg:CC FLAGS_REG))])]
4411 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4415 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4420 ;; Unsigned conversion to SImode.
4422 (define_expand "fixuns_trunc<mode>si2"
4424 [(set (match_operand:SI 0 "register_operand")
4426 (match_operand:MODEF 1 "nonimmediate_operand")))
4428 (clobber (match_scratch:<ssevecmode> 3))
4429 (clobber (match_scratch:<ssevecmode> 4))])]
4430 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4432 enum machine_mode mode = <MODE>mode;
4433 enum machine_mode vecmode = <ssevecmode>mode;
4434 REAL_VALUE_TYPE TWO31r;
4437 if (optimize_insn_for_size_p ())
4440 real_ldexp (&TWO31r, &dconst1, 31);
4441 two31 = const_double_from_real_value (TWO31r, mode);
4442 two31 = ix86_build_const_vector (vecmode, true, two31);
4443 operands[2] = force_reg (vecmode, two31);
4446 (define_insn_and_split "*fixuns_trunc<mode>_1"
4447 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4449 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4450 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4451 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4452 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4453 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4454 && optimize_function_for_speed_p (cfun)"
4456 "&& reload_completed"
4459 ix86_split_convert_uns_si_sse (operands);
4463 ;; Unsigned conversion to HImode.
4464 ;; Without these patterns, we'll try the unsigned SI conversion which
4465 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4467 (define_expand "fixuns_trunc<mode>hi2"
4469 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4470 (set (match_operand:HI 0 "nonimmediate_operand")
4471 (subreg:HI (match_dup 2) 0))]
4472 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4473 "operands[2] = gen_reg_rtx (SImode);")
4475 ;; When SSE is available, it is always faster to use it!
4476 (define_insn "fix_trunc<mode>di_sse"
4477 [(set (match_operand:DI 0 "register_operand" "=r,r")
4478 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4479 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4480 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4481 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4482 [(set_attr "type" "sseicvt")
4483 (set_attr "prefix" "maybe_vex")
4484 (set_attr "prefix_rex" "1")
4485 (set_attr "mode" "<MODE>")
4486 (set_attr "athlon_decode" "double,vector")
4487 (set_attr "amdfam10_decode" "double,double")
4488 (set_attr "bdver1_decode" "double,double")])
4490 (define_insn "fix_trunc<mode>si_sse"
4491 [(set (match_operand:SI 0 "register_operand" "=r,r")
4492 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4493 "SSE_FLOAT_MODE_P (<MODE>mode)
4494 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4495 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4496 [(set_attr "type" "sseicvt")
4497 (set_attr "prefix" "maybe_vex")
4498 (set_attr "mode" "<MODE>")
4499 (set_attr "athlon_decode" "double,vector")
4500 (set_attr "amdfam10_decode" "double,double")
4501 (set_attr "bdver1_decode" "double,double")])
4503 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4505 [(set (match_operand:MODEF 0 "register_operand")
4506 (match_operand:MODEF 1 "memory_operand"))
4507 (set (match_operand:SWI48x 2 "register_operand")
4508 (fix:SWI48x (match_dup 0)))]
4509 "TARGET_SHORTEN_X87_SSE
4510 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4511 && peep2_reg_dead_p (2, operands[0])"
4512 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4514 ;; Avoid vector decoded forms of the instruction.
4516 [(match_scratch:DF 2 "x")
4517 (set (match_operand:SWI48x 0 "register_operand")
4518 (fix:SWI48x (match_operand:DF 1 "memory_operand")))]
4519 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4520 [(set (match_dup 2) (match_dup 1))
4521 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4524 [(match_scratch:SF 2 "x")
4525 (set (match_operand:SWI48x 0 "register_operand")
4526 (fix:SWI48x (match_operand:SF 1 "memory_operand")))]
4527 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4528 [(set (match_dup 2) (match_dup 1))
4529 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4531 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4532 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4533 (fix:SWI248x (match_operand 1 "register_operand")))]
4534 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4536 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4537 && (TARGET_64BIT || <MODE>mode != DImode))
4539 && can_create_pseudo_p ()"
4544 if (memory_operand (operands[0], VOIDmode))
4545 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4548 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4549 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4555 [(set_attr "type" "fisttp")
4556 (set_attr "mode" "<MODE>")])
4558 (define_insn "fix_trunc<mode>_i387_fisttp"
4559 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4560 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4561 (clobber (match_scratch:XF 2 "=&1f"))]
4562 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4564 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4565 && (TARGET_64BIT || <MODE>mode != DImode))
4566 && TARGET_SSE_MATH)"
4567 "* return output_fix_trunc (insn, operands, true);"
4568 [(set_attr "type" "fisttp")
4569 (set_attr "mode" "<MODE>")])
4571 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4572 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4573 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4574 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4575 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4576 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4578 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4579 && (TARGET_64BIT || <MODE>mode != DImode))
4580 && TARGET_SSE_MATH)"
4582 [(set_attr "type" "fisttp")
4583 (set_attr "mode" "<MODE>")])
4586 [(set (match_operand:SWI248x 0 "register_operand")
4587 (fix:SWI248x (match_operand 1 "register_operand")))
4588 (clobber (match_operand:SWI248x 2 "memory_operand"))
4589 (clobber (match_scratch 3))]
4591 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4592 (clobber (match_dup 3))])
4593 (set (match_dup 0) (match_dup 2))])
4596 [(set (match_operand:SWI248x 0 "memory_operand")
4597 (fix:SWI248x (match_operand 1 "register_operand")))
4598 (clobber (match_operand:SWI248x 2 "memory_operand"))
4599 (clobber (match_scratch 3))]
4601 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4602 (clobber (match_dup 3))])])
4604 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4605 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4606 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4607 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4608 ;; function in i386.c.
4609 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4610 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4611 (fix:SWI248x (match_operand 1 "register_operand")))
4612 (clobber (reg:CC FLAGS_REG))]
4613 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4615 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4616 && (TARGET_64BIT || <MODE>mode != DImode))
4617 && can_create_pseudo_p ()"
4622 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4624 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4625 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4626 if (memory_operand (operands[0], VOIDmode))
4627 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4628 operands[2], operands[3]));
4631 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4632 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4633 operands[2], operands[3],
4638 [(set_attr "type" "fistp")
4639 (set_attr "i387_cw" "trunc")
4640 (set_attr "mode" "<MODE>")])
4642 (define_insn "fix_truncdi_i387"
4643 [(set (match_operand:DI 0 "memory_operand" "=m")
4644 (fix:DI (match_operand 1 "register_operand" "f")))
4645 (use (match_operand:HI 2 "memory_operand" "m"))
4646 (use (match_operand:HI 3 "memory_operand" "m"))
4647 (clobber (match_scratch:XF 4 "=&1f"))]
4648 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4650 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4651 "* return output_fix_trunc (insn, operands, false);"
4652 [(set_attr "type" "fistp")
4653 (set_attr "i387_cw" "trunc")
4654 (set_attr "mode" "DI")])
4656 (define_insn "fix_truncdi_i387_with_temp"
4657 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4658 (fix:DI (match_operand 1 "register_operand" "f,f")))
4659 (use (match_operand:HI 2 "memory_operand" "m,m"))
4660 (use (match_operand:HI 3 "memory_operand" "m,m"))
4661 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4662 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4663 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4665 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4667 [(set_attr "type" "fistp")
4668 (set_attr "i387_cw" "trunc")
4669 (set_attr "mode" "DI")])
4672 [(set (match_operand:DI 0 "register_operand")
4673 (fix:DI (match_operand 1 "register_operand")))
4674 (use (match_operand:HI 2 "memory_operand"))
4675 (use (match_operand:HI 3 "memory_operand"))
4676 (clobber (match_operand:DI 4 "memory_operand"))
4677 (clobber (match_scratch 5))]
4679 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4682 (clobber (match_dup 5))])
4683 (set (match_dup 0) (match_dup 4))])
4686 [(set (match_operand:DI 0 "memory_operand")
4687 (fix:DI (match_operand 1 "register_operand")))
4688 (use (match_operand:HI 2 "memory_operand"))
4689 (use (match_operand:HI 3 "memory_operand"))
4690 (clobber (match_operand:DI 4 "memory_operand"))
4691 (clobber (match_scratch 5))]
4693 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4696 (clobber (match_dup 5))])])
4698 (define_insn "fix_trunc<mode>_i387"
4699 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4700 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4701 (use (match_operand:HI 2 "memory_operand" "m"))
4702 (use (match_operand:HI 3 "memory_operand" "m"))]
4703 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4705 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4706 "* return output_fix_trunc (insn, operands, false);"
4707 [(set_attr "type" "fistp")
4708 (set_attr "i387_cw" "trunc")
4709 (set_attr "mode" "<MODE>")])
4711 (define_insn "fix_trunc<mode>_i387_with_temp"
4712 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4713 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4714 (use (match_operand:HI 2 "memory_operand" "m,m"))
4715 (use (match_operand:HI 3 "memory_operand" "m,m"))
4716 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4717 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4719 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4721 [(set_attr "type" "fistp")
4722 (set_attr "i387_cw" "trunc")
4723 (set_attr "mode" "<MODE>")])
4726 [(set (match_operand:SWI24 0 "register_operand")
4727 (fix:SWI24 (match_operand 1 "register_operand")))
4728 (use (match_operand:HI 2 "memory_operand"))
4729 (use (match_operand:HI 3 "memory_operand"))
4730 (clobber (match_operand:SWI24 4 "memory_operand"))]
4732 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4734 (use (match_dup 3))])
4735 (set (match_dup 0) (match_dup 4))])
4738 [(set (match_operand:SWI24 0 "memory_operand")
4739 (fix:SWI24 (match_operand 1 "register_operand")))
4740 (use (match_operand:HI 2 "memory_operand"))
4741 (use (match_operand:HI 3 "memory_operand"))
4742 (clobber (match_operand:SWI24 4 "memory_operand"))]
4744 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4746 (use (match_dup 3))])])
4748 (define_insn "x86_fnstcw_1"
4749 [(set (match_operand:HI 0 "memory_operand" "=m")
4750 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4753 [(set (attr "length")
4754 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4755 (set_attr "mode" "HI")
4756 (set_attr "unit" "i387")
4757 (set_attr "bdver1_decode" "vector")])
4759 (define_insn "x86_fldcw_1"
4760 [(set (reg:HI FPCR_REG)
4761 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4764 [(set (attr "length")
4765 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4766 (set_attr "mode" "HI")
4767 (set_attr "unit" "i387")
4768 (set_attr "athlon_decode" "vector")
4769 (set_attr "amdfam10_decode" "vector")
4770 (set_attr "bdver1_decode" "vector")])
4772 ;; Conversion between fixed point and floating point.
4774 ;; Even though we only accept memory inputs, the backend _really_
4775 ;; wants to be able to do this between registers.
4777 (define_expand "floathi<mode>2"
4778 [(set (match_operand:X87MODEF 0 "register_operand")
4779 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4781 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4782 || TARGET_MIX_SSE_I387)")
4784 ;; Pre-reload splitter to add memory clobber to the pattern.
4785 (define_insn_and_split "*floathi<mode>2_1"
4786 [(set (match_operand:X87MODEF 0 "register_operand")
4787 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4789 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4790 || TARGET_MIX_SSE_I387)
4791 && can_create_pseudo_p ()"
4794 [(parallel [(set (match_dup 0)
4795 (float:X87MODEF (match_dup 1)))
4796 (clobber (match_dup 2))])]
4797 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4799 (define_insn "*floathi<mode>2_i387_with_temp"
4800 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4801 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4802 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4804 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4805 || TARGET_MIX_SSE_I387)"
4807 [(set_attr "type" "fmov,multi")
4808 (set_attr "mode" "<MODE>")
4809 (set_attr "unit" "*,i387")
4810 (set_attr "fp_int_src" "true")])
4812 (define_insn "*floathi<mode>2_i387"
4813 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4814 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4816 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4817 || TARGET_MIX_SSE_I387)"
4819 [(set_attr "type" "fmov")
4820 (set_attr "mode" "<MODE>")
4821 (set_attr "fp_int_src" "true")])
4824 [(set (match_operand:X87MODEF 0 "register_operand")
4825 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4826 (clobber (match_operand:HI 2 "memory_operand"))]
4828 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4829 || TARGET_MIX_SSE_I387)
4830 && reload_completed"
4831 [(set (match_dup 2) (match_dup 1))
4832 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4835 [(set (match_operand:X87MODEF 0 "register_operand")
4836 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4837 (clobber (match_operand:HI 2 "memory_operand"))]
4839 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4840 || TARGET_MIX_SSE_I387)
4841 && reload_completed"
4842 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4844 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4845 [(set (match_operand:X87MODEF 0 "register_operand")
4847 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4849 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4850 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4852 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4853 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4854 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4856 rtx reg = gen_reg_rtx (XFmode);
4857 rtx (*insn)(rtx, rtx);
4859 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4861 if (<X87MODEF:MODE>mode == SFmode)
4862 insn = gen_truncxfsf2;
4863 else if (<X87MODEF:MODE>mode == DFmode)
4864 insn = gen_truncxfdf2;
4868 emit_insn (insn (operands[0], reg));
4873 ;; Pre-reload splitter to add memory clobber to the pattern.
4874 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4875 [(set (match_operand:X87MODEF 0 "register_operand")
4876 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4878 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4879 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4880 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4881 || TARGET_MIX_SSE_I387))
4882 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4883 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4884 && ((<SWI48x:MODE>mode == SImode
4885 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4886 && optimize_function_for_speed_p (cfun)
4887 && flag_trapping_math)
4888 || !(TARGET_INTER_UNIT_CONVERSIONS
4889 || optimize_function_for_size_p (cfun)))))
4890 && can_create_pseudo_p ()"
4893 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4894 (clobber (match_dup 2))])]
4896 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4898 /* Avoid store forwarding (partial memory) stall penalty
4899 by passing DImode value through XMM registers. */
4900 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4901 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4902 && optimize_function_for_speed_p (cfun))
4904 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4911 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4912 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4914 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4915 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4916 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4917 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4919 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4920 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4921 (set_attr "unit" "*,i387,*,*,*")
4922 (set_attr "athlon_decode" "*,*,double,direct,double")
4923 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4924 (set_attr "bdver1_decode" "*,*,double,direct,double")
4925 (set_attr "fp_int_src" "true")])
4927 (define_insn "*floatsi<mode>2_vector_mixed"
4928 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4929 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4930 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4931 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4935 [(set_attr "type" "fmov,sseicvt")
4936 (set_attr "mode" "<MODE>,<ssevecmode>")
4937 (set_attr "unit" "i387,*")
4938 (set_attr "athlon_decode" "*,direct")
4939 (set_attr "amdfam10_decode" "*,double")
4940 (set_attr "bdver1_decode" "*,direct")
4941 (set_attr "fp_int_src" "true")])
4943 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4944 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4946 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4947 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4948 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4949 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4951 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4952 (set_attr "mode" "<MODEF:MODE>")
4953 (set_attr "unit" "*,i387,*,*")
4954 (set_attr "athlon_decode" "*,*,double,direct")
4955 (set_attr "amdfam10_decode" "*,*,vector,double")
4956 (set_attr "bdver1_decode" "*,*,double,direct")
4957 (set_attr "fp_int_src" "true")])
4960 [(set (match_operand:MODEF 0 "register_operand")
4961 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4962 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4963 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4964 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4965 && TARGET_INTER_UNIT_CONVERSIONS
4967 && (SSE_REG_P (operands[0])
4968 || (GET_CODE (operands[0]) == SUBREG
4969 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4970 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4973 [(set (match_operand:MODEF 0 "register_operand")
4974 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4975 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4976 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4977 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4978 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4980 && (SSE_REG_P (operands[0])
4981 || (GET_CODE (operands[0]) == SUBREG
4982 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4983 [(set (match_dup 2) (match_dup 1))
4984 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4986 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4987 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4989 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4990 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4991 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4992 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4995 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4996 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4997 [(set_attr "type" "fmov,sseicvt,sseicvt")
4998 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4999 (set_attr "mode" "<MODEF:MODE>")
5000 (set (attr "prefix_rex")
5002 (and (eq_attr "prefix" "maybe_vex")
5003 (match_test "<SWI48x:MODE>mode == DImode"))
5005 (const_string "*")))
5006 (set_attr "unit" "i387,*,*")
5007 (set_attr "athlon_decode" "*,double,direct")
5008 (set_attr "amdfam10_decode" "*,vector,double")
5009 (set_attr "bdver1_decode" "*,double,direct")
5010 (set_attr "fp_int_src" "true")])
5012 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
5013 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5015 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
5016 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5017 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5018 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5021 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5022 [(set_attr "type" "fmov,sseicvt")
5023 (set_attr "prefix" "orig,maybe_vex")
5024 (set_attr "mode" "<MODEF:MODE>")
5025 (set (attr "prefix_rex")
5027 (and (eq_attr "prefix" "maybe_vex")
5028 (match_test "<SWI48x:MODE>mode == DImode"))
5030 (const_string "*")))
5031 (set_attr "athlon_decode" "*,direct")
5032 (set_attr "amdfam10_decode" "*,double")
5033 (set_attr "bdver1_decode" "*,direct")
5034 (set_attr "fp_int_src" "true")])
5036 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5037 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5039 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5040 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5041 "TARGET_SSE2 && TARGET_SSE_MATH
5042 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5044 [(set_attr "type" "sseicvt")
5045 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5046 (set_attr "athlon_decode" "double,direct,double")
5047 (set_attr "amdfam10_decode" "vector,double,double")
5048 (set_attr "bdver1_decode" "double,direct,double")
5049 (set_attr "fp_int_src" "true")])
5051 (define_insn "*floatsi<mode>2_vector_sse"
5052 [(set (match_operand:MODEF 0 "register_operand" "=x")
5053 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5054 "TARGET_SSE2 && TARGET_SSE_MATH
5055 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5057 [(set_attr "type" "sseicvt")
5058 (set_attr "mode" "<MODE>")
5059 (set_attr "athlon_decode" "direct")
5060 (set_attr "amdfam10_decode" "double")
5061 (set_attr "bdver1_decode" "direct")
5062 (set_attr "fp_int_src" "true")])
5065 [(set (match_operand:MODEF 0 "register_operand")
5066 (float:MODEF (match_operand:SI 1 "register_operand")))
5067 (clobber (match_operand:SI 2 "memory_operand"))]
5068 "TARGET_SSE2 && TARGET_SSE_MATH
5069 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5071 && (SSE_REG_P (operands[0])
5072 || (GET_CODE (operands[0]) == SUBREG
5073 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5076 rtx op1 = operands[1];
5078 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5080 if (GET_CODE (op1) == SUBREG)
5081 op1 = SUBREG_REG (op1);
5083 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5085 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5086 emit_insn (gen_sse2_loadld (operands[4],
5087 CONST0_RTX (V4SImode), operands[1]));
5089 /* We can ignore possible trapping value in the
5090 high part of SSE register for non-trapping math. */
5091 else if (SSE_REG_P (op1) && !flag_trapping_math)
5092 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5095 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5096 emit_move_insn (operands[2], operands[1]);
5097 emit_insn (gen_sse2_loadld (operands[4],
5098 CONST0_RTX (V4SImode), operands[2]));
5100 if (<ssevecmode>mode == V4SFmode)
5101 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5103 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5108 [(set (match_operand:MODEF 0 "register_operand")
5109 (float:MODEF (match_operand:SI 1 "memory_operand")))
5110 (clobber (match_operand:SI 2 "memory_operand"))]
5111 "TARGET_SSE2 && TARGET_SSE_MATH
5112 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5114 && (SSE_REG_P (operands[0])
5115 || (GET_CODE (operands[0]) == SUBREG
5116 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5119 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5121 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5123 emit_insn (gen_sse2_loadld (operands[4],
5124 CONST0_RTX (V4SImode), operands[1]));
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 "register_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 rtx op1 = operands[1];
5145 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5147 if (GET_CODE (op1) == SUBREG)
5148 op1 = SUBREG_REG (op1);
5150 if (GENERAL_REG_P (op1))
5152 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5153 if (TARGET_INTER_UNIT_MOVES)
5154 emit_insn (gen_sse2_loadld (operands[4],
5155 CONST0_RTX (V4SImode), operands[1]));
5158 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5160 emit_insn (gen_sse2_loadld (operands[4],
5161 CONST0_RTX (V4SImode), operands[5]));
5162 ix86_free_from_memory (GET_MODE (operands[1]));
5165 /* We can ignore possible trapping value in the
5166 high part of SSE register for non-trapping math. */
5167 else if (SSE_REG_P (op1) && !flag_trapping_math)
5168 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5171 if (<ssevecmode>mode == V4SFmode)
5172 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5174 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5179 [(set (match_operand:MODEF 0 "register_operand")
5180 (float:MODEF (match_operand:SI 1 "memory_operand")))]
5181 "TARGET_SSE2 && TARGET_SSE_MATH
5182 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5184 && (SSE_REG_P (operands[0])
5185 || (GET_CODE (operands[0]) == SUBREG
5186 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5189 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5191 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5193 emit_insn (gen_sse2_loadld (operands[4],
5194 CONST0_RTX (V4SImode), operands[1]));
5195 if (<ssevecmode>mode == V4SFmode)
5196 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5198 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5202 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5203 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5205 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5206 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5207 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5208 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5210 [(set_attr "type" "sseicvt")
5211 (set_attr "mode" "<MODEF:MODE>")
5212 (set_attr "athlon_decode" "double,direct")
5213 (set_attr "amdfam10_decode" "vector,double")
5214 (set_attr "bdver1_decode" "double,direct")
5215 (set_attr "fp_int_src" "true")])
5217 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5218 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5220 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5221 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5222 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5223 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5224 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5225 [(set_attr "type" "sseicvt")
5226 (set_attr "prefix" "maybe_vex")
5227 (set_attr "mode" "<MODEF:MODE>")
5228 (set (attr "prefix_rex")
5230 (and (eq_attr "prefix" "maybe_vex")
5231 (match_test "<SWI48x:MODE>mode == DImode"))
5233 (const_string "*")))
5234 (set_attr "athlon_decode" "double,direct")
5235 (set_attr "amdfam10_decode" "vector,double")
5236 (set_attr "bdver1_decode" "double,direct")
5237 (set_attr "fp_int_src" "true")])
5240 [(set (match_operand:MODEF 0 "register_operand")
5241 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))
5242 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5243 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5244 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5245 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5247 && (SSE_REG_P (operands[0])
5248 || (GET_CODE (operands[0]) == SUBREG
5249 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5250 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5252 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5253 [(set (match_operand:MODEF 0 "register_operand" "=x")
5255 (match_operand:SWI48x 1 "memory_operand" "m")))]
5256 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5257 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5258 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5259 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5260 [(set_attr "type" "sseicvt")
5261 (set_attr "prefix" "maybe_vex")
5262 (set_attr "mode" "<MODEF:MODE>")
5263 (set (attr "prefix_rex")
5265 (and (eq_attr "prefix" "maybe_vex")
5266 (match_test "<SWI48x:MODE>mode == DImode"))
5268 (const_string "*")))
5269 (set_attr "athlon_decode" "direct")
5270 (set_attr "amdfam10_decode" "double")
5271 (set_attr "bdver1_decode" "direct")
5272 (set_attr "fp_int_src" "true")])
5275 [(set (match_operand:MODEF 0 "register_operand")
5276 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
5277 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5278 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5279 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5280 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5282 && (SSE_REG_P (operands[0])
5283 || (GET_CODE (operands[0]) == SUBREG
5284 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5285 [(set (match_dup 2) (match_dup 1))
5286 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5289 [(set (match_operand:MODEF 0 "register_operand")
5290 (float:MODEF (match_operand:SWI48x 1 "memory_operand")))
5291 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5292 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5293 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5295 && (SSE_REG_P (operands[0])
5296 || (GET_CODE (operands[0]) == SUBREG
5297 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5298 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5300 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5301 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5303 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5304 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5306 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5310 [(set_attr "type" "fmov,multi")
5311 (set_attr "mode" "<X87MODEF:MODE>")
5312 (set_attr "unit" "*,i387")
5313 (set_attr "fp_int_src" "true")])
5315 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5316 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5318 (match_operand:SWI48x 1 "memory_operand" "m")))]
5320 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5322 [(set_attr "type" "fmov")
5323 (set_attr "mode" "<X87MODEF:MODE>")
5324 (set_attr "fp_int_src" "true")])
5327 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5328 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5329 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5331 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5332 && reload_completed"
5333 [(set (match_dup 2) (match_dup 1))
5334 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5337 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5338 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5339 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5341 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5342 && reload_completed"
5343 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5345 ;; Avoid store forwarding (partial memory) stall penalty
5346 ;; by passing DImode value through XMM registers. */
5348 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5349 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5351 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5352 (clobber (match_scratch:V4SI 3 "=X,x"))
5353 (clobber (match_scratch:V4SI 4 "=X,x"))
5354 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5355 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5356 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5357 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5359 [(set_attr "type" "multi")
5360 (set_attr "mode" "<X87MODEF:MODE>")
5361 (set_attr "unit" "i387")
5362 (set_attr "fp_int_src" "true")])
5365 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5366 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5367 (clobber (match_scratch:V4SI 3))
5368 (clobber (match_scratch:V4SI 4))
5369 (clobber (match_operand:DI 2 "memory_operand"))]
5370 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5371 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5372 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5373 && reload_completed"
5374 [(set (match_dup 2) (match_dup 3))
5375 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5377 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5378 Assemble the 64-bit DImode value in an xmm register. */
5379 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5380 gen_rtx_SUBREG (SImode, operands[1], 0)));
5381 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5382 gen_rtx_SUBREG (SImode, operands[1], 4)));
5383 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5386 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5390 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5391 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5392 (clobber (match_scratch:V4SI 3))
5393 (clobber (match_scratch:V4SI 4))
5394 (clobber (match_operand:DI 2 "memory_operand"))]
5395 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5396 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5397 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5398 && reload_completed"
5399 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5401 ;; Avoid store forwarding (partial memory) stall penalty by extending
5402 ;; SImode value to DImode through XMM register instead of pushing two
5403 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5404 ;; targets benefit from this optimization. Also note that fild
5405 ;; loads from memory only.
5407 (define_insn "*floatunssi<mode>2_1"
5408 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5409 (unsigned_float:X87MODEF
5410 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5411 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5412 (clobber (match_scratch:SI 3 "=X,x"))]
5414 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5417 [(set_attr "type" "multi")
5418 (set_attr "mode" "<MODE>")])
5421 [(set (match_operand:X87MODEF 0 "register_operand")
5422 (unsigned_float:X87MODEF
5423 (match_operand:SI 1 "register_operand")))
5424 (clobber (match_operand:DI 2 "memory_operand"))
5425 (clobber (match_scratch:SI 3))]
5427 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5429 && reload_completed"
5430 [(set (match_dup 2) (match_dup 1))
5432 (float:X87MODEF (match_dup 2)))]
5433 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5436 [(set (match_operand:X87MODEF 0 "register_operand")
5437 (unsigned_float:X87MODEF
5438 (match_operand:SI 1 "memory_operand")))
5439 (clobber (match_operand:DI 2 "memory_operand"))
5440 (clobber (match_scratch:SI 3))]
5442 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5444 && reload_completed"
5445 [(set (match_dup 2) (match_dup 3))
5447 (float:X87MODEF (match_dup 2)))]
5449 emit_move_insn (operands[3], operands[1]);
5450 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5453 (define_expand "floatunssi<mode>2"
5455 [(set (match_operand:X87MODEF 0 "register_operand")
5456 (unsigned_float:X87MODEF
5457 (match_operand:SI 1 "nonimmediate_operand")))
5458 (clobber (match_dup 2))
5459 (clobber (match_scratch:SI 3))])]
5461 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5463 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5465 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5467 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5472 enum ix86_stack_slot slot = (virtuals_instantiated
5475 operands[2] = assign_386_stack_local (DImode, slot);
5479 (define_expand "floatunsdisf2"
5480 [(use (match_operand:SF 0 "register_operand"))
5481 (use (match_operand:DI 1 "nonimmediate_operand"))]
5482 "TARGET_64BIT && TARGET_SSE_MATH"
5483 "x86_emit_floatuns (operands); DONE;")
5485 (define_expand "floatunsdidf2"
5486 [(use (match_operand:DF 0 "register_operand"))
5487 (use (match_operand:DI 1 "nonimmediate_operand"))]
5488 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5489 && TARGET_SSE2 && TARGET_SSE_MATH"
5492 x86_emit_floatuns (operands);
5494 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5498 ;; Load effective address instructions
5500 (define_insn_and_split "*lea<mode>"
5501 [(set (match_operand:SWI48 0 "register_operand" "=r")
5502 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5505 if (SImode_address_operand (operands[1], VOIDmode))
5507 gcc_assert (TARGET_64BIT);
5508 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5511 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5513 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5516 enum machine_mode mode = <MODE>mode;
5519 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5520 change operands[] array behind our back. */
5521 pat = PATTERN (curr_insn);
5523 operands[0] = SET_DEST (pat);
5524 operands[1] = SET_SRC (pat);
5526 /* Emit all operations in SImode for zero-extended addresses. Recall
5527 that x86_64 inheretly zero-extends SImode operations to DImode. */
5528 if (SImode_address_operand (operands[1], VOIDmode))
5531 ix86_split_lea_for_addr (curr_insn, operands, mode);
5534 [(set_attr "type" "lea")
5537 (match_operand 1 "SImode_address_operand")
5539 (const_string "<MODE>")))])
5543 (define_expand "add<mode>3"
5544 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5545 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5546 (match_operand:SDWIM 2 "<general_operand>")))]
5548 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5550 (define_insn_and_split "*add<dwi>3_doubleword"
5551 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5553 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5554 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5555 (clobber (reg:CC FLAGS_REG))]
5556 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5559 [(parallel [(set (reg:CC FLAGS_REG)
5560 (unspec:CC [(match_dup 1) (match_dup 2)]
5563 (plus:DWIH (match_dup 1) (match_dup 2)))])
5564 (parallel [(set (match_dup 3)
5568 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5570 (clobber (reg:CC FLAGS_REG))])]
5571 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5573 (define_insn "*add<mode>3_cc"
5574 [(set (reg:CC FLAGS_REG)
5576 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5577 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5579 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5580 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5581 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5582 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5583 [(set_attr "type" "alu")
5584 (set_attr "mode" "<MODE>")])
5586 (define_insn "addqi3_cc"
5587 [(set (reg:CC FLAGS_REG)
5589 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5590 (match_operand:QI 2 "general_operand" "qn,qm")]
5592 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5593 (plus:QI (match_dup 1) (match_dup 2)))]
5594 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5595 "add{b}\t{%2, %0|%0, %2}"
5596 [(set_attr "type" "alu")
5597 (set_attr "mode" "QI")])
5599 (define_insn "*add<mode>_1"
5600 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5602 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5603 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5604 (clobber (reg:CC FLAGS_REG))]
5605 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5607 switch (get_attr_type (insn))
5613 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5614 if (operands[2] == const1_rtx)
5615 return "inc{<imodesuffix>}\t%0";
5618 gcc_assert (operands[2] == constm1_rtx);
5619 return "dec{<imodesuffix>}\t%0";
5623 /* For most processors, ADD is faster than LEA. This alternative
5624 was added to use ADD as much as possible. */
5625 if (which_alternative == 2)
5628 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5631 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5632 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5633 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5635 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5639 (cond [(eq_attr "alternative" "3")
5640 (const_string "lea")
5641 (match_operand:SWI48 2 "incdec_operand")
5642 (const_string "incdec")
5644 (const_string "alu")))
5645 (set (attr "length_immediate")
5647 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5649 (const_string "*")))
5650 (set_attr "mode" "<MODE>")])
5652 ;; It may seem that nonimmediate operand is proper one for operand 1.
5653 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5654 ;; we take care in ix86_binary_operator_ok to not allow two memory
5655 ;; operands so proper swapping will be done in reload. This allow
5656 ;; patterns constructed from addsi_1 to match.
5658 (define_insn "addsi_1_zext"
5659 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5661 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5662 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5663 (clobber (reg:CC FLAGS_REG))]
5664 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5666 switch (get_attr_type (insn))
5672 if (operands[2] == const1_rtx)
5673 return "inc{l}\t%k0";
5676 gcc_assert (operands[2] == constm1_rtx);
5677 return "dec{l}\t%k0";
5681 /* For most processors, ADD is faster than LEA. This alternative
5682 was added to use ADD as much as possible. */
5683 if (which_alternative == 1)
5686 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5689 if (x86_maybe_negate_const_int (&operands[2], SImode))
5690 return "sub{l}\t{%2, %k0|%k0, %2}";
5692 return "add{l}\t{%2, %k0|%k0, %2}";
5696 (cond [(eq_attr "alternative" "2")
5697 (const_string "lea")
5698 (match_operand:SI 2 "incdec_operand")
5699 (const_string "incdec")
5701 (const_string "alu")))
5702 (set (attr "length_immediate")
5704 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5706 (const_string "*")))
5707 (set_attr "mode" "SI")])
5709 (define_insn "*addhi_1"
5710 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5711 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5712 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5713 (clobber (reg:CC FLAGS_REG))]
5714 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5716 switch (get_attr_type (insn))
5722 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5723 if (operands[2] == const1_rtx)
5724 return "inc{w}\t%0";
5727 gcc_assert (operands[2] == constm1_rtx);
5728 return "dec{w}\t%0";
5732 /* For most processors, ADD is faster than LEA. This alternative
5733 was added to use ADD as much as possible. */
5734 if (which_alternative == 2)
5737 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5740 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5741 if (x86_maybe_negate_const_int (&operands[2], HImode))
5742 return "sub{w}\t{%2, %0|%0, %2}";
5744 return "add{w}\t{%2, %0|%0, %2}";
5748 (cond [(eq_attr "alternative" "3")
5749 (const_string "lea")
5750 (match_operand:HI 2 "incdec_operand")
5751 (const_string "incdec")
5753 (const_string "alu")))
5754 (set (attr "length_immediate")
5756 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5758 (const_string "*")))
5759 (set_attr "mode" "HI,HI,HI,SI")])
5761 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5762 (define_insn "*addqi_1"
5763 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5764 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5765 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5766 (clobber (reg:CC FLAGS_REG))]
5767 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5769 bool widen = (which_alternative == 3 || which_alternative == 4);
5771 switch (get_attr_type (insn))
5777 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5778 if (operands[2] == const1_rtx)
5779 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5782 gcc_assert (operands[2] == constm1_rtx);
5783 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5787 /* For most processors, ADD is faster than LEA. These alternatives
5788 were added to use ADD as much as possible. */
5789 if (which_alternative == 2 || which_alternative == 4)
5792 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5795 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5796 if (x86_maybe_negate_const_int (&operands[2], QImode))
5799 return "sub{l}\t{%2, %k0|%k0, %2}";
5801 return "sub{b}\t{%2, %0|%0, %2}";
5804 return "add{l}\t{%k2, %k0|%k0, %k2}";
5806 return "add{b}\t{%2, %0|%0, %2}";
5810 (cond [(eq_attr "alternative" "5")
5811 (const_string "lea")
5812 (match_operand:QI 2 "incdec_operand")
5813 (const_string "incdec")
5815 (const_string "alu")))
5816 (set (attr "length_immediate")
5818 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5820 (const_string "*")))
5821 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5823 (define_insn "*addqi_1_slp"
5824 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5825 (plus:QI (match_dup 0)
5826 (match_operand:QI 1 "general_operand" "qn,qm")))
5827 (clobber (reg:CC FLAGS_REG))]
5828 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5829 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5831 switch (get_attr_type (insn))
5834 if (operands[1] == const1_rtx)
5835 return "inc{b}\t%0";
5838 gcc_assert (operands[1] == constm1_rtx);
5839 return "dec{b}\t%0";
5843 if (x86_maybe_negate_const_int (&operands[1], QImode))
5844 return "sub{b}\t{%1, %0|%0, %1}";
5846 return "add{b}\t{%1, %0|%0, %1}";
5850 (if_then_else (match_operand:QI 1 "incdec_operand")
5851 (const_string "incdec")
5852 (const_string "alu1")))
5853 (set (attr "memory")
5854 (if_then_else (match_operand 1 "memory_operand")
5855 (const_string "load")
5856 (const_string "none")))
5857 (set_attr "mode" "QI")])
5859 ;; Split non destructive adds if we cannot use lea.
5861 [(set (match_operand:SWI48 0 "register_operand")
5862 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5863 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5864 (clobber (reg:CC FLAGS_REG))]
5865 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5866 [(set (match_dup 0) (match_dup 1))
5867 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5868 (clobber (reg:CC FLAGS_REG))])])
5870 ;; Convert add to the lea pattern to avoid flags dependency.
5872 [(set (match_operand:SWI 0 "register_operand")
5873 (plus:SWI (match_operand:SWI 1 "register_operand")
5874 (match_operand:SWI 2 "<nonmemory_operand>")))
5875 (clobber (reg:CC FLAGS_REG))]
5876 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5879 enum machine_mode mode = <MODE>mode;
5882 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5885 operands[0] = gen_lowpart (mode, operands[0]);
5886 operands[1] = gen_lowpart (mode, operands[1]);
5887 operands[2] = gen_lowpart (mode, operands[2]);
5890 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5892 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5896 ;; Split non destructive adds if we cannot use lea.
5898 [(set (match_operand:DI 0 "register_operand")
5900 (plus:SI (match_operand:SI 1 "register_operand")
5901 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5902 (clobber (reg:CC FLAGS_REG))]
5904 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5905 [(set (match_dup 3) (match_dup 1))
5906 (parallel [(set (match_dup 0)
5907 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5908 (clobber (reg:CC FLAGS_REG))])]
5909 "operands[3] = gen_lowpart (SImode, operands[0]);")
5911 ;; Convert add to the lea pattern to avoid flags dependency.
5913 [(set (match_operand:DI 0 "register_operand")
5915 (plus:SI (match_operand:SI 1 "register_operand")
5916 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5917 (clobber (reg:CC FLAGS_REG))]
5918 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5920 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5922 (define_insn "*add<mode>_2"
5923 [(set (reg FLAGS_REG)
5926 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5927 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5929 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5930 (plus:SWI (match_dup 1) (match_dup 2)))]
5931 "ix86_match_ccmode (insn, CCGOCmode)
5932 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5934 switch (get_attr_type (insn))
5937 if (operands[2] == const1_rtx)
5938 return "inc{<imodesuffix>}\t%0";
5941 gcc_assert (operands[2] == constm1_rtx);
5942 return "dec{<imodesuffix>}\t%0";
5946 if (which_alternative == 2)
5949 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5952 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5953 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5954 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5956 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5960 (if_then_else (match_operand:SWI 2 "incdec_operand")
5961 (const_string "incdec")
5962 (const_string "alu")))
5963 (set (attr "length_immediate")
5965 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5967 (const_string "*")))
5968 (set_attr "mode" "<MODE>")])
5970 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5971 (define_insn "*addsi_2_zext"
5972 [(set (reg FLAGS_REG)
5974 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5975 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5977 (set (match_operand:DI 0 "register_operand" "=r,r")
5978 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5979 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5980 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5982 switch (get_attr_type (insn))
5985 if (operands[2] == const1_rtx)
5986 return "inc{l}\t%k0";
5989 gcc_assert (operands[2] == constm1_rtx);
5990 return "dec{l}\t%k0";
5994 if (which_alternative == 1)
5997 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6000 if (x86_maybe_negate_const_int (&operands[2], SImode))
6001 return "sub{l}\t{%2, %k0|%k0, %2}";
6003 return "add{l}\t{%2, %k0|%k0, %2}";
6007 (if_then_else (match_operand:SI 2 "incdec_operand")
6008 (const_string "incdec")
6009 (const_string "alu")))
6010 (set (attr "length_immediate")
6012 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6014 (const_string "*")))
6015 (set_attr "mode" "SI")])
6017 (define_insn "*add<mode>_3"
6018 [(set (reg FLAGS_REG)
6020 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6021 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6022 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6023 "ix86_match_ccmode (insn, CCZmode)
6024 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6026 switch (get_attr_type (insn))
6029 if (operands[2] == const1_rtx)
6030 return "inc{<imodesuffix>}\t%0";
6033 gcc_assert (operands[2] == constm1_rtx);
6034 return "dec{<imodesuffix>}\t%0";
6038 if (which_alternative == 1)
6041 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6044 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6045 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6046 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6048 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6052 (if_then_else (match_operand:SWI 2 "incdec_operand")
6053 (const_string "incdec")
6054 (const_string "alu")))
6055 (set (attr "length_immediate")
6057 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6059 (const_string "*")))
6060 (set_attr "mode" "<MODE>")])
6062 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6063 (define_insn "*addsi_3_zext"
6064 [(set (reg FLAGS_REG)
6066 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6067 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6068 (set (match_operand:DI 0 "register_operand" "=r,r")
6069 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6070 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6071 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6073 switch (get_attr_type (insn))
6076 if (operands[2] == const1_rtx)
6077 return "inc{l}\t%k0";
6080 gcc_assert (operands[2] == constm1_rtx);
6081 return "dec{l}\t%k0";
6085 if (which_alternative == 1)
6088 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6091 if (x86_maybe_negate_const_int (&operands[2], SImode))
6092 return "sub{l}\t{%2, %k0|%k0, %2}";
6094 return "add{l}\t{%2, %k0|%k0, %2}";
6098 (if_then_else (match_operand:SI 2 "incdec_operand")
6099 (const_string "incdec")
6100 (const_string "alu")))
6101 (set (attr "length_immediate")
6103 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6105 (const_string "*")))
6106 (set_attr "mode" "SI")])
6108 ; For comparisons against 1, -1 and 128, we may generate better code
6109 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6110 ; is matched then. We can't accept general immediate, because for
6111 ; case of overflows, the result is messed up.
6112 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6113 ; only for comparisons not depending on it.
6115 (define_insn "*adddi_4"
6116 [(set (reg FLAGS_REG)
6118 (match_operand:DI 1 "nonimmediate_operand" "0")
6119 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6120 (clobber (match_scratch:DI 0 "=rm"))]
6122 && ix86_match_ccmode (insn, CCGCmode)"
6124 switch (get_attr_type (insn))
6127 if (operands[2] == constm1_rtx)
6128 return "inc{q}\t%0";
6131 gcc_assert (operands[2] == const1_rtx);
6132 return "dec{q}\t%0";
6136 if (x86_maybe_negate_const_int (&operands[2], DImode))
6137 return "add{q}\t{%2, %0|%0, %2}";
6139 return "sub{q}\t{%2, %0|%0, %2}";
6143 (if_then_else (match_operand:DI 2 "incdec_operand")
6144 (const_string "incdec")
6145 (const_string "alu")))
6146 (set (attr "length_immediate")
6148 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6150 (const_string "*")))
6151 (set_attr "mode" "DI")])
6153 ; For comparisons against 1, -1 and 128, we may generate better code
6154 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6155 ; is matched then. We can't accept general immediate, because for
6156 ; case of overflows, the result is messed up.
6157 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6158 ; only for comparisons not depending on it.
6160 (define_insn "*add<mode>_4"
6161 [(set (reg FLAGS_REG)
6163 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6164 (match_operand:SWI124 2 "const_int_operand" "n")))
6165 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6166 "ix86_match_ccmode (insn, CCGCmode)"
6168 switch (get_attr_type (insn))
6171 if (operands[2] == constm1_rtx)
6172 return "inc{<imodesuffix>}\t%0";
6175 gcc_assert (operands[2] == const1_rtx);
6176 return "dec{<imodesuffix>}\t%0";
6180 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6181 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6183 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6187 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6188 (const_string "incdec")
6189 (const_string "alu")))
6190 (set (attr "length_immediate")
6192 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6194 (const_string "*")))
6195 (set_attr "mode" "<MODE>")])
6197 (define_insn "*add<mode>_5"
6198 [(set (reg FLAGS_REG)
6201 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6202 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6204 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6205 "ix86_match_ccmode (insn, CCGOCmode)
6206 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6208 switch (get_attr_type (insn))
6211 if (operands[2] == const1_rtx)
6212 return "inc{<imodesuffix>}\t%0";
6215 gcc_assert (operands[2] == constm1_rtx);
6216 return "dec{<imodesuffix>}\t%0";
6220 if (which_alternative == 1)
6223 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6226 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6227 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6228 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6230 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6234 (if_then_else (match_operand:SWI 2 "incdec_operand")
6235 (const_string "incdec")
6236 (const_string "alu")))
6237 (set (attr "length_immediate")
6239 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6241 (const_string "*")))
6242 (set_attr "mode" "<MODE>")])
6244 (define_insn "*addqi_ext_1_rex64"
6245 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6250 (match_operand 1 "ext_register_operand" "0")
6253 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6254 (clobber (reg:CC FLAGS_REG))]
6257 switch (get_attr_type (insn))
6260 if (operands[2] == const1_rtx)
6261 return "inc{b}\t%h0";
6264 gcc_assert (operands[2] == constm1_rtx);
6265 return "dec{b}\t%h0";
6269 return "add{b}\t{%2, %h0|%h0, %2}";
6273 (if_then_else (match_operand:QI 2 "incdec_operand")
6274 (const_string "incdec")
6275 (const_string "alu")))
6276 (set_attr "modrm" "1")
6277 (set_attr "mode" "QI")])
6279 (define_insn "addqi_ext_1"
6280 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6285 (match_operand 1 "ext_register_operand" "0")
6288 (match_operand:QI 2 "general_operand" "Qmn")))
6289 (clobber (reg:CC FLAGS_REG))]
6292 switch (get_attr_type (insn))
6295 if (operands[2] == const1_rtx)
6296 return "inc{b}\t%h0";
6299 gcc_assert (operands[2] == constm1_rtx);
6300 return "dec{b}\t%h0";
6304 return "add{b}\t{%2, %h0|%h0, %2}";
6308 (if_then_else (match_operand:QI 2 "incdec_operand")
6309 (const_string "incdec")
6310 (const_string "alu")))
6311 (set_attr "modrm" "1")
6312 (set_attr "mode" "QI")])
6314 (define_insn "*addqi_ext_2"
6315 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6320 (match_operand 1 "ext_register_operand" "%0")
6324 (match_operand 2 "ext_register_operand" "Q")
6327 (clobber (reg:CC FLAGS_REG))]
6329 "add{b}\t{%h2, %h0|%h0, %h2}"
6330 [(set_attr "type" "alu")
6331 (set_attr "mode" "QI")])
6333 ;; The lea patterns for modes less than 32 bits need to be matched by
6334 ;; several insns converted to real lea by splitters.
6336 (define_insn_and_split "*lea_general_1"
6337 [(set (match_operand 0 "register_operand" "=r")
6338 (plus (plus (match_operand 1 "index_register_operand" "l")
6339 (match_operand 2 "register_operand" "r"))
6340 (match_operand 3 "immediate_operand" "i")))]
6341 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6342 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6343 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6344 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6345 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6346 || GET_MODE (operands[3]) == VOIDmode)"
6348 "&& reload_completed"
6351 enum machine_mode mode = SImode;
6354 operands[0] = gen_lowpart (mode, operands[0]);
6355 operands[1] = gen_lowpart (mode, operands[1]);
6356 operands[2] = gen_lowpart (mode, operands[2]);
6357 operands[3] = gen_lowpart (mode, operands[3]);
6359 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6362 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6365 [(set_attr "type" "lea")
6366 (set_attr "mode" "SI")])
6368 (define_insn_and_split "*lea_general_2"
6369 [(set (match_operand 0 "register_operand" "=r")
6370 (plus (mult (match_operand 1 "index_register_operand" "l")
6371 (match_operand 2 "const248_operand" "n"))
6372 (match_operand 3 "nonmemory_operand" "ri")))]
6373 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6374 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6375 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6376 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6377 || GET_MODE (operands[3]) == VOIDmode)"
6379 "&& reload_completed"
6382 enum machine_mode mode = SImode;
6385 operands[0] = gen_lowpart (mode, operands[0]);
6386 operands[1] = gen_lowpart (mode, operands[1]);
6387 operands[3] = gen_lowpart (mode, operands[3]);
6389 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6392 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6395 [(set_attr "type" "lea")
6396 (set_attr "mode" "SI")])
6398 (define_insn_and_split "*lea_general_3"
6399 [(set (match_operand 0 "register_operand" "=r")
6400 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6401 (match_operand 2 "const248_operand" "n"))
6402 (match_operand 3 "register_operand" "r"))
6403 (match_operand 4 "immediate_operand" "i")))]
6404 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6405 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6406 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6407 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6409 "&& reload_completed"
6412 enum machine_mode mode = SImode;
6415 operands[0] = gen_lowpart (mode, operands[0]);
6416 operands[1] = gen_lowpart (mode, operands[1]);
6417 operands[3] = gen_lowpart (mode, operands[3]);
6418 operands[4] = gen_lowpart (mode, operands[4]);
6420 pat = gen_rtx_PLUS (mode,
6422 gen_rtx_MULT (mode, operands[1],
6427 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6430 [(set_attr "type" "lea")
6431 (set_attr "mode" "SI")])
6433 (define_insn_and_split "*lea_general_4"
6434 [(set (match_operand 0 "register_operand" "=r")
6436 (match_operand 1 "index_register_operand" "l")
6437 (match_operand 2 "const_int_operand" "n"))
6438 (match_operand 3 "const_int_operand" "n")))]
6439 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6440 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6441 || GET_MODE (operands[0]) == SImode
6442 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6443 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6444 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6445 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6446 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6448 "&& reload_completed"
6451 enum machine_mode mode = GET_MODE (operands[0]);
6454 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6457 operands[0] = gen_lowpart (mode, operands[0]);
6458 operands[1] = gen_lowpart (mode, operands[1]);
6461 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6463 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6464 INTVAL (operands[3]));
6466 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6469 [(set_attr "type" "lea")
6471 (if_then_else (match_operand:DI 0)
6473 (const_string "SI")))])
6475 ;; Subtract instructions
6477 (define_expand "sub<mode>3"
6478 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6479 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6480 (match_operand:SDWIM 2 "<general_operand>")))]
6482 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6484 (define_insn_and_split "*sub<dwi>3_doubleword"
6485 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6487 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6488 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6489 (clobber (reg:CC FLAGS_REG))]
6490 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6493 [(parallel [(set (reg:CC FLAGS_REG)
6494 (compare:CC (match_dup 1) (match_dup 2)))
6496 (minus:DWIH (match_dup 1) (match_dup 2)))])
6497 (parallel [(set (match_dup 3)
6501 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6503 (clobber (reg:CC FLAGS_REG))])]
6504 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6506 (define_insn "*sub<mode>_1"
6507 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6509 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6510 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6511 (clobber (reg:CC FLAGS_REG))]
6512 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6513 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6514 [(set_attr "type" "alu")
6515 (set_attr "mode" "<MODE>")])
6517 (define_insn "*subsi_1_zext"
6518 [(set (match_operand:DI 0 "register_operand" "=r")
6520 (minus:SI (match_operand:SI 1 "register_operand" "0")
6521 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6522 (clobber (reg:CC FLAGS_REG))]
6523 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6524 "sub{l}\t{%2, %k0|%k0, %2}"
6525 [(set_attr "type" "alu")
6526 (set_attr "mode" "SI")])
6528 (define_insn "*subqi_1_slp"
6529 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6530 (minus:QI (match_dup 0)
6531 (match_operand:QI 1 "general_operand" "qn,qm")))
6532 (clobber (reg:CC FLAGS_REG))]
6533 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6534 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6535 "sub{b}\t{%1, %0|%0, %1}"
6536 [(set_attr "type" "alu1")
6537 (set_attr "mode" "QI")])
6539 (define_insn "*sub<mode>_2"
6540 [(set (reg FLAGS_REG)
6543 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6544 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6546 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6547 (minus:SWI (match_dup 1) (match_dup 2)))]
6548 "ix86_match_ccmode (insn, CCGOCmode)
6549 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6550 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6551 [(set_attr "type" "alu")
6552 (set_attr "mode" "<MODE>")])
6554 (define_insn "*subsi_2_zext"
6555 [(set (reg FLAGS_REG)
6557 (minus:SI (match_operand:SI 1 "register_operand" "0")
6558 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6560 (set (match_operand:DI 0 "register_operand" "=r")
6562 (minus:SI (match_dup 1)
6564 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6565 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6566 "sub{l}\t{%2, %k0|%k0, %2}"
6567 [(set_attr "type" "alu")
6568 (set_attr "mode" "SI")])
6570 (define_insn "*sub<mode>_3"
6571 [(set (reg FLAGS_REG)
6572 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6573 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6574 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6575 (minus:SWI (match_dup 1) (match_dup 2)))]
6576 "ix86_match_ccmode (insn, CCmode)
6577 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6578 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6579 [(set_attr "type" "alu")
6580 (set_attr "mode" "<MODE>")])
6582 (define_insn "*subsi_3_zext"
6583 [(set (reg FLAGS_REG)
6584 (compare (match_operand:SI 1 "register_operand" "0")
6585 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6586 (set (match_operand:DI 0 "register_operand" "=r")
6588 (minus:SI (match_dup 1)
6590 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6591 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6592 "sub{l}\t{%2, %1|%1, %2}"
6593 [(set_attr "type" "alu")
6594 (set_attr "mode" "SI")])
6596 ;; Add with carry and subtract with borrow
6598 (define_expand "<plusminus_insn><mode>3_carry"
6600 [(set (match_operand:SWI 0 "nonimmediate_operand")
6602 (match_operand:SWI 1 "nonimmediate_operand")
6603 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6604 [(match_operand 3 "flags_reg_operand")
6606 (match_operand:SWI 2 "<general_operand>"))))
6607 (clobber (reg:CC FLAGS_REG))])]
6608 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6610 (define_insn "*<plusminus_insn><mode>3_carry"
6611 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6613 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6615 (match_operator 3 "ix86_carry_flag_operator"
6616 [(reg FLAGS_REG) (const_int 0)])
6617 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6618 (clobber (reg:CC FLAGS_REG))]
6619 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6620 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6621 [(set_attr "type" "alu")
6622 (set_attr "use_carry" "1")
6623 (set_attr "pent_pair" "pu")
6624 (set_attr "mode" "<MODE>")])
6626 (define_insn "*addsi3_carry_zext"
6627 [(set (match_operand:DI 0 "register_operand" "=r")
6629 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6630 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6631 [(reg FLAGS_REG) (const_int 0)])
6632 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6633 (clobber (reg:CC FLAGS_REG))]
6634 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6635 "adc{l}\t{%2, %k0|%k0, %2}"
6636 [(set_attr "type" "alu")
6637 (set_attr "use_carry" "1")
6638 (set_attr "pent_pair" "pu")
6639 (set_attr "mode" "SI")])
6641 (define_insn "*subsi3_carry_zext"
6642 [(set (match_operand:DI 0 "register_operand" "=r")
6644 (minus:SI (match_operand:SI 1 "register_operand" "0")
6645 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6646 [(reg FLAGS_REG) (const_int 0)])
6647 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6648 (clobber (reg:CC FLAGS_REG))]
6649 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6650 "sbb{l}\t{%2, %k0|%k0, %2}"
6651 [(set_attr "type" "alu")
6652 (set_attr "pent_pair" "pu")
6653 (set_attr "mode" "SI")])
6657 (define_insn "adcx<mode>3"
6658 [(set (reg:CCC FLAGS_REG)
6661 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6663 (match_operator 4 "ix86_carry_flag_operator"
6664 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6665 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6667 (set (match_operand:SWI48 0 "register_operand" "=r")
6668 (plus:SWI48 (match_dup 1)
6669 (plus:SWI48 (match_op_dup 4
6670 [(match_dup 3) (const_int 0)])
6672 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6673 "adcx\t{%2, %0|%0, %2}"
6674 [(set_attr "type" "alu")
6675 (set_attr "use_carry" "1")
6676 (set_attr "mode" "<MODE>")])
6678 ;; Overflow setting add and subtract instructions
6680 (define_insn "*add<mode>3_cconly_overflow"
6681 [(set (reg:CCC FLAGS_REG)
6684 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6685 (match_operand:SWI 2 "<general_operand>" "<g>"))
6687 (clobber (match_scratch:SWI 0 "=<r>"))]
6688 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6689 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6690 [(set_attr "type" "alu")
6691 (set_attr "mode" "<MODE>")])
6693 (define_insn "*sub<mode>3_cconly_overflow"
6694 [(set (reg:CCC FLAGS_REG)
6697 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6698 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6701 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6702 [(set_attr "type" "icmp")
6703 (set_attr "mode" "<MODE>")])
6705 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6706 [(set (reg:CCC FLAGS_REG)
6709 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6710 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6712 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6713 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6714 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6715 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6716 [(set_attr "type" "alu")
6717 (set_attr "mode" "<MODE>")])
6719 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6720 [(set (reg:CCC FLAGS_REG)
6723 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6724 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6726 (set (match_operand:DI 0 "register_operand" "=r")
6727 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6728 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6729 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6730 [(set_attr "type" "alu")
6731 (set_attr "mode" "SI")])
6733 ;; The patterns that match these are at the end of this file.
6735 (define_expand "<plusminus_insn>xf3"
6736 [(set (match_operand:XF 0 "register_operand")
6738 (match_operand:XF 1 "register_operand")
6739 (match_operand:XF 2 "register_operand")))]
6742 (define_expand "<plusminus_insn><mode>3"
6743 [(set (match_operand:MODEF 0 "register_operand")
6745 (match_operand:MODEF 1 "register_operand")
6746 (match_operand:MODEF 2 "nonimmediate_operand")))]
6747 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6748 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6750 ;; Multiply instructions
6752 (define_expand "mul<mode>3"
6753 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6755 (match_operand:SWIM248 1 "register_operand")
6756 (match_operand:SWIM248 2 "<general_operand>")))
6757 (clobber (reg:CC FLAGS_REG))])])
6759 (define_expand "mulqi3"
6760 [(parallel [(set (match_operand:QI 0 "register_operand")
6762 (match_operand:QI 1 "register_operand")
6763 (match_operand:QI 2 "nonimmediate_operand")))
6764 (clobber (reg:CC FLAGS_REG))])]
6765 "TARGET_QIMODE_MATH")
6768 ;; IMUL reg32/64, reg32/64, imm8 Direct
6769 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6770 ;; IMUL reg32/64, reg32/64, imm32 Direct
6771 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6772 ;; IMUL reg32/64, reg32/64 Direct
6773 ;; IMUL reg32/64, mem32/64 Direct
6775 ;; On BDVER1, all above IMULs use DirectPath
6777 (define_insn "*mul<mode>3_1"
6778 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6780 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6781 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6782 (clobber (reg:CC FLAGS_REG))]
6783 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6785 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6786 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6787 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6788 [(set_attr "type" "imul")
6789 (set_attr "prefix_0f" "0,0,1")
6790 (set (attr "athlon_decode")
6791 (cond [(eq_attr "cpu" "athlon")
6792 (const_string "vector")
6793 (eq_attr "alternative" "1")
6794 (const_string "vector")
6795 (and (eq_attr "alternative" "2")
6796 (match_operand 1 "memory_operand"))
6797 (const_string "vector")]
6798 (const_string "direct")))
6799 (set (attr "amdfam10_decode")
6800 (cond [(and (eq_attr "alternative" "0,1")
6801 (match_operand 1 "memory_operand"))
6802 (const_string "vector")]
6803 (const_string "direct")))
6804 (set_attr "bdver1_decode" "direct")
6805 (set_attr "mode" "<MODE>")])
6807 (define_insn "*mulsi3_1_zext"
6808 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6810 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6811 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6812 (clobber (reg:CC FLAGS_REG))]
6814 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6816 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6817 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6818 imul{l}\t{%2, %k0|%k0, %2}"
6819 [(set_attr "type" "imul")
6820 (set_attr "prefix_0f" "0,0,1")
6821 (set (attr "athlon_decode")
6822 (cond [(eq_attr "cpu" "athlon")
6823 (const_string "vector")
6824 (eq_attr "alternative" "1")
6825 (const_string "vector")
6826 (and (eq_attr "alternative" "2")
6827 (match_operand 1 "memory_operand"))
6828 (const_string "vector")]
6829 (const_string "direct")))
6830 (set (attr "amdfam10_decode")
6831 (cond [(and (eq_attr "alternative" "0,1")
6832 (match_operand 1 "memory_operand"))
6833 (const_string "vector")]
6834 (const_string "direct")))
6835 (set_attr "bdver1_decode" "direct")
6836 (set_attr "mode" "SI")])
6839 ;; IMUL reg16, reg16, imm8 VectorPath
6840 ;; IMUL reg16, mem16, imm8 VectorPath
6841 ;; IMUL reg16, reg16, imm16 VectorPath
6842 ;; IMUL reg16, mem16, imm16 VectorPath
6843 ;; IMUL reg16, reg16 Direct
6844 ;; IMUL reg16, mem16 Direct
6846 ;; On BDVER1, all HI MULs use DoublePath
6848 (define_insn "*mulhi3_1"
6849 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6850 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6851 (match_operand:HI 2 "general_operand" "K,n,mr")))
6852 (clobber (reg:CC FLAGS_REG))]
6854 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6856 imul{w}\t{%2, %1, %0|%0, %1, %2}
6857 imul{w}\t{%2, %1, %0|%0, %1, %2}
6858 imul{w}\t{%2, %0|%0, %2}"
6859 [(set_attr "type" "imul")
6860 (set_attr "prefix_0f" "0,0,1")
6861 (set (attr "athlon_decode")
6862 (cond [(eq_attr "cpu" "athlon")
6863 (const_string "vector")
6864 (eq_attr "alternative" "1,2")
6865 (const_string "vector")]
6866 (const_string "direct")))
6867 (set (attr "amdfam10_decode")
6868 (cond [(eq_attr "alternative" "0,1")
6869 (const_string "vector")]
6870 (const_string "direct")))
6871 (set_attr "bdver1_decode" "double")
6872 (set_attr "mode" "HI")])
6874 ;;On AMDFAM10 and BDVER1
6878 (define_insn "*mulqi3_1"
6879 [(set (match_operand:QI 0 "register_operand" "=a")
6880 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6881 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6882 (clobber (reg:CC FLAGS_REG))]
6884 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6886 [(set_attr "type" "imul")
6887 (set_attr "length_immediate" "0")
6888 (set (attr "athlon_decode")
6889 (if_then_else (eq_attr "cpu" "athlon")
6890 (const_string "vector")
6891 (const_string "direct")))
6892 (set_attr "amdfam10_decode" "direct")
6893 (set_attr "bdver1_decode" "direct")
6894 (set_attr "mode" "QI")])
6896 (define_expand "<u>mul<mode><dwi>3"
6897 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6900 (match_operand:DWIH 1 "nonimmediate_operand"))
6902 (match_operand:DWIH 2 "register_operand"))))
6903 (clobber (reg:CC FLAGS_REG))])])
6905 (define_expand "<u>mulqihi3"
6906 [(parallel [(set (match_operand:HI 0 "register_operand")
6909 (match_operand:QI 1 "nonimmediate_operand"))
6911 (match_operand:QI 2 "register_operand"))))
6912 (clobber (reg:CC FLAGS_REG))])]
6913 "TARGET_QIMODE_MATH")
6915 (define_insn "*bmi2_umulditi3_1"
6916 [(set (match_operand:DI 0 "register_operand" "=r")
6918 (match_operand:DI 2 "nonimmediate_operand" "%d")
6919 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6920 (set (match_operand:DI 1 "register_operand" "=r")
6923 (mult:TI (zero_extend:TI (match_dup 2))
6924 (zero_extend:TI (match_dup 3)))
6926 "TARGET_64BIT && TARGET_BMI2
6927 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6928 "mulx\t{%3, %0, %1|%1, %0, %3}"
6929 [(set_attr "type" "imulx")
6930 (set_attr "prefix" "vex")
6931 (set_attr "mode" "DI")])
6933 (define_insn "*bmi2_umulsidi3_1"
6934 [(set (match_operand:SI 0 "register_operand" "=r")
6936 (match_operand:SI 2 "nonimmediate_operand" "%d")
6937 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6938 (set (match_operand:SI 1 "register_operand" "=r")
6941 (mult:DI (zero_extend:DI (match_dup 2))
6942 (zero_extend:DI (match_dup 3)))
6944 "!TARGET_64BIT && TARGET_BMI2
6945 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6946 "mulx\t{%3, %0, %1|%1, %0, %3}"
6947 [(set_attr "type" "imulx")
6948 (set_attr "prefix" "vex")
6949 (set_attr "mode" "SI")])
6951 (define_insn "*umul<mode><dwi>3_1"
6952 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6955 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6957 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6958 (clobber (reg:CC FLAGS_REG))]
6959 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6962 mul{<imodesuffix>}\t%2"
6963 [(set_attr "isa" "bmi2,*")
6964 (set_attr "type" "imulx,imul")
6965 (set_attr "length_immediate" "*,0")
6966 (set (attr "athlon_decode")
6967 (cond [(eq_attr "alternative" "1")
6968 (if_then_else (eq_attr "cpu" "athlon")
6969 (const_string "vector")
6970 (const_string "double"))]
6971 (const_string "*")))
6972 (set_attr "amdfam10_decode" "*,double")
6973 (set_attr "bdver1_decode" "*,direct")
6974 (set_attr "prefix" "vex,orig")
6975 (set_attr "mode" "<MODE>")])
6977 ;; Convert mul to the mulx pattern to avoid flags dependency.
6979 [(set (match_operand:<DWI> 0 "register_operand")
6982 (match_operand:DWIH 1 "register_operand"))
6984 (match_operand:DWIH 2 "nonimmediate_operand"))))
6985 (clobber (reg:CC FLAGS_REG))]
6986 "TARGET_BMI2 && reload_completed
6987 && true_regnum (operands[1]) == DX_REG"
6988 [(parallel [(set (match_dup 3)
6989 (mult:DWIH (match_dup 1) (match_dup 2)))
6993 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6994 (zero_extend:<DWI> (match_dup 2)))
6997 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6999 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
7002 (define_insn "*mul<mode><dwi>3_1"
7003 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7006 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7008 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7009 (clobber (reg:CC FLAGS_REG))]
7010 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7011 "imul{<imodesuffix>}\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" "<MODE>")])
7022 (define_insn "*<u>mulqihi3_1"
7023 [(set (match_operand:HI 0 "register_operand" "=a")
7026 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7028 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7029 (clobber (reg:CC FLAGS_REG))]
7031 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7032 "<sgnprefix>mul{b}\t%2"
7033 [(set_attr "type" "imul")
7034 (set_attr "length_immediate" "0")
7035 (set (attr "athlon_decode")
7036 (if_then_else (eq_attr "cpu" "athlon")
7037 (const_string "vector")
7038 (const_string "direct")))
7039 (set_attr "amdfam10_decode" "direct")
7040 (set_attr "bdver1_decode" "direct")
7041 (set_attr "mode" "QI")])
7043 (define_expand "<s>mul<mode>3_highpart"
7044 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7049 (match_operand:SWI48 1 "nonimmediate_operand"))
7051 (match_operand:SWI48 2 "register_operand")))
7053 (clobber (match_scratch:SWI48 3))
7054 (clobber (reg:CC FLAGS_REG))])]
7056 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7058 (define_insn "*<s>muldi3_highpart_1"
7059 [(set (match_operand:DI 0 "register_operand" "=d")
7064 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7066 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7068 (clobber (match_scratch:DI 3 "=1"))
7069 (clobber (reg:CC FLAGS_REG))]
7071 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7072 "<sgnprefix>mul{q}\t%2"
7073 [(set_attr "type" "imul")
7074 (set_attr "length_immediate" "0")
7075 (set (attr "athlon_decode")
7076 (if_then_else (eq_attr "cpu" "athlon")
7077 (const_string "vector")
7078 (const_string "double")))
7079 (set_attr "amdfam10_decode" "double")
7080 (set_attr "bdver1_decode" "direct")
7081 (set_attr "mode" "DI")])
7083 (define_insn "*<s>mulsi3_highpart_1"
7084 [(set (match_operand:SI 0 "register_operand" "=d")
7089 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7091 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7093 (clobber (match_scratch:SI 3 "=1"))
7094 (clobber (reg:CC FLAGS_REG))]
7095 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7096 "<sgnprefix>mul{l}\t%2"
7097 [(set_attr "type" "imul")
7098 (set_attr "length_immediate" "0")
7099 (set (attr "athlon_decode")
7100 (if_then_else (eq_attr "cpu" "athlon")
7101 (const_string "vector")
7102 (const_string "double")))
7103 (set_attr "amdfam10_decode" "double")
7104 (set_attr "bdver1_decode" "direct")
7105 (set_attr "mode" "SI")])
7107 (define_insn "*<s>mulsi3_highpart_zext"
7108 [(set (match_operand:DI 0 "register_operand" "=d")
7109 (zero_extend:DI (truncate:SI
7111 (mult:DI (any_extend:DI
7112 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7114 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7116 (clobber (match_scratch:SI 3 "=1"))
7117 (clobber (reg:CC FLAGS_REG))]
7119 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7120 "<sgnprefix>mul{l}\t%2"
7121 [(set_attr "type" "imul")
7122 (set_attr "length_immediate" "0")
7123 (set (attr "athlon_decode")
7124 (if_then_else (eq_attr "cpu" "athlon")
7125 (const_string "vector")
7126 (const_string "double")))
7127 (set_attr "amdfam10_decode" "double")
7128 (set_attr "bdver1_decode" "direct")
7129 (set_attr "mode" "SI")])
7131 ;; The patterns that match these are at the end of this file.
7133 (define_expand "mulxf3"
7134 [(set (match_operand:XF 0 "register_operand")
7135 (mult:XF (match_operand:XF 1 "register_operand")
7136 (match_operand:XF 2 "register_operand")))]
7139 (define_expand "mul<mode>3"
7140 [(set (match_operand:MODEF 0 "register_operand")
7141 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7142 (match_operand:MODEF 2 "nonimmediate_operand")))]
7143 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7144 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7146 ;; Divide instructions
7148 ;; The patterns that match these are at the end of this file.
7150 (define_expand "divxf3"
7151 [(set (match_operand:XF 0 "register_operand")
7152 (div:XF (match_operand:XF 1 "register_operand")
7153 (match_operand:XF 2 "register_operand")))]
7156 (define_expand "divdf3"
7157 [(set (match_operand:DF 0 "register_operand")
7158 (div:DF (match_operand:DF 1 "register_operand")
7159 (match_operand:DF 2 "nonimmediate_operand")))]
7160 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7161 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7163 (define_expand "divsf3"
7164 [(set (match_operand:SF 0 "register_operand")
7165 (div:SF (match_operand:SF 1 "register_operand")
7166 (match_operand:SF 2 "nonimmediate_operand")))]
7167 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7172 && optimize_insn_for_speed_p ()
7173 && flag_finite_math_only && !flag_trapping_math
7174 && flag_unsafe_math_optimizations)
7176 ix86_emit_swdivsf (operands[0], operands[1],
7177 operands[2], SFmode);
7182 ;; Divmod instructions.
7184 (define_expand "divmod<mode>4"
7185 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7187 (match_operand:SWIM248 1 "register_operand")
7188 (match_operand:SWIM248 2 "nonimmediate_operand")))
7189 (set (match_operand:SWIM248 3 "register_operand")
7190 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7191 (clobber (reg:CC FLAGS_REG))])])
7193 ;; Split with 8bit unsigned divide:
7194 ;; if (dividend an divisor are in [0-255])
7195 ;; use 8bit unsigned integer divide
7197 ;; use original integer divide
7199 [(set (match_operand:SWI48 0 "register_operand")
7200 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7201 (match_operand:SWI48 3 "nonimmediate_operand")))
7202 (set (match_operand:SWI48 1 "register_operand")
7203 (mod:SWI48 (match_dup 2) (match_dup 3)))
7204 (clobber (reg:CC FLAGS_REG))]
7205 "TARGET_USE_8BIT_IDIV
7206 && TARGET_QIMODE_MATH
7207 && can_create_pseudo_p ()
7208 && !optimize_insn_for_size_p ()"
7210 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7212 (define_insn_and_split "divmod<mode>4_1"
7213 [(set (match_operand:SWI48 0 "register_operand" "=a")
7214 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7215 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7216 (set (match_operand:SWI48 1 "register_operand" "=&d")
7217 (mod:SWI48 (match_dup 2) (match_dup 3)))
7218 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7219 (clobber (reg:CC FLAGS_REG))]
7223 [(parallel [(set (match_dup 1)
7224 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7225 (clobber (reg:CC FLAGS_REG))])
7226 (parallel [(set (match_dup 0)
7227 (div:SWI48 (match_dup 2) (match_dup 3)))
7229 (mod:SWI48 (match_dup 2) (match_dup 3)))
7231 (clobber (reg:CC FLAGS_REG))])]
7233 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7235 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7236 operands[4] = operands[2];
7239 /* Avoid use of cltd in favor of a mov+shift. */
7240 emit_move_insn (operands[1], operands[2]);
7241 operands[4] = operands[1];
7244 [(set_attr "type" "multi")
7245 (set_attr "mode" "<MODE>")])
7247 (define_insn_and_split "*divmod<mode>4"
7248 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7249 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7250 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7251 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7252 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7253 (clobber (reg:CC FLAGS_REG))]
7257 [(parallel [(set (match_dup 1)
7258 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7259 (clobber (reg:CC FLAGS_REG))])
7260 (parallel [(set (match_dup 0)
7261 (div:SWIM248 (match_dup 2) (match_dup 3)))
7263 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7265 (clobber (reg:CC FLAGS_REG))])]
7267 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7269 if (<MODE>mode != HImode
7270 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7271 operands[4] = operands[2];
7274 /* Avoid use of cltd in favor of a mov+shift. */
7275 emit_move_insn (operands[1], operands[2]);
7276 operands[4] = operands[1];
7279 [(set_attr "type" "multi")
7280 (set_attr "mode" "<MODE>")])
7282 (define_insn "*divmod<mode>4_noext"
7283 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7284 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7285 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7286 (set (match_operand:SWIM248 1 "register_operand" "=d")
7287 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7288 (use (match_operand:SWIM248 4 "register_operand" "1"))
7289 (clobber (reg:CC FLAGS_REG))]
7291 "idiv{<imodesuffix>}\t%3"
7292 [(set_attr "type" "idiv")
7293 (set_attr "mode" "<MODE>")])
7295 (define_expand "divmodqi4"
7296 [(parallel [(set (match_operand:QI 0 "register_operand")
7298 (match_operand:QI 1 "register_operand")
7299 (match_operand:QI 2 "nonimmediate_operand")))
7300 (set (match_operand:QI 3 "register_operand")
7301 (mod:QI (match_dup 1) (match_dup 2)))
7302 (clobber (reg:CC FLAGS_REG))])]
7303 "TARGET_QIMODE_MATH"
7308 tmp0 = gen_reg_rtx (HImode);
7309 tmp1 = gen_reg_rtx (HImode);
7311 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7313 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7314 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7316 /* Extract remainder from AH. */
7317 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7318 insn = emit_move_insn (operands[3], tmp1);
7320 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7321 set_unique_reg_note (insn, REG_EQUAL, mod);
7323 /* Extract quotient from AL. */
7324 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7326 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7327 set_unique_reg_note (insn, REG_EQUAL, div);
7332 ;; Divide AX by r/m8, with result stored in
7335 ;; Change div/mod to HImode and extend the second argument to HImode
7336 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7337 ;; combine may fail.
7338 (define_insn "divmodhiqi3"
7339 [(set (match_operand:HI 0 "register_operand" "=a")
7344 (mod:HI (match_operand:HI 1 "register_operand" "0")
7346 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7350 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7351 (clobber (reg:CC FLAGS_REG))]
7352 "TARGET_QIMODE_MATH"
7354 [(set_attr "type" "idiv")
7355 (set_attr "mode" "QI")])
7357 (define_expand "udivmod<mode>4"
7358 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7360 (match_operand:SWIM248 1 "register_operand")
7361 (match_operand:SWIM248 2 "nonimmediate_operand")))
7362 (set (match_operand:SWIM248 3 "register_operand")
7363 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7364 (clobber (reg:CC FLAGS_REG))])])
7366 ;; Split with 8bit unsigned divide:
7367 ;; if (dividend an divisor are in [0-255])
7368 ;; use 8bit unsigned integer divide
7370 ;; use original integer divide
7372 [(set (match_operand:SWI48 0 "register_operand")
7373 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7374 (match_operand:SWI48 3 "nonimmediate_operand")))
7375 (set (match_operand:SWI48 1 "register_operand")
7376 (umod:SWI48 (match_dup 2) (match_dup 3)))
7377 (clobber (reg:CC FLAGS_REG))]
7378 "TARGET_USE_8BIT_IDIV
7379 && TARGET_QIMODE_MATH
7380 && can_create_pseudo_p ()
7381 && !optimize_insn_for_size_p ()"
7383 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7385 (define_insn_and_split "udivmod<mode>4_1"
7386 [(set (match_operand:SWI48 0 "register_operand" "=a")
7387 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7388 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7389 (set (match_operand:SWI48 1 "register_operand" "=&d")
7390 (umod:SWI48 (match_dup 2) (match_dup 3)))
7391 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7392 (clobber (reg:CC FLAGS_REG))]
7396 [(set (match_dup 1) (const_int 0))
7397 (parallel [(set (match_dup 0)
7398 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7400 (umod:SWI48 (match_dup 2) (match_dup 3)))
7402 (clobber (reg:CC FLAGS_REG))])]
7404 [(set_attr "type" "multi")
7405 (set_attr "mode" "<MODE>")])
7407 (define_insn_and_split "*udivmod<mode>4"
7408 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7409 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7410 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7411 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7412 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7413 (clobber (reg:CC FLAGS_REG))]
7417 [(set (match_dup 1) (const_int 0))
7418 (parallel [(set (match_dup 0)
7419 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7421 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7423 (clobber (reg:CC FLAGS_REG))])]
7425 [(set_attr "type" "multi")
7426 (set_attr "mode" "<MODE>")])
7428 (define_insn "*udivmod<mode>4_noext"
7429 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7430 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7431 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7432 (set (match_operand:SWIM248 1 "register_operand" "=d")
7433 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7434 (use (match_operand:SWIM248 4 "register_operand" "1"))
7435 (clobber (reg:CC FLAGS_REG))]
7437 "div{<imodesuffix>}\t%3"
7438 [(set_attr "type" "idiv")
7439 (set_attr "mode" "<MODE>")])
7441 (define_expand "udivmodqi4"
7442 [(parallel [(set (match_operand:QI 0 "register_operand")
7444 (match_operand:QI 1 "register_operand")
7445 (match_operand:QI 2 "nonimmediate_operand")))
7446 (set (match_operand:QI 3 "register_operand")
7447 (umod:QI (match_dup 1) (match_dup 2)))
7448 (clobber (reg:CC FLAGS_REG))])]
7449 "TARGET_QIMODE_MATH"
7454 tmp0 = gen_reg_rtx (HImode);
7455 tmp1 = gen_reg_rtx (HImode);
7457 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7459 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7460 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7462 /* Extract remainder from AH. */
7463 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7464 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7465 insn = emit_move_insn (operands[3], tmp1);
7467 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7468 set_unique_reg_note (insn, REG_EQUAL, mod);
7470 /* Extract quotient from AL. */
7471 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7473 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7474 set_unique_reg_note (insn, REG_EQUAL, div);
7479 (define_insn "udivmodhiqi3"
7480 [(set (match_operand:HI 0 "register_operand" "=a")
7485 (mod:HI (match_operand:HI 1 "register_operand" "0")
7487 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7491 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7492 (clobber (reg:CC FLAGS_REG))]
7493 "TARGET_QIMODE_MATH"
7495 [(set_attr "type" "idiv")
7496 (set_attr "mode" "QI")])
7498 ;; We cannot use div/idiv for double division, because it causes
7499 ;; "division by zero" on the overflow and that's not what we expect
7500 ;; from truncate. Because true (non truncating) double division is
7501 ;; never generated, we can't create this insn anyway.
7504 ; [(set (match_operand:SI 0 "register_operand" "=a")
7506 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7508 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7509 ; (set (match_operand:SI 3 "register_operand" "=d")
7511 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7512 ; (clobber (reg:CC FLAGS_REG))]
7514 ; "div{l}\t{%2, %0|%0, %2}"
7515 ; [(set_attr "type" "idiv")])
7517 ;;- Logical AND instructions
7519 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7520 ;; Note that this excludes ah.
7522 (define_expand "testsi_ccno_1"
7523 [(set (reg:CCNO FLAGS_REG)
7525 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7526 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7529 (define_expand "testqi_ccz_1"
7530 [(set (reg:CCZ FLAGS_REG)
7531 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7532 (match_operand:QI 1 "nonmemory_operand"))
7535 (define_expand "testdi_ccno_1"
7536 [(set (reg:CCNO FLAGS_REG)
7538 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7539 (match_operand:DI 1 "x86_64_szext_general_operand"))
7541 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7543 (define_insn "*testdi_1"
7544 [(set (reg FLAGS_REG)
7547 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7548 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7550 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7551 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7553 test{l}\t{%k1, %k0|%k0, %k1}
7554 test{l}\t{%k1, %k0|%k0, %k1}
7555 test{q}\t{%1, %0|%0, %1}
7556 test{q}\t{%1, %0|%0, %1}
7557 test{q}\t{%1, %0|%0, %1}"
7558 [(set_attr "type" "test")
7559 (set_attr "modrm" "0,1,0,1,1")
7560 (set_attr "mode" "SI,SI,DI,DI,DI")])
7562 (define_insn "*testqi_1_maybe_si"
7563 [(set (reg FLAGS_REG)
7566 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7567 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7569 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7570 && ix86_match_ccmode (insn,
7571 CONST_INT_P (operands[1])
7572 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7574 if (which_alternative == 3)
7576 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7577 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7578 return "test{l}\t{%1, %k0|%k0, %1}";
7580 return "test{b}\t{%1, %0|%0, %1}";
7582 [(set_attr "type" "test")
7583 (set_attr "modrm" "0,1,1,1")
7584 (set_attr "mode" "QI,QI,QI,SI")
7585 (set_attr "pent_pair" "uv,np,uv,np")])
7587 (define_insn "*test<mode>_1"
7588 [(set (reg FLAGS_REG)
7591 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7592 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7594 "ix86_match_ccmode (insn, CCNOmode)
7595 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7596 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7597 [(set_attr "type" "test")
7598 (set_attr "modrm" "0,1,1")
7599 (set_attr "mode" "<MODE>")
7600 (set_attr "pent_pair" "uv,np,uv")])
7602 (define_expand "testqi_ext_ccno_0"
7603 [(set (reg:CCNO FLAGS_REG)
7607 (match_operand 0 "ext_register_operand")
7610 (match_operand 1 "const_int_operand"))
7613 (define_insn "*testqi_ext_0"
7614 [(set (reg FLAGS_REG)
7618 (match_operand 0 "ext_register_operand" "Q")
7621 (match_operand 1 "const_int_operand" "n"))
7623 "ix86_match_ccmode (insn, CCNOmode)"
7624 "test{b}\t{%1, %h0|%h0, %1}"
7625 [(set_attr "type" "test")
7626 (set_attr "mode" "QI")
7627 (set_attr "length_immediate" "1")
7628 (set_attr "modrm" "1")
7629 (set_attr "pent_pair" "np")])
7631 (define_insn "*testqi_ext_1_rex64"
7632 [(set (reg FLAGS_REG)
7636 (match_operand 0 "ext_register_operand" "Q")
7640 (match_operand:QI 1 "register_operand" "Q")))
7642 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7643 "test{b}\t{%1, %h0|%h0, %1}"
7644 [(set_attr "type" "test")
7645 (set_attr "mode" "QI")])
7647 (define_insn "*testqi_ext_1"
7648 [(set (reg FLAGS_REG)
7652 (match_operand 0 "ext_register_operand" "Q")
7656 (match_operand:QI 1 "general_operand" "Qm")))
7658 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7659 "test{b}\t{%1, %h0|%h0, %1}"
7660 [(set_attr "type" "test")
7661 (set_attr "mode" "QI")])
7663 (define_insn "*testqi_ext_2"
7664 [(set (reg FLAGS_REG)
7668 (match_operand 0 "ext_register_operand" "Q")
7672 (match_operand 1 "ext_register_operand" "Q")
7676 "ix86_match_ccmode (insn, CCNOmode)"
7677 "test{b}\t{%h1, %h0|%h0, %h1}"
7678 [(set_attr "type" "test")
7679 (set_attr "mode" "QI")])
7681 (define_insn "*testqi_ext_3_rex64"
7682 [(set (reg FLAGS_REG)
7683 (compare (zero_extract:DI
7684 (match_operand 0 "nonimmediate_operand" "rm")
7685 (match_operand:DI 1 "const_int_operand")
7686 (match_operand:DI 2 "const_int_operand"))
7689 && ix86_match_ccmode (insn, CCNOmode)
7690 && INTVAL (operands[1]) > 0
7691 && INTVAL (operands[2]) >= 0
7692 /* Ensure that resulting mask is zero or sign extended operand. */
7693 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7694 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7695 && INTVAL (operands[1]) > 32))
7696 && (GET_MODE (operands[0]) == SImode
7697 || GET_MODE (operands[0]) == DImode
7698 || GET_MODE (operands[0]) == HImode
7699 || GET_MODE (operands[0]) == QImode)"
7702 ;; Combine likes to form bit extractions for some tests. Humor it.
7703 (define_insn "*testqi_ext_3"
7704 [(set (reg FLAGS_REG)
7705 (compare (zero_extract:SI
7706 (match_operand 0 "nonimmediate_operand" "rm")
7707 (match_operand:SI 1 "const_int_operand")
7708 (match_operand:SI 2 "const_int_operand"))
7710 "ix86_match_ccmode (insn, CCNOmode)
7711 && INTVAL (operands[1]) > 0
7712 && INTVAL (operands[2]) >= 0
7713 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7714 && (GET_MODE (operands[0]) == SImode
7715 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7716 || GET_MODE (operands[0]) == HImode
7717 || GET_MODE (operands[0]) == QImode)"
7721 [(set (match_operand 0 "flags_reg_operand")
7722 (match_operator 1 "compare_operator"
7724 (match_operand 2 "nonimmediate_operand")
7725 (match_operand 3 "const_int_operand")
7726 (match_operand 4 "const_int_operand"))
7728 "ix86_match_ccmode (insn, CCNOmode)"
7729 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7731 rtx val = operands[2];
7732 HOST_WIDE_INT len = INTVAL (operands[3]);
7733 HOST_WIDE_INT pos = INTVAL (operands[4]);
7735 enum machine_mode mode, submode;
7737 mode = GET_MODE (val);
7740 /* ??? Combine likes to put non-volatile mem extractions in QImode
7741 no matter the size of the test. So find a mode that works. */
7742 if (! MEM_VOLATILE_P (val))
7744 mode = smallest_mode_for_size (pos + len, MODE_INT);
7745 val = adjust_address (val, mode, 0);
7748 else if (GET_CODE (val) == SUBREG
7749 && (submode = GET_MODE (SUBREG_REG (val)),
7750 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7751 && pos + len <= GET_MODE_BITSIZE (submode)
7752 && GET_MODE_CLASS (submode) == MODE_INT)
7754 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7756 val = SUBREG_REG (val);
7758 else if (mode == HImode && pos + len <= 8)
7760 /* Small HImode tests can be converted to QImode. */
7762 val = gen_lowpart (QImode, val);
7765 if (len == HOST_BITS_PER_WIDE_INT)
7768 mask = ((HOST_WIDE_INT)1 << len) - 1;
7771 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7774 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7775 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7776 ;; this is relatively important trick.
7777 ;; Do the conversion only post-reload to avoid limiting of the register class
7780 [(set (match_operand 0 "flags_reg_operand")
7781 (match_operator 1 "compare_operator"
7782 [(and (match_operand 2 "register_operand")
7783 (match_operand 3 "const_int_operand"))
7786 && QI_REG_P (operands[2])
7787 && GET_MODE (operands[2]) != QImode
7788 && ((ix86_match_ccmode (insn, CCZmode)
7789 && !(INTVAL (operands[3]) & ~(255 << 8)))
7790 || (ix86_match_ccmode (insn, CCNOmode)
7791 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7794 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7798 operands[2] = gen_lowpart (SImode, operands[2]);
7799 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7803 [(set (match_operand 0 "flags_reg_operand")
7804 (match_operator 1 "compare_operator"
7805 [(and (match_operand 2 "nonimmediate_operand")
7806 (match_operand 3 "const_int_operand"))
7809 && GET_MODE (operands[2]) != QImode
7810 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7811 && ((ix86_match_ccmode (insn, CCZmode)
7812 && !(INTVAL (operands[3]) & ~255))
7813 || (ix86_match_ccmode (insn, CCNOmode)
7814 && !(INTVAL (operands[3]) & ~127)))"
7816 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7819 operands[2] = gen_lowpart (QImode, operands[2]);
7820 operands[3] = gen_lowpart (QImode, operands[3]);
7823 ;; %%% This used to optimize known byte-wide and operations to memory,
7824 ;; and sometimes to QImode registers. If this is considered useful,
7825 ;; it should be done with splitters.
7827 (define_expand "and<mode>3"
7828 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7829 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7830 (match_operand:SWIM 2 "<general_szext_operand>")))]
7833 enum machine_mode mode = <MODE>mode;
7834 rtx (*insn) (rtx, rtx);
7836 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7838 HOST_WIDE_INT ival = INTVAL (operands[2]);
7840 if (ival == (HOST_WIDE_INT) 0xffffffff)
7842 else if (ival == 0xffff)
7844 else if (ival == 0xff)
7848 if (mode == <MODE>mode)
7850 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7854 if (<MODE>mode == DImode)
7855 insn = (mode == SImode)
7856 ? gen_zero_extendsidi2
7858 ? gen_zero_extendhidi2
7859 : gen_zero_extendqidi2;
7860 else if (<MODE>mode == SImode)
7861 insn = (mode == HImode)
7862 ? gen_zero_extendhisi2
7863 : gen_zero_extendqisi2;
7864 else if (<MODE>mode == HImode)
7865 insn = gen_zero_extendqihi2;
7869 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7873 (define_insn "*anddi_1"
7874 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7876 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7877 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7878 (clobber (reg:CC FLAGS_REG))]
7879 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7881 switch (get_attr_type (insn))
7887 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7888 if (get_attr_mode (insn) == MODE_SI)
7889 return "and{l}\t{%k2, %k0|%k0, %k2}";
7891 return "and{q}\t{%2, %0|%0, %2}";
7894 [(set_attr "type" "alu,alu,alu,imovx")
7895 (set_attr "length_immediate" "*,*,*,0")
7896 (set (attr "prefix_rex")
7898 (and (eq_attr "type" "imovx")
7899 (and (match_test "INTVAL (operands[2]) == 0xff")
7900 (match_operand 1 "ext_QIreg_operand")))
7902 (const_string "*")))
7903 (set_attr "mode" "SI,DI,DI,SI")])
7905 (define_insn "*andsi_1"
7906 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7907 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7908 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7909 (clobber (reg:CC FLAGS_REG))]
7910 "ix86_binary_operator_ok (AND, SImode, operands)"
7912 switch (get_attr_type (insn))
7918 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7919 return "and{l}\t{%2, %0|%0, %2}";
7922 [(set_attr "type" "alu,alu,imovx")
7923 (set (attr "prefix_rex")
7925 (and (eq_attr "type" "imovx")
7926 (and (match_test "INTVAL (operands[2]) == 0xff")
7927 (match_operand 1 "ext_QIreg_operand")))
7929 (const_string "*")))
7930 (set_attr "length_immediate" "*,*,0")
7931 (set_attr "mode" "SI")])
7933 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7934 (define_insn "*andsi_1_zext"
7935 [(set (match_operand:DI 0 "register_operand" "=r")
7937 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7938 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7939 (clobber (reg:CC FLAGS_REG))]
7940 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7941 "and{l}\t{%2, %k0|%k0, %2}"
7942 [(set_attr "type" "alu")
7943 (set_attr "mode" "SI")])
7945 (define_insn "*andhi_1"
7946 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7947 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7948 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7949 (clobber (reg:CC FLAGS_REG))]
7950 "ix86_binary_operator_ok (AND, HImode, operands)"
7952 switch (get_attr_type (insn))
7958 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7959 return "and{w}\t{%2, %0|%0, %2}";
7962 [(set_attr "type" "alu,alu,imovx")
7963 (set_attr "length_immediate" "*,*,0")
7964 (set (attr "prefix_rex")
7966 (and (eq_attr "type" "imovx")
7967 (match_operand 1 "ext_QIreg_operand"))
7969 (const_string "*")))
7970 (set_attr "mode" "HI,HI,SI")])
7972 ;; %%% Potential partial reg stall on alternative 2. What to do?
7973 (define_insn "*andqi_1"
7974 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7975 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7976 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7977 (clobber (reg:CC FLAGS_REG))]
7978 "ix86_binary_operator_ok (AND, QImode, operands)"
7980 and{b}\t{%2, %0|%0, %2}
7981 and{b}\t{%2, %0|%0, %2}
7982 and{l}\t{%k2, %k0|%k0, %k2}"
7983 [(set_attr "type" "alu")
7984 (set_attr "mode" "QI,QI,SI")])
7986 (define_insn "*andqi_1_slp"
7987 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7988 (and:QI (match_dup 0)
7989 (match_operand:QI 1 "general_operand" "qn,qmn")))
7990 (clobber (reg:CC FLAGS_REG))]
7991 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7992 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7993 "and{b}\t{%1, %0|%0, %1}"
7994 [(set_attr "type" "alu1")
7995 (set_attr "mode" "QI")])
7997 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7999 [(set (match_operand:DI 0 "register_operand")
8000 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8001 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8002 (clobber (reg:CC FLAGS_REG))]
8004 [(parallel [(set (match_dup 0)
8005 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8006 (clobber (reg:CC FLAGS_REG))])]
8007 "operands[2] = gen_lowpart (SImode, operands[2]);")
8010 [(set (match_operand:SWI248 0 "register_operand")
8011 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8012 (match_operand:SWI248 2 "const_int_operand")))
8013 (clobber (reg:CC FLAGS_REG))]
8015 && true_regnum (operands[0]) != true_regnum (operands[1])"
8018 HOST_WIDE_INT ival = INTVAL (operands[2]);
8019 enum machine_mode mode;
8020 rtx (*insn) (rtx, rtx);
8022 if (ival == (HOST_WIDE_INT) 0xffffffff)
8024 else if (ival == 0xffff)
8028 gcc_assert (ival == 0xff);
8032 if (<MODE>mode == DImode)
8033 insn = (mode == SImode)
8034 ? gen_zero_extendsidi2
8036 ? gen_zero_extendhidi2
8037 : gen_zero_extendqidi2;
8040 if (<MODE>mode != SImode)
8041 /* Zero extend to SImode to avoid partial register stalls. */
8042 operands[0] = gen_lowpart (SImode, operands[0]);
8044 insn = (mode == HImode)
8045 ? gen_zero_extendhisi2
8046 : gen_zero_extendqisi2;
8048 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8053 [(set (match_operand 0 "register_operand")
8055 (const_int -65536)))
8056 (clobber (reg:CC FLAGS_REG))]
8057 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8058 || optimize_function_for_size_p (cfun)"
8059 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8060 "operands[1] = gen_lowpart (HImode, operands[0]);")
8063 [(set (match_operand 0 "ext_register_operand")
8066 (clobber (reg:CC FLAGS_REG))]
8067 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8068 && reload_completed"
8069 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8070 "operands[1] = gen_lowpart (QImode, operands[0]);")
8073 [(set (match_operand 0 "ext_register_operand")
8075 (const_int -65281)))
8076 (clobber (reg:CC FLAGS_REG))]
8077 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8078 && reload_completed"
8079 [(parallel [(set (zero_extract:SI (match_dup 0)
8083 (zero_extract:SI (match_dup 0)
8086 (zero_extract:SI (match_dup 0)
8089 (clobber (reg:CC FLAGS_REG))])]
8090 "operands[0] = gen_lowpart (SImode, operands[0]);")
8092 (define_insn "*anddi_2"
8093 [(set (reg FLAGS_REG)
8096 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8097 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8099 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8100 (and:DI (match_dup 1) (match_dup 2)))]
8101 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8102 && ix86_binary_operator_ok (AND, DImode, operands)"
8104 and{l}\t{%k2, %k0|%k0, %k2}
8105 and{q}\t{%2, %0|%0, %2}
8106 and{q}\t{%2, %0|%0, %2}"
8107 [(set_attr "type" "alu")
8108 (set_attr "mode" "SI,DI,DI")])
8110 (define_insn "*andqi_2_maybe_si"
8111 [(set (reg FLAGS_REG)
8113 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8114 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8116 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8117 (and:QI (match_dup 1) (match_dup 2)))]
8118 "ix86_binary_operator_ok (AND, QImode, operands)
8119 && ix86_match_ccmode (insn,
8120 CONST_INT_P (operands[2])
8121 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8123 if (which_alternative == 2)
8125 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8126 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8127 return "and{l}\t{%2, %k0|%k0, %2}";
8129 return "and{b}\t{%2, %0|%0, %2}";
8131 [(set_attr "type" "alu")
8132 (set_attr "mode" "QI,QI,SI")])
8134 (define_insn "*and<mode>_2"
8135 [(set (reg FLAGS_REG)
8136 (compare (and:SWI124
8137 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8138 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8140 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8141 (and:SWI124 (match_dup 1) (match_dup 2)))]
8142 "ix86_match_ccmode (insn, CCNOmode)
8143 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8144 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8145 [(set_attr "type" "alu")
8146 (set_attr "mode" "<MODE>")])
8148 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8149 (define_insn "*andsi_2_zext"
8150 [(set (reg FLAGS_REG)
8152 (match_operand:SI 1 "nonimmediate_operand" "%0")
8153 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8155 (set (match_operand:DI 0 "register_operand" "=r")
8156 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8157 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8158 && ix86_binary_operator_ok (AND, SImode, operands)"
8159 "and{l}\t{%2, %k0|%k0, %2}"
8160 [(set_attr "type" "alu")
8161 (set_attr "mode" "SI")])
8163 (define_insn "*andqi_2_slp"
8164 [(set (reg FLAGS_REG)
8166 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8167 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8169 (set (strict_low_part (match_dup 0))
8170 (and:QI (match_dup 0) (match_dup 1)))]
8171 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8172 && ix86_match_ccmode (insn, CCNOmode)
8173 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8174 "and{b}\t{%1, %0|%0, %1}"
8175 [(set_attr "type" "alu1")
8176 (set_attr "mode" "QI")])
8178 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8179 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8180 ;; for a QImode operand, which of course failed.
8181 (define_insn "andqi_ext_0"
8182 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8187 (match_operand 1 "ext_register_operand" "0")
8190 (match_operand 2 "const_int_operand" "n")))
8191 (clobber (reg:CC FLAGS_REG))]
8193 "and{b}\t{%2, %h0|%h0, %2}"
8194 [(set_attr "type" "alu")
8195 (set_attr "length_immediate" "1")
8196 (set_attr "modrm" "1")
8197 (set_attr "mode" "QI")])
8199 ;; Generated by peephole translating test to and. This shows up
8200 ;; often in fp comparisons.
8201 (define_insn "*andqi_ext_0_cc"
8202 [(set (reg FLAGS_REG)
8206 (match_operand 1 "ext_register_operand" "0")
8209 (match_operand 2 "const_int_operand" "n"))
8211 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8220 "ix86_match_ccmode (insn, CCNOmode)"
8221 "and{b}\t{%2, %h0|%h0, %2}"
8222 [(set_attr "type" "alu")
8223 (set_attr "length_immediate" "1")
8224 (set_attr "modrm" "1")
8225 (set_attr "mode" "QI")])
8227 (define_insn "*andqi_ext_1_rex64"
8228 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8233 (match_operand 1 "ext_register_operand" "0")
8237 (match_operand 2 "ext_register_operand" "Q"))))
8238 (clobber (reg:CC FLAGS_REG))]
8240 "and{b}\t{%2, %h0|%h0, %2}"
8241 [(set_attr "type" "alu")
8242 (set_attr "length_immediate" "0")
8243 (set_attr "mode" "QI")])
8245 (define_insn "*andqi_ext_1"
8246 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8251 (match_operand 1 "ext_register_operand" "0")
8255 (match_operand:QI 2 "general_operand" "Qm"))))
8256 (clobber (reg:CC FLAGS_REG))]
8258 "and{b}\t{%2, %h0|%h0, %2}"
8259 [(set_attr "type" "alu")
8260 (set_attr "length_immediate" "0")
8261 (set_attr "mode" "QI")])
8263 (define_insn "*andqi_ext_2"
8264 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8269 (match_operand 1 "ext_register_operand" "%0")
8273 (match_operand 2 "ext_register_operand" "Q")
8276 (clobber (reg:CC FLAGS_REG))]
8278 "and{b}\t{%h2, %h0|%h0, %h2}"
8279 [(set_attr "type" "alu")
8280 (set_attr "length_immediate" "0")
8281 (set_attr "mode" "QI")])
8283 ;; Convert wide AND instructions with immediate operand to shorter QImode
8284 ;; equivalents when possible.
8285 ;; Don't do the splitting with memory operands, since it introduces risk
8286 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8287 ;; for size, but that can (should?) be handled by generic code instead.
8289 [(set (match_operand 0 "register_operand")
8290 (and (match_operand 1 "register_operand")
8291 (match_operand 2 "const_int_operand")))
8292 (clobber (reg:CC FLAGS_REG))]
8294 && QI_REG_P (operands[0])
8295 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8296 && !(~INTVAL (operands[2]) & ~(255 << 8))
8297 && GET_MODE (operands[0]) != QImode"
8298 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8299 (and:SI (zero_extract:SI (match_dup 1)
8300 (const_int 8) (const_int 8))
8302 (clobber (reg:CC FLAGS_REG))])]
8304 operands[0] = gen_lowpart (SImode, operands[0]);
8305 operands[1] = gen_lowpart (SImode, operands[1]);
8306 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8309 ;; Since AND can be encoded with sign extended immediate, this is only
8310 ;; profitable when 7th bit is not set.
8312 [(set (match_operand 0 "register_operand")
8313 (and (match_operand 1 "general_operand")
8314 (match_operand 2 "const_int_operand")))
8315 (clobber (reg:CC FLAGS_REG))]
8317 && ANY_QI_REG_P (operands[0])
8318 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8319 && !(~INTVAL (operands[2]) & ~255)
8320 && !(INTVAL (operands[2]) & 128)
8321 && GET_MODE (operands[0]) != QImode"
8322 [(parallel [(set (strict_low_part (match_dup 0))
8323 (and:QI (match_dup 1)
8325 (clobber (reg:CC FLAGS_REG))])]
8327 operands[0] = gen_lowpart (QImode, operands[0]);
8328 operands[1] = gen_lowpart (QImode, operands[1]);
8329 operands[2] = gen_lowpart (QImode, operands[2]);
8332 ;; Logical inclusive and exclusive OR instructions
8334 ;; %%% This used to optimize known byte-wide and operations to memory.
8335 ;; If this is considered useful, it should be done with splitters.
8337 (define_expand "<code><mode>3"
8338 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8339 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8340 (match_operand:SWIM 2 "<general_operand>")))]
8342 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8344 (define_insn "*<code><mode>_1"
8345 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8347 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8348 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8349 (clobber (reg:CC FLAGS_REG))]
8350 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8351 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8352 [(set_attr "type" "alu")
8353 (set_attr "mode" "<MODE>")])
8355 ;; %%% Potential partial reg stall on alternative 2. What to do?
8356 (define_insn "*<code>qi_1"
8357 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8358 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8359 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8360 (clobber (reg:CC FLAGS_REG))]
8361 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8363 <logic>{b}\t{%2, %0|%0, %2}
8364 <logic>{b}\t{%2, %0|%0, %2}
8365 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8366 [(set_attr "type" "alu")
8367 (set_attr "mode" "QI,QI,SI")])
8369 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8370 (define_insn "*<code>si_1_zext"
8371 [(set (match_operand:DI 0 "register_operand" "=r")
8373 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8374 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8375 (clobber (reg:CC FLAGS_REG))]
8376 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8377 "<logic>{l}\t{%2, %k0|%k0, %2}"
8378 [(set_attr "type" "alu")
8379 (set_attr "mode" "SI")])
8381 (define_insn "*<code>si_1_zext_imm"
8382 [(set (match_operand:DI 0 "register_operand" "=r")
8384 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8385 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8386 (clobber (reg:CC FLAGS_REG))]
8387 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8388 "<logic>{l}\t{%2, %k0|%k0, %2}"
8389 [(set_attr "type" "alu")
8390 (set_attr "mode" "SI")])
8392 (define_insn "*<code>qi_1_slp"
8393 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8394 (any_or:QI (match_dup 0)
8395 (match_operand:QI 1 "general_operand" "qmn,qn")))
8396 (clobber (reg:CC FLAGS_REG))]
8397 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8398 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8399 "<logic>{b}\t{%1, %0|%0, %1}"
8400 [(set_attr "type" "alu1")
8401 (set_attr "mode" "QI")])
8403 (define_insn "*<code><mode>_2"
8404 [(set (reg FLAGS_REG)
8405 (compare (any_or:SWI
8406 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8407 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8409 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8410 (any_or:SWI (match_dup 1) (match_dup 2)))]
8411 "ix86_match_ccmode (insn, CCNOmode)
8412 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8413 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8414 [(set_attr "type" "alu")
8415 (set_attr "mode" "<MODE>")])
8417 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8418 ;; ??? Special case for immediate operand is missing - it is tricky.
8419 (define_insn "*<code>si_2_zext"
8420 [(set (reg FLAGS_REG)
8421 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8422 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8424 (set (match_operand:DI 0 "register_operand" "=r")
8425 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8426 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8427 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8428 "<logic>{l}\t{%2, %k0|%k0, %2}"
8429 [(set_attr "type" "alu")
8430 (set_attr "mode" "SI")])
8432 (define_insn "*<code>si_2_zext_imm"
8433 [(set (reg FLAGS_REG)
8435 (match_operand:SI 1 "nonimmediate_operand" "%0")
8436 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8438 (set (match_operand:DI 0 "register_operand" "=r")
8439 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8440 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8441 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8442 "<logic>{l}\t{%2, %k0|%k0, %2}"
8443 [(set_attr "type" "alu")
8444 (set_attr "mode" "SI")])
8446 (define_insn "*<code>qi_2_slp"
8447 [(set (reg FLAGS_REG)
8448 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8449 (match_operand:QI 1 "general_operand" "qmn,qn"))
8451 (set (strict_low_part (match_dup 0))
8452 (any_or:QI (match_dup 0) (match_dup 1)))]
8453 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8454 && ix86_match_ccmode (insn, CCNOmode)
8455 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8456 "<logic>{b}\t{%1, %0|%0, %1}"
8457 [(set_attr "type" "alu1")
8458 (set_attr "mode" "QI")])
8460 (define_insn "*<code><mode>_3"
8461 [(set (reg FLAGS_REG)
8462 (compare (any_or:SWI
8463 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8464 (match_operand:SWI 2 "<general_operand>" "<g>"))
8466 (clobber (match_scratch:SWI 0 "=<r>"))]
8467 "ix86_match_ccmode (insn, CCNOmode)
8468 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8469 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8470 [(set_attr "type" "alu")
8471 (set_attr "mode" "<MODE>")])
8473 (define_insn "*<code>qi_ext_0"
8474 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8479 (match_operand 1 "ext_register_operand" "0")
8482 (match_operand 2 "const_int_operand" "n")))
8483 (clobber (reg:CC FLAGS_REG))]
8484 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8485 "<logic>{b}\t{%2, %h0|%h0, %2}"
8486 [(set_attr "type" "alu")
8487 (set_attr "length_immediate" "1")
8488 (set_attr "modrm" "1")
8489 (set_attr "mode" "QI")])
8491 (define_insn "*<code>qi_ext_1_rex64"
8492 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8497 (match_operand 1 "ext_register_operand" "0")
8501 (match_operand 2 "ext_register_operand" "Q"))))
8502 (clobber (reg:CC FLAGS_REG))]
8504 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8505 "<logic>{b}\t{%2, %h0|%h0, %2}"
8506 [(set_attr "type" "alu")
8507 (set_attr "length_immediate" "0")
8508 (set_attr "mode" "QI")])
8510 (define_insn "*<code>qi_ext_1"
8511 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8516 (match_operand 1 "ext_register_operand" "0")
8520 (match_operand:QI 2 "general_operand" "Qm"))))
8521 (clobber (reg:CC FLAGS_REG))]
8523 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8524 "<logic>{b}\t{%2, %h0|%h0, %2}"
8525 [(set_attr "type" "alu")
8526 (set_attr "length_immediate" "0")
8527 (set_attr "mode" "QI")])
8529 (define_insn "*<code>qi_ext_2"
8530 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8534 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8537 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8540 (clobber (reg:CC FLAGS_REG))]
8541 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8542 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8543 [(set_attr "type" "alu")
8544 (set_attr "length_immediate" "0")
8545 (set_attr "mode" "QI")])
8548 [(set (match_operand 0 "register_operand")
8549 (any_or (match_operand 1 "register_operand")
8550 (match_operand 2 "const_int_operand")))
8551 (clobber (reg:CC FLAGS_REG))]
8553 && QI_REG_P (operands[0])
8554 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8555 && !(INTVAL (operands[2]) & ~(255 << 8))
8556 && GET_MODE (operands[0]) != QImode"
8557 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8558 (any_or:SI (zero_extract:SI (match_dup 1)
8559 (const_int 8) (const_int 8))
8561 (clobber (reg:CC FLAGS_REG))])]
8563 operands[0] = gen_lowpart (SImode, operands[0]);
8564 operands[1] = gen_lowpart (SImode, operands[1]);
8565 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8568 ;; Since OR can be encoded with sign extended immediate, this is only
8569 ;; profitable when 7th bit is set.
8571 [(set (match_operand 0 "register_operand")
8572 (any_or (match_operand 1 "general_operand")
8573 (match_operand 2 "const_int_operand")))
8574 (clobber (reg:CC FLAGS_REG))]
8576 && ANY_QI_REG_P (operands[0])
8577 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8578 && !(INTVAL (operands[2]) & ~255)
8579 && (INTVAL (operands[2]) & 128)
8580 && GET_MODE (operands[0]) != QImode"
8581 [(parallel [(set (strict_low_part (match_dup 0))
8582 (any_or:QI (match_dup 1)
8584 (clobber (reg:CC FLAGS_REG))])]
8586 operands[0] = gen_lowpart (QImode, operands[0]);
8587 operands[1] = gen_lowpart (QImode, operands[1]);
8588 operands[2] = gen_lowpart (QImode, operands[2]);
8591 (define_expand "xorqi_cc_ext_1"
8593 (set (reg:CCNO FLAGS_REG)
8597 (match_operand 1 "ext_register_operand")
8600 (match_operand:QI 2 "general_operand"))
8602 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8612 (define_insn "*xorqi_cc_ext_1_rex64"
8613 [(set (reg FLAGS_REG)
8617 (match_operand 1 "ext_register_operand" "0")
8620 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8622 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8631 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8632 "xor{b}\t{%2, %h0|%h0, %2}"
8633 [(set_attr "type" "alu")
8634 (set_attr "modrm" "1")
8635 (set_attr "mode" "QI")])
8637 (define_insn "*xorqi_cc_ext_1"
8638 [(set (reg FLAGS_REG)
8642 (match_operand 1 "ext_register_operand" "0")
8645 (match_operand:QI 2 "general_operand" "qmn"))
8647 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8656 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8657 "xor{b}\t{%2, %h0|%h0, %2}"
8658 [(set_attr "type" "alu")
8659 (set_attr "modrm" "1")
8660 (set_attr "mode" "QI")])
8662 ;; Negation instructions
8664 (define_expand "neg<mode>2"
8665 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8666 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8668 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8670 (define_insn_and_split "*neg<dwi>2_doubleword"
8671 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8672 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8673 (clobber (reg:CC FLAGS_REG))]
8674 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8678 [(set (reg:CCZ FLAGS_REG)
8679 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8680 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8683 (plus:DWIH (match_dup 3)
8684 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8686 (clobber (reg:CC FLAGS_REG))])
8689 (neg:DWIH (match_dup 2)))
8690 (clobber (reg:CC FLAGS_REG))])]
8691 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8693 (define_insn "*neg<mode>2_1"
8694 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8695 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8696 (clobber (reg:CC FLAGS_REG))]
8697 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8698 "neg{<imodesuffix>}\t%0"
8699 [(set_attr "type" "negnot")
8700 (set_attr "mode" "<MODE>")])
8702 ;; Combine is quite creative about this pattern.
8703 (define_insn "*negsi2_1_zext"
8704 [(set (match_operand:DI 0 "register_operand" "=r")
8706 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8709 (clobber (reg:CC FLAGS_REG))]
8710 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8712 [(set_attr "type" "negnot")
8713 (set_attr "mode" "SI")])
8715 ;; The problem with neg is that it does not perform (compare x 0),
8716 ;; it really performs (compare 0 x), which leaves us with the zero
8717 ;; flag being the only useful item.
8719 (define_insn "*neg<mode>2_cmpz"
8720 [(set (reg:CCZ FLAGS_REG)
8722 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8724 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8725 (neg:SWI (match_dup 1)))]
8726 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8727 "neg{<imodesuffix>}\t%0"
8728 [(set_attr "type" "negnot")
8729 (set_attr "mode" "<MODE>")])
8731 (define_insn "*negsi2_cmpz_zext"
8732 [(set (reg:CCZ FLAGS_REG)
8736 (match_operand:DI 1 "register_operand" "0")
8740 (set (match_operand:DI 0 "register_operand" "=r")
8741 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8744 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8746 [(set_attr "type" "negnot")
8747 (set_attr "mode" "SI")])
8749 ;; Changing of sign for FP values is doable using integer unit too.
8751 (define_expand "<code><mode>2"
8752 [(set (match_operand:X87MODEF 0 "register_operand")
8753 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8754 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8755 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8757 (define_insn "*absneg<mode>2_mixed"
8758 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8759 (match_operator:MODEF 3 "absneg_operator"
8760 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8761 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8762 (clobber (reg:CC FLAGS_REG))]
8763 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8766 (define_insn "*absneg<mode>2_sse"
8767 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8768 (match_operator:MODEF 3 "absneg_operator"
8769 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8770 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8771 (clobber (reg:CC FLAGS_REG))]
8772 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8775 (define_insn "*absneg<mode>2_i387"
8776 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8777 (match_operator:X87MODEF 3 "absneg_operator"
8778 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8779 (use (match_operand 2))
8780 (clobber (reg:CC FLAGS_REG))]
8781 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8784 (define_expand "<code>tf2"
8785 [(set (match_operand:TF 0 "register_operand")
8786 (absneg:TF (match_operand:TF 1 "register_operand")))]
8788 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8790 (define_insn "*absnegtf2_sse"
8791 [(set (match_operand:TF 0 "register_operand" "=x,x")
8792 (match_operator:TF 3 "absneg_operator"
8793 [(match_operand:TF 1 "register_operand" "0,x")]))
8794 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8795 (clobber (reg:CC FLAGS_REG))]
8799 ;; Splitters for fp abs and neg.
8802 [(set (match_operand 0 "fp_register_operand")
8803 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8804 (use (match_operand 2))
8805 (clobber (reg:CC FLAGS_REG))]
8807 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8810 [(set (match_operand 0 "register_operand")
8811 (match_operator 3 "absneg_operator"
8812 [(match_operand 1 "register_operand")]))
8813 (use (match_operand 2 "nonimmediate_operand"))
8814 (clobber (reg:CC FLAGS_REG))]
8815 "reload_completed && SSE_REG_P (operands[0])"
8816 [(set (match_dup 0) (match_dup 3))]
8818 enum machine_mode mode = GET_MODE (operands[0]);
8819 enum machine_mode vmode = GET_MODE (operands[2]);
8822 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8823 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8824 if (operands_match_p (operands[0], operands[2]))
8827 operands[1] = operands[2];
8830 if (GET_CODE (operands[3]) == ABS)
8831 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8833 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8838 [(set (match_operand:SF 0 "register_operand")
8839 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8840 (use (match_operand:V4SF 2))
8841 (clobber (reg:CC FLAGS_REG))]
8843 [(parallel [(set (match_dup 0) (match_dup 1))
8844 (clobber (reg:CC FLAGS_REG))])]
8847 operands[0] = gen_lowpart (SImode, operands[0]);
8848 if (GET_CODE (operands[1]) == ABS)
8850 tmp = gen_int_mode (0x7fffffff, SImode);
8851 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8855 tmp = gen_int_mode (0x80000000, SImode);
8856 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8862 [(set (match_operand:DF 0 "register_operand")
8863 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8864 (use (match_operand 2))
8865 (clobber (reg:CC FLAGS_REG))]
8867 [(parallel [(set (match_dup 0) (match_dup 1))
8868 (clobber (reg:CC FLAGS_REG))])]
8873 tmp = gen_lowpart (DImode, operands[0]);
8874 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8877 if (GET_CODE (operands[1]) == ABS)
8880 tmp = gen_rtx_NOT (DImode, tmp);
8884 operands[0] = gen_highpart (SImode, operands[0]);
8885 if (GET_CODE (operands[1]) == ABS)
8887 tmp = gen_int_mode (0x7fffffff, SImode);
8888 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8892 tmp = gen_int_mode (0x80000000, SImode);
8893 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8900 [(set (match_operand:XF 0 "register_operand")
8901 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8902 (use (match_operand 2))
8903 (clobber (reg:CC FLAGS_REG))]
8905 [(parallel [(set (match_dup 0) (match_dup 1))
8906 (clobber (reg:CC FLAGS_REG))])]
8909 operands[0] = gen_rtx_REG (SImode,
8910 true_regnum (operands[0])
8911 + (TARGET_64BIT ? 1 : 2));
8912 if (GET_CODE (operands[1]) == ABS)
8914 tmp = GEN_INT (0x7fff);
8915 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8919 tmp = GEN_INT (0x8000);
8920 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8925 ;; Conditionalize these after reload. If they match before reload, we
8926 ;; lose the clobber and ability to use integer instructions.
8928 (define_insn "*<code><mode>2_1"
8929 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8930 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8932 && (reload_completed
8933 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8934 "f<absneg_mnemonic>"
8935 [(set_attr "type" "fsgn")
8936 (set_attr "mode" "<MODE>")])
8938 (define_insn "*<code>extendsfdf2"
8939 [(set (match_operand:DF 0 "register_operand" "=f")
8940 (absneg:DF (float_extend:DF
8941 (match_operand:SF 1 "register_operand" "0"))))]
8942 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8943 "f<absneg_mnemonic>"
8944 [(set_attr "type" "fsgn")
8945 (set_attr "mode" "DF")])
8947 (define_insn "*<code>extendsfxf2"
8948 [(set (match_operand:XF 0 "register_operand" "=f")
8949 (absneg:XF (float_extend:XF
8950 (match_operand:SF 1 "register_operand" "0"))))]
8952 "f<absneg_mnemonic>"
8953 [(set_attr "type" "fsgn")
8954 (set_attr "mode" "XF")])
8956 (define_insn "*<code>extenddfxf2"
8957 [(set (match_operand:XF 0 "register_operand" "=f")
8958 (absneg:XF (float_extend:XF
8959 (match_operand:DF 1 "register_operand" "0"))))]
8961 "f<absneg_mnemonic>"
8962 [(set_attr "type" "fsgn")
8963 (set_attr "mode" "XF")])
8965 ;; Copysign instructions
8967 (define_mode_iterator CSGNMODE [SF DF TF])
8968 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8970 (define_expand "copysign<mode>3"
8971 [(match_operand:CSGNMODE 0 "register_operand")
8972 (match_operand:CSGNMODE 1 "nonmemory_operand")
8973 (match_operand:CSGNMODE 2 "register_operand")]
8974 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8975 || (TARGET_SSE && (<MODE>mode == TFmode))"
8976 "ix86_expand_copysign (operands); DONE;")
8978 (define_insn_and_split "copysign<mode>3_const"
8979 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8981 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8982 (match_operand:CSGNMODE 2 "register_operand" "0")
8983 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8985 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8986 || (TARGET_SSE && (<MODE>mode == TFmode))"
8988 "&& reload_completed"
8990 "ix86_split_copysign_const (operands); DONE;")
8992 (define_insn "copysign<mode>3_var"
8993 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8995 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8996 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8997 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8998 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9000 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9001 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9002 || (TARGET_SSE && (<MODE>mode == TFmode))"
9006 [(set (match_operand:CSGNMODE 0 "register_operand")
9008 [(match_operand:CSGNMODE 2 "register_operand")
9009 (match_operand:CSGNMODE 3 "register_operand")
9010 (match_operand:<CSGNVMODE> 4)
9011 (match_operand:<CSGNVMODE> 5)]
9013 (clobber (match_scratch:<CSGNVMODE> 1))]
9014 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9015 || (TARGET_SSE && (<MODE>mode == TFmode)))
9016 && reload_completed"
9018 "ix86_split_copysign_var (operands); DONE;")
9020 ;; One complement instructions
9022 (define_expand "one_cmpl<mode>2"
9023 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9024 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9026 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9028 (define_insn "*one_cmpl<mode>2_1"
9029 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9030 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9031 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9032 "not{<imodesuffix>}\t%0"
9033 [(set_attr "type" "negnot")
9034 (set_attr "mode" "<MODE>")])
9036 ;; %%% Potential partial reg stall on alternative 1. What to do?
9037 (define_insn "*one_cmplqi2_1"
9038 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9039 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9040 "ix86_unary_operator_ok (NOT, QImode, operands)"
9044 [(set_attr "type" "negnot")
9045 (set_attr "mode" "QI,SI")])
9047 ;; ??? Currently never generated - xor is used instead.
9048 (define_insn "*one_cmplsi2_1_zext"
9049 [(set (match_operand:DI 0 "register_operand" "=r")
9051 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9052 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9054 [(set_attr "type" "negnot")
9055 (set_attr "mode" "SI")])
9057 (define_insn "*one_cmpl<mode>2_2"
9058 [(set (reg FLAGS_REG)
9059 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9061 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9062 (not:SWI (match_dup 1)))]
9063 "ix86_match_ccmode (insn, CCNOmode)
9064 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9066 [(set_attr "type" "alu1")
9067 (set_attr "mode" "<MODE>")])
9070 [(set (match_operand 0 "flags_reg_operand")
9071 (match_operator 2 "compare_operator"
9072 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9074 (set (match_operand:SWI 1 "nonimmediate_operand")
9075 (not:SWI (match_dup 3)))]
9076 "ix86_match_ccmode (insn, CCNOmode)"
9077 [(parallel [(set (match_dup 0)
9078 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9081 (xor:SWI (match_dup 3) (const_int -1)))])])
9083 ;; ??? Currently never generated - xor is used instead.
9084 (define_insn "*one_cmplsi2_2_zext"
9085 [(set (reg FLAGS_REG)
9086 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9088 (set (match_operand:DI 0 "register_operand" "=r")
9089 (zero_extend:DI (not:SI (match_dup 1))))]
9090 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9091 && ix86_unary_operator_ok (NOT, SImode, operands)"
9093 [(set_attr "type" "alu1")
9094 (set_attr "mode" "SI")])
9097 [(set (match_operand 0 "flags_reg_operand")
9098 (match_operator 2 "compare_operator"
9099 [(not:SI (match_operand:SI 3 "register_operand"))
9101 (set (match_operand:DI 1 "register_operand")
9102 (zero_extend:DI (not:SI (match_dup 3))))]
9103 "ix86_match_ccmode (insn, CCNOmode)"
9104 [(parallel [(set (match_dup 0)
9105 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9108 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9110 ;; Shift instructions
9112 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9113 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9114 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9115 ;; from the assembler input.
9117 ;; This instruction shifts the target reg/mem as usual, but instead of
9118 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9119 ;; is a left shift double, bits are taken from the high order bits of
9120 ;; reg, else if the insn is a shift right double, bits are taken from the
9121 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9122 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9124 ;; Since sh[lr]d does not change the `reg' operand, that is done
9125 ;; separately, making all shifts emit pairs of shift double and normal
9126 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9127 ;; support a 63 bit shift, each shift where the count is in a reg expands
9128 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9130 ;; If the shift count is a constant, we need never emit more than one
9131 ;; shift pair, instead using moves and sign extension for counts greater
9134 (define_expand "ashl<mode>3"
9135 [(set (match_operand:SDWIM 0 "<shift_operand>")
9136 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9137 (match_operand:QI 2 "nonmemory_operand")))]
9139 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9141 (define_insn "*ashl<mode>3_doubleword"
9142 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9143 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9144 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9145 (clobber (reg:CC FLAGS_REG))]
9148 [(set_attr "type" "multi")])
9151 [(set (match_operand:DWI 0 "register_operand")
9152 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9153 (match_operand:QI 2 "nonmemory_operand")))
9154 (clobber (reg:CC FLAGS_REG))]
9155 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9157 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9159 ;; By default we don't ask for a scratch register, because when DWImode
9160 ;; values are manipulated, registers are already at a premium. But if
9161 ;; we have one handy, we won't turn it away.
9164 [(match_scratch:DWIH 3 "r")
9165 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9167 (match_operand:<DWI> 1 "nonmemory_operand")
9168 (match_operand:QI 2 "nonmemory_operand")))
9169 (clobber (reg:CC FLAGS_REG))])
9173 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9175 (define_insn "x86_64_shld"
9176 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9177 (ior:DI (ashift:DI (match_dup 0)
9178 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9179 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9180 (minus:QI (const_int 64) (match_dup 2)))))
9181 (clobber (reg:CC FLAGS_REG))]
9183 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9184 [(set_attr "type" "ishift")
9185 (set_attr "prefix_0f" "1")
9186 (set_attr "mode" "DI")
9187 (set_attr "athlon_decode" "vector")
9188 (set_attr "amdfam10_decode" "vector")
9189 (set_attr "bdver1_decode" "vector")])
9191 (define_insn "x86_shld"
9192 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9193 (ior:SI (ashift:SI (match_dup 0)
9194 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9195 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9196 (minus:QI (const_int 32) (match_dup 2)))))
9197 (clobber (reg:CC FLAGS_REG))]
9199 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9200 [(set_attr "type" "ishift")
9201 (set_attr "prefix_0f" "1")
9202 (set_attr "mode" "SI")
9203 (set_attr "pent_pair" "np")
9204 (set_attr "athlon_decode" "vector")
9205 (set_attr "amdfam10_decode" "vector")
9206 (set_attr "bdver1_decode" "vector")])
9208 (define_expand "x86_shift<mode>_adj_1"
9209 [(set (reg:CCZ FLAGS_REG)
9210 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9213 (set (match_operand:SWI48 0 "register_operand")
9214 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9215 (match_operand:SWI48 1 "register_operand")
9218 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9219 (match_operand:SWI48 3 "register_operand")
9222 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9224 (define_expand "x86_shift<mode>_adj_2"
9225 [(use (match_operand:SWI48 0 "register_operand"))
9226 (use (match_operand:SWI48 1 "register_operand"))
9227 (use (match_operand:QI 2 "register_operand"))]
9230 rtx label = gen_label_rtx ();
9233 emit_insn (gen_testqi_ccz_1 (operands[2],
9234 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9236 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9237 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9238 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9239 gen_rtx_LABEL_REF (VOIDmode, label),
9241 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9242 JUMP_LABEL (tmp) = label;
9244 emit_move_insn (operands[0], operands[1]);
9245 ix86_expand_clear (operands[1]);
9248 LABEL_NUSES (label) = 1;
9253 ;; Avoid useless masking of count operand.
9254 (define_insn_and_split "*ashl<mode>3_mask"
9255 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9257 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9260 (match_operand:SI 2 "nonimmediate_operand" "c")
9261 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9262 (clobber (reg:CC FLAGS_REG))]
9263 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9264 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9265 == GET_MODE_BITSIZE (<MODE>mode)-1"
9268 [(parallel [(set (match_dup 0)
9269 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9270 (clobber (reg:CC FLAGS_REG))])]
9272 if (can_create_pseudo_p ())
9273 operands [2] = force_reg (SImode, operands[2]);
9275 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9277 [(set_attr "type" "ishift")
9278 (set_attr "mode" "<MODE>")])
9280 (define_insn "*bmi2_ashl<mode>3_1"
9281 [(set (match_operand:SWI48 0 "register_operand" "=r")
9282 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9283 (match_operand:SWI48 2 "register_operand" "r")))]
9285 "shlx\t{%2, %1, %0|%0, %1, %2}"
9286 [(set_attr "type" "ishiftx")
9287 (set_attr "mode" "<MODE>")])
9289 (define_insn "*ashl<mode>3_1"
9290 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9291 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9292 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9293 (clobber (reg:CC FLAGS_REG))]
9294 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9296 switch (get_attr_type (insn))
9303 gcc_assert (operands[2] == const1_rtx);
9304 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9305 return "add{<imodesuffix>}\t%0, %0";
9308 if (operands[2] == const1_rtx
9309 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9310 return "sal{<imodesuffix>}\t%0";
9312 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9315 [(set_attr "isa" "*,*,bmi2")
9317 (cond [(eq_attr "alternative" "1")
9318 (const_string "lea")
9319 (eq_attr "alternative" "2")
9320 (const_string "ishiftx")
9321 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9322 (match_operand 0 "register_operand"))
9323 (match_operand 2 "const1_operand"))
9324 (const_string "alu")
9326 (const_string "ishift")))
9327 (set (attr "length_immediate")
9329 (ior (eq_attr "type" "alu")
9330 (and (eq_attr "type" "ishift")
9331 (and (match_operand 2 "const1_operand")
9332 (ior (match_test "TARGET_SHIFT1")
9333 (match_test "optimize_function_for_size_p (cfun)")))))
9335 (const_string "*")))
9336 (set_attr "mode" "<MODE>")])
9338 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9340 [(set (match_operand:SWI48 0 "register_operand")
9341 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9342 (match_operand:QI 2 "register_operand")))
9343 (clobber (reg:CC FLAGS_REG))]
9344 "TARGET_BMI2 && reload_completed"
9346 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9347 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9349 (define_insn "*bmi2_ashlsi3_1_zext"
9350 [(set (match_operand:DI 0 "register_operand" "=r")
9352 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9353 (match_operand:SI 2 "register_operand" "r"))))]
9354 "TARGET_64BIT && TARGET_BMI2"
9355 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9356 [(set_attr "type" "ishiftx")
9357 (set_attr "mode" "SI")])
9359 (define_insn "*ashlsi3_1_zext"
9360 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9362 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9363 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9364 (clobber (reg:CC FLAGS_REG))]
9365 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9367 switch (get_attr_type (insn))
9374 gcc_assert (operands[2] == const1_rtx);
9375 return "add{l}\t%k0, %k0";
9378 if (operands[2] == const1_rtx
9379 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9380 return "sal{l}\t%k0";
9382 return "sal{l}\t{%2, %k0|%k0, %2}";
9385 [(set_attr "isa" "*,*,bmi2")
9387 (cond [(eq_attr "alternative" "1")
9388 (const_string "lea")
9389 (eq_attr "alternative" "2")
9390 (const_string "ishiftx")
9391 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9392 (match_operand 2 "const1_operand"))
9393 (const_string "alu")
9395 (const_string "ishift")))
9396 (set (attr "length_immediate")
9398 (ior (eq_attr "type" "alu")
9399 (and (eq_attr "type" "ishift")
9400 (and (match_operand 2 "const1_operand")
9401 (ior (match_test "TARGET_SHIFT1")
9402 (match_test "optimize_function_for_size_p (cfun)")))))
9404 (const_string "*")))
9405 (set_attr "mode" "SI")])
9407 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9409 [(set (match_operand:DI 0 "register_operand")
9411 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9412 (match_operand:QI 2 "register_operand"))))
9413 (clobber (reg:CC FLAGS_REG))]
9414 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9416 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9417 "operands[2] = gen_lowpart (SImode, operands[2]);")
9419 (define_insn "*ashlhi3_1"
9420 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9421 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9422 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9423 (clobber (reg:CC FLAGS_REG))]
9424 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9426 switch (get_attr_type (insn))
9432 gcc_assert (operands[2] == const1_rtx);
9433 return "add{w}\t%0, %0";
9436 if (operands[2] == const1_rtx
9437 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9438 return "sal{w}\t%0";
9440 return "sal{w}\t{%2, %0|%0, %2}";
9444 (cond [(eq_attr "alternative" "1")
9445 (const_string "lea")
9446 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9447 (match_operand 0 "register_operand"))
9448 (match_operand 2 "const1_operand"))
9449 (const_string "alu")
9451 (const_string "ishift")))
9452 (set (attr "length_immediate")
9454 (ior (eq_attr "type" "alu")
9455 (and (eq_attr "type" "ishift")
9456 (and (match_operand 2 "const1_operand")
9457 (ior (match_test "TARGET_SHIFT1")
9458 (match_test "optimize_function_for_size_p (cfun)")))))
9460 (const_string "*")))
9461 (set_attr "mode" "HI,SI")])
9463 ;; %%% Potential partial reg stall on alternative 1. What to do?
9464 (define_insn "*ashlqi3_1"
9465 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9466 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9467 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9468 (clobber (reg:CC FLAGS_REG))]
9469 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9471 switch (get_attr_type (insn))
9477 gcc_assert (operands[2] == const1_rtx);
9478 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9479 return "add{l}\t%k0, %k0";
9481 return "add{b}\t%0, %0";
9484 if (operands[2] == const1_rtx
9485 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9487 if (get_attr_mode (insn) == MODE_SI)
9488 return "sal{l}\t%k0";
9490 return "sal{b}\t%0";
9494 if (get_attr_mode (insn) == MODE_SI)
9495 return "sal{l}\t{%2, %k0|%k0, %2}";
9497 return "sal{b}\t{%2, %0|%0, %2}";
9502 (cond [(eq_attr "alternative" "2")
9503 (const_string "lea")
9504 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9505 (match_operand 0 "register_operand"))
9506 (match_operand 2 "const1_operand"))
9507 (const_string "alu")
9509 (const_string "ishift")))
9510 (set (attr "length_immediate")
9512 (ior (eq_attr "type" "alu")
9513 (and (eq_attr "type" "ishift")
9514 (and (match_operand 2 "const1_operand")
9515 (ior (match_test "TARGET_SHIFT1")
9516 (match_test "optimize_function_for_size_p (cfun)")))))
9518 (const_string "*")))
9519 (set_attr "mode" "QI,SI,SI")])
9521 (define_insn "*ashlqi3_1_slp"
9522 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9523 (ashift:QI (match_dup 0)
9524 (match_operand:QI 1 "nonmemory_operand" "cI")))
9525 (clobber (reg:CC FLAGS_REG))]
9526 "(optimize_function_for_size_p (cfun)
9527 || !TARGET_PARTIAL_FLAG_REG_STALL
9528 || (operands[1] == const1_rtx
9530 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9532 switch (get_attr_type (insn))
9535 gcc_assert (operands[1] == const1_rtx);
9536 return "add{b}\t%0, %0";
9539 if (operands[1] == const1_rtx
9540 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9541 return "sal{b}\t%0";
9543 return "sal{b}\t{%1, %0|%0, %1}";
9547 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9548 (match_operand 0 "register_operand"))
9549 (match_operand 1 "const1_operand"))
9550 (const_string "alu")
9552 (const_string "ishift1")))
9553 (set (attr "length_immediate")
9555 (ior (eq_attr "type" "alu")
9556 (and (eq_attr "type" "ishift1")
9557 (and (match_operand 1 "const1_operand")
9558 (ior (match_test "TARGET_SHIFT1")
9559 (match_test "optimize_function_for_size_p (cfun)")))))
9561 (const_string "*")))
9562 (set_attr "mode" "QI")])
9564 ;; Convert ashift to the lea pattern to avoid flags dependency.
9566 [(set (match_operand 0 "register_operand")
9567 (ashift (match_operand 1 "index_register_operand")
9568 (match_operand:QI 2 "const_int_operand")))
9569 (clobber (reg:CC FLAGS_REG))]
9570 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9572 && true_regnum (operands[0]) != true_regnum (operands[1])"
9575 enum machine_mode mode = GET_MODE (operands[0]);
9578 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9581 operands[0] = gen_lowpart (mode, operands[0]);
9582 operands[1] = gen_lowpart (mode, operands[1]);
9585 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9587 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9589 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9593 ;; Convert ashift to the lea pattern to avoid flags dependency.
9595 [(set (match_operand:DI 0 "register_operand")
9597 (ashift:SI (match_operand:SI 1 "index_register_operand")
9598 (match_operand:QI 2 "const_int_operand"))))
9599 (clobber (reg:CC FLAGS_REG))]
9600 "TARGET_64BIT && reload_completed
9601 && true_regnum (operands[0]) != true_regnum (operands[1])"
9603 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9605 operands[1] = gen_lowpart (DImode, operands[1]);
9606 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9609 ;; This pattern can't accept a variable shift count, since shifts by
9610 ;; zero don't affect the flags. We assume that shifts by constant
9611 ;; zero are optimized away.
9612 (define_insn "*ashl<mode>3_cmp"
9613 [(set (reg FLAGS_REG)
9615 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9616 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9618 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9619 (ashift:SWI (match_dup 1) (match_dup 2)))]
9620 "(optimize_function_for_size_p (cfun)
9621 || !TARGET_PARTIAL_FLAG_REG_STALL
9622 || (operands[2] == const1_rtx
9624 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9625 && ix86_match_ccmode (insn, CCGOCmode)
9626 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9628 switch (get_attr_type (insn))
9631 gcc_assert (operands[2] == const1_rtx);
9632 return "add{<imodesuffix>}\t%0, %0";
9635 if (operands[2] == const1_rtx
9636 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9637 return "sal{<imodesuffix>}\t%0";
9639 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9643 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9644 (match_operand 0 "register_operand"))
9645 (match_operand 2 "const1_operand"))
9646 (const_string "alu")
9648 (const_string "ishift")))
9649 (set (attr "length_immediate")
9651 (ior (eq_attr "type" "alu")
9652 (and (eq_attr "type" "ishift")
9653 (and (match_operand 2 "const1_operand")
9654 (ior (match_test "TARGET_SHIFT1")
9655 (match_test "optimize_function_for_size_p (cfun)")))))
9657 (const_string "*")))
9658 (set_attr "mode" "<MODE>")])
9660 (define_insn "*ashlsi3_cmp_zext"
9661 [(set (reg FLAGS_REG)
9663 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9664 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9666 (set (match_operand:DI 0 "register_operand" "=r")
9667 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9669 && (optimize_function_for_size_p (cfun)
9670 || !TARGET_PARTIAL_FLAG_REG_STALL
9671 || (operands[2] == const1_rtx
9673 || TARGET_DOUBLE_WITH_ADD)))
9674 && ix86_match_ccmode (insn, CCGOCmode)
9675 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9677 switch (get_attr_type (insn))
9680 gcc_assert (operands[2] == const1_rtx);
9681 return "add{l}\t%k0, %k0";
9684 if (operands[2] == const1_rtx
9685 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9686 return "sal{l}\t%k0";
9688 return "sal{l}\t{%2, %k0|%k0, %2}";
9692 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9693 (match_operand 2 "const1_operand"))
9694 (const_string "alu")
9696 (const_string "ishift")))
9697 (set (attr "length_immediate")
9699 (ior (eq_attr "type" "alu")
9700 (and (eq_attr "type" "ishift")
9701 (and (match_operand 2 "const1_operand")
9702 (ior (match_test "TARGET_SHIFT1")
9703 (match_test "optimize_function_for_size_p (cfun)")))))
9705 (const_string "*")))
9706 (set_attr "mode" "SI")])
9708 (define_insn "*ashl<mode>3_cconly"
9709 [(set (reg FLAGS_REG)
9711 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9712 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9714 (clobber (match_scratch:SWI 0 "=<r>"))]
9715 "(optimize_function_for_size_p (cfun)
9716 || !TARGET_PARTIAL_FLAG_REG_STALL
9717 || (operands[2] == const1_rtx
9719 || TARGET_DOUBLE_WITH_ADD)))
9720 && ix86_match_ccmode (insn, CCGOCmode)"
9722 switch (get_attr_type (insn))
9725 gcc_assert (operands[2] == const1_rtx);
9726 return "add{<imodesuffix>}\t%0, %0";
9729 if (operands[2] == const1_rtx
9730 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9731 return "sal{<imodesuffix>}\t%0";
9733 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9737 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9738 (match_operand 0 "register_operand"))
9739 (match_operand 2 "const1_operand"))
9740 (const_string "alu")
9742 (const_string "ishift")))
9743 (set (attr "length_immediate")
9745 (ior (eq_attr "type" "alu")
9746 (and (eq_attr "type" "ishift")
9747 (and (match_operand 2 "const1_operand")
9748 (ior (match_test "TARGET_SHIFT1")
9749 (match_test "optimize_function_for_size_p (cfun)")))))
9751 (const_string "*")))
9752 (set_attr "mode" "<MODE>")])
9754 ;; See comment above `ashl<mode>3' about how this works.
9756 (define_expand "<shift_insn><mode>3"
9757 [(set (match_operand:SDWIM 0 "<shift_operand>")
9758 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9759 (match_operand:QI 2 "nonmemory_operand")))]
9761 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9763 ;; Avoid useless masking of count operand.
9764 (define_insn_and_split "*<shift_insn><mode>3_mask"
9765 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9767 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9770 (match_operand:SI 2 "nonimmediate_operand" "c")
9771 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9772 (clobber (reg:CC FLAGS_REG))]
9773 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9774 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9775 == GET_MODE_BITSIZE (<MODE>mode)-1"
9778 [(parallel [(set (match_dup 0)
9779 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9780 (clobber (reg:CC FLAGS_REG))])]
9782 if (can_create_pseudo_p ())
9783 operands [2] = force_reg (SImode, operands[2]);
9785 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9787 [(set_attr "type" "ishift")
9788 (set_attr "mode" "<MODE>")])
9790 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9791 [(set (match_operand:DWI 0 "register_operand" "=r")
9792 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9793 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9794 (clobber (reg:CC FLAGS_REG))]
9797 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9799 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9800 [(set_attr "type" "multi")])
9802 ;; By default we don't ask for a scratch register, because when DWImode
9803 ;; values are manipulated, registers are already at a premium. But if
9804 ;; we have one handy, we won't turn it away.
9807 [(match_scratch:DWIH 3 "r")
9808 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9810 (match_operand:<DWI> 1 "register_operand")
9811 (match_operand:QI 2 "nonmemory_operand")))
9812 (clobber (reg:CC FLAGS_REG))])
9816 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9818 (define_insn "x86_64_shrd"
9819 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9820 (ior:DI (ashiftrt:DI (match_dup 0)
9821 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9822 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9823 (minus:QI (const_int 64) (match_dup 2)))))
9824 (clobber (reg:CC FLAGS_REG))]
9826 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9827 [(set_attr "type" "ishift")
9828 (set_attr "prefix_0f" "1")
9829 (set_attr "mode" "DI")
9830 (set_attr "athlon_decode" "vector")
9831 (set_attr "amdfam10_decode" "vector")
9832 (set_attr "bdver1_decode" "vector")])
9834 (define_insn "x86_shrd"
9835 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9836 (ior:SI (ashiftrt:SI (match_dup 0)
9837 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9838 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9839 (minus:QI (const_int 32) (match_dup 2)))))
9840 (clobber (reg:CC FLAGS_REG))]
9842 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9843 [(set_attr "type" "ishift")
9844 (set_attr "prefix_0f" "1")
9845 (set_attr "mode" "SI")
9846 (set_attr "pent_pair" "np")
9847 (set_attr "athlon_decode" "vector")
9848 (set_attr "amdfam10_decode" "vector")
9849 (set_attr "bdver1_decode" "vector")])
9851 (define_insn "ashrdi3_cvt"
9852 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9853 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9854 (match_operand:QI 2 "const_int_operand")))
9855 (clobber (reg:CC FLAGS_REG))]
9856 "TARGET_64BIT && INTVAL (operands[2]) == 63
9857 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9858 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9861 sar{q}\t{%2, %0|%0, %2}"
9862 [(set_attr "type" "imovx,ishift")
9863 (set_attr "prefix_0f" "0,*")
9864 (set_attr "length_immediate" "0,*")
9865 (set_attr "modrm" "0,1")
9866 (set_attr "mode" "DI")])
9868 (define_insn "ashrsi3_cvt"
9869 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9870 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9871 (match_operand:QI 2 "const_int_operand")))
9872 (clobber (reg:CC FLAGS_REG))]
9873 "INTVAL (operands[2]) == 31
9874 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9875 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9878 sar{l}\t{%2, %0|%0, %2}"
9879 [(set_attr "type" "imovx,ishift")
9880 (set_attr "prefix_0f" "0,*")
9881 (set_attr "length_immediate" "0,*")
9882 (set_attr "modrm" "0,1")
9883 (set_attr "mode" "SI")])
9885 (define_insn "*ashrsi3_cvt_zext"
9886 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9888 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9889 (match_operand:QI 2 "const_int_operand"))))
9890 (clobber (reg:CC FLAGS_REG))]
9891 "TARGET_64BIT && INTVAL (operands[2]) == 31
9892 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9893 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9896 sar{l}\t{%2, %k0|%k0, %2}"
9897 [(set_attr "type" "imovx,ishift")
9898 (set_attr "prefix_0f" "0,*")
9899 (set_attr "length_immediate" "0,*")
9900 (set_attr "modrm" "0,1")
9901 (set_attr "mode" "SI")])
9903 (define_expand "x86_shift<mode>_adj_3"
9904 [(use (match_operand:SWI48 0 "register_operand"))
9905 (use (match_operand:SWI48 1 "register_operand"))
9906 (use (match_operand:QI 2 "register_operand"))]
9909 rtx label = gen_label_rtx ();
9912 emit_insn (gen_testqi_ccz_1 (operands[2],
9913 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9915 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9916 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9917 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9918 gen_rtx_LABEL_REF (VOIDmode, label),
9920 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9921 JUMP_LABEL (tmp) = label;
9923 emit_move_insn (operands[0], operands[1]);
9924 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9925 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9927 LABEL_NUSES (label) = 1;
9932 (define_insn "*bmi2_<shift_insn><mode>3_1"
9933 [(set (match_operand:SWI48 0 "register_operand" "=r")
9934 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9935 (match_operand:SWI48 2 "register_operand" "r")))]
9937 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9938 [(set_attr "type" "ishiftx")
9939 (set_attr "mode" "<MODE>")])
9941 (define_insn "*<shift_insn><mode>3_1"
9942 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9944 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9945 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9946 (clobber (reg:CC FLAGS_REG))]
9947 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9949 switch (get_attr_type (insn))
9955 if (operands[2] == const1_rtx
9956 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9957 return "<shift>{<imodesuffix>}\t%0";
9959 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9962 [(set_attr "isa" "*,bmi2")
9963 (set_attr "type" "ishift,ishiftx")
9964 (set (attr "length_immediate")
9966 (and (match_operand 2 "const1_operand")
9967 (ior (match_test "TARGET_SHIFT1")
9968 (match_test "optimize_function_for_size_p (cfun)")))
9970 (const_string "*")))
9971 (set_attr "mode" "<MODE>")])
9973 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9975 [(set (match_operand:SWI48 0 "register_operand")
9976 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9977 (match_operand:QI 2 "register_operand")))
9978 (clobber (reg:CC FLAGS_REG))]
9979 "TARGET_BMI2 && reload_completed"
9981 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9982 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9984 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9985 [(set (match_operand:DI 0 "register_operand" "=r")
9987 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9988 (match_operand:SI 2 "register_operand" "r"))))]
9989 "TARGET_64BIT && TARGET_BMI2"
9990 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9991 [(set_attr "type" "ishiftx")
9992 (set_attr "mode" "SI")])
9994 (define_insn "*<shift_insn>si3_1_zext"
9995 [(set (match_operand:DI 0 "register_operand" "=r,r")
9997 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9998 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9999 (clobber (reg:CC FLAGS_REG))]
10000 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10002 switch (get_attr_type (insn))
10008 if (operands[2] == const1_rtx
10009 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10010 return "<shift>{l}\t%k0";
10012 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10015 [(set_attr "isa" "*,bmi2")
10016 (set_attr "type" "ishift,ishiftx")
10017 (set (attr "length_immediate")
10019 (and (match_operand 2 "const1_operand")
10020 (ior (match_test "TARGET_SHIFT1")
10021 (match_test "optimize_function_for_size_p (cfun)")))
10023 (const_string "*")))
10024 (set_attr "mode" "SI")])
10026 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10028 [(set (match_operand:DI 0 "register_operand")
10030 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10031 (match_operand:QI 2 "register_operand"))))
10032 (clobber (reg:CC FLAGS_REG))]
10033 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10034 [(set (match_dup 0)
10035 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10036 "operands[2] = gen_lowpart (SImode, operands[2]);")
10038 (define_insn "*<shift_insn><mode>3_1"
10039 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10041 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10042 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10043 (clobber (reg:CC FLAGS_REG))]
10044 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10046 if (operands[2] == const1_rtx
10047 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10048 return "<shift>{<imodesuffix>}\t%0";
10050 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10052 [(set_attr "type" "ishift")
10053 (set (attr "length_immediate")
10055 (and (match_operand 2 "const1_operand")
10056 (ior (match_test "TARGET_SHIFT1")
10057 (match_test "optimize_function_for_size_p (cfun)")))
10059 (const_string "*")))
10060 (set_attr "mode" "<MODE>")])
10062 (define_insn "*<shift_insn>qi3_1_slp"
10063 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10064 (any_shiftrt:QI (match_dup 0)
10065 (match_operand:QI 1 "nonmemory_operand" "cI")))
10066 (clobber (reg:CC FLAGS_REG))]
10067 "(optimize_function_for_size_p (cfun)
10068 || !TARGET_PARTIAL_REG_STALL
10069 || (operands[1] == const1_rtx
10070 && TARGET_SHIFT1))"
10072 if (operands[1] == const1_rtx
10073 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10074 return "<shift>{b}\t%0";
10076 return "<shift>{b}\t{%1, %0|%0, %1}";
10078 [(set_attr "type" "ishift1")
10079 (set (attr "length_immediate")
10081 (and (match_operand 1 "const1_operand")
10082 (ior (match_test "TARGET_SHIFT1")
10083 (match_test "optimize_function_for_size_p (cfun)")))
10085 (const_string "*")))
10086 (set_attr "mode" "QI")])
10088 ;; This pattern can't accept a variable shift count, since shifts by
10089 ;; zero don't affect the flags. We assume that shifts by constant
10090 ;; zero are optimized away.
10091 (define_insn "*<shift_insn><mode>3_cmp"
10092 [(set (reg FLAGS_REG)
10095 (match_operand:SWI 1 "nonimmediate_operand" "0")
10096 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10098 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10099 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10100 "(optimize_function_for_size_p (cfun)
10101 || !TARGET_PARTIAL_FLAG_REG_STALL
10102 || (operands[2] == const1_rtx
10104 && ix86_match_ccmode (insn, CCGOCmode)
10105 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10107 if (operands[2] == const1_rtx
10108 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10109 return "<shift>{<imodesuffix>}\t%0";
10111 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10113 [(set_attr "type" "ishift")
10114 (set (attr "length_immediate")
10116 (and (match_operand 2 "const1_operand")
10117 (ior (match_test "TARGET_SHIFT1")
10118 (match_test "optimize_function_for_size_p (cfun)")))
10120 (const_string "*")))
10121 (set_attr "mode" "<MODE>")])
10123 (define_insn "*<shift_insn>si3_cmp_zext"
10124 [(set (reg FLAGS_REG)
10126 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10127 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10129 (set (match_operand:DI 0 "register_operand" "=r")
10130 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10132 && (optimize_function_for_size_p (cfun)
10133 || !TARGET_PARTIAL_FLAG_REG_STALL
10134 || (operands[2] == const1_rtx
10136 && ix86_match_ccmode (insn, CCGOCmode)
10137 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10139 if (operands[2] == const1_rtx
10140 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10141 return "<shift>{l}\t%k0";
10143 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10145 [(set_attr "type" "ishift")
10146 (set (attr "length_immediate")
10148 (and (match_operand 2 "const1_operand")
10149 (ior (match_test "TARGET_SHIFT1")
10150 (match_test "optimize_function_for_size_p (cfun)")))
10152 (const_string "*")))
10153 (set_attr "mode" "SI")])
10155 (define_insn "*<shift_insn><mode>3_cconly"
10156 [(set (reg FLAGS_REG)
10159 (match_operand:SWI 1 "register_operand" "0")
10160 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10162 (clobber (match_scratch:SWI 0 "=<r>"))]
10163 "(optimize_function_for_size_p (cfun)
10164 || !TARGET_PARTIAL_FLAG_REG_STALL
10165 || (operands[2] == const1_rtx
10167 && ix86_match_ccmode (insn, CCGOCmode)"
10169 if (operands[2] == const1_rtx
10170 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10171 return "<shift>{<imodesuffix>}\t%0";
10173 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10175 [(set_attr "type" "ishift")
10176 (set (attr "length_immediate")
10178 (and (match_operand 2 "const1_operand")
10179 (ior (match_test "TARGET_SHIFT1")
10180 (match_test "optimize_function_for_size_p (cfun)")))
10182 (const_string "*")))
10183 (set_attr "mode" "<MODE>")])
10185 ;; Rotate instructions
10187 (define_expand "<rotate_insn>ti3"
10188 [(set (match_operand:TI 0 "register_operand")
10189 (any_rotate:TI (match_operand:TI 1 "register_operand")
10190 (match_operand:QI 2 "nonmemory_operand")))]
10193 if (const_1_to_63_operand (operands[2], VOIDmode))
10194 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10195 (operands[0], operands[1], operands[2]));
10202 (define_expand "<rotate_insn>di3"
10203 [(set (match_operand:DI 0 "shiftdi_operand")
10204 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10205 (match_operand:QI 2 "nonmemory_operand")))]
10209 ix86_expand_binary_operator (<CODE>, DImode, operands);
10210 else if (const_1_to_31_operand (operands[2], VOIDmode))
10211 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10212 (operands[0], operands[1], operands[2]));
10219 (define_expand "<rotate_insn><mode>3"
10220 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10221 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10222 (match_operand:QI 2 "nonmemory_operand")))]
10224 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10226 ;; Avoid useless masking of count operand.
10227 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10228 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10230 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10233 (match_operand:SI 2 "nonimmediate_operand" "c")
10234 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10235 (clobber (reg:CC FLAGS_REG))]
10236 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10237 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10238 == GET_MODE_BITSIZE (<MODE>mode)-1"
10241 [(parallel [(set (match_dup 0)
10242 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10243 (clobber (reg:CC FLAGS_REG))])]
10245 if (can_create_pseudo_p ())
10246 operands [2] = force_reg (SImode, operands[2]);
10248 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10250 [(set_attr "type" "rotate")
10251 (set_attr "mode" "<MODE>")])
10253 ;; Implement rotation using two double-precision
10254 ;; shift instructions and a scratch register.
10256 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10257 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10258 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10259 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10260 (clobber (reg:CC FLAGS_REG))
10261 (clobber (match_scratch:DWIH 3 "=&r"))]
10265 [(set (match_dup 3) (match_dup 4))
10267 [(set (match_dup 4)
10268 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10269 (lshiftrt:DWIH (match_dup 5)
10270 (minus:QI (match_dup 6) (match_dup 2)))))
10271 (clobber (reg:CC FLAGS_REG))])
10273 [(set (match_dup 5)
10274 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10275 (lshiftrt:DWIH (match_dup 3)
10276 (minus:QI (match_dup 6) (match_dup 2)))))
10277 (clobber (reg:CC FLAGS_REG))])]
10279 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10281 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10284 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10285 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10286 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10287 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10288 (clobber (reg:CC FLAGS_REG))
10289 (clobber (match_scratch:DWIH 3 "=&r"))]
10293 [(set (match_dup 3) (match_dup 4))
10295 [(set (match_dup 4)
10296 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10297 (ashift:DWIH (match_dup 5)
10298 (minus:QI (match_dup 6) (match_dup 2)))))
10299 (clobber (reg:CC FLAGS_REG))])
10301 [(set (match_dup 5)
10302 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10303 (ashift:DWIH (match_dup 3)
10304 (minus:QI (match_dup 6) (match_dup 2)))))
10305 (clobber (reg:CC FLAGS_REG))])]
10307 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10309 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10312 (define_insn "*bmi2_rorx<mode>3_1"
10313 [(set (match_operand:SWI48 0 "register_operand" "=r")
10314 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10315 (match_operand:QI 2 "immediate_operand" "<S>")))]
10317 "rorx\t{%2, %1, %0|%0, %1, %2}"
10318 [(set_attr "type" "rotatex")
10319 (set_attr "mode" "<MODE>")])
10321 (define_insn "*<rotate_insn><mode>3_1"
10322 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10324 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10325 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10326 (clobber (reg:CC FLAGS_REG))]
10327 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10329 switch (get_attr_type (insn))
10335 if (operands[2] == const1_rtx
10336 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10337 return "<rotate>{<imodesuffix>}\t%0";
10339 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10342 [(set_attr "isa" "*,bmi2")
10343 (set_attr "type" "rotate,rotatex")
10344 (set (attr "length_immediate")
10346 (and (eq_attr "type" "rotate")
10347 (and (match_operand 2 "const1_operand")
10348 (ior (match_test "TARGET_SHIFT1")
10349 (match_test "optimize_function_for_size_p (cfun)"))))
10351 (const_string "*")))
10352 (set_attr "mode" "<MODE>")])
10354 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10356 [(set (match_operand:SWI48 0 "register_operand")
10357 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10358 (match_operand:QI 2 "immediate_operand")))
10359 (clobber (reg:CC FLAGS_REG))]
10360 "TARGET_BMI2 && reload_completed"
10361 [(set (match_dup 0)
10362 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10365 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10369 [(set (match_operand:SWI48 0 "register_operand")
10370 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10371 (match_operand:QI 2 "immediate_operand")))
10372 (clobber (reg:CC FLAGS_REG))]
10373 "TARGET_BMI2 && reload_completed"
10374 [(set (match_dup 0)
10375 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10377 (define_insn "*bmi2_rorxsi3_1_zext"
10378 [(set (match_operand:DI 0 "register_operand" "=r")
10380 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10381 (match_operand:QI 2 "immediate_operand" "I"))))]
10382 "TARGET_64BIT && TARGET_BMI2"
10383 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10384 [(set_attr "type" "rotatex")
10385 (set_attr "mode" "SI")])
10387 (define_insn "*<rotate_insn>si3_1_zext"
10388 [(set (match_operand:DI 0 "register_operand" "=r,r")
10390 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10391 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10392 (clobber (reg:CC FLAGS_REG))]
10393 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10395 switch (get_attr_type (insn))
10401 if (operands[2] == const1_rtx
10402 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10403 return "<rotate>{l}\t%k0";
10405 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10408 [(set_attr "isa" "*,bmi2")
10409 (set_attr "type" "rotate,rotatex")
10410 (set (attr "length_immediate")
10412 (and (eq_attr "type" "rotate")
10413 (and (match_operand 2 "const1_operand")
10414 (ior (match_test "TARGET_SHIFT1")
10415 (match_test "optimize_function_for_size_p (cfun)"))))
10417 (const_string "*")))
10418 (set_attr "mode" "SI")])
10420 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10422 [(set (match_operand:DI 0 "register_operand")
10424 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10425 (match_operand:QI 2 "immediate_operand"))))
10426 (clobber (reg:CC FLAGS_REG))]
10427 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10428 [(set (match_dup 0)
10429 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10432 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10436 [(set (match_operand:DI 0 "register_operand")
10438 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10439 (match_operand:QI 2 "immediate_operand"))))
10440 (clobber (reg:CC FLAGS_REG))]
10441 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10442 [(set (match_dup 0)
10443 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10445 (define_insn "*<rotate_insn><mode>3_1"
10446 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10447 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10448 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10449 (clobber (reg:CC FLAGS_REG))]
10450 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10452 if (operands[2] == const1_rtx
10453 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10454 return "<rotate>{<imodesuffix>}\t%0";
10456 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10458 [(set_attr "type" "rotate")
10459 (set (attr "length_immediate")
10461 (and (match_operand 2 "const1_operand")
10462 (ior (match_test "TARGET_SHIFT1")
10463 (match_test "optimize_function_for_size_p (cfun)")))
10465 (const_string "*")))
10466 (set_attr "mode" "<MODE>")])
10468 (define_insn "*<rotate_insn>qi3_1_slp"
10469 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10470 (any_rotate:QI (match_dup 0)
10471 (match_operand:QI 1 "nonmemory_operand" "cI")))
10472 (clobber (reg:CC FLAGS_REG))]
10473 "(optimize_function_for_size_p (cfun)
10474 || !TARGET_PARTIAL_REG_STALL
10475 || (operands[1] == const1_rtx
10476 && TARGET_SHIFT1))"
10478 if (operands[1] == const1_rtx
10479 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10480 return "<rotate>{b}\t%0";
10482 return "<rotate>{b}\t{%1, %0|%0, %1}";
10484 [(set_attr "type" "rotate1")
10485 (set (attr "length_immediate")
10487 (and (match_operand 1 "const1_operand")
10488 (ior (match_test "TARGET_SHIFT1")
10489 (match_test "optimize_function_for_size_p (cfun)")))
10491 (const_string "*")))
10492 (set_attr "mode" "QI")])
10495 [(set (match_operand:HI 0 "register_operand")
10496 (any_rotate:HI (match_dup 0) (const_int 8)))
10497 (clobber (reg:CC FLAGS_REG))]
10499 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10500 [(parallel [(set (strict_low_part (match_dup 0))
10501 (bswap:HI (match_dup 0)))
10502 (clobber (reg:CC FLAGS_REG))])])
10504 ;; Bit set / bit test instructions
10506 (define_expand "extv"
10507 [(set (match_operand:SI 0 "register_operand")
10508 (sign_extract:SI (match_operand:SI 1 "register_operand")
10509 (match_operand:SI 2 "const8_operand")
10510 (match_operand:SI 3 "const8_operand")))]
10513 /* Handle extractions from %ah et al. */
10514 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10517 /* From mips.md: extract_bit_field doesn't verify that our source
10518 matches the predicate, so check it again here. */
10519 if (! ext_register_operand (operands[1], VOIDmode))
10523 (define_expand "extzv"
10524 [(set (match_operand:SI 0 "register_operand")
10525 (zero_extract:SI (match_operand 1 "ext_register_operand")
10526 (match_operand:SI 2 "const8_operand")
10527 (match_operand:SI 3 "const8_operand")))]
10530 /* Handle extractions from %ah et al. */
10531 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10534 /* From mips.md: extract_bit_field doesn't verify that our source
10535 matches the predicate, so check it again here. */
10536 if (! ext_register_operand (operands[1], VOIDmode))
10540 (define_expand "insv"
10541 [(set (zero_extract (match_operand 0 "register_operand")
10542 (match_operand 1 "const_int_operand")
10543 (match_operand 2 "const_int_operand"))
10544 (match_operand 3 "register_operand"))]
10547 rtx (*gen_mov_insv_1) (rtx, rtx);
10549 if (ix86_expand_pinsr (operands))
10552 /* Handle insertions to %ah et al. */
10553 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10556 /* From mips.md: insert_bit_field doesn't verify that our source
10557 matches the predicate, so check it again here. */
10558 if (! ext_register_operand (operands[0], VOIDmode))
10561 gen_mov_insv_1 = (TARGET_64BIT
10562 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10564 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10568 ;; %%% bts, btr, btc, bt.
10569 ;; In general these instructions are *slow* when applied to memory,
10570 ;; since they enforce atomic operation. When applied to registers,
10571 ;; it depends on the cpu implementation. They're never faster than
10572 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10573 ;; no point. But in 64-bit, we can't hold the relevant immediates
10574 ;; within the instruction itself, so operating on bits in the high
10575 ;; 32-bits of a register becomes easier.
10577 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10578 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10579 ;; negdf respectively, so they can never be disabled entirely.
10581 (define_insn "*btsq"
10582 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10584 (match_operand:DI 1 "const_0_to_63_operand"))
10586 (clobber (reg:CC FLAGS_REG))]
10587 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10588 "bts{q}\t{%1, %0|%0, %1}"
10589 [(set_attr "type" "alu1")
10590 (set_attr "prefix_0f" "1")
10591 (set_attr "mode" "DI")])
10593 (define_insn "*btrq"
10594 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10596 (match_operand:DI 1 "const_0_to_63_operand"))
10598 (clobber (reg:CC FLAGS_REG))]
10599 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10600 "btr{q}\t{%1, %0|%0, %1}"
10601 [(set_attr "type" "alu1")
10602 (set_attr "prefix_0f" "1")
10603 (set_attr "mode" "DI")])
10605 (define_insn "*btcq"
10606 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10608 (match_operand:DI 1 "const_0_to_63_operand"))
10609 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10610 (clobber (reg:CC FLAGS_REG))]
10611 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10612 "btc{q}\t{%1, %0|%0, %1}"
10613 [(set_attr "type" "alu1")
10614 (set_attr "prefix_0f" "1")
10615 (set_attr "mode" "DI")])
10617 ;; Allow Nocona to avoid these instructions if a register is available.
10620 [(match_scratch:DI 2 "r")
10621 (parallel [(set (zero_extract:DI
10622 (match_operand:DI 0 "register_operand")
10624 (match_operand:DI 1 "const_0_to_63_operand"))
10626 (clobber (reg:CC FLAGS_REG))])]
10627 "TARGET_64BIT && !TARGET_USE_BT"
10630 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10633 if (HOST_BITS_PER_WIDE_INT >= 64)
10634 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10635 else if (i < HOST_BITS_PER_WIDE_INT)
10636 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10638 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10640 op1 = immed_double_const (lo, hi, DImode);
10643 emit_move_insn (operands[2], op1);
10647 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10652 [(match_scratch:DI 2 "r")
10653 (parallel [(set (zero_extract:DI
10654 (match_operand:DI 0 "register_operand")
10656 (match_operand:DI 1 "const_0_to_63_operand"))
10658 (clobber (reg:CC FLAGS_REG))])]
10659 "TARGET_64BIT && !TARGET_USE_BT"
10662 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10665 if (HOST_BITS_PER_WIDE_INT >= 64)
10666 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10667 else if (i < HOST_BITS_PER_WIDE_INT)
10668 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10670 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10672 op1 = immed_double_const (~lo, ~hi, DImode);
10675 emit_move_insn (operands[2], op1);
10679 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10684 [(match_scratch:DI 2 "r")
10685 (parallel [(set (zero_extract:DI
10686 (match_operand:DI 0 "register_operand")
10688 (match_operand:DI 1 "const_0_to_63_operand"))
10689 (not:DI (zero_extract:DI
10690 (match_dup 0) (const_int 1) (match_dup 1))))
10691 (clobber (reg:CC FLAGS_REG))])]
10692 "TARGET_64BIT && !TARGET_USE_BT"
10695 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10698 if (HOST_BITS_PER_WIDE_INT >= 64)
10699 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10700 else if (i < HOST_BITS_PER_WIDE_INT)
10701 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10703 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10705 op1 = immed_double_const (lo, hi, DImode);
10708 emit_move_insn (operands[2], op1);
10712 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10716 (define_insn "*bt<mode>"
10717 [(set (reg:CCC FLAGS_REG)
10719 (zero_extract:SWI48
10720 (match_operand:SWI48 0 "register_operand" "r")
10722 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10724 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10725 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10726 [(set_attr "type" "alu1")
10727 (set_attr "prefix_0f" "1")
10728 (set_attr "mode" "<MODE>")])
10730 ;; Store-flag instructions.
10732 ;; For all sCOND expanders, also expand the compare or test insn that
10733 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10735 (define_insn_and_split "*setcc_di_1"
10736 [(set (match_operand:DI 0 "register_operand" "=q")
10737 (match_operator:DI 1 "ix86_comparison_operator"
10738 [(reg FLAGS_REG) (const_int 0)]))]
10739 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10741 "&& reload_completed"
10742 [(set (match_dup 2) (match_dup 1))
10743 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10745 PUT_MODE (operands[1], QImode);
10746 operands[2] = gen_lowpart (QImode, operands[0]);
10749 (define_insn_and_split "*setcc_si_1_and"
10750 [(set (match_operand:SI 0 "register_operand" "=q")
10751 (match_operator:SI 1 "ix86_comparison_operator"
10752 [(reg FLAGS_REG) (const_int 0)]))
10753 (clobber (reg:CC FLAGS_REG))]
10754 "!TARGET_PARTIAL_REG_STALL
10755 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10757 "&& reload_completed"
10758 [(set (match_dup 2) (match_dup 1))
10759 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10760 (clobber (reg:CC FLAGS_REG))])]
10762 PUT_MODE (operands[1], QImode);
10763 operands[2] = gen_lowpart (QImode, operands[0]);
10766 (define_insn_and_split "*setcc_si_1_movzbl"
10767 [(set (match_operand:SI 0 "register_operand" "=q")
10768 (match_operator:SI 1 "ix86_comparison_operator"
10769 [(reg FLAGS_REG) (const_int 0)]))]
10770 "!TARGET_PARTIAL_REG_STALL
10771 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10773 "&& reload_completed"
10774 [(set (match_dup 2) (match_dup 1))
10775 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10777 PUT_MODE (operands[1], QImode);
10778 operands[2] = gen_lowpart (QImode, operands[0]);
10781 (define_insn "*setcc_qi"
10782 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10783 (match_operator:QI 1 "ix86_comparison_operator"
10784 [(reg FLAGS_REG) (const_int 0)]))]
10787 [(set_attr "type" "setcc")
10788 (set_attr "mode" "QI")])
10790 (define_insn "*setcc_qi_slp"
10791 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10792 (match_operator:QI 1 "ix86_comparison_operator"
10793 [(reg FLAGS_REG) (const_int 0)]))]
10796 [(set_attr "type" "setcc")
10797 (set_attr "mode" "QI")])
10799 ;; In general it is not safe to assume too much about CCmode registers,
10800 ;; so simplify-rtx stops when it sees a second one. Under certain
10801 ;; conditions this is safe on x86, so help combine not create
10808 [(set (match_operand:QI 0 "nonimmediate_operand")
10809 (ne:QI (match_operator 1 "ix86_comparison_operator"
10810 [(reg FLAGS_REG) (const_int 0)])
10813 [(set (match_dup 0) (match_dup 1))]
10814 "PUT_MODE (operands[1], QImode);")
10817 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10818 (ne:QI (match_operator 1 "ix86_comparison_operator"
10819 [(reg FLAGS_REG) (const_int 0)])
10822 [(set (match_dup 0) (match_dup 1))]
10823 "PUT_MODE (operands[1], QImode);")
10826 [(set (match_operand:QI 0 "nonimmediate_operand")
10827 (eq:QI (match_operator 1 "ix86_comparison_operator"
10828 [(reg FLAGS_REG) (const_int 0)])
10831 [(set (match_dup 0) (match_dup 1))]
10833 rtx new_op1 = copy_rtx (operands[1]);
10834 operands[1] = new_op1;
10835 PUT_MODE (new_op1, QImode);
10836 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10837 GET_MODE (XEXP (new_op1, 0))));
10839 /* Make sure that (a) the CCmode we have for the flags is strong
10840 enough for the reversed compare or (b) we have a valid FP compare. */
10841 if (! ix86_comparison_operator (new_op1, VOIDmode))
10846 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10847 (eq:QI (match_operator 1 "ix86_comparison_operator"
10848 [(reg FLAGS_REG) (const_int 0)])
10851 [(set (match_dup 0) (match_dup 1))]
10853 rtx new_op1 = copy_rtx (operands[1]);
10854 operands[1] = new_op1;
10855 PUT_MODE (new_op1, QImode);
10856 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10857 GET_MODE (XEXP (new_op1, 0))));
10859 /* Make sure that (a) the CCmode we have for the flags is strong
10860 enough for the reversed compare or (b) we have a valid FP compare. */
10861 if (! ix86_comparison_operator (new_op1, VOIDmode))
10865 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10866 ;; subsequent logical operations are used to imitate conditional moves.
10867 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10870 (define_insn "setcc_<mode>_sse"
10871 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10872 (match_operator:MODEF 3 "sse_comparison_operator"
10873 [(match_operand:MODEF 1 "register_operand" "0,x")
10874 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10875 "SSE_FLOAT_MODE_P (<MODE>mode)"
10877 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10878 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10879 [(set_attr "isa" "noavx,avx")
10880 (set_attr "type" "ssecmp")
10881 (set_attr "length_immediate" "1")
10882 (set_attr "prefix" "orig,vex")
10883 (set_attr "mode" "<MODE>")])
10885 ;; Basic conditional jump instructions.
10886 ;; We ignore the overflow flag for signed branch instructions.
10888 (define_insn "*jcc_1"
10890 (if_then_else (match_operator 1 "ix86_comparison_operator"
10891 [(reg FLAGS_REG) (const_int 0)])
10892 (label_ref (match_operand 0))
10896 [(set_attr "type" "ibr")
10897 (set_attr "modrm" "0")
10898 (set (attr "length")
10899 (if_then_else (and (ge (minus (match_dup 0) (pc))
10901 (lt (minus (match_dup 0) (pc))
10906 (define_insn "*jcc_2"
10908 (if_then_else (match_operator 1 "ix86_comparison_operator"
10909 [(reg FLAGS_REG) (const_int 0)])
10911 (label_ref (match_operand 0))))]
10914 [(set_attr "type" "ibr")
10915 (set_attr "modrm" "0")
10916 (set (attr "length")
10917 (if_then_else (and (ge (minus (match_dup 0) (pc))
10919 (lt (minus (match_dup 0) (pc))
10924 ;; In general it is not safe to assume too much about CCmode registers,
10925 ;; so simplify-rtx stops when it sees a second one. Under certain
10926 ;; conditions this is safe on x86, so help combine not create
10934 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10935 [(reg FLAGS_REG) (const_int 0)])
10937 (label_ref (match_operand 1))
10941 (if_then_else (match_dup 0)
10942 (label_ref (match_dup 1))
10944 "PUT_MODE (operands[0], VOIDmode);")
10948 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10949 [(reg FLAGS_REG) (const_int 0)])
10951 (label_ref (match_operand 1))
10955 (if_then_else (match_dup 0)
10956 (label_ref (match_dup 1))
10959 rtx new_op0 = copy_rtx (operands[0]);
10960 operands[0] = new_op0;
10961 PUT_MODE (new_op0, VOIDmode);
10962 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10963 GET_MODE (XEXP (new_op0, 0))));
10965 /* Make sure that (a) the CCmode we have for the flags is strong
10966 enough for the reversed compare or (b) we have a valid FP compare. */
10967 if (! ix86_comparison_operator (new_op0, VOIDmode))
10971 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10972 ;; pass generates from shift insn with QImode operand. Actually, the mode
10973 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10974 ;; appropriate modulo of the bit offset value.
10976 (define_insn_and_split "*jcc_bt<mode>"
10978 (if_then_else (match_operator 0 "bt_comparison_operator"
10979 [(zero_extract:SWI48
10980 (match_operand:SWI48 1 "register_operand" "r")
10983 (match_operand:QI 2 "register_operand" "r")))
10985 (label_ref (match_operand 3))
10987 (clobber (reg:CC FLAGS_REG))]
10988 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10991 [(set (reg:CCC FLAGS_REG)
10993 (zero_extract:SWI48
10999 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11000 (label_ref (match_dup 3))
11003 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11005 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11008 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
11009 ;; also for DImode, this is what combine produces.
11010 (define_insn_and_split "*jcc_bt<mode>_mask"
11012 (if_then_else (match_operator 0 "bt_comparison_operator"
11013 [(zero_extract:SWI48
11014 (match_operand:SWI48 1 "register_operand" "r")
11017 (match_operand:SI 2 "register_operand" "r")
11018 (match_operand:SI 3 "const_int_operand" "n")))])
11019 (label_ref (match_operand 4))
11021 (clobber (reg:CC FLAGS_REG))]
11022 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11023 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11024 == GET_MODE_BITSIZE (<MODE>mode)-1"
11027 [(set (reg:CCC FLAGS_REG)
11029 (zero_extract:SWI48
11035 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11036 (label_ref (match_dup 4))
11039 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11041 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11044 (define_insn_and_split "*jcc_btsi_1"
11046 (if_then_else (match_operator 0 "bt_comparison_operator"
11049 (match_operand:SI 1 "register_operand" "r")
11050 (match_operand:QI 2 "register_operand" "r"))
11053 (label_ref (match_operand 3))
11055 (clobber (reg:CC FLAGS_REG))]
11056 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11059 [(set (reg:CCC FLAGS_REG)
11067 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11068 (label_ref (match_dup 3))
11071 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11073 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11076 ;; avoid useless masking of bit offset operand
11077 (define_insn_and_split "*jcc_btsi_mask_1"
11080 (match_operator 0 "bt_comparison_operator"
11083 (match_operand:SI 1 "register_operand" "r")
11086 (match_operand:SI 2 "register_operand" "r")
11087 (match_operand:SI 3 "const_int_operand" "n")) 0))
11090 (label_ref (match_operand 4))
11092 (clobber (reg:CC FLAGS_REG))]
11093 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11094 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11097 [(set (reg:CCC FLAGS_REG)
11105 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11106 (label_ref (match_dup 4))
11108 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11110 ;; Define combination compare-and-branch fp compare instructions to help
11113 (define_insn "*fp_jcc_1_387"
11115 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11116 [(match_operand 1 "register_operand" "f")
11117 (match_operand 2 "nonimmediate_operand" "fm")])
11118 (label_ref (match_operand 3))
11120 (clobber (reg:CCFP FPSR_REG))
11121 (clobber (reg:CCFP FLAGS_REG))
11122 (clobber (match_scratch:HI 4 "=a"))]
11124 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11125 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11126 && SELECT_CC_MODE (GET_CODE (operands[0]),
11127 operands[1], operands[2]) == CCFPmode
11131 (define_insn "*fp_jcc_1r_387"
11133 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11134 [(match_operand 1 "register_operand" "f")
11135 (match_operand 2 "nonimmediate_operand" "fm")])
11137 (label_ref (match_operand 3))))
11138 (clobber (reg:CCFP FPSR_REG))
11139 (clobber (reg:CCFP FLAGS_REG))
11140 (clobber (match_scratch:HI 4 "=a"))]
11142 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11143 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11144 && SELECT_CC_MODE (GET_CODE (operands[0]),
11145 operands[1], operands[2]) == CCFPmode
11149 (define_insn "*fp_jcc_2_387"
11151 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11152 [(match_operand 1 "register_operand" "f")
11153 (match_operand 2 "register_operand" "f")])
11154 (label_ref (match_operand 3))
11156 (clobber (reg:CCFP FPSR_REG))
11157 (clobber (reg:CCFP FLAGS_REG))
11158 (clobber (match_scratch:HI 4 "=a"))]
11159 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11160 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11164 (define_insn "*fp_jcc_2r_387"
11166 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11167 [(match_operand 1 "register_operand" "f")
11168 (match_operand 2 "register_operand" "f")])
11170 (label_ref (match_operand 3))))
11171 (clobber (reg:CCFP FPSR_REG))
11172 (clobber (reg:CCFP FLAGS_REG))
11173 (clobber (match_scratch:HI 4 "=a"))]
11174 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11175 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11179 (define_insn "*fp_jcc_3_387"
11181 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11182 [(match_operand 1 "register_operand" "f")
11183 (match_operand 2 "const0_operand")])
11184 (label_ref (match_operand 3))
11186 (clobber (reg:CCFP FPSR_REG))
11187 (clobber (reg:CCFP FLAGS_REG))
11188 (clobber (match_scratch:HI 4 "=a"))]
11189 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11190 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11191 && SELECT_CC_MODE (GET_CODE (operands[0]),
11192 operands[1], operands[2]) == CCFPmode
11198 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11199 [(match_operand 1 "register_operand")
11200 (match_operand 2 "nonimmediate_operand")])
11202 (match_operand 4)))
11203 (clobber (reg:CCFP FPSR_REG))
11204 (clobber (reg:CCFP FLAGS_REG))]
11208 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11209 operands[3], operands[4], NULL_RTX, NULL_RTX);
11215 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11216 [(match_operand 1 "register_operand")
11217 (match_operand 2 "general_operand")])
11219 (match_operand 4)))
11220 (clobber (reg:CCFP FPSR_REG))
11221 (clobber (reg:CCFP FLAGS_REG))
11222 (clobber (match_scratch:HI 5 "=a"))]
11226 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11227 operands[3], operands[4], operands[5], NULL_RTX);
11231 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11232 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11233 ;; with a precedence over other operators and is always put in the first
11234 ;; place. Swap condition and operands to match ficom instruction.
11236 (define_insn "*fp_jcc_4_<mode>_387"
11239 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11240 [(match_operator 1 "float_operator"
11241 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11242 (match_operand 3 "register_operand" "f,f")])
11243 (label_ref (match_operand 4))
11245 (clobber (reg:CCFP FPSR_REG))
11246 (clobber (reg:CCFP FLAGS_REG))
11247 (clobber (match_scratch:HI 5 "=a,a"))]
11248 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11249 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11250 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11251 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11258 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11259 [(match_operator 1 "float_operator"
11260 [(match_operand:SWI24 2 "memory_operand")])
11261 (match_operand 3 "register_operand")])
11263 (match_operand 5)))
11264 (clobber (reg:CCFP FPSR_REG))
11265 (clobber (reg:CCFP FLAGS_REG))
11266 (clobber (match_scratch:HI 6 "=a"))]
11270 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11272 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11273 operands[3], operands[7],
11274 operands[4], operands[5], operands[6], NULL_RTX);
11278 ;; %%% Kill this when reload knows how to do it.
11282 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11283 [(match_operator 1 "float_operator"
11284 [(match_operand:SWI24 2 "register_operand")])
11285 (match_operand 3 "register_operand")])
11287 (match_operand 5)))
11288 (clobber (reg:CCFP FPSR_REG))
11289 (clobber (reg:CCFP FLAGS_REG))
11290 (clobber (match_scratch:HI 6 "=a"))]
11294 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11295 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11297 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11298 operands[3], operands[7],
11299 operands[4], operands[5], operands[6], operands[2]);
11303 ;; Unconditional and other jump instructions
11305 (define_insn "jump"
11307 (label_ref (match_operand 0)))]
11310 [(set_attr "type" "ibr")
11311 (set (attr "length")
11312 (if_then_else (and (ge (minus (match_dup 0) (pc))
11314 (lt (minus (match_dup 0) (pc))
11318 (set_attr "modrm" "0")])
11320 (define_expand "indirect_jump"
11321 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11325 operands[0] = convert_memory_address (word_mode, operands[0]);
11328 (define_insn "*indirect_jump"
11329 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11332 [(set_attr "type" "ibr")
11333 (set_attr "length_immediate" "0")])
11335 (define_expand "tablejump"
11336 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11337 (use (label_ref (match_operand 1)))])]
11340 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11341 relative. Convert the relative address to an absolute address. */
11345 enum rtx_code code;
11347 /* We can't use @GOTOFF for text labels on VxWorks;
11348 see gotoff_operand. */
11349 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11353 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11355 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11359 op1 = pic_offset_table_rtx;
11364 op0 = pic_offset_table_rtx;
11368 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11373 operands[0] = convert_memory_address (word_mode, operands[0]);
11376 (define_insn "*tablejump_1"
11377 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11378 (use (label_ref (match_operand 1)))]
11381 [(set_attr "type" "ibr")
11382 (set_attr "length_immediate" "0")])
11384 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11387 [(set (reg FLAGS_REG) (match_operand 0))
11388 (set (match_operand:QI 1 "register_operand")
11389 (match_operator:QI 2 "ix86_comparison_operator"
11390 [(reg FLAGS_REG) (const_int 0)]))
11391 (set (match_operand 3 "q_regs_operand")
11392 (zero_extend (match_dup 1)))]
11393 "(peep2_reg_dead_p (3, operands[1])
11394 || operands_match_p (operands[1], operands[3]))
11395 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11396 [(set (match_dup 4) (match_dup 0))
11397 (set (strict_low_part (match_dup 5))
11400 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11401 operands[5] = gen_lowpart (QImode, operands[3]);
11402 ix86_expand_clear (operands[3]);
11406 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11407 (match_operand 4)])
11408 (set (match_operand:QI 1 "register_operand")
11409 (match_operator:QI 2 "ix86_comparison_operator"
11410 [(reg FLAGS_REG) (const_int 0)]))
11411 (set (match_operand 3 "q_regs_operand")
11412 (zero_extend (match_dup 1)))]
11413 "(peep2_reg_dead_p (3, operands[1])
11414 || operands_match_p (operands[1], operands[3]))
11415 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11416 [(parallel [(set (match_dup 5) (match_dup 0))
11418 (set (strict_low_part (match_dup 6))
11421 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11422 operands[6] = gen_lowpart (QImode, operands[3]);
11423 ix86_expand_clear (operands[3]);
11426 ;; Similar, but match zero extend with andsi3.
11429 [(set (reg FLAGS_REG) (match_operand 0))
11430 (set (match_operand:QI 1 "register_operand")
11431 (match_operator:QI 2 "ix86_comparison_operator"
11432 [(reg FLAGS_REG) (const_int 0)]))
11433 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11434 (and:SI (match_dup 3) (const_int 255)))
11435 (clobber (reg:CC FLAGS_REG))])]
11436 "REGNO (operands[1]) == REGNO (operands[3])
11437 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11438 [(set (match_dup 4) (match_dup 0))
11439 (set (strict_low_part (match_dup 5))
11442 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11443 operands[5] = gen_lowpart (QImode, operands[3]);
11444 ix86_expand_clear (operands[3]);
11448 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11449 (match_operand 4)])
11450 (set (match_operand:QI 1 "register_operand")
11451 (match_operator:QI 2 "ix86_comparison_operator"
11452 [(reg FLAGS_REG) (const_int 0)]))
11453 (parallel [(set (match_operand 3 "q_regs_operand")
11454 (zero_extend (match_dup 1)))
11455 (clobber (reg:CC FLAGS_REG))])]
11456 "(peep2_reg_dead_p (3, operands[1])
11457 || operands_match_p (operands[1], operands[3]))
11458 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11459 [(parallel [(set (match_dup 5) (match_dup 0))
11461 (set (strict_low_part (match_dup 6))
11464 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11465 operands[6] = gen_lowpart (QImode, operands[3]);
11466 ix86_expand_clear (operands[3]);
11469 ;; Call instructions.
11471 ;; The predicates normally associated with named expanders are not properly
11472 ;; checked for calls. This is a bug in the generic code, but it isn't that
11473 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11475 ;; P6 processors will jump to the address after the decrement when %esp
11476 ;; is used as a call operand, so they will execute return address as a code.
11477 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11479 ;; Register constraint for call instruction.
11480 (define_mode_attr c [(SI "l") (DI "r")])
11482 ;; Call subroutine returning no value.
11484 (define_expand "call"
11485 [(call (match_operand:QI 0)
11487 (use (match_operand 2))]
11490 ix86_expand_call (NULL, operands[0], operands[1],
11491 operands[2], NULL, false);
11495 (define_expand "sibcall"
11496 [(call (match_operand:QI 0)
11498 (use (match_operand 2))]
11501 ix86_expand_call (NULL, operands[0], operands[1],
11502 operands[2], NULL, true);
11506 (define_insn_and_split "*call_vzeroupper"
11507 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11509 (unspec [(match_operand 2 "const_int_operand")]
11510 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11511 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11513 "&& reload_completed"
11515 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11516 [(set_attr "type" "call")])
11518 (define_insn "*call"
11519 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11520 (match_operand 1))]
11521 "!SIBLING_CALL_P (insn)"
11522 "* return ix86_output_call_insn (insn, operands[0]);"
11523 [(set_attr "type" "call")])
11525 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11526 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11528 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11529 (clobber (reg:TI XMM6_REG))
11530 (clobber (reg:TI XMM7_REG))
11531 (clobber (reg:TI XMM8_REG))
11532 (clobber (reg:TI XMM9_REG))
11533 (clobber (reg:TI XMM10_REG))
11534 (clobber (reg:TI XMM11_REG))
11535 (clobber (reg:TI XMM12_REG))
11536 (clobber (reg:TI XMM13_REG))
11537 (clobber (reg:TI XMM14_REG))
11538 (clobber (reg:TI XMM15_REG))
11539 (clobber (reg:DI SI_REG))
11540 (clobber (reg:DI DI_REG))
11541 (unspec [(match_operand 2 "const_int_operand")]
11542 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11543 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11545 "&& reload_completed"
11547 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11548 [(set_attr "type" "call")])
11550 (define_insn "*call_rex64_ms_sysv"
11551 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11553 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11554 (clobber (reg:TI XMM6_REG))
11555 (clobber (reg:TI XMM7_REG))
11556 (clobber (reg:TI XMM8_REG))
11557 (clobber (reg:TI XMM9_REG))
11558 (clobber (reg:TI XMM10_REG))
11559 (clobber (reg:TI XMM11_REG))
11560 (clobber (reg:TI XMM12_REG))
11561 (clobber (reg:TI XMM13_REG))
11562 (clobber (reg:TI XMM14_REG))
11563 (clobber (reg:TI XMM15_REG))
11564 (clobber (reg:DI SI_REG))
11565 (clobber (reg:DI DI_REG))]
11566 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11567 "* return ix86_output_call_insn (insn, operands[0]);"
11568 [(set_attr "type" "call")])
11570 (define_insn_and_split "*sibcall_vzeroupper"
11571 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11573 (unspec [(match_operand 2 "const_int_operand")]
11574 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11575 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11577 "&& reload_completed"
11579 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11580 [(set_attr "type" "call")])
11582 (define_insn "*sibcall"
11583 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11584 (match_operand 1))]
11585 "SIBLING_CALL_P (insn)"
11586 "* return ix86_output_call_insn (insn, operands[0]);"
11587 [(set_attr "type" "call")])
11589 (define_expand "call_pop"
11590 [(parallel [(call (match_operand:QI 0)
11591 (match_operand:SI 1))
11592 (set (reg:SI SP_REG)
11593 (plus:SI (reg:SI SP_REG)
11594 (match_operand:SI 3)))])]
11597 ix86_expand_call (NULL, operands[0], operands[1],
11598 operands[2], operands[3], false);
11602 (define_insn_and_split "*call_pop_vzeroupper"
11603 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11605 (set (reg:SI SP_REG)
11606 (plus:SI (reg:SI SP_REG)
11607 (match_operand:SI 2 "immediate_operand" "i")))
11608 (unspec [(match_operand 3 "const_int_operand")]
11609 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11610 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11612 "&& reload_completed"
11614 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11615 [(set_attr "type" "call")])
11617 (define_insn "*call_pop"
11618 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11620 (set (reg:SI SP_REG)
11621 (plus:SI (reg:SI SP_REG)
11622 (match_operand:SI 2 "immediate_operand" "i")))]
11623 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11624 "* return ix86_output_call_insn (insn, operands[0]);"
11625 [(set_attr "type" "call")])
11627 (define_insn_and_split "*sibcall_pop_vzeroupper"
11628 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11630 (set (reg:SI SP_REG)
11631 (plus:SI (reg:SI SP_REG)
11632 (match_operand:SI 2 "immediate_operand" "i")))
11633 (unspec [(match_operand 3 "const_int_operand")]
11634 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11635 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11637 "&& reload_completed"
11639 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11640 [(set_attr "type" "call")])
11642 (define_insn "*sibcall_pop"
11643 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11645 (set (reg:SI SP_REG)
11646 (plus:SI (reg:SI SP_REG)
11647 (match_operand:SI 2 "immediate_operand" "i")))]
11648 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11649 "* return ix86_output_call_insn (insn, operands[0]);"
11650 [(set_attr "type" "call")])
11652 ;; Call subroutine, returning value in operand 0
11654 (define_expand "call_value"
11655 [(set (match_operand 0)
11656 (call (match_operand:QI 1)
11657 (match_operand 2)))
11658 (use (match_operand 3))]
11661 ix86_expand_call (operands[0], operands[1], operands[2],
11662 operands[3], NULL, false);
11666 (define_expand "sibcall_value"
11667 [(set (match_operand 0)
11668 (call (match_operand:QI 1)
11669 (match_operand 2)))
11670 (use (match_operand 3))]
11673 ix86_expand_call (operands[0], operands[1], operands[2],
11674 operands[3], NULL, true);
11678 (define_insn_and_split "*call_value_vzeroupper"
11679 [(set (match_operand 0)
11680 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11681 (match_operand 2)))
11682 (unspec [(match_operand 3 "const_int_operand")]
11683 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11684 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11686 "&& reload_completed"
11688 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11689 [(set_attr "type" "callv")])
11691 (define_insn "*call_value"
11692 [(set (match_operand 0)
11693 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11694 (match_operand 2)))]
11695 "!SIBLING_CALL_P (insn)"
11696 "* return ix86_output_call_insn (insn, operands[1]);"
11697 [(set_attr "type" "callv")])
11699 (define_insn_and_split "*sibcall_value_vzeroupper"
11700 [(set (match_operand 0)
11701 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11702 (match_operand 2)))
11703 (unspec [(match_operand 3 "const_int_operand")]
11704 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11705 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11707 "&& reload_completed"
11709 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11710 [(set_attr "type" "callv")])
11712 (define_insn "*sibcall_value"
11713 [(set (match_operand 0)
11714 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11715 (match_operand 2)))]
11716 "SIBLING_CALL_P (insn)"
11717 "* return ix86_output_call_insn (insn, operands[1]);"
11718 [(set_attr "type" "callv")])
11720 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11721 [(set (match_operand 0)
11722 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11723 (match_operand 2)))
11724 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11725 (clobber (reg:TI XMM6_REG))
11726 (clobber (reg:TI XMM7_REG))
11727 (clobber (reg:TI XMM8_REG))
11728 (clobber (reg:TI XMM9_REG))
11729 (clobber (reg:TI XMM10_REG))
11730 (clobber (reg:TI XMM11_REG))
11731 (clobber (reg:TI XMM12_REG))
11732 (clobber (reg:TI XMM13_REG))
11733 (clobber (reg:TI XMM14_REG))
11734 (clobber (reg:TI XMM15_REG))
11735 (clobber (reg:DI SI_REG))
11736 (clobber (reg:DI DI_REG))
11737 (unspec [(match_operand 3 "const_int_operand")]
11738 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11739 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11741 "&& reload_completed"
11743 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11744 [(set_attr "type" "callv")])
11746 (define_insn "*call_value_rex64_ms_sysv"
11747 [(set (match_operand 0)
11748 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11749 (match_operand 2)))
11750 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11751 (clobber (reg:TI XMM6_REG))
11752 (clobber (reg:TI XMM7_REG))
11753 (clobber (reg:TI XMM8_REG))
11754 (clobber (reg:TI XMM9_REG))
11755 (clobber (reg:TI XMM10_REG))
11756 (clobber (reg:TI XMM11_REG))
11757 (clobber (reg:TI XMM12_REG))
11758 (clobber (reg:TI XMM13_REG))
11759 (clobber (reg:TI XMM14_REG))
11760 (clobber (reg:TI XMM15_REG))
11761 (clobber (reg:DI SI_REG))
11762 (clobber (reg:DI DI_REG))]
11763 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11764 "* return ix86_output_call_insn (insn, operands[1]);"
11765 [(set_attr "type" "callv")])
11767 (define_expand "call_value_pop"
11768 [(parallel [(set (match_operand 0)
11769 (call (match_operand:QI 1)
11770 (match_operand:SI 2)))
11771 (set (reg:SI SP_REG)
11772 (plus:SI (reg:SI SP_REG)
11773 (match_operand:SI 4)))])]
11776 ix86_expand_call (operands[0], operands[1], operands[2],
11777 operands[3], operands[4], false);
11781 (define_insn_and_split "*call_value_pop_vzeroupper"
11782 [(set (match_operand 0)
11783 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11784 (match_operand 2)))
11785 (set (reg:SI SP_REG)
11786 (plus:SI (reg:SI SP_REG)
11787 (match_operand:SI 3 "immediate_operand" "i")))
11788 (unspec [(match_operand 4 "const_int_operand")]
11789 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11790 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11792 "&& reload_completed"
11794 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11795 [(set_attr "type" "callv")])
11797 (define_insn "*call_value_pop"
11798 [(set (match_operand 0)
11799 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11800 (match_operand 2)))
11801 (set (reg:SI SP_REG)
11802 (plus:SI (reg:SI SP_REG)
11803 (match_operand:SI 3 "immediate_operand" "i")))]
11804 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11805 "* return ix86_output_call_insn (insn, operands[1]);"
11806 [(set_attr "type" "callv")])
11808 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11809 [(set (match_operand 0)
11810 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11811 (match_operand 2)))
11812 (set (reg:SI SP_REG)
11813 (plus:SI (reg:SI SP_REG)
11814 (match_operand:SI 3 "immediate_operand" "i")))
11815 (unspec [(match_operand 4 "const_int_operand")]
11816 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11817 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11819 "&& reload_completed"
11821 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11822 [(set_attr "type" "callv")])
11824 (define_insn "*sibcall_value_pop"
11825 [(set (match_operand 0)
11826 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11827 (match_operand 2)))
11828 (set (reg:SI SP_REG)
11829 (plus:SI (reg:SI SP_REG)
11830 (match_operand:SI 3 "immediate_operand" "i")))]
11831 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11832 "* return ix86_output_call_insn (insn, operands[1]);"
11833 [(set_attr "type" "callv")])
11835 ;; Call subroutine returning any type.
11837 (define_expand "untyped_call"
11838 [(parallel [(call (match_operand 0)
11841 (match_operand 2)])]
11846 /* In order to give reg-stack an easier job in validating two
11847 coprocessor registers as containing a possible return value,
11848 simply pretend the untyped call returns a complex long double
11851 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11852 and should have the default ABI. */
11854 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11855 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11856 operands[0], const0_rtx,
11857 GEN_INT ((TARGET_64BIT
11858 ? (ix86_abi == SYSV_ABI
11859 ? X86_64_SSE_REGPARM_MAX
11860 : X86_64_MS_SSE_REGPARM_MAX)
11861 : X86_32_SSE_REGPARM_MAX)
11865 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11867 rtx set = XVECEXP (operands[2], 0, i);
11868 emit_move_insn (SET_DEST (set), SET_SRC (set));
11871 /* The optimizer does not know that the call sets the function value
11872 registers we stored in the result block. We avoid problems by
11873 claiming that all hard registers are used and clobbered at this
11875 emit_insn (gen_blockage ());
11880 ;; Prologue and epilogue instructions
11882 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11883 ;; all of memory. This blocks insns from being moved across this point.
11885 (define_insn "blockage"
11886 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11889 [(set_attr "length" "0")])
11891 ;; Do not schedule instructions accessing memory across this point.
11893 (define_expand "memory_blockage"
11894 [(set (match_dup 0)
11895 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11898 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11899 MEM_VOLATILE_P (operands[0]) = 1;
11902 (define_insn "*memory_blockage"
11903 [(set (match_operand:BLK 0)
11904 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11907 [(set_attr "length" "0")])
11909 ;; As USE insns aren't meaningful after reload, this is used instead
11910 ;; to prevent deleting instructions setting registers for PIC code
11911 (define_insn "prologue_use"
11912 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11915 [(set_attr "length" "0")])
11917 ;; Insn emitted into the body of a function to return from a function.
11918 ;; This is only done if the function's epilogue is known to be simple.
11919 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11921 (define_expand "return"
11923 "ix86_can_use_return_insn_p ()"
11925 ix86_maybe_emit_epilogue_vzeroupper ();
11926 if (crtl->args.pops_args)
11928 rtx popc = GEN_INT (crtl->args.pops_args);
11929 emit_jump_insn (gen_simple_return_pop_internal (popc));
11934 ;; We need to disable this for TARGET_SEH, as otherwise
11935 ;; shrink-wrapped prologue gets enabled too. This might exceed
11936 ;; the maximum size of prologue in unwind information.
11938 (define_expand "simple_return"
11942 ix86_maybe_emit_epilogue_vzeroupper ();
11943 if (crtl->args.pops_args)
11945 rtx popc = GEN_INT (crtl->args.pops_args);
11946 emit_jump_insn (gen_simple_return_pop_internal (popc));
11951 (define_insn "simple_return_internal"
11955 [(set_attr "length" "1")
11956 (set_attr "atom_unit" "jeu")
11957 (set_attr "length_immediate" "0")
11958 (set_attr "modrm" "0")])
11960 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11961 ;; instruction Athlon and K8 have.
11963 (define_insn "simple_return_internal_long"
11965 (unspec [(const_int 0)] UNSPEC_REP)]
11968 [(set_attr "length" "2")
11969 (set_attr "atom_unit" "jeu")
11970 (set_attr "length_immediate" "0")
11971 (set_attr "prefix_rep" "1")
11972 (set_attr "modrm" "0")])
11974 (define_insn "simple_return_pop_internal"
11976 (use (match_operand:SI 0 "const_int_operand"))]
11979 [(set_attr "length" "3")
11980 (set_attr "atom_unit" "jeu")
11981 (set_attr "length_immediate" "2")
11982 (set_attr "modrm" "0")])
11984 (define_insn "simple_return_indirect_internal"
11986 (use (match_operand:SI 0 "register_operand" "r"))]
11989 [(set_attr "type" "ibr")
11990 (set_attr "length_immediate" "0")])
11996 [(set_attr "length" "1")
11997 (set_attr "length_immediate" "0")
11998 (set_attr "modrm" "0")])
12000 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12001 (define_insn "nops"
12002 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12006 int num = INTVAL (operands[0]);
12008 gcc_assert (IN_RANGE (num, 1, 8));
12011 fputs ("\tnop\n", asm_out_file);
12015 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12016 (set_attr "length_immediate" "0")
12017 (set_attr "modrm" "0")])
12019 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12020 ;; branch prediction penalty for the third jump in a 16-byte
12024 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12027 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12028 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12030 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12031 The align insn is used to avoid 3 jump instructions in the row to improve
12032 branch prediction and the benefits hardly outweigh the cost of extra 8
12033 nops on the average inserted by full alignment pseudo operation. */
12037 [(set_attr "length" "16")])
12039 (define_expand "prologue"
12042 "ix86_expand_prologue (); DONE;")
12044 (define_insn "set_got"
12045 [(set (match_operand:SI 0 "register_operand" "=r")
12046 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12047 (clobber (reg:CC FLAGS_REG))]
12049 "* return output_set_got (operands[0], NULL_RTX);"
12050 [(set_attr "type" "multi")
12051 (set_attr "length" "12")])
12053 (define_insn "set_got_labelled"
12054 [(set (match_operand:SI 0 "register_operand" "=r")
12055 (unspec:SI [(label_ref (match_operand 1))]
12057 (clobber (reg:CC FLAGS_REG))]
12059 "* return output_set_got (operands[0], operands[1]);"
12060 [(set_attr "type" "multi")
12061 (set_attr "length" "12")])
12063 (define_insn "set_got_rex64"
12064 [(set (match_operand:DI 0 "register_operand" "=r")
12065 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12067 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12068 [(set_attr "type" "lea")
12069 (set_attr "length_address" "4")
12070 (set_attr "mode" "DI")])
12072 (define_insn "set_rip_rex64"
12073 [(set (match_operand:DI 0 "register_operand" "=r")
12074 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12076 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12077 [(set_attr "type" "lea")
12078 (set_attr "length_address" "4")
12079 (set_attr "mode" "DI")])
12081 (define_insn "set_got_offset_rex64"
12082 [(set (match_operand:DI 0 "register_operand" "=r")
12084 [(label_ref (match_operand 1))]
12085 UNSPEC_SET_GOT_OFFSET))]
12087 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12088 [(set_attr "type" "imov")
12089 (set_attr "length_immediate" "0")
12090 (set_attr "length_address" "8")
12091 (set_attr "mode" "DI")])
12093 (define_expand "epilogue"
12096 "ix86_expand_epilogue (1); DONE;")
12098 (define_expand "sibcall_epilogue"
12101 "ix86_expand_epilogue (0); DONE;")
12103 (define_expand "eh_return"
12104 [(use (match_operand 0 "register_operand"))]
12107 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12109 /* Tricky bit: we write the address of the handler to which we will
12110 be returning into someone else's stack frame, one word below the
12111 stack address we wish to restore. */
12112 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12113 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12114 tmp = gen_rtx_MEM (Pmode, tmp);
12115 emit_move_insn (tmp, ra);
12117 emit_jump_insn (gen_eh_return_internal ());
12122 (define_insn_and_split "eh_return_internal"
12126 "epilogue_completed"
12128 "ix86_expand_epilogue (2); DONE;")
12130 (define_insn "leave"
12131 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12132 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12133 (clobber (mem:BLK (scratch)))]
12136 [(set_attr "type" "leave")])
12138 (define_insn "leave_rex64"
12139 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12140 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12141 (clobber (mem:BLK (scratch)))]
12144 [(set_attr "type" "leave")])
12146 ;; Handle -fsplit-stack.
12148 (define_expand "split_stack_prologue"
12152 ix86_expand_split_stack_prologue ();
12156 ;; In order to support the call/return predictor, we use a return
12157 ;; instruction which the middle-end doesn't see.
12158 (define_insn "split_stack_return"
12159 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12160 UNSPECV_SPLIT_STACK_RETURN)]
12163 if (operands[0] == const0_rtx)
12168 [(set_attr "atom_unit" "jeu")
12169 (set_attr "modrm" "0")
12170 (set (attr "length")
12171 (if_then_else (match_operand:SI 0 "const0_operand")
12174 (set (attr "length_immediate")
12175 (if_then_else (match_operand:SI 0 "const0_operand")
12179 ;; If there are operand 0 bytes available on the stack, jump to
12182 (define_expand "split_stack_space_check"
12183 [(set (pc) (if_then_else
12184 (ltu (minus (reg SP_REG)
12185 (match_operand 0 "register_operand"))
12186 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12187 (label_ref (match_operand 1))
12191 rtx reg, size, limit;
12193 reg = gen_reg_rtx (Pmode);
12194 size = force_reg (Pmode, operands[0]);
12195 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12196 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12197 UNSPEC_STACK_CHECK);
12198 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12199 ix86_expand_branch (GEU, reg, limit, operands[1]);
12204 ;; Bit manipulation instructions.
12206 (define_expand "ffs<mode>2"
12207 [(set (match_dup 2) (const_int -1))
12208 (parallel [(set (match_dup 3) (match_dup 4))
12209 (set (match_operand:SWI48 0 "register_operand")
12211 (match_operand:SWI48 1 "nonimmediate_operand")))])
12212 (set (match_dup 0) (if_then_else:SWI48
12213 (eq (match_dup 3) (const_int 0))
12216 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12217 (clobber (reg:CC FLAGS_REG))])]
12220 enum machine_mode flags_mode;
12222 if (<MODE>mode == SImode && !TARGET_CMOVE)
12224 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12228 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12230 operands[2] = gen_reg_rtx (<MODE>mode);
12231 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12232 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12235 (define_insn_and_split "ffssi2_no_cmove"
12236 [(set (match_operand:SI 0 "register_operand" "=r")
12237 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12238 (clobber (match_scratch:SI 2 "=&q"))
12239 (clobber (reg:CC FLAGS_REG))]
12242 "&& reload_completed"
12243 [(parallel [(set (match_dup 4) (match_dup 5))
12244 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12245 (set (strict_low_part (match_dup 3))
12246 (eq:QI (match_dup 4) (const_int 0)))
12247 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12248 (clobber (reg:CC FLAGS_REG))])
12249 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12250 (clobber (reg:CC FLAGS_REG))])
12251 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12252 (clobber (reg:CC FLAGS_REG))])]
12254 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12256 operands[3] = gen_lowpart (QImode, operands[2]);
12257 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12258 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12260 ix86_expand_clear (operands[2]);
12263 (define_insn "*tzcnt<mode>_1"
12264 [(set (reg:CCC FLAGS_REG)
12265 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12267 (set (match_operand:SWI48 0 "register_operand" "=r")
12268 (ctz:SWI48 (match_dup 1)))]
12270 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12271 [(set_attr "type" "alu1")
12272 (set_attr "prefix_0f" "1")
12273 (set_attr "prefix_rep" "1")
12274 (set_attr "mode" "<MODE>")])
12276 (define_insn "*bsf<mode>_1"
12277 [(set (reg:CCZ FLAGS_REG)
12278 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12280 (set (match_operand:SWI48 0 "register_operand" "=r")
12281 (ctz:SWI48 (match_dup 1)))]
12283 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12284 [(set_attr "type" "alu1")
12285 (set_attr "prefix_0f" "1")
12286 (set_attr "mode" "<MODE>")])
12288 (define_insn "ctz<mode>2"
12289 [(set (match_operand:SWI248 0 "register_operand" "=r")
12290 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12291 (clobber (reg:CC FLAGS_REG))]
12295 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12296 else if (optimize_function_for_size_p (cfun))
12298 else if (TARGET_GENERIC)
12299 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12300 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12302 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12304 [(set_attr "type" "alu1")
12305 (set_attr "prefix_0f" "1")
12306 (set (attr "prefix_rep")
12308 (ior (match_test "TARGET_BMI")
12309 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12310 (match_test "TARGET_GENERIC")))
12312 (const_string "0")))
12313 (set_attr "mode" "<MODE>")])
12315 (define_expand "clz<mode>2"
12317 [(set (match_operand:SWI248 0 "register_operand")
12320 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12321 (clobber (reg:CC FLAGS_REG))])
12323 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12324 (clobber (reg:CC FLAGS_REG))])]
12329 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12332 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12335 (define_insn "clz<mode>2_lzcnt"
12336 [(set (match_operand:SWI248 0 "register_operand" "=r")
12337 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12338 (clobber (reg:CC FLAGS_REG))]
12340 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12341 [(set_attr "prefix_rep" "1")
12342 (set_attr "type" "bitmanip")
12343 (set_attr "mode" "<MODE>")])
12345 ;; BMI instructions.
12346 (define_insn "*bmi_andn_<mode>"
12347 [(set (match_operand:SWI48 0 "register_operand" "=r")
12350 (match_operand:SWI48 1 "register_operand" "r"))
12351 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12352 (clobber (reg:CC FLAGS_REG))]
12354 "andn\t{%2, %1, %0|%0, %1, %2}"
12355 [(set_attr "type" "bitmanip")
12356 (set_attr "mode" "<MODE>")])
12358 (define_insn "bmi_bextr_<mode>"
12359 [(set (match_operand:SWI48 0 "register_operand" "=r")
12360 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12361 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12363 (clobber (reg:CC FLAGS_REG))]
12365 "bextr\t{%2, %1, %0|%0, %1, %2}"
12366 [(set_attr "type" "bitmanip")
12367 (set_attr "mode" "<MODE>")])
12369 (define_insn "*bmi_blsi_<mode>"
12370 [(set (match_operand:SWI48 0 "register_operand" "=r")
12373 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12375 (clobber (reg:CC FLAGS_REG))]
12377 "blsi\t{%1, %0|%0, %1}"
12378 [(set_attr "type" "bitmanip")
12379 (set_attr "mode" "<MODE>")])
12381 (define_insn "*bmi_blsmsk_<mode>"
12382 [(set (match_operand:SWI48 0 "register_operand" "=r")
12385 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12388 (clobber (reg:CC FLAGS_REG))]
12390 "blsmsk\t{%1, %0|%0, %1}"
12391 [(set_attr "type" "bitmanip")
12392 (set_attr "mode" "<MODE>")])
12394 (define_insn "*bmi_blsr_<mode>"
12395 [(set (match_operand:SWI48 0 "register_operand" "=r")
12398 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12401 (clobber (reg:CC FLAGS_REG))]
12403 "blsr\t{%1, %0|%0, %1}"
12404 [(set_attr "type" "bitmanip")
12405 (set_attr "mode" "<MODE>")])
12407 ;; BMI2 instructions.
12408 (define_insn "bmi2_bzhi_<mode>3"
12409 [(set (match_operand:SWI48 0 "register_operand" "=r")
12410 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12411 (lshiftrt:SWI48 (const_int -1)
12412 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12413 (clobber (reg:CC FLAGS_REG))]
12415 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12416 [(set_attr "type" "bitmanip")
12417 (set_attr "prefix" "vex")
12418 (set_attr "mode" "<MODE>")])
12420 (define_insn "bmi2_pdep_<mode>3"
12421 [(set (match_operand:SWI48 0 "register_operand" "=r")
12422 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12423 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12426 "pdep\t{%2, %1, %0|%0, %1, %2}"
12427 [(set_attr "type" "bitmanip")
12428 (set_attr "prefix" "vex")
12429 (set_attr "mode" "<MODE>")])
12431 (define_insn "bmi2_pext_<mode>3"
12432 [(set (match_operand:SWI48 0 "register_operand" "=r")
12433 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12434 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12437 "pext\t{%2, %1, %0|%0, %1, %2}"
12438 [(set_attr "type" "bitmanip")
12439 (set_attr "prefix" "vex")
12440 (set_attr "mode" "<MODE>")])
12442 ;; TBM instructions.
12443 (define_insn "tbm_bextri_<mode>"
12444 [(set (match_operand:SWI48 0 "register_operand" "=r")
12445 (zero_extract:SWI48
12446 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12447 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12448 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12449 (clobber (reg:CC FLAGS_REG))]
12452 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12453 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12455 [(set_attr "type" "bitmanip")
12456 (set_attr "mode" "<MODE>")])
12458 (define_insn "*tbm_blcfill_<mode>"
12459 [(set (match_operand:SWI48 0 "register_operand" "=r")
12462 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12465 (clobber (reg:CC FLAGS_REG))]
12467 "blcfill\t{%1, %0|%0, %1}"
12468 [(set_attr "type" "bitmanip")
12469 (set_attr "mode" "<MODE>")])
12471 (define_insn "*tbm_blci_<mode>"
12472 [(set (match_operand:SWI48 0 "register_operand" "=r")
12476 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12479 (clobber (reg:CC FLAGS_REG))]
12481 "blci\t{%1, %0|%0, %1}"
12482 [(set_attr "type" "bitmanip")
12483 (set_attr "mode" "<MODE>")])
12485 (define_insn "*tbm_blcic_<mode>"
12486 [(set (match_operand:SWI48 0 "register_operand" "=r")
12489 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12493 (clobber (reg:CC FLAGS_REG))]
12495 "blcic\t{%1, %0|%0, %1}"
12496 [(set_attr "type" "bitmanip")
12497 (set_attr "mode" "<MODE>")])
12499 (define_insn "*tbm_blcmsk_<mode>"
12500 [(set (match_operand:SWI48 0 "register_operand" "=r")
12503 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12506 (clobber (reg:CC FLAGS_REG))]
12508 "blcmsk\t{%1, %0|%0, %1}"
12509 [(set_attr "type" "bitmanip")
12510 (set_attr "mode" "<MODE>")])
12512 (define_insn "*tbm_blcs_<mode>"
12513 [(set (match_operand:SWI48 0 "register_operand" "=r")
12516 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12519 (clobber (reg:CC FLAGS_REG))]
12521 "blcs\t{%1, %0|%0, %1}"
12522 [(set_attr "type" "bitmanip")
12523 (set_attr "mode" "<MODE>")])
12525 (define_insn "*tbm_blsfill_<mode>"
12526 [(set (match_operand:SWI48 0 "register_operand" "=r")
12529 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12532 (clobber (reg:CC FLAGS_REG))]
12534 "blsfill\t{%1, %0|%0, %1}"
12535 [(set_attr "type" "bitmanip")
12536 (set_attr "mode" "<MODE>")])
12538 (define_insn "*tbm_blsic_<mode>"
12539 [(set (match_operand:SWI48 0 "register_operand" "=r")
12542 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12546 (clobber (reg:CC FLAGS_REG))]
12548 "blsic\t{%1, %0|%0, %1}"
12549 [(set_attr "type" "bitmanip")
12550 (set_attr "mode" "<MODE>")])
12552 (define_insn "*tbm_t1mskc_<mode>"
12553 [(set (match_operand:SWI48 0 "register_operand" "=r")
12556 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12560 (clobber (reg:CC FLAGS_REG))]
12562 "t1mskc\t{%1, %0|%0, %1}"
12563 [(set_attr "type" "bitmanip")
12564 (set_attr "mode" "<MODE>")])
12566 (define_insn "*tbm_tzmsk_<mode>"
12567 [(set (match_operand:SWI48 0 "register_operand" "=r")
12570 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12574 (clobber (reg:CC FLAGS_REG))]
12576 "tzmsk\t{%1, %0|%0, %1}"
12577 [(set_attr "type" "bitmanip")
12578 (set_attr "mode" "<MODE>")])
12580 (define_insn "bsr_rex64"
12581 [(set (match_operand:DI 0 "register_operand" "=r")
12582 (minus:DI (const_int 63)
12583 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12584 (clobber (reg:CC FLAGS_REG))]
12586 "bsr{q}\t{%1, %0|%0, %1}"
12587 [(set_attr "type" "alu1")
12588 (set_attr "prefix_0f" "1")
12589 (set_attr "mode" "DI")])
12592 [(set (match_operand:SI 0 "register_operand" "=r")
12593 (minus:SI (const_int 31)
12594 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12595 (clobber (reg:CC FLAGS_REG))]
12597 "bsr{l}\t{%1, %0|%0, %1}"
12598 [(set_attr "type" "alu1")
12599 (set_attr "prefix_0f" "1")
12600 (set_attr "mode" "SI")])
12602 (define_insn "*bsrhi"
12603 [(set (match_operand:HI 0 "register_operand" "=r")
12604 (minus:HI (const_int 15)
12605 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12606 (clobber (reg:CC FLAGS_REG))]
12608 "bsr{w}\t{%1, %0|%0, %1}"
12609 [(set_attr "type" "alu1")
12610 (set_attr "prefix_0f" "1")
12611 (set_attr "mode" "HI")])
12613 (define_insn "popcount<mode>2"
12614 [(set (match_operand:SWI248 0 "register_operand" "=r")
12616 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12617 (clobber (reg:CC FLAGS_REG))]
12621 return "popcnt\t{%1, %0|%0, %1}";
12623 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12626 [(set_attr "prefix_rep" "1")
12627 (set_attr "type" "bitmanip")
12628 (set_attr "mode" "<MODE>")])
12630 (define_insn "*popcount<mode>2_cmp"
12631 [(set (reg FLAGS_REG)
12634 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12636 (set (match_operand:SWI248 0 "register_operand" "=r")
12637 (popcount:SWI248 (match_dup 1)))]
12638 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12641 return "popcnt\t{%1, %0|%0, %1}";
12643 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12646 [(set_attr "prefix_rep" "1")
12647 (set_attr "type" "bitmanip")
12648 (set_attr "mode" "<MODE>")])
12650 (define_insn "*popcountsi2_cmp_zext"
12651 [(set (reg FLAGS_REG)
12653 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12655 (set (match_operand:DI 0 "register_operand" "=r")
12656 (zero_extend:DI(popcount:SI (match_dup 1))))]
12657 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12660 return "popcnt\t{%1, %0|%0, %1}";
12662 return "popcnt{l}\t{%1, %0|%0, %1}";
12665 [(set_attr "prefix_rep" "1")
12666 (set_attr "type" "bitmanip")
12667 (set_attr "mode" "SI")])
12669 (define_expand "bswapdi2"
12670 [(set (match_operand:DI 0 "register_operand")
12671 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12674 if (TARGET_64BIT && !TARGET_MOVBE)
12675 operands[1] = force_reg (DImode, operands[1]);
12678 (define_insn_and_split "*bswapdi2_doubleword"
12679 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12681 (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12683 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12685 "&& reload_completed"
12686 [(set (match_dup 2)
12687 (bswap:SI (match_dup 1)))
12689 (bswap:SI (match_dup 3)))]
12691 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
12693 if (REG_P (operands[0]) && REG_P (operands[1]))
12695 emit_insn (gen_swapsi (operands[0], operands[2]));
12696 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12697 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12703 if (MEM_P (operands[0]))
12705 emit_insn (gen_bswapsi2 (operands[3], operands[3]));
12706 emit_insn (gen_bswapsi2 (operands[1], operands[1]));
12708 emit_move_insn (operands[0], operands[3]);
12709 emit_move_insn (operands[2], operands[1]);
12711 if (MEM_P (operands[1]))
12713 emit_move_insn (operands[2], operands[1]);
12714 emit_move_insn (operands[0], operands[3]);
12716 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12717 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12723 (define_expand "bswapsi2"
12724 [(set (match_operand:SI 0 "register_operand")
12725 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12730 else if (TARGET_BSWAP)
12731 operands[1] = force_reg (SImode, operands[1]);
12734 rtx x = operands[0];
12736 emit_move_insn (x, operands[1]);
12737 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12738 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12739 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12744 (define_insn "*bswap<mode>2_movbe"
12745 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12746 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12748 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12751 movbe\t{%1, %0|%0, %1}
12752 movbe\t{%1, %0|%0, %1}"
12753 [(set_attr "type" "bitmanip,imov,imov")
12754 (set_attr "modrm" "0,1,1")
12755 (set_attr "prefix_0f" "*,1,1")
12756 (set_attr "prefix_extra" "*,1,1")
12757 (set_attr "mode" "<MODE>")])
12759 (define_insn "*bswap<mode>2"
12760 [(set (match_operand:SWI48 0 "register_operand" "=r")
12761 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12764 [(set_attr "type" "bitmanip")
12765 (set_attr "modrm" "0")
12766 (set_attr "mode" "<MODE>")])
12768 (define_insn "*bswaphi_lowpart_1"
12769 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12770 (bswap:HI (match_dup 0)))
12771 (clobber (reg:CC FLAGS_REG))]
12772 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12774 xchg{b}\t{%h0, %b0|%b0, %h0}
12775 rol{w}\t{$8, %0|%0, 8}"
12776 [(set_attr "length" "2,4")
12777 (set_attr "mode" "QI,HI")])
12779 (define_insn "bswaphi_lowpart"
12780 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12781 (bswap:HI (match_dup 0)))
12782 (clobber (reg:CC FLAGS_REG))]
12784 "rol{w}\t{$8, %0|%0, 8}"
12785 [(set_attr "length" "4")
12786 (set_attr "mode" "HI")])
12788 (define_expand "paritydi2"
12789 [(set (match_operand:DI 0 "register_operand")
12790 (parity:DI (match_operand:DI 1 "register_operand")))]
12793 rtx scratch = gen_reg_rtx (QImode);
12796 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12797 NULL_RTX, operands[1]));
12799 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12800 gen_rtx_REG (CCmode, FLAGS_REG),
12802 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12805 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12808 rtx tmp = gen_reg_rtx (SImode);
12810 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12811 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12816 (define_expand "paritysi2"
12817 [(set (match_operand:SI 0 "register_operand")
12818 (parity:SI (match_operand:SI 1 "register_operand")))]
12821 rtx scratch = gen_reg_rtx (QImode);
12824 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12826 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12827 gen_rtx_REG (CCmode, FLAGS_REG),
12829 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12831 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12835 (define_insn_and_split "paritydi2_cmp"
12836 [(set (reg:CC FLAGS_REG)
12837 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12839 (clobber (match_scratch:DI 0 "=r"))
12840 (clobber (match_scratch:SI 1 "=&r"))
12841 (clobber (match_scratch:HI 2 "=Q"))]
12844 "&& reload_completed"
12846 [(set (match_dup 1)
12847 (xor:SI (match_dup 1) (match_dup 4)))
12848 (clobber (reg:CC FLAGS_REG))])
12850 [(set (reg:CC FLAGS_REG)
12851 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12852 (clobber (match_dup 1))
12853 (clobber (match_dup 2))])]
12855 operands[4] = gen_lowpart (SImode, operands[3]);
12859 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12860 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12863 operands[1] = gen_highpart (SImode, operands[3]);
12866 (define_insn_and_split "paritysi2_cmp"
12867 [(set (reg:CC FLAGS_REG)
12868 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12870 (clobber (match_scratch:SI 0 "=r"))
12871 (clobber (match_scratch:HI 1 "=&Q"))]
12874 "&& reload_completed"
12876 [(set (match_dup 1)
12877 (xor:HI (match_dup 1) (match_dup 3)))
12878 (clobber (reg:CC FLAGS_REG))])
12880 [(set (reg:CC FLAGS_REG)
12881 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12882 (clobber (match_dup 1))])]
12884 operands[3] = gen_lowpart (HImode, operands[2]);
12886 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12887 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12890 (define_insn "*parityhi2_cmp"
12891 [(set (reg:CC FLAGS_REG)
12892 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12894 (clobber (match_scratch:HI 0 "=Q"))]
12896 "xor{b}\t{%h0, %b0|%b0, %h0}"
12897 [(set_attr "length" "2")
12898 (set_attr "mode" "HI")])
12901 ;; Thread-local storage patterns for ELF.
12903 ;; Note that these code sequences must appear exactly as shown
12904 ;; in order to allow linker relaxation.
12906 (define_insn "*tls_global_dynamic_32_gnu"
12907 [(set (match_operand:SI 0 "register_operand" "=a")
12909 [(match_operand:SI 1 "register_operand" "b")
12910 (match_operand 2 "tls_symbolic_operand")
12911 (match_operand 3 "constant_call_address_operand" "z")]
12913 (clobber (match_scratch:SI 4 "=d"))
12914 (clobber (match_scratch:SI 5 "=c"))
12915 (clobber (reg:CC FLAGS_REG))]
12916 "!TARGET_64BIT && TARGET_GNU_TLS"
12919 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12920 if (TARGET_SUN_TLS)
12921 #ifdef HAVE_AS_IX86_TLSGDPLT
12922 return "call\t%a2@tlsgdplt";
12924 return "call\t%p3@plt";
12926 return "call\t%P3";
12928 [(set_attr "type" "multi")
12929 (set_attr "length" "12")])
12931 (define_expand "tls_global_dynamic_32"
12933 [(set (match_operand:SI 0 "register_operand")
12934 (unspec:SI [(match_operand:SI 2 "register_operand")
12935 (match_operand 1 "tls_symbolic_operand")
12936 (match_operand 3 "constant_call_address_operand")]
12938 (clobber (match_scratch:SI 4))
12939 (clobber (match_scratch:SI 5))
12940 (clobber (reg:CC FLAGS_REG))])])
12942 (define_insn "*tls_global_dynamic_64_<mode>"
12943 [(set (match_operand:P 0 "register_operand" "=a")
12945 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12946 (match_operand 3)))
12947 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12952 fputs (ASM_BYTE "0x66\n", asm_out_file);
12954 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12955 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12956 fputs ("\trex64\n", asm_out_file);
12957 if (TARGET_SUN_TLS)
12958 return "call\t%p2@plt";
12959 return "call\t%P2";
12961 [(set_attr "type" "multi")
12962 (set (attr "length")
12963 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12965 (define_expand "tls_global_dynamic_64_<mode>"
12967 [(set (match_operand:P 0 "register_operand")
12969 (mem:QI (match_operand 2 "constant_call_address_operand"))
12971 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12975 (define_insn "*tls_local_dynamic_base_32_gnu"
12976 [(set (match_operand:SI 0 "register_operand" "=a")
12978 [(match_operand:SI 1 "register_operand" "b")
12979 (match_operand 2 "constant_call_address_operand" "z")]
12980 UNSPEC_TLS_LD_BASE))
12981 (clobber (match_scratch:SI 3 "=d"))
12982 (clobber (match_scratch:SI 4 "=c"))
12983 (clobber (reg:CC FLAGS_REG))]
12984 "!TARGET_64BIT && TARGET_GNU_TLS"
12987 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12988 if (TARGET_SUN_TLS)
12989 #ifdef HAVE_AS_IX86_TLSLDMPLT
12990 return "call\t%&@tlsldmplt";
12992 return "call\t%p2@plt";
12994 return "call\t%P2";
12996 [(set_attr "type" "multi")
12997 (set_attr "length" "11")])
12999 (define_expand "tls_local_dynamic_base_32"
13001 [(set (match_operand:SI 0 "register_operand")
13003 [(match_operand:SI 1 "register_operand")
13004 (match_operand 2 "constant_call_address_operand")]
13005 UNSPEC_TLS_LD_BASE))
13006 (clobber (match_scratch:SI 3))
13007 (clobber (match_scratch:SI 4))
13008 (clobber (reg:CC FLAGS_REG))])])
13010 (define_insn "*tls_local_dynamic_base_64_<mode>"
13011 [(set (match_operand:P 0 "register_operand" "=a")
13013 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
13014 (match_operand 2)))
13015 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13019 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13020 if (TARGET_SUN_TLS)
13021 return "call\t%p1@plt";
13022 return "call\t%P1";
13024 [(set_attr "type" "multi")
13025 (set_attr "length" "12")])
13027 (define_expand "tls_local_dynamic_base_64_<mode>"
13029 [(set (match_operand:P 0 "register_operand")
13031 (mem:QI (match_operand 1 "constant_call_address_operand"))
13033 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13036 ;; Local dynamic of a single variable is a lose. Show combine how
13037 ;; to convert that back to global dynamic.
13039 (define_insn_and_split "*tls_local_dynamic_32_once"
13040 [(set (match_operand:SI 0 "register_operand" "=a")
13042 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13043 (match_operand 2 "constant_call_address_operand" "z")]
13044 UNSPEC_TLS_LD_BASE)
13045 (const:SI (unspec:SI
13046 [(match_operand 3 "tls_symbolic_operand")]
13048 (clobber (match_scratch:SI 4 "=d"))
13049 (clobber (match_scratch:SI 5 "=c"))
13050 (clobber (reg:CC FLAGS_REG))]
13055 [(set (match_dup 0)
13056 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13058 (clobber (match_dup 4))
13059 (clobber (match_dup 5))
13060 (clobber (reg:CC FLAGS_REG))])])
13062 ;; Segment register for the thread base ptr load
13063 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13065 ;; Load and add the thread base pointer from %<tp_seg>:0.
13066 (define_insn "*load_tp_x32"
13067 [(set (match_operand:SI 0 "register_operand" "=r")
13068 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13070 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13071 [(set_attr "type" "imov")
13072 (set_attr "modrm" "0")
13073 (set_attr "length" "7")
13074 (set_attr "memory" "load")
13075 (set_attr "imm_disp" "false")])
13077 (define_insn "*load_tp_x32_zext"
13078 [(set (match_operand:DI 0 "register_operand" "=r")
13079 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13081 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13082 [(set_attr "type" "imov")
13083 (set_attr "modrm" "0")
13084 (set_attr "length" "7")
13085 (set_attr "memory" "load")
13086 (set_attr "imm_disp" "false")])
13088 (define_insn "*load_tp_<mode>"
13089 [(set (match_operand:P 0 "register_operand" "=r")
13090 (unspec:P [(const_int 0)] UNSPEC_TP))]
13092 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13093 [(set_attr "type" "imov")
13094 (set_attr "modrm" "0")
13095 (set_attr "length" "7")
13096 (set_attr "memory" "load")
13097 (set_attr "imm_disp" "false")])
13099 (define_insn "*add_tp_x32"
13100 [(set (match_operand:SI 0 "register_operand" "=r")
13101 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13102 (match_operand:SI 1 "register_operand" "0")))
13103 (clobber (reg:CC FLAGS_REG))]
13105 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13106 [(set_attr "type" "alu")
13107 (set_attr "modrm" "0")
13108 (set_attr "length" "7")
13109 (set_attr "memory" "load")
13110 (set_attr "imm_disp" "false")])
13112 (define_insn "*add_tp_x32_zext"
13113 [(set (match_operand:DI 0 "register_operand" "=r")
13115 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13116 (match_operand:SI 1 "register_operand" "0"))))
13117 (clobber (reg:CC FLAGS_REG))]
13119 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13120 [(set_attr "type" "alu")
13121 (set_attr "modrm" "0")
13122 (set_attr "length" "7")
13123 (set_attr "memory" "load")
13124 (set_attr "imm_disp" "false")])
13126 (define_insn "*add_tp_<mode>"
13127 [(set (match_operand:P 0 "register_operand" "=r")
13128 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13129 (match_operand:P 1 "register_operand" "0")))
13130 (clobber (reg:CC FLAGS_REG))]
13132 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13133 [(set_attr "type" "alu")
13134 (set_attr "modrm" "0")
13135 (set_attr "length" "7")
13136 (set_attr "memory" "load")
13137 (set_attr "imm_disp" "false")])
13139 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13140 ;; %rax as destination of the initial executable code sequence.
13141 (define_insn "tls_initial_exec_64_sun"
13142 [(set (match_operand:DI 0 "register_operand" "=a")
13144 [(match_operand 1 "tls_symbolic_operand")]
13145 UNSPEC_TLS_IE_SUN))
13146 (clobber (reg:CC FLAGS_REG))]
13147 "TARGET_64BIT && TARGET_SUN_TLS"
13150 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13151 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13153 [(set_attr "type" "multi")])
13155 ;; GNU2 TLS patterns can be split.
13157 (define_expand "tls_dynamic_gnu2_32"
13158 [(set (match_dup 3)
13159 (plus:SI (match_operand:SI 2 "register_operand")
13161 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13164 [(set (match_operand:SI 0 "register_operand")
13165 (unspec:SI [(match_dup 1) (match_dup 3)
13166 (match_dup 2) (reg:SI SP_REG)]
13168 (clobber (reg:CC FLAGS_REG))])]
13169 "!TARGET_64BIT && TARGET_GNU2_TLS"
13171 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13172 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13175 (define_insn "*tls_dynamic_gnu2_lea_32"
13176 [(set (match_operand:SI 0 "register_operand" "=r")
13177 (plus:SI (match_operand:SI 1 "register_operand" "b")
13179 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13180 UNSPEC_TLSDESC))))]
13181 "!TARGET_64BIT && TARGET_GNU2_TLS"
13182 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13183 [(set_attr "type" "lea")
13184 (set_attr "mode" "SI")
13185 (set_attr "length" "6")
13186 (set_attr "length_address" "4")])
13188 (define_insn "*tls_dynamic_gnu2_call_32"
13189 [(set (match_operand:SI 0 "register_operand" "=a")
13190 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13191 (match_operand:SI 2 "register_operand" "0")
13192 ;; we have to make sure %ebx still points to the GOT
13193 (match_operand:SI 3 "register_operand" "b")
13196 (clobber (reg:CC FLAGS_REG))]
13197 "!TARGET_64BIT && TARGET_GNU2_TLS"
13198 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13199 [(set_attr "type" "call")
13200 (set_attr "length" "2")
13201 (set_attr "length_address" "0")])
13203 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13204 [(set (match_operand:SI 0 "register_operand" "=&a")
13206 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13207 (match_operand:SI 4)
13208 (match_operand:SI 2 "register_operand" "b")
13211 (const:SI (unspec:SI
13212 [(match_operand 1 "tls_symbolic_operand")]
13214 (clobber (reg:CC FLAGS_REG))]
13215 "!TARGET_64BIT && TARGET_GNU2_TLS"
13218 [(set (match_dup 0) (match_dup 5))]
13220 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13221 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13224 (define_expand "tls_dynamic_gnu2_64"
13225 [(set (match_dup 2)
13226 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13229 [(set (match_operand:DI 0 "register_operand")
13230 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13232 (clobber (reg:CC FLAGS_REG))])]
13233 "TARGET_64BIT && TARGET_GNU2_TLS"
13235 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13236 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13239 (define_insn "*tls_dynamic_gnu2_lea_64"
13240 [(set (match_operand:DI 0 "register_operand" "=r")
13241 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13243 "TARGET_64BIT && TARGET_GNU2_TLS"
13244 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13245 [(set_attr "type" "lea")
13246 (set_attr "mode" "DI")
13247 (set_attr "length" "7")
13248 (set_attr "length_address" "4")])
13250 (define_insn "*tls_dynamic_gnu2_call_64"
13251 [(set (match_operand:DI 0 "register_operand" "=a")
13252 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13253 (match_operand:DI 2 "register_operand" "0")
13256 (clobber (reg:CC FLAGS_REG))]
13257 "TARGET_64BIT && TARGET_GNU2_TLS"
13258 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13259 [(set_attr "type" "call")
13260 (set_attr "length" "2")
13261 (set_attr "length_address" "0")])
13263 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13264 [(set (match_operand:DI 0 "register_operand" "=&a")
13266 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13267 (match_operand:DI 3)
13270 (const:DI (unspec:DI
13271 [(match_operand 1 "tls_symbolic_operand")]
13273 (clobber (reg:CC FLAGS_REG))]
13274 "TARGET_64BIT && TARGET_GNU2_TLS"
13277 [(set (match_dup 0) (match_dup 4))]
13279 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13280 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13283 ;; These patterns match the binary 387 instructions for addM3, subM3,
13284 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13285 ;; SFmode. The first is the normal insn, the second the same insn but
13286 ;; with one operand a conversion, and the third the same insn but with
13287 ;; the other operand a conversion. The conversion may be SFmode or
13288 ;; SImode if the target mode DFmode, but only SImode if the target mode
13291 ;; Gcc is slightly more smart about handling normal two address instructions
13292 ;; so use special patterns for add and mull.
13294 (define_insn "*fop_<mode>_comm_mixed"
13295 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13296 (match_operator:MODEF 3 "binary_fp_operator"
13297 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13298 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13299 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13300 && COMMUTATIVE_ARITH_P (operands[3])
13301 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13302 "* return output_387_binary_op (insn, operands);"
13303 [(set (attr "type")
13304 (if_then_else (eq_attr "alternative" "1,2")
13305 (if_then_else (match_operand:MODEF 3 "mult_operator")
13306 (const_string "ssemul")
13307 (const_string "sseadd"))
13308 (if_then_else (match_operand:MODEF 3 "mult_operator")
13309 (const_string "fmul")
13310 (const_string "fop"))))
13311 (set_attr "isa" "*,noavx,avx")
13312 (set_attr "prefix" "orig,orig,vex")
13313 (set_attr "mode" "<MODE>")])
13315 (define_insn "*fop_<mode>_comm_sse"
13316 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13317 (match_operator:MODEF 3 "binary_fp_operator"
13318 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13319 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13320 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13321 && COMMUTATIVE_ARITH_P (operands[3])
13322 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13323 "* return output_387_binary_op (insn, operands);"
13324 [(set (attr "type")
13325 (if_then_else (match_operand:MODEF 3 "mult_operator")
13326 (const_string "ssemul")
13327 (const_string "sseadd")))
13328 (set_attr "isa" "noavx,avx")
13329 (set_attr "prefix" "orig,vex")
13330 (set_attr "mode" "<MODE>")])
13332 (define_insn "*fop_<mode>_comm_i387"
13333 [(set (match_operand:MODEF 0 "register_operand" "=f")
13334 (match_operator:MODEF 3 "binary_fp_operator"
13335 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13336 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13337 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13338 && COMMUTATIVE_ARITH_P (operands[3])
13339 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13340 "* return output_387_binary_op (insn, operands);"
13341 [(set (attr "type")
13342 (if_then_else (match_operand:MODEF 3 "mult_operator")
13343 (const_string "fmul")
13344 (const_string "fop")))
13345 (set_attr "mode" "<MODE>")])
13347 (define_insn "*fop_<mode>_1_mixed"
13348 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13349 (match_operator:MODEF 3 "binary_fp_operator"
13350 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13351 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13352 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13353 && !COMMUTATIVE_ARITH_P (operands[3])
13354 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13355 "* return output_387_binary_op (insn, operands);"
13356 [(set (attr "type")
13357 (cond [(and (eq_attr "alternative" "2,3")
13358 (match_operand:MODEF 3 "mult_operator"))
13359 (const_string "ssemul")
13360 (and (eq_attr "alternative" "2,3")
13361 (match_operand:MODEF 3 "div_operator"))
13362 (const_string "ssediv")
13363 (eq_attr "alternative" "2,3")
13364 (const_string "sseadd")
13365 (match_operand:MODEF 3 "mult_operator")
13366 (const_string "fmul")
13367 (match_operand:MODEF 3 "div_operator")
13368 (const_string "fdiv")
13370 (const_string "fop")))
13371 (set_attr "isa" "*,*,noavx,avx")
13372 (set_attr "prefix" "orig,orig,orig,vex")
13373 (set_attr "mode" "<MODE>")])
13375 (define_insn "*rcpsf2_sse"
13376 [(set (match_operand:SF 0 "register_operand" "=x")
13377 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13380 "%vrcpss\t{%1, %d0|%d0, %1}"
13381 [(set_attr "type" "sse")
13382 (set_attr "atom_sse_attr" "rcp")
13383 (set_attr "prefix" "maybe_vex")
13384 (set_attr "mode" "SF")])
13386 (define_insn "*fop_<mode>_1_sse"
13387 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13388 (match_operator:MODEF 3 "binary_fp_operator"
13389 [(match_operand:MODEF 1 "register_operand" "0,x")
13390 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13391 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13392 && !COMMUTATIVE_ARITH_P (operands[3])"
13393 "* return output_387_binary_op (insn, operands);"
13394 [(set (attr "type")
13395 (cond [(match_operand:MODEF 3 "mult_operator")
13396 (const_string "ssemul")
13397 (match_operand:MODEF 3 "div_operator")
13398 (const_string "ssediv")
13400 (const_string "sseadd")))
13401 (set_attr "isa" "noavx,avx")
13402 (set_attr "prefix" "orig,vex")
13403 (set_attr "mode" "<MODE>")])
13405 ;; This pattern is not fully shadowed by the pattern above.
13406 (define_insn "*fop_<mode>_1_i387"
13407 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13408 (match_operator:MODEF 3 "binary_fp_operator"
13409 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13410 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13411 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13412 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13413 && !COMMUTATIVE_ARITH_P (operands[3])
13414 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13415 "* return output_387_binary_op (insn, operands);"
13416 [(set (attr "type")
13417 (cond [(match_operand:MODEF 3 "mult_operator")
13418 (const_string "fmul")
13419 (match_operand:MODEF 3 "div_operator")
13420 (const_string "fdiv")
13422 (const_string "fop")))
13423 (set_attr "mode" "<MODE>")])
13425 ;; ??? Add SSE splitters for these!
13426 (define_insn "*fop_<MODEF:mode>_2_i387"
13427 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13428 (match_operator:MODEF 3 "binary_fp_operator"
13430 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13431 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13432 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13433 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13434 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13435 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13436 [(set (attr "type")
13437 (cond [(match_operand:MODEF 3 "mult_operator")
13438 (const_string "fmul")
13439 (match_operand:MODEF 3 "div_operator")
13440 (const_string "fdiv")
13442 (const_string "fop")))
13443 (set_attr "fp_int_src" "true")
13444 (set_attr "mode" "<SWI24:MODE>")])
13446 (define_insn "*fop_<MODEF:mode>_3_i387"
13447 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13448 (match_operator:MODEF 3 "binary_fp_operator"
13449 [(match_operand:MODEF 1 "register_operand" "0,0")
13451 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13452 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13453 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13454 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13455 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13456 [(set (attr "type")
13457 (cond [(match_operand:MODEF 3 "mult_operator")
13458 (const_string "fmul")
13459 (match_operand:MODEF 3 "div_operator")
13460 (const_string "fdiv")
13462 (const_string "fop")))
13463 (set_attr "fp_int_src" "true")
13464 (set_attr "mode" "<MODE>")])
13466 (define_insn "*fop_df_4_i387"
13467 [(set (match_operand:DF 0 "register_operand" "=f,f")
13468 (match_operator:DF 3 "binary_fp_operator"
13470 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13471 (match_operand:DF 2 "register_operand" "0,f")]))]
13472 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13473 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13474 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13475 "* return output_387_binary_op (insn, operands);"
13476 [(set (attr "type")
13477 (cond [(match_operand:DF 3 "mult_operator")
13478 (const_string "fmul")
13479 (match_operand:DF 3 "div_operator")
13480 (const_string "fdiv")
13482 (const_string "fop")))
13483 (set_attr "mode" "SF")])
13485 (define_insn "*fop_df_5_i387"
13486 [(set (match_operand:DF 0 "register_operand" "=f,f")
13487 (match_operator:DF 3 "binary_fp_operator"
13488 [(match_operand:DF 1 "register_operand" "0,f")
13490 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13491 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13492 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13493 "* return output_387_binary_op (insn, operands);"
13494 [(set (attr "type")
13495 (cond [(match_operand:DF 3 "mult_operator")
13496 (const_string "fmul")
13497 (match_operand:DF 3 "div_operator")
13498 (const_string "fdiv")
13500 (const_string "fop")))
13501 (set_attr "mode" "SF")])
13503 (define_insn "*fop_df_6_i387"
13504 [(set (match_operand:DF 0 "register_operand" "=f,f")
13505 (match_operator:DF 3 "binary_fp_operator"
13507 (match_operand:SF 1 "register_operand" "0,f"))
13509 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13510 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13511 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13512 "* return output_387_binary_op (insn, operands);"
13513 [(set (attr "type")
13514 (cond [(match_operand:DF 3 "mult_operator")
13515 (const_string "fmul")
13516 (match_operand:DF 3 "div_operator")
13517 (const_string "fdiv")
13519 (const_string "fop")))
13520 (set_attr "mode" "SF")])
13522 (define_insn "*fop_xf_comm_i387"
13523 [(set (match_operand:XF 0 "register_operand" "=f")
13524 (match_operator:XF 3 "binary_fp_operator"
13525 [(match_operand:XF 1 "register_operand" "%0")
13526 (match_operand:XF 2 "register_operand" "f")]))]
13528 && COMMUTATIVE_ARITH_P (operands[3])"
13529 "* return output_387_binary_op (insn, operands);"
13530 [(set (attr "type")
13531 (if_then_else (match_operand:XF 3 "mult_operator")
13532 (const_string "fmul")
13533 (const_string "fop")))
13534 (set_attr "mode" "XF")])
13536 (define_insn "*fop_xf_1_i387"
13537 [(set (match_operand:XF 0 "register_operand" "=f,f")
13538 (match_operator:XF 3 "binary_fp_operator"
13539 [(match_operand:XF 1 "register_operand" "0,f")
13540 (match_operand:XF 2 "register_operand" "f,0")]))]
13542 && !COMMUTATIVE_ARITH_P (operands[3])"
13543 "* return output_387_binary_op (insn, operands);"
13544 [(set (attr "type")
13545 (cond [(match_operand:XF 3 "mult_operator")
13546 (const_string "fmul")
13547 (match_operand:XF 3 "div_operator")
13548 (const_string "fdiv")
13550 (const_string "fop")))
13551 (set_attr "mode" "XF")])
13553 (define_insn "*fop_xf_2_i387"
13554 [(set (match_operand:XF 0 "register_operand" "=f,f")
13555 (match_operator:XF 3 "binary_fp_operator"
13557 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13558 (match_operand:XF 2 "register_operand" "0,0")]))]
13559 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13560 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13561 [(set (attr "type")
13562 (cond [(match_operand:XF 3 "mult_operator")
13563 (const_string "fmul")
13564 (match_operand:XF 3 "div_operator")
13565 (const_string "fdiv")
13567 (const_string "fop")))
13568 (set_attr "fp_int_src" "true")
13569 (set_attr "mode" "<MODE>")])
13571 (define_insn "*fop_xf_3_i387"
13572 [(set (match_operand:XF 0 "register_operand" "=f,f")
13573 (match_operator:XF 3 "binary_fp_operator"
13574 [(match_operand:XF 1 "register_operand" "0,0")
13576 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13577 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13578 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13579 [(set (attr "type")
13580 (cond [(match_operand:XF 3 "mult_operator")
13581 (const_string "fmul")
13582 (match_operand:XF 3 "div_operator")
13583 (const_string "fdiv")
13585 (const_string "fop")))
13586 (set_attr "fp_int_src" "true")
13587 (set_attr "mode" "<MODE>")])
13589 (define_insn "*fop_xf_4_i387"
13590 [(set (match_operand:XF 0 "register_operand" "=f,f")
13591 (match_operator:XF 3 "binary_fp_operator"
13593 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13594 (match_operand:XF 2 "register_operand" "0,f")]))]
13596 "* return output_387_binary_op (insn, operands);"
13597 [(set (attr "type")
13598 (cond [(match_operand:XF 3 "mult_operator")
13599 (const_string "fmul")
13600 (match_operand:XF 3 "div_operator")
13601 (const_string "fdiv")
13603 (const_string "fop")))
13604 (set_attr "mode" "<MODE>")])
13606 (define_insn "*fop_xf_5_i387"
13607 [(set (match_operand:XF 0 "register_operand" "=f,f")
13608 (match_operator:XF 3 "binary_fp_operator"
13609 [(match_operand:XF 1 "register_operand" "0,f")
13611 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13613 "* return output_387_binary_op (insn, operands);"
13614 [(set (attr "type")
13615 (cond [(match_operand:XF 3 "mult_operator")
13616 (const_string "fmul")
13617 (match_operand:XF 3 "div_operator")
13618 (const_string "fdiv")
13620 (const_string "fop")))
13621 (set_attr "mode" "<MODE>")])
13623 (define_insn "*fop_xf_6_i387"
13624 [(set (match_operand:XF 0 "register_operand" "=f,f")
13625 (match_operator:XF 3 "binary_fp_operator"
13627 (match_operand:MODEF 1 "register_operand" "0,f"))
13629 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13631 "* return output_387_binary_op (insn, operands);"
13632 [(set (attr "type")
13633 (cond [(match_operand:XF 3 "mult_operator")
13634 (const_string "fmul")
13635 (match_operand:XF 3 "div_operator")
13636 (const_string "fdiv")
13638 (const_string "fop")))
13639 (set_attr "mode" "<MODE>")])
13642 [(set (match_operand 0 "register_operand")
13643 (match_operator 3 "binary_fp_operator"
13644 [(float (match_operand:SWI24 1 "register_operand"))
13645 (match_operand 2 "register_operand")]))]
13647 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13648 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13651 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13652 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13653 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13654 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13655 GET_MODE (operands[3]),
13658 ix86_free_from_memory (GET_MODE (operands[1]));
13663 [(set (match_operand 0 "register_operand")
13664 (match_operator 3 "binary_fp_operator"
13665 [(match_operand 1 "register_operand")
13666 (float (match_operand:SWI24 2 "register_operand"))]))]
13668 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13669 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13672 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13673 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13674 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13675 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13676 GET_MODE (operands[3]),
13679 ix86_free_from_memory (GET_MODE (operands[2]));
13683 ;; FPU special functions.
13685 ;; This pattern implements a no-op XFmode truncation for
13686 ;; all fancy i386 XFmode math functions.
13688 (define_insn "truncxf<mode>2_i387_noop_unspec"
13689 [(set (match_operand:MODEF 0 "register_operand" "=f")
13690 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13691 UNSPEC_TRUNC_NOOP))]
13692 "TARGET_USE_FANCY_MATH_387"
13693 "* return output_387_reg_move (insn, operands);"
13694 [(set_attr "type" "fmov")
13695 (set_attr "mode" "<MODE>")])
13697 (define_insn "sqrtxf2"
13698 [(set (match_operand:XF 0 "register_operand" "=f")
13699 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13700 "TARGET_USE_FANCY_MATH_387"
13702 [(set_attr "type" "fpspc")
13703 (set_attr "mode" "XF")
13704 (set_attr "athlon_decode" "direct")
13705 (set_attr "amdfam10_decode" "direct")
13706 (set_attr "bdver1_decode" "direct")])
13708 (define_insn "sqrt_extend<mode>xf2_i387"
13709 [(set (match_operand:XF 0 "register_operand" "=f")
13712 (match_operand:MODEF 1 "register_operand" "0"))))]
13713 "TARGET_USE_FANCY_MATH_387"
13715 [(set_attr "type" "fpspc")
13716 (set_attr "mode" "XF")
13717 (set_attr "athlon_decode" "direct")
13718 (set_attr "amdfam10_decode" "direct")
13719 (set_attr "bdver1_decode" "direct")])
13721 (define_insn "*rsqrtsf2_sse"
13722 [(set (match_operand:SF 0 "register_operand" "=x")
13723 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13726 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13727 [(set_attr "type" "sse")
13728 (set_attr "atom_sse_attr" "rcp")
13729 (set_attr "prefix" "maybe_vex")
13730 (set_attr "mode" "SF")])
13732 (define_expand "rsqrtsf2"
13733 [(set (match_operand:SF 0 "register_operand")
13734 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13738 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13742 (define_insn "*sqrt<mode>2_sse"
13743 [(set (match_operand:MODEF 0 "register_operand" "=x")
13745 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13746 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13747 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13748 [(set_attr "type" "sse")
13749 (set_attr "atom_sse_attr" "sqrt")
13750 (set_attr "prefix" "maybe_vex")
13751 (set_attr "mode" "<MODE>")
13752 (set_attr "athlon_decode" "*")
13753 (set_attr "amdfam10_decode" "*")
13754 (set_attr "bdver1_decode" "*")])
13756 (define_expand "sqrt<mode>2"
13757 [(set (match_operand:MODEF 0 "register_operand")
13759 (match_operand:MODEF 1 "nonimmediate_operand")))]
13760 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13761 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13763 if (<MODE>mode == SFmode
13765 && TARGET_RECIP_SQRT
13766 && !optimize_function_for_size_p (cfun)
13767 && flag_finite_math_only && !flag_trapping_math
13768 && flag_unsafe_math_optimizations)
13770 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13774 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13776 rtx op0 = gen_reg_rtx (XFmode);
13777 rtx op1 = force_reg (<MODE>mode, operands[1]);
13779 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13780 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13785 (define_insn "fpremxf4_i387"
13786 [(set (match_operand:XF 0 "register_operand" "=f")
13787 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13788 (match_operand:XF 3 "register_operand" "1")]
13790 (set (match_operand:XF 1 "register_operand" "=u")
13791 (unspec:XF [(match_dup 2) (match_dup 3)]
13793 (set (reg:CCFP FPSR_REG)
13794 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13796 "TARGET_USE_FANCY_MATH_387"
13798 [(set_attr "type" "fpspc")
13799 (set_attr "mode" "XF")])
13801 (define_expand "fmodxf3"
13802 [(use (match_operand:XF 0 "register_operand"))
13803 (use (match_operand:XF 1 "general_operand"))
13804 (use (match_operand:XF 2 "general_operand"))]
13805 "TARGET_USE_FANCY_MATH_387"
13807 rtx label = gen_label_rtx ();
13809 rtx op1 = gen_reg_rtx (XFmode);
13810 rtx op2 = gen_reg_rtx (XFmode);
13812 emit_move_insn (op2, operands[2]);
13813 emit_move_insn (op1, operands[1]);
13815 emit_label (label);
13816 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13817 ix86_emit_fp_unordered_jump (label);
13818 LABEL_NUSES (label) = 1;
13820 emit_move_insn (operands[0], op1);
13824 (define_expand "fmod<mode>3"
13825 [(use (match_operand:MODEF 0 "register_operand"))
13826 (use (match_operand:MODEF 1 "general_operand"))
13827 (use (match_operand:MODEF 2 "general_operand"))]
13828 "TARGET_USE_FANCY_MATH_387"
13830 rtx (*gen_truncxf) (rtx, rtx);
13832 rtx label = gen_label_rtx ();
13834 rtx op1 = gen_reg_rtx (XFmode);
13835 rtx op2 = gen_reg_rtx (XFmode);
13837 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13838 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13840 emit_label (label);
13841 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13842 ix86_emit_fp_unordered_jump (label);
13843 LABEL_NUSES (label) = 1;
13845 /* Truncate the result properly for strict SSE math. */
13846 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13847 && !TARGET_MIX_SSE_I387)
13848 gen_truncxf = gen_truncxf<mode>2;
13850 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13852 emit_insn (gen_truncxf (operands[0], op1));
13856 (define_insn "fprem1xf4_i387"
13857 [(set (match_operand:XF 0 "register_operand" "=f")
13858 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13859 (match_operand:XF 3 "register_operand" "1")]
13861 (set (match_operand:XF 1 "register_operand" "=u")
13862 (unspec:XF [(match_dup 2) (match_dup 3)]
13864 (set (reg:CCFP FPSR_REG)
13865 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13867 "TARGET_USE_FANCY_MATH_387"
13869 [(set_attr "type" "fpspc")
13870 (set_attr "mode" "XF")])
13872 (define_expand "remainderxf3"
13873 [(use (match_operand:XF 0 "register_operand"))
13874 (use (match_operand:XF 1 "general_operand"))
13875 (use (match_operand:XF 2 "general_operand"))]
13876 "TARGET_USE_FANCY_MATH_387"
13878 rtx label = gen_label_rtx ();
13880 rtx op1 = gen_reg_rtx (XFmode);
13881 rtx op2 = gen_reg_rtx (XFmode);
13883 emit_move_insn (op2, operands[2]);
13884 emit_move_insn (op1, operands[1]);
13886 emit_label (label);
13887 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13888 ix86_emit_fp_unordered_jump (label);
13889 LABEL_NUSES (label) = 1;
13891 emit_move_insn (operands[0], op1);
13895 (define_expand "remainder<mode>3"
13896 [(use (match_operand:MODEF 0 "register_operand"))
13897 (use (match_operand:MODEF 1 "general_operand"))
13898 (use (match_operand:MODEF 2 "general_operand"))]
13899 "TARGET_USE_FANCY_MATH_387"
13901 rtx (*gen_truncxf) (rtx, rtx);
13903 rtx label = gen_label_rtx ();
13905 rtx op1 = gen_reg_rtx (XFmode);
13906 rtx op2 = gen_reg_rtx (XFmode);
13908 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13909 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13911 emit_label (label);
13913 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13914 ix86_emit_fp_unordered_jump (label);
13915 LABEL_NUSES (label) = 1;
13917 /* Truncate the result properly for strict SSE math. */
13918 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13919 && !TARGET_MIX_SSE_I387)
13920 gen_truncxf = gen_truncxf<mode>2;
13922 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13924 emit_insn (gen_truncxf (operands[0], op1));
13928 (define_int_iterator SINCOS
13932 (define_int_attr sincos
13933 [(UNSPEC_SIN "sin")
13934 (UNSPEC_COS "cos")])
13936 (define_insn "*<sincos>xf2_i387"
13937 [(set (match_operand:XF 0 "register_operand" "=f")
13938 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13940 "TARGET_USE_FANCY_MATH_387
13941 && flag_unsafe_math_optimizations"
13943 [(set_attr "type" "fpspc")
13944 (set_attr "mode" "XF")])
13946 (define_insn "*<sincos>_extend<mode>xf2_i387"
13947 [(set (match_operand:XF 0 "register_operand" "=f")
13948 (unspec:XF [(float_extend:XF
13949 (match_operand:MODEF 1 "register_operand" "0"))]
13951 "TARGET_USE_FANCY_MATH_387
13952 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13953 || TARGET_MIX_SSE_I387)
13954 && flag_unsafe_math_optimizations"
13956 [(set_attr "type" "fpspc")
13957 (set_attr "mode" "XF")])
13959 ;; When sincos pattern is defined, sin and cos builtin functions will be
13960 ;; expanded to sincos pattern with one of its outputs left unused.
13961 ;; CSE pass will figure out if two sincos patterns can be combined,
13962 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13963 ;; depending on the unused output.
13965 (define_insn "sincosxf3"
13966 [(set (match_operand:XF 0 "register_operand" "=f")
13967 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13968 UNSPEC_SINCOS_COS))
13969 (set (match_operand:XF 1 "register_operand" "=u")
13970 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13971 "TARGET_USE_FANCY_MATH_387
13972 && flag_unsafe_math_optimizations"
13974 [(set_attr "type" "fpspc")
13975 (set_attr "mode" "XF")])
13978 [(set (match_operand:XF 0 "register_operand")
13979 (unspec:XF [(match_operand:XF 2 "register_operand")]
13980 UNSPEC_SINCOS_COS))
13981 (set (match_operand:XF 1 "register_operand")
13982 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13983 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13984 && can_create_pseudo_p ()"
13985 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13988 [(set (match_operand:XF 0 "register_operand")
13989 (unspec:XF [(match_operand:XF 2 "register_operand")]
13990 UNSPEC_SINCOS_COS))
13991 (set (match_operand:XF 1 "register_operand")
13992 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13993 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13994 && can_create_pseudo_p ()"
13995 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13997 (define_insn "sincos_extend<mode>xf3_i387"
13998 [(set (match_operand:XF 0 "register_operand" "=f")
13999 (unspec:XF [(float_extend:XF
14000 (match_operand:MODEF 2 "register_operand" "0"))]
14001 UNSPEC_SINCOS_COS))
14002 (set (match_operand:XF 1 "register_operand" "=u")
14003 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14004 "TARGET_USE_FANCY_MATH_387
14005 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14006 || TARGET_MIX_SSE_I387)
14007 && flag_unsafe_math_optimizations"
14009 [(set_attr "type" "fpspc")
14010 (set_attr "mode" "XF")])
14013 [(set (match_operand:XF 0 "register_operand")
14014 (unspec:XF [(float_extend:XF
14015 (match_operand:MODEF 2 "register_operand"))]
14016 UNSPEC_SINCOS_COS))
14017 (set (match_operand:XF 1 "register_operand")
14018 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14019 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14020 && can_create_pseudo_p ()"
14021 [(set (match_dup 1)
14022 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14025 [(set (match_operand:XF 0 "register_operand")
14026 (unspec:XF [(float_extend:XF
14027 (match_operand:MODEF 2 "register_operand"))]
14028 UNSPEC_SINCOS_COS))
14029 (set (match_operand:XF 1 "register_operand")
14030 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14031 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14032 && can_create_pseudo_p ()"
14033 [(set (match_dup 0)
14034 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14036 (define_expand "sincos<mode>3"
14037 [(use (match_operand:MODEF 0 "register_operand"))
14038 (use (match_operand:MODEF 1 "register_operand"))
14039 (use (match_operand:MODEF 2 "register_operand"))]
14040 "TARGET_USE_FANCY_MATH_387
14041 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14042 || TARGET_MIX_SSE_I387)
14043 && flag_unsafe_math_optimizations"
14045 rtx op0 = gen_reg_rtx (XFmode);
14046 rtx op1 = gen_reg_rtx (XFmode);
14048 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14049 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14050 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14054 (define_insn "fptanxf4_i387"
14055 [(set (match_operand:XF 0 "register_operand" "=f")
14056 (match_operand:XF 3 "const_double_operand" "F"))
14057 (set (match_operand:XF 1 "register_operand" "=u")
14058 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14060 "TARGET_USE_FANCY_MATH_387
14061 && flag_unsafe_math_optimizations
14062 && standard_80387_constant_p (operands[3]) == 2"
14064 [(set_attr "type" "fpspc")
14065 (set_attr "mode" "XF")])
14067 (define_insn "fptan_extend<mode>xf4_i387"
14068 [(set (match_operand:MODEF 0 "register_operand" "=f")
14069 (match_operand:MODEF 3 "const_double_operand" "F"))
14070 (set (match_operand:XF 1 "register_operand" "=u")
14071 (unspec:XF [(float_extend:XF
14072 (match_operand:MODEF 2 "register_operand" "0"))]
14074 "TARGET_USE_FANCY_MATH_387
14075 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14076 || TARGET_MIX_SSE_I387)
14077 && flag_unsafe_math_optimizations
14078 && standard_80387_constant_p (operands[3]) == 2"
14080 [(set_attr "type" "fpspc")
14081 (set_attr "mode" "XF")])
14083 (define_expand "tanxf2"
14084 [(use (match_operand:XF 0 "register_operand"))
14085 (use (match_operand:XF 1 "register_operand"))]
14086 "TARGET_USE_FANCY_MATH_387
14087 && flag_unsafe_math_optimizations"
14089 rtx one = gen_reg_rtx (XFmode);
14090 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14092 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14096 (define_expand "tan<mode>2"
14097 [(use (match_operand:MODEF 0 "register_operand"))
14098 (use (match_operand:MODEF 1 "register_operand"))]
14099 "TARGET_USE_FANCY_MATH_387
14100 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14101 || TARGET_MIX_SSE_I387)
14102 && flag_unsafe_math_optimizations"
14104 rtx op0 = gen_reg_rtx (XFmode);
14106 rtx one = gen_reg_rtx (<MODE>mode);
14107 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14109 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14110 operands[1], op2));
14111 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14115 (define_insn "*fpatanxf3_i387"
14116 [(set (match_operand:XF 0 "register_operand" "=f")
14117 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14118 (match_operand:XF 2 "register_operand" "u")]
14120 (clobber (match_scratch:XF 3 "=2"))]
14121 "TARGET_USE_FANCY_MATH_387
14122 && flag_unsafe_math_optimizations"
14124 [(set_attr "type" "fpspc")
14125 (set_attr "mode" "XF")])
14127 (define_insn "fpatan_extend<mode>xf3_i387"
14128 [(set (match_operand:XF 0 "register_operand" "=f")
14129 (unspec:XF [(float_extend:XF
14130 (match_operand:MODEF 1 "register_operand" "0"))
14132 (match_operand:MODEF 2 "register_operand" "u"))]
14134 (clobber (match_scratch:XF 3 "=2"))]
14135 "TARGET_USE_FANCY_MATH_387
14136 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14137 || TARGET_MIX_SSE_I387)
14138 && flag_unsafe_math_optimizations"
14140 [(set_attr "type" "fpspc")
14141 (set_attr "mode" "XF")])
14143 (define_expand "atan2xf3"
14144 [(parallel [(set (match_operand:XF 0 "register_operand")
14145 (unspec:XF [(match_operand:XF 2 "register_operand")
14146 (match_operand:XF 1 "register_operand")]
14148 (clobber (match_scratch:XF 3))])]
14149 "TARGET_USE_FANCY_MATH_387
14150 && flag_unsafe_math_optimizations")
14152 (define_expand "atan2<mode>3"
14153 [(use (match_operand:MODEF 0 "register_operand"))
14154 (use (match_operand:MODEF 1 "register_operand"))
14155 (use (match_operand:MODEF 2 "register_operand"))]
14156 "TARGET_USE_FANCY_MATH_387
14157 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14158 || TARGET_MIX_SSE_I387)
14159 && flag_unsafe_math_optimizations"
14161 rtx op0 = gen_reg_rtx (XFmode);
14163 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14164 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14168 (define_expand "atanxf2"
14169 [(parallel [(set (match_operand:XF 0 "register_operand")
14170 (unspec:XF [(match_dup 2)
14171 (match_operand:XF 1 "register_operand")]
14173 (clobber (match_scratch:XF 3))])]
14174 "TARGET_USE_FANCY_MATH_387
14175 && flag_unsafe_math_optimizations"
14177 operands[2] = gen_reg_rtx (XFmode);
14178 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14181 (define_expand "atan<mode>2"
14182 [(use (match_operand:MODEF 0 "register_operand"))
14183 (use (match_operand:MODEF 1 "register_operand"))]
14184 "TARGET_USE_FANCY_MATH_387
14185 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14186 || TARGET_MIX_SSE_I387)
14187 && flag_unsafe_math_optimizations"
14189 rtx op0 = gen_reg_rtx (XFmode);
14191 rtx op2 = gen_reg_rtx (<MODE>mode);
14192 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14194 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14195 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14199 (define_expand "asinxf2"
14200 [(set (match_dup 2)
14201 (mult:XF (match_operand:XF 1 "register_operand")
14203 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14204 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14205 (parallel [(set (match_operand:XF 0 "register_operand")
14206 (unspec:XF [(match_dup 5) (match_dup 1)]
14208 (clobber (match_scratch:XF 6))])]
14209 "TARGET_USE_FANCY_MATH_387
14210 && flag_unsafe_math_optimizations"
14214 if (optimize_insn_for_size_p ())
14217 for (i = 2; i < 6; i++)
14218 operands[i] = gen_reg_rtx (XFmode);
14220 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14223 (define_expand "asin<mode>2"
14224 [(use (match_operand:MODEF 0 "register_operand"))
14225 (use (match_operand:MODEF 1 "general_operand"))]
14226 "TARGET_USE_FANCY_MATH_387
14227 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14228 || TARGET_MIX_SSE_I387)
14229 && flag_unsafe_math_optimizations"
14231 rtx op0 = gen_reg_rtx (XFmode);
14232 rtx op1 = gen_reg_rtx (XFmode);
14234 if (optimize_insn_for_size_p ())
14237 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14238 emit_insn (gen_asinxf2 (op0, op1));
14239 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14243 (define_expand "acosxf2"
14244 [(set (match_dup 2)
14245 (mult:XF (match_operand:XF 1 "register_operand")
14247 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14248 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14249 (parallel [(set (match_operand:XF 0 "register_operand")
14250 (unspec:XF [(match_dup 1) (match_dup 5)]
14252 (clobber (match_scratch:XF 6))])]
14253 "TARGET_USE_FANCY_MATH_387
14254 && flag_unsafe_math_optimizations"
14258 if (optimize_insn_for_size_p ())
14261 for (i = 2; i < 6; i++)
14262 operands[i] = gen_reg_rtx (XFmode);
14264 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14267 (define_expand "acos<mode>2"
14268 [(use (match_operand:MODEF 0 "register_operand"))
14269 (use (match_operand:MODEF 1 "general_operand"))]
14270 "TARGET_USE_FANCY_MATH_387
14271 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14272 || TARGET_MIX_SSE_I387)
14273 && flag_unsafe_math_optimizations"
14275 rtx op0 = gen_reg_rtx (XFmode);
14276 rtx op1 = gen_reg_rtx (XFmode);
14278 if (optimize_insn_for_size_p ())
14281 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14282 emit_insn (gen_acosxf2 (op0, op1));
14283 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14287 (define_insn "fyl2xxf3_i387"
14288 [(set (match_operand:XF 0 "register_operand" "=f")
14289 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14290 (match_operand:XF 2 "register_operand" "u")]
14292 (clobber (match_scratch:XF 3 "=2"))]
14293 "TARGET_USE_FANCY_MATH_387
14294 && flag_unsafe_math_optimizations"
14296 [(set_attr "type" "fpspc")
14297 (set_attr "mode" "XF")])
14299 (define_insn "fyl2x_extend<mode>xf3_i387"
14300 [(set (match_operand:XF 0 "register_operand" "=f")
14301 (unspec:XF [(float_extend:XF
14302 (match_operand:MODEF 1 "register_operand" "0"))
14303 (match_operand:XF 2 "register_operand" "u")]
14305 (clobber (match_scratch:XF 3 "=2"))]
14306 "TARGET_USE_FANCY_MATH_387
14307 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14308 || TARGET_MIX_SSE_I387)
14309 && flag_unsafe_math_optimizations"
14311 [(set_attr "type" "fpspc")
14312 (set_attr "mode" "XF")])
14314 (define_expand "logxf2"
14315 [(parallel [(set (match_operand:XF 0 "register_operand")
14316 (unspec:XF [(match_operand:XF 1 "register_operand")
14317 (match_dup 2)] UNSPEC_FYL2X))
14318 (clobber (match_scratch:XF 3))])]
14319 "TARGET_USE_FANCY_MATH_387
14320 && flag_unsafe_math_optimizations"
14322 operands[2] = gen_reg_rtx (XFmode);
14323 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14326 (define_expand "log<mode>2"
14327 [(use (match_operand:MODEF 0 "register_operand"))
14328 (use (match_operand:MODEF 1 "register_operand"))]
14329 "TARGET_USE_FANCY_MATH_387
14330 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14331 || TARGET_MIX_SSE_I387)
14332 && flag_unsafe_math_optimizations"
14334 rtx op0 = gen_reg_rtx (XFmode);
14336 rtx op2 = gen_reg_rtx (XFmode);
14337 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14339 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14340 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14344 (define_expand "log10xf2"
14345 [(parallel [(set (match_operand:XF 0 "register_operand")
14346 (unspec:XF [(match_operand:XF 1 "register_operand")
14347 (match_dup 2)] UNSPEC_FYL2X))
14348 (clobber (match_scratch:XF 3))])]
14349 "TARGET_USE_FANCY_MATH_387
14350 && flag_unsafe_math_optimizations"
14352 operands[2] = gen_reg_rtx (XFmode);
14353 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14356 (define_expand "log10<mode>2"
14357 [(use (match_operand:MODEF 0 "register_operand"))
14358 (use (match_operand:MODEF 1 "register_operand"))]
14359 "TARGET_USE_FANCY_MATH_387
14360 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14361 || TARGET_MIX_SSE_I387)
14362 && flag_unsafe_math_optimizations"
14364 rtx op0 = gen_reg_rtx (XFmode);
14366 rtx op2 = gen_reg_rtx (XFmode);
14367 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14369 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14370 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14374 (define_expand "log2xf2"
14375 [(parallel [(set (match_operand:XF 0 "register_operand")
14376 (unspec:XF [(match_operand:XF 1 "register_operand")
14377 (match_dup 2)] UNSPEC_FYL2X))
14378 (clobber (match_scratch:XF 3))])]
14379 "TARGET_USE_FANCY_MATH_387
14380 && flag_unsafe_math_optimizations"
14382 operands[2] = gen_reg_rtx (XFmode);
14383 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14386 (define_expand "log2<mode>2"
14387 [(use (match_operand:MODEF 0 "register_operand"))
14388 (use (match_operand:MODEF 1 "register_operand"))]
14389 "TARGET_USE_FANCY_MATH_387
14390 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14391 || TARGET_MIX_SSE_I387)
14392 && flag_unsafe_math_optimizations"
14394 rtx op0 = gen_reg_rtx (XFmode);
14396 rtx op2 = gen_reg_rtx (XFmode);
14397 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14399 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14400 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14404 (define_insn "fyl2xp1xf3_i387"
14405 [(set (match_operand:XF 0 "register_operand" "=f")
14406 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14407 (match_operand:XF 2 "register_operand" "u")]
14409 (clobber (match_scratch:XF 3 "=2"))]
14410 "TARGET_USE_FANCY_MATH_387
14411 && flag_unsafe_math_optimizations"
14413 [(set_attr "type" "fpspc")
14414 (set_attr "mode" "XF")])
14416 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14417 [(set (match_operand:XF 0 "register_operand" "=f")
14418 (unspec:XF [(float_extend:XF
14419 (match_operand:MODEF 1 "register_operand" "0"))
14420 (match_operand:XF 2 "register_operand" "u")]
14422 (clobber (match_scratch:XF 3 "=2"))]
14423 "TARGET_USE_FANCY_MATH_387
14424 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14425 || TARGET_MIX_SSE_I387)
14426 && flag_unsafe_math_optimizations"
14428 [(set_attr "type" "fpspc")
14429 (set_attr "mode" "XF")])
14431 (define_expand "log1pxf2"
14432 [(use (match_operand:XF 0 "register_operand"))
14433 (use (match_operand:XF 1 "register_operand"))]
14434 "TARGET_USE_FANCY_MATH_387
14435 && flag_unsafe_math_optimizations"
14437 if (optimize_insn_for_size_p ())
14440 ix86_emit_i387_log1p (operands[0], operands[1]);
14444 (define_expand "log1p<mode>2"
14445 [(use (match_operand:MODEF 0 "register_operand"))
14446 (use (match_operand:MODEF 1 "register_operand"))]
14447 "TARGET_USE_FANCY_MATH_387
14448 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14449 || TARGET_MIX_SSE_I387)
14450 && flag_unsafe_math_optimizations"
14454 if (optimize_insn_for_size_p ())
14457 op0 = gen_reg_rtx (XFmode);
14459 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14461 ix86_emit_i387_log1p (op0, operands[1]);
14462 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14466 (define_insn "fxtractxf3_i387"
14467 [(set (match_operand:XF 0 "register_operand" "=f")
14468 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14469 UNSPEC_XTRACT_FRACT))
14470 (set (match_operand:XF 1 "register_operand" "=u")
14471 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14472 "TARGET_USE_FANCY_MATH_387
14473 && flag_unsafe_math_optimizations"
14475 [(set_attr "type" "fpspc")
14476 (set_attr "mode" "XF")])
14478 (define_insn "fxtract_extend<mode>xf3_i387"
14479 [(set (match_operand:XF 0 "register_operand" "=f")
14480 (unspec:XF [(float_extend:XF
14481 (match_operand:MODEF 2 "register_operand" "0"))]
14482 UNSPEC_XTRACT_FRACT))
14483 (set (match_operand:XF 1 "register_operand" "=u")
14484 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14485 "TARGET_USE_FANCY_MATH_387
14486 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14487 || TARGET_MIX_SSE_I387)
14488 && flag_unsafe_math_optimizations"
14490 [(set_attr "type" "fpspc")
14491 (set_attr "mode" "XF")])
14493 (define_expand "logbxf2"
14494 [(parallel [(set (match_dup 2)
14495 (unspec:XF [(match_operand:XF 1 "register_operand")]
14496 UNSPEC_XTRACT_FRACT))
14497 (set (match_operand:XF 0 "register_operand")
14498 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14499 "TARGET_USE_FANCY_MATH_387
14500 && flag_unsafe_math_optimizations"
14501 "operands[2] = gen_reg_rtx (XFmode);")
14503 (define_expand "logb<mode>2"
14504 [(use (match_operand:MODEF 0 "register_operand"))
14505 (use (match_operand:MODEF 1 "register_operand"))]
14506 "TARGET_USE_FANCY_MATH_387
14507 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14508 || TARGET_MIX_SSE_I387)
14509 && flag_unsafe_math_optimizations"
14511 rtx op0 = gen_reg_rtx (XFmode);
14512 rtx op1 = gen_reg_rtx (XFmode);
14514 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14515 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14519 (define_expand "ilogbxf2"
14520 [(use (match_operand:SI 0 "register_operand"))
14521 (use (match_operand:XF 1 "register_operand"))]
14522 "TARGET_USE_FANCY_MATH_387
14523 && flag_unsafe_math_optimizations"
14527 if (optimize_insn_for_size_p ())
14530 op0 = gen_reg_rtx (XFmode);
14531 op1 = gen_reg_rtx (XFmode);
14533 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14534 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14538 (define_expand "ilogb<mode>2"
14539 [(use (match_operand:SI 0 "register_operand"))
14540 (use (match_operand:MODEF 1 "register_operand"))]
14541 "TARGET_USE_FANCY_MATH_387
14542 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14543 || TARGET_MIX_SSE_I387)
14544 && flag_unsafe_math_optimizations"
14548 if (optimize_insn_for_size_p ())
14551 op0 = gen_reg_rtx (XFmode);
14552 op1 = gen_reg_rtx (XFmode);
14554 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14555 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14559 (define_insn "*f2xm1xf2_i387"
14560 [(set (match_operand:XF 0 "register_operand" "=f")
14561 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14563 "TARGET_USE_FANCY_MATH_387
14564 && flag_unsafe_math_optimizations"
14566 [(set_attr "type" "fpspc")
14567 (set_attr "mode" "XF")])
14569 (define_insn "*fscalexf4_i387"
14570 [(set (match_operand:XF 0 "register_operand" "=f")
14571 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14572 (match_operand:XF 3 "register_operand" "1")]
14573 UNSPEC_FSCALE_FRACT))
14574 (set (match_operand:XF 1 "register_operand" "=u")
14575 (unspec:XF [(match_dup 2) (match_dup 3)]
14576 UNSPEC_FSCALE_EXP))]
14577 "TARGET_USE_FANCY_MATH_387
14578 && flag_unsafe_math_optimizations"
14580 [(set_attr "type" "fpspc")
14581 (set_attr "mode" "XF")])
14583 (define_expand "expNcorexf3"
14584 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14585 (match_operand:XF 2 "register_operand")))
14586 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14587 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14588 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14589 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14590 (parallel [(set (match_operand:XF 0 "register_operand")
14591 (unspec:XF [(match_dup 8) (match_dup 4)]
14592 UNSPEC_FSCALE_FRACT))
14594 (unspec:XF [(match_dup 8) (match_dup 4)]
14595 UNSPEC_FSCALE_EXP))])]
14596 "TARGET_USE_FANCY_MATH_387
14597 && flag_unsafe_math_optimizations"
14601 if (optimize_insn_for_size_p ())
14604 for (i = 3; i < 10; i++)
14605 operands[i] = gen_reg_rtx (XFmode);
14607 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14610 (define_expand "expxf2"
14611 [(use (match_operand:XF 0 "register_operand"))
14612 (use (match_operand:XF 1 "register_operand"))]
14613 "TARGET_USE_FANCY_MATH_387
14614 && flag_unsafe_math_optimizations"
14618 if (optimize_insn_for_size_p ())
14621 op2 = gen_reg_rtx (XFmode);
14622 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14624 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14628 (define_expand "exp<mode>2"
14629 [(use (match_operand:MODEF 0 "register_operand"))
14630 (use (match_operand:MODEF 1 "general_operand"))]
14631 "TARGET_USE_FANCY_MATH_387
14632 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14633 || TARGET_MIX_SSE_I387)
14634 && flag_unsafe_math_optimizations"
14638 if (optimize_insn_for_size_p ())
14641 op0 = gen_reg_rtx (XFmode);
14642 op1 = gen_reg_rtx (XFmode);
14644 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14645 emit_insn (gen_expxf2 (op0, op1));
14646 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14650 (define_expand "exp10xf2"
14651 [(use (match_operand:XF 0 "register_operand"))
14652 (use (match_operand:XF 1 "register_operand"))]
14653 "TARGET_USE_FANCY_MATH_387
14654 && flag_unsafe_math_optimizations"
14658 if (optimize_insn_for_size_p ())
14661 op2 = gen_reg_rtx (XFmode);
14662 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14664 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14668 (define_expand "exp10<mode>2"
14669 [(use (match_operand:MODEF 0 "register_operand"))
14670 (use (match_operand:MODEF 1 "general_operand"))]
14671 "TARGET_USE_FANCY_MATH_387
14672 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14673 || TARGET_MIX_SSE_I387)
14674 && flag_unsafe_math_optimizations"
14678 if (optimize_insn_for_size_p ())
14681 op0 = gen_reg_rtx (XFmode);
14682 op1 = gen_reg_rtx (XFmode);
14684 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14685 emit_insn (gen_exp10xf2 (op0, op1));
14686 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14690 (define_expand "exp2xf2"
14691 [(use (match_operand:XF 0 "register_operand"))
14692 (use (match_operand:XF 1 "register_operand"))]
14693 "TARGET_USE_FANCY_MATH_387
14694 && flag_unsafe_math_optimizations"
14698 if (optimize_insn_for_size_p ())
14701 op2 = gen_reg_rtx (XFmode);
14702 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14704 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14708 (define_expand "exp2<mode>2"
14709 [(use (match_operand:MODEF 0 "register_operand"))
14710 (use (match_operand:MODEF 1 "general_operand"))]
14711 "TARGET_USE_FANCY_MATH_387
14712 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14713 || TARGET_MIX_SSE_I387)
14714 && flag_unsafe_math_optimizations"
14718 if (optimize_insn_for_size_p ())
14721 op0 = gen_reg_rtx (XFmode);
14722 op1 = gen_reg_rtx (XFmode);
14724 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14725 emit_insn (gen_exp2xf2 (op0, op1));
14726 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14730 (define_expand "expm1xf2"
14731 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14733 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14734 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14735 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14736 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14737 (parallel [(set (match_dup 7)
14738 (unspec:XF [(match_dup 6) (match_dup 4)]
14739 UNSPEC_FSCALE_FRACT))
14741 (unspec:XF [(match_dup 6) (match_dup 4)]
14742 UNSPEC_FSCALE_EXP))])
14743 (parallel [(set (match_dup 10)
14744 (unspec:XF [(match_dup 9) (match_dup 8)]
14745 UNSPEC_FSCALE_FRACT))
14746 (set (match_dup 11)
14747 (unspec:XF [(match_dup 9) (match_dup 8)]
14748 UNSPEC_FSCALE_EXP))])
14749 (set (match_dup 12) (minus:XF (match_dup 10)
14750 (float_extend:XF (match_dup 13))))
14751 (set (match_operand:XF 0 "register_operand")
14752 (plus:XF (match_dup 12) (match_dup 7)))]
14753 "TARGET_USE_FANCY_MATH_387
14754 && flag_unsafe_math_optimizations"
14758 if (optimize_insn_for_size_p ())
14761 for (i = 2; i < 13; i++)
14762 operands[i] = gen_reg_rtx (XFmode);
14765 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14767 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14770 (define_expand "expm1<mode>2"
14771 [(use (match_operand:MODEF 0 "register_operand"))
14772 (use (match_operand:MODEF 1 "general_operand"))]
14773 "TARGET_USE_FANCY_MATH_387
14774 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14775 || TARGET_MIX_SSE_I387)
14776 && flag_unsafe_math_optimizations"
14780 if (optimize_insn_for_size_p ())
14783 op0 = gen_reg_rtx (XFmode);
14784 op1 = gen_reg_rtx (XFmode);
14786 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14787 emit_insn (gen_expm1xf2 (op0, op1));
14788 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14792 (define_expand "ldexpxf3"
14793 [(set (match_dup 3)
14794 (float:XF (match_operand:SI 2 "register_operand")))
14795 (parallel [(set (match_operand:XF 0 " register_operand")
14796 (unspec:XF [(match_operand:XF 1 "register_operand")
14798 UNSPEC_FSCALE_FRACT))
14800 (unspec:XF [(match_dup 1) (match_dup 3)]
14801 UNSPEC_FSCALE_EXP))])]
14802 "TARGET_USE_FANCY_MATH_387
14803 && flag_unsafe_math_optimizations"
14805 if (optimize_insn_for_size_p ())
14808 operands[3] = gen_reg_rtx (XFmode);
14809 operands[4] = gen_reg_rtx (XFmode);
14812 (define_expand "ldexp<mode>3"
14813 [(use (match_operand:MODEF 0 "register_operand"))
14814 (use (match_operand:MODEF 1 "general_operand"))
14815 (use (match_operand:SI 2 "register_operand"))]
14816 "TARGET_USE_FANCY_MATH_387
14817 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14818 || TARGET_MIX_SSE_I387)
14819 && flag_unsafe_math_optimizations"
14823 if (optimize_insn_for_size_p ())
14826 op0 = gen_reg_rtx (XFmode);
14827 op1 = gen_reg_rtx (XFmode);
14829 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14830 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14831 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14835 (define_expand "scalbxf3"
14836 [(parallel [(set (match_operand:XF 0 " register_operand")
14837 (unspec:XF [(match_operand:XF 1 "register_operand")
14838 (match_operand:XF 2 "register_operand")]
14839 UNSPEC_FSCALE_FRACT))
14841 (unspec:XF [(match_dup 1) (match_dup 2)]
14842 UNSPEC_FSCALE_EXP))])]
14843 "TARGET_USE_FANCY_MATH_387
14844 && flag_unsafe_math_optimizations"
14846 if (optimize_insn_for_size_p ())
14849 operands[3] = gen_reg_rtx (XFmode);
14852 (define_expand "scalb<mode>3"
14853 [(use (match_operand:MODEF 0 "register_operand"))
14854 (use (match_operand:MODEF 1 "general_operand"))
14855 (use (match_operand:MODEF 2 "general_operand"))]
14856 "TARGET_USE_FANCY_MATH_387
14857 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14858 || TARGET_MIX_SSE_I387)
14859 && flag_unsafe_math_optimizations"
14863 if (optimize_insn_for_size_p ())
14866 op0 = gen_reg_rtx (XFmode);
14867 op1 = gen_reg_rtx (XFmode);
14868 op2 = gen_reg_rtx (XFmode);
14870 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14871 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14872 emit_insn (gen_scalbxf3 (op0, op1, op2));
14873 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14877 (define_expand "significandxf2"
14878 [(parallel [(set (match_operand:XF 0 "register_operand")
14879 (unspec:XF [(match_operand:XF 1 "register_operand")]
14880 UNSPEC_XTRACT_FRACT))
14882 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14883 "TARGET_USE_FANCY_MATH_387
14884 && flag_unsafe_math_optimizations"
14885 "operands[2] = gen_reg_rtx (XFmode);")
14887 (define_expand "significand<mode>2"
14888 [(use (match_operand:MODEF 0 "register_operand"))
14889 (use (match_operand:MODEF 1 "register_operand"))]
14890 "TARGET_USE_FANCY_MATH_387
14891 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14892 || TARGET_MIX_SSE_I387)
14893 && flag_unsafe_math_optimizations"
14895 rtx op0 = gen_reg_rtx (XFmode);
14896 rtx op1 = gen_reg_rtx (XFmode);
14898 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14899 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14904 (define_insn "sse4_1_round<mode>2"
14905 [(set (match_operand:MODEF 0 "register_operand" "=x")
14906 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14907 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14910 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14911 [(set_attr "type" "ssecvt")
14912 (set_attr "prefix_extra" "1")
14913 (set_attr "prefix" "maybe_vex")
14914 (set_attr "mode" "<MODE>")])
14916 (define_insn "rintxf2"
14917 [(set (match_operand:XF 0 "register_operand" "=f")
14918 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14920 "TARGET_USE_FANCY_MATH_387
14921 && flag_unsafe_math_optimizations"
14923 [(set_attr "type" "fpspc")
14924 (set_attr "mode" "XF")])
14926 (define_expand "rint<mode>2"
14927 [(use (match_operand:MODEF 0 "register_operand"))
14928 (use (match_operand:MODEF 1 "register_operand"))]
14929 "(TARGET_USE_FANCY_MATH_387
14930 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14931 || TARGET_MIX_SSE_I387)
14932 && flag_unsafe_math_optimizations)
14933 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14934 && !flag_trapping_math)"
14936 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14937 && !flag_trapping_math)
14940 emit_insn (gen_sse4_1_round<mode>2
14941 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14942 else if (optimize_insn_for_size_p ())
14945 ix86_expand_rint (operands[0], operands[1]);
14949 rtx op0 = gen_reg_rtx (XFmode);
14950 rtx op1 = gen_reg_rtx (XFmode);
14952 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14953 emit_insn (gen_rintxf2 (op0, op1));
14955 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14960 (define_expand "round<mode>2"
14961 [(match_operand:X87MODEF 0 "register_operand")
14962 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14963 "(TARGET_USE_FANCY_MATH_387
14964 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14965 || TARGET_MIX_SSE_I387)
14966 && flag_unsafe_math_optimizations)
14967 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14968 && !flag_trapping_math && !flag_rounding_math)"
14970 if (optimize_insn_for_size_p ())
14973 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14974 && !flag_trapping_math && !flag_rounding_math)
14978 operands[1] = force_reg (<MODE>mode, operands[1]);
14979 ix86_expand_round_sse4 (operands[0], operands[1]);
14981 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14982 ix86_expand_round (operands[0], operands[1]);
14984 ix86_expand_rounddf_32 (operands[0], operands[1]);
14988 operands[1] = force_reg (<MODE>mode, operands[1]);
14989 ix86_emit_i387_round (operands[0], operands[1]);
14994 (define_insn_and_split "*fistdi2_1"
14995 [(set (match_operand:DI 0 "nonimmediate_operand")
14996 (unspec:DI [(match_operand:XF 1 "register_operand")]
14998 "TARGET_USE_FANCY_MATH_387
14999 && can_create_pseudo_p ()"
15004 if (memory_operand (operands[0], VOIDmode))
15005 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15008 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15009 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15014 [(set_attr "type" "fpspc")
15015 (set_attr "mode" "DI")])
15017 (define_insn "fistdi2"
15018 [(set (match_operand:DI 0 "memory_operand" "=m")
15019 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15021 (clobber (match_scratch:XF 2 "=&1f"))]
15022 "TARGET_USE_FANCY_MATH_387"
15023 "* return output_fix_trunc (insn, operands, false);"
15024 [(set_attr "type" "fpspc")
15025 (set_attr "mode" "DI")])
15027 (define_insn "fistdi2_with_temp"
15028 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15029 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15031 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15032 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15033 "TARGET_USE_FANCY_MATH_387"
15035 [(set_attr "type" "fpspc")
15036 (set_attr "mode" "DI")])
15039 [(set (match_operand:DI 0 "register_operand")
15040 (unspec:DI [(match_operand:XF 1 "register_operand")]
15042 (clobber (match_operand:DI 2 "memory_operand"))
15043 (clobber (match_scratch 3))]
15045 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15046 (clobber (match_dup 3))])
15047 (set (match_dup 0) (match_dup 2))])
15050 [(set (match_operand:DI 0 "memory_operand")
15051 (unspec:DI [(match_operand:XF 1 "register_operand")]
15053 (clobber (match_operand:DI 2 "memory_operand"))
15054 (clobber (match_scratch 3))]
15056 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15057 (clobber (match_dup 3))])])
15059 (define_insn_and_split "*fist<mode>2_1"
15060 [(set (match_operand:SWI24 0 "register_operand")
15061 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15063 "TARGET_USE_FANCY_MATH_387
15064 && can_create_pseudo_p ()"
15069 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15070 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15074 [(set_attr "type" "fpspc")
15075 (set_attr "mode" "<MODE>")])
15077 (define_insn "fist<mode>2"
15078 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15079 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15081 "TARGET_USE_FANCY_MATH_387"
15082 "* return output_fix_trunc (insn, operands, false);"
15083 [(set_attr "type" "fpspc")
15084 (set_attr "mode" "<MODE>")])
15086 (define_insn "fist<mode>2_with_temp"
15087 [(set (match_operand:SWI24 0 "register_operand" "=r")
15088 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15090 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15091 "TARGET_USE_FANCY_MATH_387"
15093 [(set_attr "type" "fpspc")
15094 (set_attr "mode" "<MODE>")])
15097 [(set (match_operand:SWI24 0 "register_operand")
15098 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15100 (clobber (match_operand:SWI24 2 "memory_operand"))]
15102 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15103 (set (match_dup 0) (match_dup 2))])
15106 [(set (match_operand:SWI24 0 "memory_operand")
15107 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15109 (clobber (match_operand:SWI24 2 "memory_operand"))]
15111 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15113 (define_expand "lrintxf<mode>2"
15114 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15115 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15117 "TARGET_USE_FANCY_MATH_387")
15119 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
15120 [(set (match_operand:SWI48x 0 "nonimmediate_operand")
15121 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand")]
15122 UNSPEC_FIX_NOTRUNC))]
15123 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15124 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
15126 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15127 [(match_operand:SWI248x 0 "nonimmediate_operand")
15128 (match_operand:X87MODEF 1 "register_operand")]
15129 "(TARGET_USE_FANCY_MATH_387
15130 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15131 || TARGET_MIX_SSE_I387)
15132 && flag_unsafe_math_optimizations)
15133 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15134 && <SWI248x:MODE>mode != HImode
15135 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15136 && !flag_trapping_math && !flag_rounding_math)"
15138 if (optimize_insn_for_size_p ())
15141 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15142 && <SWI248x:MODE>mode != HImode
15143 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15144 && !flag_trapping_math && !flag_rounding_math)
15145 ix86_expand_lround (operands[0], operands[1]);
15147 ix86_emit_i387_round (operands[0], operands[1]);
15151 (define_int_iterator FRNDINT_ROUNDING
15152 [UNSPEC_FRNDINT_FLOOR
15153 UNSPEC_FRNDINT_CEIL
15154 UNSPEC_FRNDINT_TRUNC])
15156 (define_int_iterator FIST_ROUNDING
15160 ;; Base name for define_insn
15161 (define_int_attr rounding_insn
15162 [(UNSPEC_FRNDINT_FLOOR "floor")
15163 (UNSPEC_FRNDINT_CEIL "ceil")
15164 (UNSPEC_FRNDINT_TRUNC "btrunc")
15165 (UNSPEC_FIST_FLOOR "floor")
15166 (UNSPEC_FIST_CEIL "ceil")])
15168 (define_int_attr rounding
15169 [(UNSPEC_FRNDINT_FLOOR "floor")
15170 (UNSPEC_FRNDINT_CEIL "ceil")
15171 (UNSPEC_FRNDINT_TRUNC "trunc")
15172 (UNSPEC_FIST_FLOOR "floor")
15173 (UNSPEC_FIST_CEIL "ceil")])
15175 (define_int_attr ROUNDING
15176 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15177 (UNSPEC_FRNDINT_CEIL "CEIL")
15178 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15179 (UNSPEC_FIST_FLOOR "FLOOR")
15180 (UNSPEC_FIST_CEIL "CEIL")])
15182 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15183 (define_insn_and_split "frndintxf2_<rounding>"
15184 [(set (match_operand:XF 0 "register_operand")
15185 (unspec:XF [(match_operand:XF 1 "register_operand")]
15187 (clobber (reg:CC FLAGS_REG))]
15188 "TARGET_USE_FANCY_MATH_387
15189 && flag_unsafe_math_optimizations
15190 && can_create_pseudo_p ()"
15195 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15197 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15198 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15200 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15201 operands[2], operands[3]));
15204 [(set_attr "type" "frndint")
15205 (set_attr "i387_cw" "<rounding>")
15206 (set_attr "mode" "XF")])
15208 (define_insn "frndintxf2_<rounding>_i387"
15209 [(set (match_operand:XF 0 "register_operand" "=f")
15210 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15212 (use (match_operand:HI 2 "memory_operand" "m"))
15213 (use (match_operand:HI 3 "memory_operand" "m"))]
15214 "TARGET_USE_FANCY_MATH_387
15215 && flag_unsafe_math_optimizations"
15216 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15217 [(set_attr "type" "frndint")
15218 (set_attr "i387_cw" "<rounding>")
15219 (set_attr "mode" "XF")])
15221 (define_expand "<rounding_insn>xf2"
15222 [(parallel [(set (match_operand:XF 0 "register_operand")
15223 (unspec:XF [(match_operand:XF 1 "register_operand")]
15225 (clobber (reg:CC FLAGS_REG))])]
15226 "TARGET_USE_FANCY_MATH_387
15227 && flag_unsafe_math_optimizations
15228 && !optimize_insn_for_size_p ()")
15230 (define_expand "<rounding_insn><mode>2"
15231 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15232 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15234 (clobber (reg:CC FLAGS_REG))])]
15235 "(TARGET_USE_FANCY_MATH_387
15236 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15237 || TARGET_MIX_SSE_I387)
15238 && flag_unsafe_math_optimizations)
15239 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15240 && !flag_trapping_math)"
15242 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15243 && !flag_trapping_math)
15246 emit_insn (gen_sse4_1_round<mode>2
15247 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15248 else if (optimize_insn_for_size_p ())
15250 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15252 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15253 ix86_expand_floorceil (operands[0], operands[1], true);
15254 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15255 ix86_expand_floorceil (operands[0], operands[1], false);
15256 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15257 ix86_expand_trunc (operands[0], operands[1]);
15259 gcc_unreachable ();
15263 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15264 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15265 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15266 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15267 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15268 ix86_expand_truncdf_32 (operands[0], operands[1]);
15270 gcc_unreachable ();
15277 if (optimize_insn_for_size_p ())
15280 op0 = gen_reg_rtx (XFmode);
15281 op1 = gen_reg_rtx (XFmode);
15282 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15283 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15285 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15290 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15291 (define_insn_and_split "frndintxf2_mask_pm"
15292 [(set (match_operand:XF 0 "register_operand")
15293 (unspec:XF [(match_operand:XF 1 "register_operand")]
15294 UNSPEC_FRNDINT_MASK_PM))
15295 (clobber (reg:CC FLAGS_REG))]
15296 "TARGET_USE_FANCY_MATH_387
15297 && flag_unsafe_math_optimizations
15298 && can_create_pseudo_p ()"
15303 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15305 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15306 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15308 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15309 operands[2], operands[3]));
15312 [(set_attr "type" "frndint")
15313 (set_attr "i387_cw" "mask_pm")
15314 (set_attr "mode" "XF")])
15316 (define_insn "frndintxf2_mask_pm_i387"
15317 [(set (match_operand:XF 0 "register_operand" "=f")
15318 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15319 UNSPEC_FRNDINT_MASK_PM))
15320 (use (match_operand:HI 2 "memory_operand" "m"))
15321 (use (match_operand:HI 3 "memory_operand" "m"))]
15322 "TARGET_USE_FANCY_MATH_387
15323 && flag_unsafe_math_optimizations"
15324 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15325 [(set_attr "type" "frndint")
15326 (set_attr "i387_cw" "mask_pm")
15327 (set_attr "mode" "XF")])
15329 (define_expand "nearbyintxf2"
15330 [(parallel [(set (match_operand:XF 0 "register_operand")
15331 (unspec:XF [(match_operand:XF 1 "register_operand")]
15332 UNSPEC_FRNDINT_MASK_PM))
15333 (clobber (reg:CC FLAGS_REG))])]
15334 "TARGET_USE_FANCY_MATH_387
15335 && flag_unsafe_math_optimizations")
15337 (define_expand "nearbyint<mode>2"
15338 [(use (match_operand:MODEF 0 "register_operand"))
15339 (use (match_operand:MODEF 1 "register_operand"))]
15340 "TARGET_USE_FANCY_MATH_387
15341 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15342 || TARGET_MIX_SSE_I387)
15343 && flag_unsafe_math_optimizations"
15345 rtx op0 = gen_reg_rtx (XFmode);
15346 rtx op1 = gen_reg_rtx (XFmode);
15348 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15349 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15351 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15355 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15356 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15357 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15358 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15360 (clobber (reg:CC FLAGS_REG))]
15361 "TARGET_USE_FANCY_MATH_387
15362 && flag_unsafe_math_optimizations
15363 && can_create_pseudo_p ()"
15368 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15370 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15371 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15372 if (memory_operand (operands[0], VOIDmode))
15373 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15374 operands[2], operands[3]));
15377 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15378 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15379 (operands[0], operands[1], operands[2],
15380 operands[3], operands[4]));
15384 [(set_attr "type" "fistp")
15385 (set_attr "i387_cw" "<rounding>")
15386 (set_attr "mode" "<MODE>")])
15388 (define_insn "fistdi2_<rounding>"
15389 [(set (match_operand:DI 0 "memory_operand" "=m")
15390 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15392 (use (match_operand:HI 2 "memory_operand" "m"))
15393 (use (match_operand:HI 3 "memory_operand" "m"))
15394 (clobber (match_scratch:XF 4 "=&1f"))]
15395 "TARGET_USE_FANCY_MATH_387
15396 && flag_unsafe_math_optimizations"
15397 "* return output_fix_trunc (insn, operands, false);"
15398 [(set_attr "type" "fistp")
15399 (set_attr "i387_cw" "<rounding>")
15400 (set_attr "mode" "DI")])
15402 (define_insn "fistdi2_<rounding>_with_temp"
15403 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15404 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15406 (use (match_operand:HI 2 "memory_operand" "m,m"))
15407 (use (match_operand:HI 3 "memory_operand" "m,m"))
15408 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15409 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15410 "TARGET_USE_FANCY_MATH_387
15411 && flag_unsafe_math_optimizations"
15413 [(set_attr "type" "fistp")
15414 (set_attr "i387_cw" "<rounding>")
15415 (set_attr "mode" "DI")])
15418 [(set (match_operand:DI 0 "register_operand")
15419 (unspec:DI [(match_operand:XF 1 "register_operand")]
15421 (use (match_operand:HI 2 "memory_operand"))
15422 (use (match_operand:HI 3 "memory_operand"))
15423 (clobber (match_operand:DI 4 "memory_operand"))
15424 (clobber (match_scratch 5))]
15426 [(parallel [(set (match_dup 4)
15427 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15428 (use (match_dup 2))
15429 (use (match_dup 3))
15430 (clobber (match_dup 5))])
15431 (set (match_dup 0) (match_dup 4))])
15434 [(set (match_operand:DI 0 "memory_operand")
15435 (unspec:DI [(match_operand:XF 1 "register_operand")]
15437 (use (match_operand:HI 2 "memory_operand"))
15438 (use (match_operand:HI 3 "memory_operand"))
15439 (clobber (match_operand:DI 4 "memory_operand"))
15440 (clobber (match_scratch 5))]
15442 [(parallel [(set (match_dup 0)
15443 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15444 (use (match_dup 2))
15445 (use (match_dup 3))
15446 (clobber (match_dup 5))])])
15448 (define_insn "fist<mode>2_<rounding>"
15449 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15450 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15452 (use (match_operand:HI 2 "memory_operand" "m"))
15453 (use (match_operand:HI 3 "memory_operand" "m"))]
15454 "TARGET_USE_FANCY_MATH_387
15455 && flag_unsafe_math_optimizations"
15456 "* return output_fix_trunc (insn, operands, false);"
15457 [(set_attr "type" "fistp")
15458 (set_attr "i387_cw" "<rounding>")
15459 (set_attr "mode" "<MODE>")])
15461 (define_insn "fist<mode>2_<rounding>_with_temp"
15462 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15463 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15465 (use (match_operand:HI 2 "memory_operand" "m,m"))
15466 (use (match_operand:HI 3 "memory_operand" "m,m"))
15467 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15468 "TARGET_USE_FANCY_MATH_387
15469 && flag_unsafe_math_optimizations"
15471 [(set_attr "type" "fistp")
15472 (set_attr "i387_cw" "<rounding>")
15473 (set_attr "mode" "<MODE>")])
15476 [(set (match_operand:SWI24 0 "register_operand")
15477 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15479 (use (match_operand:HI 2 "memory_operand"))
15480 (use (match_operand:HI 3 "memory_operand"))
15481 (clobber (match_operand:SWI24 4 "memory_operand"))]
15483 [(parallel [(set (match_dup 4)
15484 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15485 (use (match_dup 2))
15486 (use (match_dup 3))])
15487 (set (match_dup 0) (match_dup 4))])
15490 [(set (match_operand:SWI24 0 "memory_operand")
15491 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15493 (use (match_operand:HI 2 "memory_operand"))
15494 (use (match_operand:HI 3 "memory_operand"))
15495 (clobber (match_operand:SWI24 4 "memory_operand"))]
15497 [(parallel [(set (match_dup 0)
15498 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15499 (use (match_dup 2))
15500 (use (match_dup 3))])])
15502 (define_expand "l<rounding_insn>xf<mode>2"
15503 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15504 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15506 (clobber (reg:CC FLAGS_REG))])]
15507 "TARGET_USE_FANCY_MATH_387
15508 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15509 && flag_unsafe_math_optimizations")
15511 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15512 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15513 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15515 (clobber (reg:CC FLAGS_REG))])]
15516 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15517 && !flag_trapping_math"
15519 if (TARGET_64BIT && optimize_insn_for_size_p ())
15522 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15523 ix86_expand_lfloorceil (operands[0], operands[1], true);
15524 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15525 ix86_expand_lfloorceil (operands[0], operands[1], false);
15527 gcc_unreachable ();
15532 (define_insn "fxam<mode>2_i387"
15533 [(set (match_operand:HI 0 "register_operand" "=a")
15535 [(match_operand:X87MODEF 1 "register_operand" "f")]
15537 "TARGET_USE_FANCY_MATH_387"
15538 "fxam\n\tfnstsw\t%0"
15539 [(set_attr "type" "multi")
15540 (set_attr "length" "4")
15541 (set_attr "unit" "i387")
15542 (set_attr "mode" "<MODE>")])
15544 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15545 [(set (match_operand:HI 0 "register_operand")
15547 [(match_operand:MODEF 1 "memory_operand")]
15549 "TARGET_USE_FANCY_MATH_387
15550 && can_create_pseudo_p ()"
15553 [(set (match_dup 2)(match_dup 1))
15555 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15557 operands[2] = gen_reg_rtx (<MODE>mode);
15559 MEM_VOLATILE_P (operands[1]) = 1;
15561 [(set_attr "type" "multi")
15562 (set_attr "unit" "i387")
15563 (set_attr "mode" "<MODE>")])
15565 (define_expand "isinfxf2"
15566 [(use (match_operand:SI 0 "register_operand"))
15567 (use (match_operand:XF 1 "register_operand"))]
15568 "TARGET_USE_FANCY_MATH_387
15569 && TARGET_C99_FUNCTIONS"
15571 rtx mask = GEN_INT (0x45);
15572 rtx val = GEN_INT (0x05);
15576 rtx scratch = gen_reg_rtx (HImode);
15577 rtx res = gen_reg_rtx (QImode);
15579 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15581 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15582 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15583 cond = gen_rtx_fmt_ee (EQ, QImode,
15584 gen_rtx_REG (CCmode, FLAGS_REG),
15586 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15587 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15591 (define_expand "isinf<mode>2"
15592 [(use (match_operand:SI 0 "register_operand"))
15593 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15594 "TARGET_USE_FANCY_MATH_387
15595 && TARGET_C99_FUNCTIONS
15596 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15598 rtx mask = GEN_INT (0x45);
15599 rtx val = GEN_INT (0x05);
15603 rtx scratch = gen_reg_rtx (HImode);
15604 rtx res = gen_reg_rtx (QImode);
15606 /* Remove excess precision by forcing value through memory. */
15607 if (memory_operand (operands[1], VOIDmode))
15608 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15611 enum ix86_stack_slot slot = (virtuals_instantiated
15614 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15616 emit_move_insn (temp, operands[1]);
15617 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15620 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15621 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15622 cond = gen_rtx_fmt_ee (EQ, QImode,
15623 gen_rtx_REG (CCmode, FLAGS_REG),
15625 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15626 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15630 (define_expand "signbitxf2"
15631 [(use (match_operand:SI 0 "register_operand"))
15632 (use (match_operand:XF 1 "register_operand"))]
15633 "TARGET_USE_FANCY_MATH_387"
15635 rtx scratch = gen_reg_rtx (HImode);
15637 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15638 emit_insn (gen_andsi3 (operands[0],
15639 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15643 (define_insn "movmsk_df"
15644 [(set (match_operand:SI 0 "register_operand" "=r")
15646 [(match_operand:DF 1 "register_operand" "x")]
15648 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15649 "%vmovmskpd\t{%1, %0|%0, %1}"
15650 [(set_attr "type" "ssemov")
15651 (set_attr "prefix" "maybe_vex")
15652 (set_attr "mode" "DF")])
15654 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15655 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15656 (define_expand "signbitdf2"
15657 [(use (match_operand:SI 0 "register_operand"))
15658 (use (match_operand:DF 1 "register_operand"))]
15659 "TARGET_USE_FANCY_MATH_387
15660 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15662 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15664 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15665 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15669 rtx scratch = gen_reg_rtx (HImode);
15671 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15672 emit_insn (gen_andsi3 (operands[0],
15673 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15678 (define_expand "signbitsf2"
15679 [(use (match_operand:SI 0 "register_operand"))
15680 (use (match_operand:SF 1 "register_operand"))]
15681 "TARGET_USE_FANCY_MATH_387
15682 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15684 rtx scratch = gen_reg_rtx (HImode);
15686 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15687 emit_insn (gen_andsi3 (operands[0],
15688 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15692 ;; Block operation instructions
15695 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15698 [(set_attr "length" "1")
15699 (set_attr "length_immediate" "0")
15700 (set_attr "modrm" "0")])
15702 (define_expand "movmem<mode>"
15703 [(use (match_operand:BLK 0 "memory_operand"))
15704 (use (match_operand:BLK 1 "memory_operand"))
15705 (use (match_operand:SWI48 2 "nonmemory_operand"))
15706 (use (match_operand:SWI48 3 "const_int_operand"))
15707 (use (match_operand:SI 4 "const_int_operand"))
15708 (use (match_operand:SI 5 "const_int_operand"))]
15711 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15712 operands[4], operands[5]))
15718 ;; Most CPUs don't like single string operations
15719 ;; Handle this case here to simplify previous expander.
15721 (define_expand "strmov"
15722 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15723 (set (match_operand 1 "memory_operand") (match_dup 4))
15724 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15725 (clobber (reg:CC FLAGS_REG))])
15726 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15727 (clobber (reg:CC FLAGS_REG))])]
15730 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15732 /* If .md ever supports :P for Pmode, these can be directly
15733 in the pattern above. */
15734 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15735 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15737 /* Can't use this if the user has appropriated esi or edi. */
15738 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15739 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15741 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15742 operands[2], operands[3],
15743 operands[5], operands[6]));
15747 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15750 (define_expand "strmov_singleop"
15751 [(parallel [(set (match_operand 1 "memory_operand")
15752 (match_operand 3 "memory_operand"))
15753 (set (match_operand 0 "register_operand")
15755 (set (match_operand 2 "register_operand")
15756 (match_operand 5))])]
15758 "ix86_current_function_needs_cld = 1;")
15760 (define_insn "*strmovdi_rex_1"
15761 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15762 (mem:DI (match_operand:P 3 "register_operand" "1")))
15763 (set (match_operand:P 0 "register_operand" "=D")
15764 (plus:P (match_dup 2)
15766 (set (match_operand:P 1 "register_operand" "=S")
15767 (plus:P (match_dup 3)
15770 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15772 [(set_attr "type" "str")
15773 (set_attr "memory" "both")
15774 (set_attr "mode" "DI")])
15776 (define_insn "*strmovsi_1"
15777 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15778 (mem:SI (match_operand:P 3 "register_operand" "1")))
15779 (set (match_operand:P 0 "register_operand" "=D")
15780 (plus:P (match_dup 2)
15782 (set (match_operand:P 1 "register_operand" "=S")
15783 (plus:P (match_dup 3)
15785 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15787 [(set_attr "type" "str")
15788 (set_attr "memory" "both")
15789 (set_attr "mode" "SI")])
15791 (define_insn "*strmovhi_1"
15792 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15793 (mem:HI (match_operand:P 3 "register_operand" "1")))
15794 (set (match_operand:P 0 "register_operand" "=D")
15795 (plus:P (match_dup 2)
15797 (set (match_operand:P 1 "register_operand" "=S")
15798 (plus:P (match_dup 3)
15800 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15802 [(set_attr "type" "str")
15803 (set_attr "memory" "both")
15804 (set_attr "mode" "HI")])
15806 (define_insn "*strmovqi_1"
15807 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15808 (mem:QI (match_operand:P 3 "register_operand" "1")))
15809 (set (match_operand:P 0 "register_operand" "=D")
15810 (plus:P (match_dup 2)
15812 (set (match_operand:P 1 "register_operand" "=S")
15813 (plus:P (match_dup 3)
15815 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15817 [(set_attr "type" "str")
15818 (set_attr "memory" "both")
15819 (set (attr "prefix_rex")
15821 (match_test "<P:MODE>mode == DImode")
15823 (const_string "*")))
15824 (set_attr "mode" "QI")])
15826 (define_expand "rep_mov"
15827 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15828 (set (match_operand 0 "register_operand")
15830 (set (match_operand 2 "register_operand")
15832 (set (match_operand 1 "memory_operand")
15833 (match_operand 3 "memory_operand"))
15834 (use (match_dup 4))])]
15836 "ix86_current_function_needs_cld = 1;")
15838 (define_insn "*rep_movdi_rex64"
15839 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15840 (set (match_operand:P 0 "register_operand" "=D")
15841 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15843 (match_operand:P 3 "register_operand" "0")))
15844 (set (match_operand:P 1 "register_operand" "=S")
15845 (plus:P (ashift:P (match_dup 5) (const_int 3))
15846 (match_operand:P 4 "register_operand" "1")))
15847 (set (mem:BLK (match_dup 3))
15848 (mem:BLK (match_dup 4)))
15849 (use (match_dup 5))]
15851 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15853 [(set_attr "type" "str")
15854 (set_attr "prefix_rep" "1")
15855 (set_attr "memory" "both")
15856 (set_attr "mode" "DI")])
15858 (define_insn "*rep_movsi"
15859 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15860 (set (match_operand:P 0 "register_operand" "=D")
15861 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15863 (match_operand:P 3 "register_operand" "0")))
15864 (set (match_operand:P 1 "register_operand" "=S")
15865 (plus:P (ashift:P (match_dup 5) (const_int 2))
15866 (match_operand:P 4 "register_operand" "1")))
15867 (set (mem:BLK (match_dup 3))
15868 (mem:BLK (match_dup 4)))
15869 (use (match_dup 5))]
15870 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15871 "%^rep{%;} movs{l|d}"
15872 [(set_attr "type" "str")
15873 (set_attr "prefix_rep" "1")
15874 (set_attr "memory" "both")
15875 (set_attr "mode" "SI")])
15877 (define_insn "*rep_movqi"
15878 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15879 (set (match_operand:P 0 "register_operand" "=D")
15880 (plus:P (match_operand:P 3 "register_operand" "0")
15881 (match_operand:P 5 "register_operand" "2")))
15882 (set (match_operand:P 1 "register_operand" "=S")
15883 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15884 (set (mem:BLK (match_dup 3))
15885 (mem:BLK (match_dup 4)))
15886 (use (match_dup 5))]
15887 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15889 [(set_attr "type" "str")
15890 (set_attr "prefix_rep" "1")
15891 (set_attr "memory" "both")
15892 (set_attr "mode" "QI")])
15894 (define_expand "setmem<mode>"
15895 [(use (match_operand:BLK 0 "memory_operand"))
15896 (use (match_operand:SWI48 1 "nonmemory_operand"))
15897 (use (match_operand:QI 2 "nonmemory_operand"))
15898 (use (match_operand 3 "const_int_operand"))
15899 (use (match_operand:SI 4 "const_int_operand"))
15900 (use (match_operand:SI 5 "const_int_operand"))]
15903 if (ix86_expand_setmem (operands[0], operands[1],
15904 operands[2], operands[3],
15905 operands[4], operands[5]))
15911 ;; Most CPUs don't like single string operations
15912 ;; Handle this case here to simplify previous expander.
15914 (define_expand "strset"
15915 [(set (match_operand 1 "memory_operand")
15916 (match_operand 2 "register_operand"))
15917 (parallel [(set (match_operand 0 "register_operand")
15919 (clobber (reg:CC FLAGS_REG))])]
15922 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15923 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15925 /* If .md ever supports :P for Pmode, this can be directly
15926 in the pattern above. */
15927 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15928 GEN_INT (GET_MODE_SIZE (GET_MODE
15930 /* Can't use this if the user has appropriated eax or edi. */
15931 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15932 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15934 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15940 (define_expand "strset_singleop"
15941 [(parallel [(set (match_operand 1 "memory_operand")
15942 (match_operand 2 "register_operand"))
15943 (set (match_operand 0 "register_operand")
15944 (match_operand 3))])]
15946 "ix86_current_function_needs_cld = 1;")
15948 (define_insn "*strsetdi_rex_1"
15949 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15950 (match_operand:DI 2 "register_operand" "a"))
15951 (set (match_operand:P 0 "register_operand" "=D")
15952 (plus:P (match_dup 1)
15955 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15957 [(set_attr "type" "str")
15958 (set_attr "memory" "store")
15959 (set_attr "mode" "DI")])
15961 (define_insn "*strsetsi_1"
15962 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15963 (match_operand:SI 2 "register_operand" "a"))
15964 (set (match_operand:P 0 "register_operand" "=D")
15965 (plus:P (match_dup 1)
15967 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15969 [(set_attr "type" "str")
15970 (set_attr "memory" "store")
15971 (set_attr "mode" "SI")])
15973 (define_insn "*strsethi_1"
15974 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15975 (match_operand:HI 2 "register_operand" "a"))
15976 (set (match_operand:P 0 "register_operand" "=D")
15977 (plus:P (match_dup 1)
15979 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15981 [(set_attr "type" "str")
15982 (set_attr "memory" "store")
15983 (set_attr "mode" "HI")])
15985 (define_insn "*strsetqi_1"
15986 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15987 (match_operand:QI 2 "register_operand" "a"))
15988 (set (match_operand:P 0 "register_operand" "=D")
15989 (plus:P (match_dup 1)
15991 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15993 [(set_attr "type" "str")
15994 (set_attr "memory" "store")
15995 (set (attr "prefix_rex")
15997 (match_test "<P:MODE>mode == DImode")
15999 (const_string "*")))
16000 (set_attr "mode" "QI")])
16002 (define_expand "rep_stos"
16003 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16004 (set (match_operand 0 "register_operand")
16006 (set (match_operand 2 "memory_operand") (const_int 0))
16007 (use (match_operand 3 "register_operand"))
16008 (use (match_dup 1))])]
16010 "ix86_current_function_needs_cld = 1;")
16012 (define_insn "*rep_stosdi_rex64"
16013 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16014 (set (match_operand:P 0 "register_operand" "=D")
16015 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16017 (match_operand:P 3 "register_operand" "0")))
16018 (set (mem:BLK (match_dup 3))
16020 (use (match_operand:DI 2 "register_operand" "a"))
16021 (use (match_dup 4))]
16023 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16025 [(set_attr "type" "str")
16026 (set_attr "prefix_rep" "1")
16027 (set_attr "memory" "store")
16028 (set_attr "mode" "DI")])
16030 (define_insn "*rep_stossi"
16031 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16032 (set (match_operand:P 0 "register_operand" "=D")
16033 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16035 (match_operand:P 3 "register_operand" "0")))
16036 (set (mem:BLK (match_dup 3))
16038 (use (match_operand:SI 2 "register_operand" "a"))
16039 (use (match_dup 4))]
16040 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16041 "%^rep{%;} stos{l|d}"
16042 [(set_attr "type" "str")
16043 (set_attr "prefix_rep" "1")
16044 (set_attr "memory" "store")
16045 (set_attr "mode" "SI")])
16047 (define_insn "*rep_stosqi"
16048 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16049 (set (match_operand:P 0 "register_operand" "=D")
16050 (plus:P (match_operand:P 3 "register_operand" "0")
16051 (match_operand:P 4 "register_operand" "1")))
16052 (set (mem:BLK (match_dup 3))
16054 (use (match_operand:QI 2 "register_operand" "a"))
16055 (use (match_dup 4))]
16056 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16058 [(set_attr "type" "str")
16059 (set_attr "prefix_rep" "1")
16060 (set_attr "memory" "store")
16061 (set (attr "prefix_rex")
16063 (match_test "<P:MODE>mode == DImode")
16065 (const_string "*")))
16066 (set_attr "mode" "QI")])
16068 (define_expand "cmpstrnsi"
16069 [(set (match_operand:SI 0 "register_operand")
16070 (compare:SI (match_operand:BLK 1 "general_operand")
16071 (match_operand:BLK 2 "general_operand")))
16072 (use (match_operand 3 "general_operand"))
16073 (use (match_operand 4 "immediate_operand"))]
16076 rtx addr1, addr2, out, outlow, count, countreg, align;
16078 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16081 /* Can't use this if the user has appropriated ecx, esi or edi. */
16082 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16087 out = gen_reg_rtx (SImode);
16089 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16090 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16091 if (addr1 != XEXP (operands[1], 0))
16092 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16093 if (addr2 != XEXP (operands[2], 0))
16094 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16096 count = operands[3];
16097 countreg = ix86_zero_extend_to_Pmode (count);
16099 /* %%% Iff we are testing strict equality, we can use known alignment
16100 to good advantage. This may be possible with combine, particularly
16101 once cc0 is dead. */
16102 align = operands[4];
16104 if (CONST_INT_P (count))
16106 if (INTVAL (count) == 0)
16108 emit_move_insn (operands[0], const0_rtx);
16111 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16112 operands[1], operands[2]));
16116 rtx (*gen_cmp) (rtx, rtx);
16118 gen_cmp = (TARGET_64BIT
16119 ? gen_cmpdi_1 : gen_cmpsi_1);
16121 emit_insn (gen_cmp (countreg, countreg));
16122 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16123 operands[1], operands[2]));
16126 outlow = gen_lowpart (QImode, out);
16127 emit_insn (gen_cmpintqi (outlow));
16128 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16130 if (operands[0] != out)
16131 emit_move_insn (operands[0], out);
16136 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16138 (define_expand "cmpintqi"
16139 [(set (match_dup 1)
16140 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16142 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16143 (parallel [(set (match_operand:QI 0 "register_operand")
16144 (minus:QI (match_dup 1)
16146 (clobber (reg:CC FLAGS_REG))])]
16149 operands[1] = gen_reg_rtx (QImode);
16150 operands[2] = gen_reg_rtx (QImode);
16153 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16154 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16156 (define_expand "cmpstrnqi_nz_1"
16157 [(parallel [(set (reg:CC FLAGS_REG)
16158 (compare:CC (match_operand 4 "memory_operand")
16159 (match_operand 5 "memory_operand")))
16160 (use (match_operand 2 "register_operand"))
16161 (use (match_operand:SI 3 "immediate_operand"))
16162 (clobber (match_operand 0 "register_operand"))
16163 (clobber (match_operand 1 "register_operand"))
16164 (clobber (match_dup 2))])]
16166 "ix86_current_function_needs_cld = 1;")
16168 (define_insn "*cmpstrnqi_nz_1"
16169 [(set (reg:CC FLAGS_REG)
16170 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16171 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16172 (use (match_operand:P 6 "register_operand" "2"))
16173 (use (match_operand:SI 3 "immediate_operand" "i"))
16174 (clobber (match_operand:P 0 "register_operand" "=S"))
16175 (clobber (match_operand:P 1 "register_operand" "=D"))
16176 (clobber (match_operand:P 2 "register_operand" "=c"))]
16177 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16179 [(set_attr "type" "str")
16180 (set_attr "mode" "QI")
16181 (set (attr "prefix_rex")
16183 (match_test "<P:MODE>mode == DImode")
16185 (const_string "*")))
16186 (set_attr "prefix_rep" "1")])
16188 ;; The same, but the count is not known to not be zero.
16190 (define_expand "cmpstrnqi_1"
16191 [(parallel [(set (reg:CC FLAGS_REG)
16192 (if_then_else:CC (ne (match_operand 2 "register_operand")
16194 (compare:CC (match_operand 4 "memory_operand")
16195 (match_operand 5 "memory_operand"))
16197 (use (match_operand:SI 3 "immediate_operand"))
16198 (use (reg:CC FLAGS_REG))
16199 (clobber (match_operand 0 "register_operand"))
16200 (clobber (match_operand 1 "register_operand"))
16201 (clobber (match_dup 2))])]
16203 "ix86_current_function_needs_cld = 1;")
16205 (define_insn "*cmpstrnqi_1"
16206 [(set (reg:CC FLAGS_REG)
16207 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16209 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16210 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16212 (use (match_operand:SI 3 "immediate_operand" "i"))
16213 (use (reg:CC FLAGS_REG))
16214 (clobber (match_operand:P 0 "register_operand" "=S"))
16215 (clobber (match_operand:P 1 "register_operand" "=D"))
16216 (clobber (match_operand:P 2 "register_operand" "=c"))]
16217 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16219 [(set_attr "type" "str")
16220 (set_attr "mode" "QI")
16221 (set (attr "prefix_rex")
16223 (match_test "<P:MODE>mode == DImode")
16225 (const_string "*")))
16226 (set_attr "prefix_rep" "1")])
16228 (define_expand "strlen<mode>"
16229 [(set (match_operand:P 0 "register_operand")
16230 (unspec:P [(match_operand:BLK 1 "general_operand")
16231 (match_operand:QI 2 "immediate_operand")
16232 (match_operand 3 "immediate_operand")]
16236 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16242 (define_expand "strlenqi_1"
16243 [(parallel [(set (match_operand 0 "register_operand")
16245 (clobber (match_operand 1 "register_operand"))
16246 (clobber (reg:CC FLAGS_REG))])]
16248 "ix86_current_function_needs_cld = 1;")
16250 (define_insn "*strlenqi_1"
16251 [(set (match_operand:P 0 "register_operand" "=&c")
16252 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16253 (match_operand:QI 2 "register_operand" "a")
16254 (match_operand:P 3 "immediate_operand" "i")
16255 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16256 (clobber (match_operand:P 1 "register_operand" "=D"))
16257 (clobber (reg:CC FLAGS_REG))]
16258 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16259 "%^repnz{%;} scasb"
16260 [(set_attr "type" "str")
16261 (set_attr "mode" "QI")
16262 (set (attr "prefix_rex")
16264 (match_test "<P:MODE>mode == DImode")
16266 (const_string "*")))
16267 (set_attr "prefix_rep" "1")])
16269 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16270 ;; handled in combine, but it is not currently up to the task.
16271 ;; When used for their truth value, the cmpstrn* expanders generate
16280 ;; The intermediate three instructions are unnecessary.
16282 ;; This one handles cmpstrn*_nz_1...
16285 (set (reg:CC FLAGS_REG)
16286 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16287 (mem:BLK (match_operand 5 "register_operand"))))
16288 (use (match_operand 6 "register_operand"))
16289 (use (match_operand:SI 3 "immediate_operand"))
16290 (clobber (match_operand 0 "register_operand"))
16291 (clobber (match_operand 1 "register_operand"))
16292 (clobber (match_operand 2 "register_operand"))])
16293 (set (match_operand:QI 7 "register_operand")
16294 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16295 (set (match_operand:QI 8 "register_operand")
16296 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16297 (set (reg FLAGS_REG)
16298 (compare (match_dup 7) (match_dup 8)))
16300 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16302 (set (reg:CC FLAGS_REG)
16303 (compare:CC (mem:BLK (match_dup 4))
16304 (mem:BLK (match_dup 5))))
16305 (use (match_dup 6))
16306 (use (match_dup 3))
16307 (clobber (match_dup 0))
16308 (clobber (match_dup 1))
16309 (clobber (match_dup 2))])])
16311 ;; ...and this one handles cmpstrn*_1.
16314 (set (reg:CC FLAGS_REG)
16315 (if_then_else:CC (ne (match_operand 6 "register_operand")
16317 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16318 (mem:BLK (match_operand 5 "register_operand")))
16320 (use (match_operand:SI 3 "immediate_operand"))
16321 (use (reg:CC FLAGS_REG))
16322 (clobber (match_operand 0 "register_operand"))
16323 (clobber (match_operand 1 "register_operand"))
16324 (clobber (match_operand 2 "register_operand"))])
16325 (set (match_operand:QI 7 "register_operand")
16326 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16327 (set (match_operand:QI 8 "register_operand")
16328 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16329 (set (reg FLAGS_REG)
16330 (compare (match_dup 7) (match_dup 8)))
16332 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16334 (set (reg:CC FLAGS_REG)
16335 (if_then_else:CC (ne (match_dup 6)
16337 (compare:CC (mem:BLK (match_dup 4))
16338 (mem:BLK (match_dup 5)))
16340 (use (match_dup 3))
16341 (use (reg:CC FLAGS_REG))
16342 (clobber (match_dup 0))
16343 (clobber (match_dup 1))
16344 (clobber (match_dup 2))])])
16346 ;; Conditional move instructions.
16348 (define_expand "mov<mode>cc"
16349 [(set (match_operand:SWIM 0 "register_operand")
16350 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator")
16351 (match_operand:SWIM 2 "<general_operand>")
16352 (match_operand:SWIM 3 "<general_operand>")))]
16354 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16356 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16357 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16358 ;; So just document what we're doing explicitly.
16360 (define_expand "x86_mov<mode>cc_0_m1"
16362 [(set (match_operand:SWI48 0 "register_operand")
16363 (if_then_else:SWI48
16364 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16365 [(match_operand 1 "flags_reg_operand")
16369 (clobber (reg:CC FLAGS_REG))])])
16371 (define_insn "*x86_mov<mode>cc_0_m1"
16372 [(set (match_operand:SWI48 0 "register_operand" "=r")
16373 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16374 [(reg FLAGS_REG) (const_int 0)])
16377 (clobber (reg:CC FLAGS_REG))]
16379 "sbb{<imodesuffix>}\t%0, %0"
16380 ; Since we don't have the proper number of operands for an alu insn,
16381 ; fill in all the blanks.
16382 [(set_attr "type" "alu")
16383 (set_attr "use_carry" "1")
16384 (set_attr "pent_pair" "pu")
16385 (set_attr "memory" "none")
16386 (set_attr "imm_disp" "false")
16387 (set_attr "mode" "<MODE>")
16388 (set_attr "length_immediate" "0")])
16390 (define_insn "*x86_mov<mode>cc_0_m1_se"
16391 [(set (match_operand:SWI48 0 "register_operand" "=r")
16392 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16393 [(reg FLAGS_REG) (const_int 0)])
16396 (clobber (reg:CC FLAGS_REG))]
16398 "sbb{<imodesuffix>}\t%0, %0"
16399 [(set_attr "type" "alu")
16400 (set_attr "use_carry" "1")
16401 (set_attr "pent_pair" "pu")
16402 (set_attr "memory" "none")
16403 (set_attr "imm_disp" "false")
16404 (set_attr "mode" "<MODE>")
16405 (set_attr "length_immediate" "0")])
16407 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16408 [(set (match_operand:SWI48 0 "register_operand" "=r")
16409 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16410 [(reg FLAGS_REG) (const_int 0)])))
16411 (clobber (reg:CC FLAGS_REG))]
16413 "sbb{<imodesuffix>}\t%0, %0"
16414 [(set_attr "type" "alu")
16415 (set_attr "use_carry" "1")
16416 (set_attr "pent_pair" "pu")
16417 (set_attr "memory" "none")
16418 (set_attr "imm_disp" "false")
16419 (set_attr "mode" "<MODE>")
16420 (set_attr "length_immediate" "0")])
16422 (define_insn "*mov<mode>cc_noc"
16423 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16424 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16425 [(reg FLAGS_REG) (const_int 0)])
16426 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16427 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16428 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16430 cmov%O2%C1\t{%2, %0|%0, %2}
16431 cmov%O2%c1\t{%3, %0|%0, %3}"
16432 [(set_attr "type" "icmov")
16433 (set_attr "mode" "<MODE>")])
16435 (define_insn "*movqicc_noc"
16436 [(set (match_operand:QI 0 "register_operand" "=r,r")
16437 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16438 [(reg FLAGS_REG) (const_int 0)])
16439 (match_operand:QI 2 "register_operand" "r,0")
16440 (match_operand:QI 3 "register_operand" "0,r")))]
16441 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16443 [(set_attr "type" "icmov")
16444 (set_attr "mode" "QI")])
16447 [(set (match_operand 0 "register_operand")
16448 (if_then_else (match_operator 1 "ix86_comparison_operator"
16449 [(reg FLAGS_REG) (const_int 0)])
16450 (match_operand 2 "register_operand")
16451 (match_operand 3 "register_operand")))]
16452 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16453 && (GET_MODE (operands[0]) == QImode
16454 || GET_MODE (operands[0]) == HImode)
16455 && reload_completed"
16456 [(set (match_dup 0)
16457 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16459 operands[0] = gen_lowpart (SImode, operands[0]);
16460 operands[2] = gen_lowpart (SImode, operands[2]);
16461 operands[3] = gen_lowpart (SImode, operands[3]);
16464 (define_expand "mov<mode>cc"
16465 [(set (match_operand:X87MODEF 0 "register_operand")
16466 (if_then_else:X87MODEF
16467 (match_operand 1 "ix86_fp_comparison_operator")
16468 (match_operand:X87MODEF 2 "register_operand")
16469 (match_operand:X87MODEF 3 "register_operand")))]
16470 "(TARGET_80387 && TARGET_CMOVE)
16471 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16472 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16474 (define_insn "*movxfcc_1"
16475 [(set (match_operand:XF 0 "register_operand" "=f,f")
16476 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16477 [(reg FLAGS_REG) (const_int 0)])
16478 (match_operand:XF 2 "register_operand" "f,0")
16479 (match_operand:XF 3 "register_operand" "0,f")))]
16480 "TARGET_80387 && TARGET_CMOVE"
16482 fcmov%F1\t{%2, %0|%0, %2}
16483 fcmov%f1\t{%3, %0|%0, %3}"
16484 [(set_attr "type" "fcmov")
16485 (set_attr "mode" "XF")])
16487 (define_insn "*movdfcc_1_rex64"
16488 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16489 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16490 [(reg FLAGS_REG) (const_int 0)])
16491 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16492 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16493 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16494 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16496 fcmov%F1\t{%2, %0|%0, %2}
16497 fcmov%f1\t{%3, %0|%0, %3}
16498 cmov%O2%C1\t{%2, %0|%0, %2}
16499 cmov%O2%c1\t{%3, %0|%0, %3}"
16500 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16501 (set_attr "mode" "DF,DF,DI,DI")])
16503 (define_insn "*movdfcc_1"
16504 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16505 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16506 [(reg FLAGS_REG) (const_int 0)])
16507 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16508 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16509 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16510 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16512 fcmov%F1\t{%2, %0|%0, %2}
16513 fcmov%f1\t{%3, %0|%0, %3}
16516 [(set_attr "type" "fcmov,fcmov,multi,multi")
16517 (set_attr "mode" "DF,DF,DI,DI")])
16520 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16521 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16522 [(reg FLAGS_REG) (const_int 0)])
16523 (match_operand:DF 2 "nonimmediate_operand")
16524 (match_operand:DF 3 "nonimmediate_operand")))]
16525 "!TARGET_64BIT && reload_completed"
16526 [(set (match_dup 2)
16527 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16529 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16531 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16532 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16535 (define_insn "*movsfcc_1_387"
16536 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16537 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16538 [(reg FLAGS_REG) (const_int 0)])
16539 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16540 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16541 "TARGET_80387 && TARGET_CMOVE
16542 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16544 fcmov%F1\t{%2, %0|%0, %2}
16545 fcmov%f1\t{%3, %0|%0, %3}
16546 cmov%O2%C1\t{%2, %0|%0, %2}
16547 cmov%O2%c1\t{%3, %0|%0, %3}"
16548 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16549 (set_attr "mode" "SF,SF,SI,SI")])
16551 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16552 ;; the scalar versions to have only XMM registers as operands.
16554 ;; XOP conditional move
16555 (define_insn "*xop_pcmov_<mode>"
16556 [(set (match_operand:MODEF 0 "register_operand" "=x")
16557 (if_then_else:MODEF
16558 (match_operand:MODEF 1 "register_operand" "x")
16559 (match_operand:MODEF 2 "register_operand" "x")
16560 (match_operand:MODEF 3 "register_operand" "x")))]
16562 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16563 [(set_attr "type" "sse4arg")])
16565 ;; These versions of the min/max patterns are intentionally ignorant of
16566 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16567 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16568 ;; are undefined in this condition, we're certain this is correct.
16570 (define_insn "<code><mode>3"
16571 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16573 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16574 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16575 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16577 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16578 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16579 [(set_attr "isa" "noavx,avx")
16580 (set_attr "prefix" "orig,vex")
16581 (set_attr "type" "sseadd")
16582 (set_attr "mode" "<MODE>")])
16584 ;; These versions of the min/max patterns implement exactly the operations
16585 ;; min = (op1 < op2 ? op1 : op2)
16586 ;; max = (!(op1 < op2) ? op1 : op2)
16587 ;; Their operands are not commutative, and thus they may be used in the
16588 ;; presence of -0.0 and NaN.
16590 (define_int_iterator IEEE_MAXMIN
16594 (define_int_attr ieee_maxmin
16595 [(UNSPEC_IEEE_MAX "max")
16596 (UNSPEC_IEEE_MIN "min")])
16598 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16599 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16601 [(match_operand:MODEF 1 "register_operand" "0,x")
16602 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16604 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16606 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16607 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16608 [(set_attr "isa" "noavx,avx")
16609 (set_attr "prefix" "orig,vex")
16610 (set_attr "type" "sseadd")
16611 (set_attr "mode" "<MODE>")])
16613 ;; Make two stack loads independent:
16615 ;; fld %st(0) -> fld bb
16616 ;; fmul bb fmul %st(1), %st
16618 ;; Actually we only match the last two instructions for simplicity.
16620 [(set (match_operand 0 "fp_register_operand")
16621 (match_operand 1 "fp_register_operand"))
16623 (match_operator 2 "binary_fp_operator"
16625 (match_operand 3 "memory_operand")]))]
16626 "REGNO (operands[0]) != REGNO (operands[1])"
16627 [(set (match_dup 0) (match_dup 3))
16628 (set (match_dup 0) (match_dup 4))]
16630 ;; The % modifier is not operational anymore in peephole2's, so we have to
16631 ;; swap the operands manually in the case of addition and multiplication.
16635 if (COMMUTATIVE_ARITH_P (operands[2]))
16636 op0 = operands[0], op1 = operands[1];
16638 op0 = operands[1], op1 = operands[0];
16640 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16641 GET_MODE (operands[2]),
16645 ;; Conditional addition patterns
16646 (define_expand "add<mode>cc"
16647 [(match_operand:SWI 0 "register_operand")
16648 (match_operand 1 "ordered_comparison_operator")
16649 (match_operand:SWI 2 "register_operand")
16650 (match_operand:SWI 3 "const_int_operand")]
16652 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16654 ;; Misc patterns (?)
16656 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16657 ;; Otherwise there will be nothing to keep
16659 ;; [(set (reg ebp) (reg esp))]
16660 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16661 ;; (clobber (eflags)]
16662 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16664 ;; in proper program order.
16666 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16667 [(set (match_operand:P 0 "register_operand" "=r,r")
16668 (plus:P (match_operand:P 1 "register_operand" "0,r")
16669 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16670 (clobber (reg:CC FLAGS_REG))
16671 (clobber (mem:BLK (scratch)))]
16674 switch (get_attr_type (insn))
16677 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16680 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16681 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16682 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16684 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16687 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16688 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16691 [(set (attr "type")
16692 (cond [(and (eq_attr "alternative" "0")
16693 (not (match_test "TARGET_OPT_AGU")))
16694 (const_string "alu")
16695 (match_operand:<MODE> 2 "const0_operand")
16696 (const_string "imov")
16698 (const_string "lea")))
16699 (set (attr "length_immediate")
16700 (cond [(eq_attr "type" "imov")
16702 (and (eq_attr "type" "alu")
16703 (match_operand 2 "const128_operand"))
16706 (const_string "*")))
16707 (set_attr "mode" "<MODE>")])
16709 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16710 [(set (match_operand:P 0 "register_operand" "=r")
16711 (minus:P (match_operand:P 1 "register_operand" "0")
16712 (match_operand:P 2 "register_operand" "r")))
16713 (clobber (reg:CC FLAGS_REG))
16714 (clobber (mem:BLK (scratch)))]
16716 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16717 [(set_attr "type" "alu")
16718 (set_attr "mode" "<MODE>")])
16720 (define_insn "allocate_stack_worker_probe_<mode>"
16721 [(set (match_operand:P 0 "register_operand" "=a")
16722 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16723 UNSPECV_STACK_PROBE))
16724 (clobber (reg:CC FLAGS_REG))]
16725 "ix86_target_stack_probe ()"
16726 "call\t___chkstk_ms"
16727 [(set_attr "type" "multi")
16728 (set_attr "length" "5")])
16730 (define_expand "allocate_stack"
16731 [(match_operand 0 "register_operand")
16732 (match_operand 1 "general_operand")]
16733 "ix86_target_stack_probe ()"
16737 #ifndef CHECK_STACK_LIMIT
16738 #define CHECK_STACK_LIMIT 0
16741 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16742 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16746 rtx (*insn) (rtx, rtx);
16748 x = copy_to_mode_reg (Pmode, operands[1]);
16750 insn = (TARGET_64BIT
16751 ? gen_allocate_stack_worker_probe_di
16752 : gen_allocate_stack_worker_probe_si);
16754 emit_insn (insn (x, x));
16757 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16758 stack_pointer_rtx, 0, OPTAB_DIRECT);
16760 if (x != stack_pointer_rtx)
16761 emit_move_insn (stack_pointer_rtx, x);
16763 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16767 ;; Use IOR for stack probes, this is shorter.
16768 (define_expand "probe_stack"
16769 [(match_operand 0 "memory_operand")]
16772 rtx (*gen_ior3) (rtx, rtx, rtx);
16774 gen_ior3 = (GET_MODE (operands[0]) == DImode
16775 ? gen_iordi3 : gen_iorsi3);
16777 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16781 (define_insn "adjust_stack_and_probe<mode>"
16782 [(set (match_operand:P 0 "register_operand" "=r")
16783 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16784 UNSPECV_PROBE_STACK_RANGE))
16785 (set (reg:P SP_REG)
16786 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16787 (clobber (reg:CC FLAGS_REG))
16788 (clobber (mem:BLK (scratch)))]
16790 "* return output_adjust_stack_and_probe (operands[0]);"
16791 [(set_attr "type" "multi")])
16793 (define_insn "probe_stack_range<mode>"
16794 [(set (match_operand:P 0 "register_operand" "=r")
16795 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16796 (match_operand:P 2 "const_int_operand" "n")]
16797 UNSPECV_PROBE_STACK_RANGE))
16798 (clobber (reg:CC FLAGS_REG))]
16800 "* return output_probe_stack_range (operands[0], operands[2]);"
16801 [(set_attr "type" "multi")])
16803 (define_expand "builtin_setjmp_receiver"
16804 [(label_ref (match_operand 0))]
16805 "!TARGET_64BIT && flag_pic"
16811 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16812 rtx label_rtx = gen_label_rtx ();
16813 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16814 xops[0] = xops[1] = picreg;
16815 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16816 ix86_expand_binary_operator (MINUS, SImode, xops);
16820 emit_insn (gen_set_got (pic_offset_table_rtx));
16824 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16827 [(set (match_operand 0 "register_operand")
16828 (match_operator 3 "promotable_binary_operator"
16829 [(match_operand 1 "register_operand")
16830 (match_operand 2 "aligned_operand")]))
16831 (clobber (reg:CC FLAGS_REG))]
16832 "! TARGET_PARTIAL_REG_STALL && reload_completed
16833 && ((GET_MODE (operands[0]) == HImode
16834 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16835 /* ??? next two lines just !satisfies_constraint_K (...) */
16836 || !CONST_INT_P (operands[2])
16837 || satisfies_constraint_K (operands[2])))
16838 || (GET_MODE (operands[0]) == QImode
16839 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16840 [(parallel [(set (match_dup 0)
16841 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16842 (clobber (reg:CC FLAGS_REG))])]
16844 operands[0] = gen_lowpart (SImode, operands[0]);
16845 operands[1] = gen_lowpart (SImode, operands[1]);
16846 if (GET_CODE (operands[3]) != ASHIFT)
16847 operands[2] = gen_lowpart (SImode, operands[2]);
16848 PUT_MODE (operands[3], SImode);
16851 ; Promote the QImode tests, as i386 has encoding of the AND
16852 ; instruction with 32-bit sign-extended immediate and thus the
16853 ; instruction size is unchanged, except in the %eax case for
16854 ; which it is increased by one byte, hence the ! optimize_size.
16856 [(set (match_operand 0 "flags_reg_operand")
16857 (match_operator 2 "compare_operator"
16858 [(and (match_operand 3 "aligned_operand")
16859 (match_operand 4 "const_int_operand"))
16861 (set (match_operand 1 "register_operand")
16862 (and (match_dup 3) (match_dup 4)))]
16863 "! TARGET_PARTIAL_REG_STALL && reload_completed
16864 && optimize_insn_for_speed_p ()
16865 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16866 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16867 /* Ensure that the operand will remain sign-extended immediate. */
16868 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16869 [(parallel [(set (match_dup 0)
16870 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16873 (and:SI (match_dup 3) (match_dup 4)))])]
16876 = gen_int_mode (INTVAL (operands[4])
16877 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16878 operands[1] = gen_lowpart (SImode, operands[1]);
16879 operands[3] = gen_lowpart (SImode, operands[3]);
16882 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16883 ; the TEST instruction with 32-bit sign-extended immediate and thus
16884 ; the instruction size would at least double, which is not what we
16885 ; want even with ! optimize_size.
16887 [(set (match_operand 0 "flags_reg_operand")
16888 (match_operator 1 "compare_operator"
16889 [(and (match_operand:HI 2 "aligned_operand")
16890 (match_operand:HI 3 "const_int_operand"))
16892 "! TARGET_PARTIAL_REG_STALL && reload_completed
16893 && ! TARGET_FAST_PREFIX
16894 && optimize_insn_for_speed_p ()
16895 /* Ensure that the operand will remain sign-extended immediate. */
16896 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16897 [(set (match_dup 0)
16898 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16902 = gen_int_mode (INTVAL (operands[3])
16903 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16904 operands[2] = gen_lowpart (SImode, operands[2]);
16908 [(set (match_operand 0 "register_operand")
16909 (neg (match_operand 1 "register_operand")))
16910 (clobber (reg:CC FLAGS_REG))]
16911 "! TARGET_PARTIAL_REG_STALL && reload_completed
16912 && (GET_MODE (operands[0]) == HImode
16913 || (GET_MODE (operands[0]) == QImode
16914 && (TARGET_PROMOTE_QImode
16915 || optimize_insn_for_size_p ())))"
16916 [(parallel [(set (match_dup 0)
16917 (neg:SI (match_dup 1)))
16918 (clobber (reg:CC FLAGS_REG))])]
16920 operands[0] = gen_lowpart (SImode, operands[0]);
16921 operands[1] = gen_lowpart (SImode, operands[1]);
16925 [(set (match_operand 0 "register_operand")
16926 (not (match_operand 1 "register_operand")))]
16927 "! TARGET_PARTIAL_REG_STALL && reload_completed
16928 && (GET_MODE (operands[0]) == HImode
16929 || (GET_MODE (operands[0]) == QImode
16930 && (TARGET_PROMOTE_QImode
16931 || optimize_insn_for_size_p ())))"
16932 [(set (match_dup 0)
16933 (not:SI (match_dup 1)))]
16935 operands[0] = gen_lowpart (SImode, operands[0]);
16936 operands[1] = gen_lowpart (SImode, operands[1]);
16939 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16940 ;; transform a complex memory operation into two memory to register operations.
16942 ;; Don't push memory operands
16944 [(set (match_operand:SWI 0 "push_operand")
16945 (match_operand:SWI 1 "memory_operand"))
16946 (match_scratch:SWI 2 "<r>")]
16947 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16948 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16949 [(set (match_dup 2) (match_dup 1))
16950 (set (match_dup 0) (match_dup 2))])
16952 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16955 [(set (match_operand:SF 0 "push_operand")
16956 (match_operand:SF 1 "memory_operand"))
16957 (match_scratch:SF 2 "r")]
16958 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16959 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16960 [(set (match_dup 2) (match_dup 1))
16961 (set (match_dup 0) (match_dup 2))])
16963 ;; Don't move an immediate directly to memory when the instruction
16964 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16966 [(match_scratch:SWI124 1 "<r>")
16967 (set (match_operand:SWI124 0 "memory_operand")
16969 "optimize_insn_for_speed_p ()
16970 && ((<MODE>mode == HImode
16971 && TARGET_LCP_STALL)
16972 || (!TARGET_USE_MOV0
16973 && TARGET_SPLIT_LONG_MOVES
16974 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16975 && peep2_regno_dead_p (0, FLAGS_REG)"
16976 [(parallel [(set (match_dup 2) (const_int 0))
16977 (clobber (reg:CC FLAGS_REG))])
16978 (set (match_dup 0) (match_dup 1))]
16979 "operands[2] = gen_lowpart (SImode, operands[1]);")
16982 [(match_scratch:SWI124 2 "<r>")
16983 (set (match_operand:SWI124 0 "memory_operand")
16984 (match_operand:SWI124 1 "immediate_operand"))]
16985 "optimize_insn_for_speed_p ()
16986 && ((<MODE>mode == HImode
16987 && TARGET_LCP_STALL)
16988 || (TARGET_SPLIT_LONG_MOVES
16989 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16990 [(set (match_dup 2) (match_dup 1))
16991 (set (match_dup 0) (match_dup 2))])
16993 ;; Don't compare memory with zero, load and use a test instead.
16995 [(set (match_operand 0 "flags_reg_operand")
16996 (match_operator 1 "compare_operator"
16997 [(match_operand:SI 2 "memory_operand")
16999 (match_scratch:SI 3 "r")]
17000 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17001 [(set (match_dup 3) (match_dup 2))
17002 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17004 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17005 ;; Don't split NOTs with a displacement operand, because resulting XOR
17006 ;; will not be pairable anyway.
17008 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17009 ;; represented using a modRM byte. The XOR replacement is long decoded,
17010 ;; so this split helps here as well.
17012 ;; Note: Can't do this as a regular split because we can't get proper
17013 ;; lifetime information then.
17016 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17017 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17018 "optimize_insn_for_speed_p ()
17019 && ((TARGET_NOT_UNPAIRABLE
17020 && (!MEM_P (operands[0])
17021 || !memory_displacement_operand (operands[0], <MODE>mode)))
17022 || (TARGET_NOT_VECTORMODE
17023 && long_memory_operand (operands[0], <MODE>mode)))
17024 && peep2_regno_dead_p (0, FLAGS_REG)"
17025 [(parallel [(set (match_dup 0)
17026 (xor:SWI124 (match_dup 1) (const_int -1)))
17027 (clobber (reg:CC FLAGS_REG))])])
17029 ;; Non pairable "test imm, reg" instructions can be translated to
17030 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17031 ;; byte opcode instead of two, have a short form for byte operands),
17032 ;; so do it for other CPUs as well. Given that the value was dead,
17033 ;; this should not create any new dependencies. Pass on the sub-word
17034 ;; versions if we're concerned about partial register stalls.
17037 [(set (match_operand 0 "flags_reg_operand")
17038 (match_operator 1 "compare_operator"
17039 [(and:SI (match_operand:SI 2 "register_operand")
17040 (match_operand:SI 3 "immediate_operand"))
17042 "ix86_match_ccmode (insn, CCNOmode)
17043 && (true_regnum (operands[2]) != AX_REG
17044 || satisfies_constraint_K (operands[3]))
17045 && peep2_reg_dead_p (1, operands[2])"
17047 [(set (match_dup 0)
17048 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17051 (and:SI (match_dup 2) (match_dup 3)))])])
17053 ;; We don't need to handle HImode case, because it will be promoted to SImode
17054 ;; on ! TARGET_PARTIAL_REG_STALL
17057 [(set (match_operand 0 "flags_reg_operand")
17058 (match_operator 1 "compare_operator"
17059 [(and:QI (match_operand:QI 2 "register_operand")
17060 (match_operand:QI 3 "immediate_operand"))
17062 "! TARGET_PARTIAL_REG_STALL
17063 && ix86_match_ccmode (insn, CCNOmode)
17064 && true_regnum (operands[2]) != AX_REG
17065 && peep2_reg_dead_p (1, operands[2])"
17067 [(set (match_dup 0)
17068 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17071 (and:QI (match_dup 2) (match_dup 3)))])])
17074 [(set (match_operand 0 "flags_reg_operand")
17075 (match_operator 1 "compare_operator"
17078 (match_operand 2 "ext_register_operand")
17081 (match_operand 3 "const_int_operand"))
17083 "! TARGET_PARTIAL_REG_STALL
17084 && ix86_match_ccmode (insn, CCNOmode)
17085 && true_regnum (operands[2]) != AX_REG
17086 && peep2_reg_dead_p (1, operands[2])"
17087 [(parallel [(set (match_dup 0)
17096 (set (zero_extract:SI (match_dup 2)
17104 (match_dup 3)))])])
17106 ;; Don't do logical operations with memory inputs.
17108 [(match_scratch:SI 2 "r")
17109 (parallel [(set (match_operand:SI 0 "register_operand")
17110 (match_operator:SI 3 "arith_or_logical_operator"
17112 (match_operand:SI 1 "memory_operand")]))
17113 (clobber (reg:CC FLAGS_REG))])]
17114 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17115 [(set (match_dup 2) (match_dup 1))
17116 (parallel [(set (match_dup 0)
17117 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17118 (clobber (reg:CC FLAGS_REG))])])
17121 [(match_scratch:SI 2 "r")
17122 (parallel [(set (match_operand:SI 0 "register_operand")
17123 (match_operator:SI 3 "arith_or_logical_operator"
17124 [(match_operand:SI 1 "memory_operand")
17126 (clobber (reg:CC FLAGS_REG))])]
17127 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17128 [(set (match_dup 2) (match_dup 1))
17129 (parallel [(set (match_dup 0)
17130 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17131 (clobber (reg:CC FLAGS_REG))])])
17133 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17134 ;; refers to the destination of the load!
17137 [(set (match_operand:SI 0 "register_operand")
17138 (match_operand:SI 1 "register_operand"))
17139 (parallel [(set (match_dup 0)
17140 (match_operator:SI 3 "commutative_operator"
17142 (match_operand:SI 2 "memory_operand")]))
17143 (clobber (reg:CC FLAGS_REG))])]
17144 "REGNO (operands[0]) != REGNO (operands[1])
17145 && GENERAL_REGNO_P (REGNO (operands[0]))
17146 && GENERAL_REGNO_P (REGNO (operands[1]))"
17147 [(set (match_dup 0) (match_dup 4))
17148 (parallel [(set (match_dup 0)
17149 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17150 (clobber (reg:CC FLAGS_REG))])]
17151 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17154 [(set (match_operand 0 "register_operand")
17155 (match_operand 1 "register_operand"))
17157 (match_operator 3 "commutative_operator"
17159 (match_operand 2 "memory_operand")]))]
17160 "REGNO (operands[0]) != REGNO (operands[1])
17161 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17162 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17163 [(set (match_dup 0) (match_dup 2))
17165 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17167 ; Don't do logical operations with memory outputs
17169 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17170 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17171 ; the same decoder scheduling characteristics as the original.
17174 [(match_scratch:SI 2 "r")
17175 (parallel [(set (match_operand:SI 0 "memory_operand")
17176 (match_operator:SI 3 "arith_or_logical_operator"
17178 (match_operand:SI 1 "nonmemory_operand")]))
17179 (clobber (reg:CC FLAGS_REG))])]
17180 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17181 /* Do not split stack checking probes. */
17182 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17183 [(set (match_dup 2) (match_dup 0))
17184 (parallel [(set (match_dup 2)
17185 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17186 (clobber (reg:CC FLAGS_REG))])
17187 (set (match_dup 0) (match_dup 2))])
17190 [(match_scratch:SI 2 "r")
17191 (parallel [(set (match_operand:SI 0 "memory_operand")
17192 (match_operator:SI 3 "arith_or_logical_operator"
17193 [(match_operand:SI 1 "nonmemory_operand")
17195 (clobber (reg:CC FLAGS_REG))])]
17196 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17197 /* Do not split stack checking probes. */
17198 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17199 [(set (match_dup 2) (match_dup 0))
17200 (parallel [(set (match_dup 2)
17201 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17202 (clobber (reg:CC FLAGS_REG))])
17203 (set (match_dup 0) (match_dup 2))])
17205 ;; Attempt to use arith or logical operations with memory outputs with
17206 ;; setting of flags.
17208 [(set (match_operand:SWI 0 "register_operand")
17209 (match_operand:SWI 1 "memory_operand"))
17210 (parallel [(set (match_dup 0)
17211 (match_operator:SWI 3 "plusminuslogic_operator"
17213 (match_operand:SWI 2 "<nonmemory_operand>")]))
17214 (clobber (reg:CC FLAGS_REG))])
17215 (set (match_dup 1) (match_dup 0))
17216 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17217 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17218 && peep2_reg_dead_p (4, operands[0])
17219 && !reg_overlap_mentioned_p (operands[0], operands[1])
17220 && (<MODE>mode != QImode
17221 || immediate_operand (operands[2], QImode)
17222 || q_regs_operand (operands[2], QImode))
17223 && ix86_match_ccmode (peep2_next_insn (3),
17224 (GET_CODE (operands[3]) == PLUS
17225 || GET_CODE (operands[3]) == MINUS)
17226 ? CCGOCmode : CCNOmode)"
17227 [(parallel [(set (match_dup 4) (match_dup 5))
17228 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17229 (match_dup 2)]))])]
17231 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17232 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17233 copy_rtx (operands[1]),
17234 copy_rtx (operands[2]));
17235 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17236 operands[5], const0_rtx);
17240 [(parallel [(set (match_operand:SWI 0 "register_operand")
17241 (match_operator:SWI 2 "plusminuslogic_operator"
17243 (match_operand:SWI 1 "memory_operand")]))
17244 (clobber (reg:CC FLAGS_REG))])
17245 (set (match_dup 1) (match_dup 0))
17246 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17247 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17248 && GET_CODE (operands[2]) != MINUS
17249 && peep2_reg_dead_p (3, operands[0])
17250 && !reg_overlap_mentioned_p (operands[0], operands[1])
17251 && ix86_match_ccmode (peep2_next_insn (2),
17252 GET_CODE (operands[2]) == PLUS
17253 ? CCGOCmode : CCNOmode)"
17254 [(parallel [(set (match_dup 3) (match_dup 4))
17255 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17256 (match_dup 0)]))])]
17258 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17259 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17260 copy_rtx (operands[1]),
17261 copy_rtx (operands[0]));
17262 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17263 operands[4], const0_rtx);
17267 [(set (match_operand:SWI12 0 "register_operand")
17268 (match_operand:SWI12 1 "memory_operand"))
17269 (parallel [(set (match_operand:SI 4 "register_operand")
17270 (match_operator:SI 3 "plusminuslogic_operator"
17272 (match_operand:SI 2 "nonmemory_operand")]))
17273 (clobber (reg:CC FLAGS_REG))])
17274 (set (match_dup 1) (match_dup 0))
17275 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17276 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17277 && REG_P (operands[0]) && REG_P (operands[4])
17278 && REGNO (operands[0]) == REGNO (operands[4])
17279 && peep2_reg_dead_p (4, operands[0])
17280 && (<MODE>mode != QImode
17281 || immediate_operand (operands[2], SImode)
17282 || q_regs_operand (operands[2], SImode))
17283 && !reg_overlap_mentioned_p (operands[0], operands[1])
17284 && ix86_match_ccmode (peep2_next_insn (3),
17285 (GET_CODE (operands[3]) == PLUS
17286 || GET_CODE (operands[3]) == MINUS)
17287 ? CCGOCmode : CCNOmode)"
17288 [(parallel [(set (match_dup 4) (match_dup 5))
17289 (set (match_dup 1) (match_dup 6))])]
17291 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17292 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17293 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17294 copy_rtx (operands[1]), operands[2]);
17295 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17296 operands[5], const0_rtx);
17297 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17298 copy_rtx (operands[1]),
17299 copy_rtx (operands[2]));
17302 ;; Attempt to always use XOR for zeroing registers.
17304 [(set (match_operand 0 "register_operand")
17305 (match_operand 1 "const0_operand"))]
17306 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17307 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17308 && GENERAL_REG_P (operands[0])
17309 && peep2_regno_dead_p (0, FLAGS_REG)"
17310 [(parallel [(set (match_dup 0) (const_int 0))
17311 (clobber (reg:CC FLAGS_REG))])]
17312 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17315 [(set (strict_low_part (match_operand 0 "register_operand"))
17317 "(GET_MODE (operands[0]) == QImode
17318 || GET_MODE (operands[0]) == HImode)
17319 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17320 && peep2_regno_dead_p (0, FLAGS_REG)"
17321 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17322 (clobber (reg:CC FLAGS_REG))])])
17324 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17326 [(set (match_operand:SWI248 0 "register_operand")
17328 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17329 && peep2_regno_dead_p (0, FLAGS_REG)"
17330 [(parallel [(set (match_dup 0) (const_int -1))
17331 (clobber (reg:CC FLAGS_REG))])]
17333 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17334 operands[0] = gen_lowpart (SImode, operands[0]);
17337 ;; Attempt to convert simple lea to add/shift.
17338 ;; These can be created by move expanders.
17339 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17340 ;; relevant lea instructions were already split.
17343 [(set (match_operand:SWI48 0 "register_operand")
17344 (plus:SWI48 (match_dup 0)
17345 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17347 && peep2_regno_dead_p (0, FLAGS_REG)"
17348 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17349 (clobber (reg:CC FLAGS_REG))])])
17352 [(set (match_operand:SWI48 0 "register_operand")
17353 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17356 && peep2_regno_dead_p (0, FLAGS_REG)"
17357 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17358 (clobber (reg:CC FLAGS_REG))])])
17361 [(set (match_operand:SI 0 "register_operand")
17362 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand")
17363 (match_operand:DI 2 "nonmemory_operand")) 0))]
17364 "TARGET_64BIT && !TARGET_OPT_AGU
17365 && REGNO (operands[0]) == REGNO (operands[1])
17366 && peep2_regno_dead_p (0, FLAGS_REG)"
17367 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17368 (clobber (reg:CC FLAGS_REG))])]
17369 "operands[2] = gen_lowpart (SImode, operands[2]);")
17372 [(set (match_operand:SI 0 "register_operand")
17373 (subreg:SI (plus:DI (match_operand:DI 1 "nonmemory_operand")
17374 (match_operand:DI 2 "register_operand")) 0))]
17375 "TARGET_64BIT && !TARGET_OPT_AGU
17376 && REGNO (operands[0]) == REGNO (operands[2])
17377 && peep2_regno_dead_p (0, FLAGS_REG)"
17378 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17379 (clobber (reg:CC FLAGS_REG))])]
17380 "operands[1] = gen_lowpart (SImode, operands[1]);")
17383 [(set (match_operand:DI 0 "register_operand")
17385 (plus:SI (match_operand:SI 1 "register_operand")
17386 (match_operand:SI 2 "nonmemory_operand"))))]
17387 "TARGET_64BIT && !TARGET_OPT_AGU
17388 && REGNO (operands[0]) == REGNO (operands[1])
17389 && peep2_regno_dead_p (0, FLAGS_REG)"
17390 [(parallel [(set (match_dup 0)
17391 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17392 (clobber (reg:CC FLAGS_REG))])])
17395 [(set (match_operand:DI 0 "register_operand")
17397 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17398 (match_operand:SI 2 "register_operand"))))]
17399 "TARGET_64BIT && !TARGET_OPT_AGU
17400 && REGNO (operands[0]) == REGNO (operands[2])
17401 && peep2_regno_dead_p (0, FLAGS_REG)"
17402 [(parallel [(set (match_dup 0)
17403 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17404 (clobber (reg:CC FLAGS_REG))])])
17407 [(set (match_operand:DI 0 "register_operand")
17409 (subreg:SI (plus:DI (match_dup 0)
17410 (match_operand:DI 1 "nonmemory_operand")) 0)))]
17411 "TARGET_64BIT && !TARGET_OPT_AGU
17412 && peep2_regno_dead_p (0, FLAGS_REG)"
17413 [(parallel [(set (match_dup 0)
17414 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17415 (clobber (reg:CC FLAGS_REG))])]
17417 operands[1] = gen_lowpart (SImode, operands[1]);
17418 operands[2] = gen_lowpart (SImode, operands[0]);
17422 [(set (match_operand:DI 0 "register_operand")
17424 (subreg:SI (plus:DI (match_operand:DI 1 "nonmemory_operand")
17425 (match_dup 0)) 0)))]
17426 "TARGET_64BIT && !TARGET_OPT_AGU
17427 && peep2_regno_dead_p (0, FLAGS_REG)"
17428 [(parallel [(set (match_dup 0)
17429 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17430 (clobber (reg:CC FLAGS_REG))])]
17432 operands[1] = gen_lowpart (SImode, operands[1]);
17433 operands[2] = gen_lowpart (SImode, operands[0]);
17437 [(set (match_operand:SWI48 0 "register_operand")
17438 (mult:SWI48 (match_dup 0)
17439 (match_operand:SWI48 1 "const_int_operand")))]
17440 "exact_log2 (INTVAL (operands[1])) >= 0
17441 && peep2_regno_dead_p (0, FLAGS_REG)"
17442 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17443 (clobber (reg:CC FLAGS_REG))])]
17444 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17447 [(set (match_operand:SI 0 "register_operand")
17448 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand")
17449 (match_operand:DI 2 "const_int_operand")) 0))]
17451 && exact_log2 (INTVAL (operands[2])) >= 0
17452 && REGNO (operands[0]) == REGNO (operands[1])
17453 && peep2_regno_dead_p (0, FLAGS_REG)"
17454 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17455 (clobber (reg:CC FLAGS_REG))])]
17456 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17459 [(set (match_operand:DI 0 "register_operand")
17461 (mult:SI (match_operand:SI 1 "register_operand")
17462 (match_operand:SI 2 "const_int_operand"))))]
17464 && exact_log2 (INTVAL (operands[2])) >= 0
17465 && REGNO (operands[0]) == REGNO (operands[1])
17466 && peep2_regno_dead_p (0, FLAGS_REG)"
17467 [(parallel [(set (match_dup 0)
17468 (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
17469 (clobber (reg:CC FLAGS_REG))])]
17470 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17473 [(set (match_operand:DI 0 "register_operand")
17475 (subreg:SI (mult:DI (match_dup 0)
17476 (match_operand:DI 1 "const_int_operand")) 0)))]
17478 && exact_log2 (INTVAL (operands[2])) >= 0
17479 && peep2_regno_dead_p (0, FLAGS_REG)"
17480 [(parallel [(set (match_dup 0)
17481 (zero_extend:DI (ashift:SI (match_dup 2) (match_dup 1))))
17482 (clobber (reg:CC FLAGS_REG))])]
17484 operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
17485 operands[2] = gen_lowpart (SImode, operands[0]);
17488 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17489 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17490 ;; On many CPUs it is also faster, since special hardware to avoid esp
17491 ;; dependencies is present.
17493 ;; While some of these conversions may be done using splitters, we use
17494 ;; peepholes in order to allow combine_stack_adjustments pass to see
17495 ;; nonobfuscated RTL.
17497 ;; Convert prologue esp subtractions to push.
17498 ;; We need register to push. In order to keep verify_flow_info happy we have
17500 ;; - use scratch and clobber it in order to avoid dependencies
17501 ;; - use already live register
17502 ;; We can't use the second way right now, since there is no reliable way how to
17503 ;; verify that given register is live. First choice will also most likely in
17504 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17505 ;; call clobbered registers are dead. We may want to use base pointer as an
17506 ;; alternative when no register is available later.
17509 [(match_scratch:W 1 "r")
17510 (parallel [(set (reg:P SP_REG)
17511 (plus:P (reg:P SP_REG)
17512 (match_operand:P 0 "const_int_operand")))
17513 (clobber (reg:CC FLAGS_REG))
17514 (clobber (mem:BLK (scratch)))])]
17515 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17516 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17517 [(clobber (match_dup 1))
17518 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17519 (clobber (mem:BLK (scratch)))])])
17522 [(match_scratch:W 1 "r")
17523 (parallel [(set (reg:P SP_REG)
17524 (plus:P (reg:P SP_REG)
17525 (match_operand:P 0 "const_int_operand")))
17526 (clobber (reg:CC FLAGS_REG))
17527 (clobber (mem:BLK (scratch)))])]
17528 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17529 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17530 [(clobber (match_dup 1))
17531 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17532 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17533 (clobber (mem:BLK (scratch)))])])
17535 ;; Convert esp subtractions to push.
17537 [(match_scratch:W 1 "r")
17538 (parallel [(set (reg:P SP_REG)
17539 (plus:P (reg:P SP_REG)
17540 (match_operand:P 0 "const_int_operand")))
17541 (clobber (reg:CC FLAGS_REG))])]
17542 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17543 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17544 [(clobber (match_dup 1))
17545 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17548 [(match_scratch:W 1 "r")
17549 (parallel [(set (reg:P SP_REG)
17550 (plus:P (reg:P SP_REG)
17551 (match_operand:P 0 "const_int_operand")))
17552 (clobber (reg:CC FLAGS_REG))])]
17553 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17554 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17555 [(clobber (match_dup 1))
17556 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17557 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17559 ;; Convert epilogue deallocator to pop.
17561 [(match_scratch:W 1 "r")
17562 (parallel [(set (reg:P SP_REG)
17563 (plus:P (reg:P SP_REG)
17564 (match_operand:P 0 "const_int_operand")))
17565 (clobber (reg:CC FLAGS_REG))
17566 (clobber (mem:BLK (scratch)))])]
17567 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17568 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17569 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17570 (clobber (mem:BLK (scratch)))])])
17572 ;; Two pops case is tricky, since pop causes dependency
17573 ;; on destination register. We use two registers if available.
17575 [(match_scratch:W 1 "r")
17576 (match_scratch:W 2 "r")
17577 (parallel [(set (reg:P SP_REG)
17578 (plus:P (reg:P SP_REG)
17579 (match_operand:P 0 "const_int_operand")))
17580 (clobber (reg:CC FLAGS_REG))
17581 (clobber (mem:BLK (scratch)))])]
17582 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17583 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17584 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17585 (clobber (mem:BLK (scratch)))])
17586 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17589 [(match_scratch:W 1 "r")
17590 (parallel [(set (reg:P SP_REG)
17591 (plus:P (reg:P SP_REG)
17592 (match_operand:P 0 "const_int_operand")))
17593 (clobber (reg:CC FLAGS_REG))
17594 (clobber (mem:BLK (scratch)))])]
17595 "optimize_insn_for_size_p ()
17596 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17597 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17598 (clobber (mem:BLK (scratch)))])
17599 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17601 ;; Convert esp additions to pop.
17603 [(match_scratch:W 1 "r")
17604 (parallel [(set (reg:P SP_REG)
17605 (plus:P (reg:P SP_REG)
17606 (match_operand:P 0 "const_int_operand")))
17607 (clobber (reg:CC FLAGS_REG))])]
17608 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17609 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17611 ;; Two pops case is tricky, since pop causes dependency
17612 ;; on destination register. We use two registers if available.
17614 [(match_scratch:W 1 "r")
17615 (match_scratch:W 2 "r")
17616 (parallel [(set (reg:P SP_REG)
17617 (plus:P (reg:P SP_REG)
17618 (match_operand:P 0 "const_int_operand")))
17619 (clobber (reg:CC FLAGS_REG))])]
17620 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17621 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17622 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17625 [(match_scratch:W 1 "r")
17626 (parallel [(set (reg:P SP_REG)
17627 (plus:P (reg:P SP_REG)
17628 (match_operand:P 0 "const_int_operand")))
17629 (clobber (reg:CC FLAGS_REG))])]
17630 "optimize_insn_for_size_p ()
17631 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17632 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17633 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17635 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17636 ;; required and register dies. Similarly for 128 to -128.
17638 [(set (match_operand 0 "flags_reg_operand")
17639 (match_operator 1 "compare_operator"
17640 [(match_operand 2 "register_operand")
17641 (match_operand 3 "const_int_operand")]))]
17642 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17643 && incdec_operand (operands[3], GET_MODE (operands[3])))
17644 || (!TARGET_FUSE_CMP_AND_BRANCH
17645 && INTVAL (operands[3]) == 128))
17646 && ix86_match_ccmode (insn, CCGCmode)
17647 && peep2_reg_dead_p (1, operands[2])"
17648 [(parallel [(set (match_dup 0)
17649 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17650 (clobber (match_dup 2))])])
17652 ;; Convert imul by three, five and nine into lea
17655 [(set (match_operand:SWI48 0 "register_operand")
17656 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17657 (match_operand:SWI48 2 "const359_operand")))
17658 (clobber (reg:CC FLAGS_REG))])]
17659 "!TARGET_PARTIAL_REG_STALL
17660 || <MODE>mode == SImode
17661 || optimize_function_for_size_p (cfun)"
17662 [(set (match_dup 0)
17663 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17665 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17669 [(set (match_operand:SWI48 0 "register_operand")
17670 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17671 (match_operand:SWI48 2 "const359_operand")))
17672 (clobber (reg:CC FLAGS_REG))])]
17673 "optimize_insn_for_speed_p ()
17674 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17675 [(set (match_dup 0) (match_dup 1))
17677 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17679 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17681 ;; imul $32bit_imm, mem, reg is vector decoded, while
17682 ;; imul $32bit_imm, reg, reg is direct decoded.
17684 [(match_scratch:SWI48 3 "r")
17685 (parallel [(set (match_operand:SWI48 0 "register_operand")
17686 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17687 (match_operand:SWI48 2 "immediate_operand")))
17688 (clobber (reg:CC FLAGS_REG))])]
17689 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17690 && !satisfies_constraint_K (operands[2])"
17691 [(set (match_dup 3) (match_dup 1))
17692 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17693 (clobber (reg:CC FLAGS_REG))])])
17696 [(match_scratch:SI 3 "r")
17697 (parallel [(set (match_operand:DI 0 "register_operand")
17699 (mult:SI (match_operand:SI 1 "memory_operand")
17700 (match_operand:SI 2 "immediate_operand"))))
17701 (clobber (reg:CC FLAGS_REG))])]
17703 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17704 && !satisfies_constraint_K (operands[2])"
17705 [(set (match_dup 3) (match_dup 1))
17706 (parallel [(set (match_dup 0)
17707 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17708 (clobber (reg:CC FLAGS_REG))])])
17710 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17711 ;; Convert it into imul reg, reg
17712 ;; It would be better to force assembler to encode instruction using long
17713 ;; immediate, but there is apparently no way to do so.
17715 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17717 (match_operand:SWI248 1 "nonimmediate_operand")
17718 (match_operand:SWI248 2 "const_int_operand")))
17719 (clobber (reg:CC FLAGS_REG))])
17720 (match_scratch:SWI248 3 "r")]
17721 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17722 && satisfies_constraint_K (operands[2])"
17723 [(set (match_dup 3) (match_dup 2))
17724 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17725 (clobber (reg:CC FLAGS_REG))])]
17727 if (!rtx_equal_p (operands[0], operands[1]))
17728 emit_move_insn (operands[0], operands[1]);
17731 ;; After splitting up read-modify operations, array accesses with memory
17732 ;; operands might end up in form:
17734 ;; movl 4(%esp), %edx
17736 ;; instead of pre-splitting:
17738 ;; addl 4(%esp), %eax
17740 ;; movl 4(%esp), %edx
17741 ;; leal (%edx,%eax,4), %eax
17744 [(match_scratch:W 5 "r")
17745 (parallel [(set (match_operand 0 "register_operand")
17746 (ashift (match_operand 1 "register_operand")
17747 (match_operand 2 "const_int_operand")))
17748 (clobber (reg:CC FLAGS_REG))])
17749 (parallel [(set (match_operand 3 "register_operand")
17750 (plus (match_dup 0)
17751 (match_operand 4 "x86_64_general_operand")))
17752 (clobber (reg:CC FLAGS_REG))])]
17753 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17754 /* Validate MODE for lea. */
17755 && ((!TARGET_PARTIAL_REG_STALL
17756 && (GET_MODE (operands[0]) == QImode
17757 || GET_MODE (operands[0]) == HImode))
17758 || GET_MODE (operands[0]) == SImode
17759 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17760 && (rtx_equal_p (operands[0], operands[3])
17761 || peep2_reg_dead_p (2, operands[0]))
17762 /* We reorder load and the shift. */
17763 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17764 [(set (match_dup 5) (match_dup 4))
17765 (set (match_dup 0) (match_dup 1))]
17767 enum machine_mode op1mode = GET_MODE (operands[1]);
17768 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17769 int scale = 1 << INTVAL (operands[2]);
17770 rtx index = gen_lowpart (word_mode, operands[1]);
17771 rtx base = gen_lowpart (word_mode, operands[5]);
17772 rtx dest = gen_lowpart (mode, operands[3]);
17774 operands[1] = gen_rtx_PLUS (word_mode, base,
17775 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17776 operands[5] = base;
17777 if (mode != word_mode)
17778 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17779 if (op1mode != word_mode)
17780 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17781 operands[0] = dest;
17784 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17785 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17786 ;; caught for use by garbage collectors and the like. Using an insn that
17787 ;; maps to SIGILL makes it more likely the program will rightfully die.
17788 ;; Keeping with tradition, "6" is in honor of #UD.
17789 (define_insn "trap"
17790 [(trap_if (const_int 1) (const_int 6))]
17792 { return ASM_SHORT "0x0b0f"; }
17793 [(set_attr "length" "2")])
17795 (define_expand "prefetch"
17796 [(prefetch (match_operand 0 "address_operand")
17797 (match_operand:SI 1 "const_int_operand")
17798 (match_operand:SI 2 "const_int_operand"))]
17799 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17801 int rw = INTVAL (operands[1]);
17802 int locality = INTVAL (operands[2]);
17804 gcc_assert (rw == 0 || rw == 1);
17805 gcc_assert (IN_RANGE (locality, 0, 3));
17807 if (TARGET_PRFCHW && rw)
17808 operands[2] = GEN_INT (3);
17809 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17810 supported by SSE counterpart or the SSE prefetch is not available
17811 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17813 else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17814 operands[2] = GEN_INT (3);
17816 operands[1] = const0_rtx;
17819 (define_insn "*prefetch_sse"
17820 [(prefetch (match_operand 0 "address_operand" "p")
17822 (match_operand:SI 1 "const_int_operand"))]
17823 "TARGET_PREFETCH_SSE"
17825 static const char * const patterns[4] = {
17826 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17829 int locality = INTVAL (operands[1]);
17830 gcc_assert (IN_RANGE (locality, 0, 3));
17832 return patterns[locality];
17834 [(set_attr "type" "sse")
17835 (set_attr "atom_sse_attr" "prefetch")
17836 (set (attr "length_address")
17837 (symbol_ref "memory_address_length (operands[0], false)"))
17838 (set_attr "memory" "none")])
17840 (define_insn "*prefetch_3dnow"
17841 [(prefetch (match_operand 0 "address_operand" "p")
17842 (match_operand:SI 1 "const_int_operand" "n")
17844 "TARGET_3DNOW || TARGET_PRFCHW"
17846 if (INTVAL (operands[1]) == 0)
17847 return "prefetch\t%a0";
17849 return "prefetchw\t%a0";
17851 [(set_attr "type" "mmx")
17852 (set (attr "length_address")
17853 (symbol_ref "memory_address_length (operands[0], false)"))
17854 (set_attr "memory" "none")])
17856 (define_expand "stack_protect_set"
17857 [(match_operand 0 "memory_operand")
17858 (match_operand 1 "memory_operand")]
17859 "!TARGET_HAS_BIONIC"
17861 rtx (*insn)(rtx, rtx);
17863 #ifdef TARGET_THREAD_SSP_OFFSET
17864 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17865 insn = (TARGET_LP64
17866 ? gen_stack_tls_protect_set_di
17867 : gen_stack_tls_protect_set_si);
17869 insn = (TARGET_LP64
17870 ? gen_stack_protect_set_di
17871 : gen_stack_protect_set_si);
17874 emit_insn (insn (operands[0], operands[1]));
17878 (define_insn "stack_protect_set_<mode>"
17879 [(set (match_operand:PTR 0 "memory_operand" "=m")
17880 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17882 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17883 (clobber (reg:CC FLAGS_REG))]
17884 "!TARGET_HAS_BIONIC"
17885 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17886 [(set_attr "type" "multi")])
17888 (define_insn "stack_tls_protect_set_<mode>"
17889 [(set (match_operand:PTR 0 "memory_operand" "=m")
17890 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17891 UNSPEC_SP_TLS_SET))
17892 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17893 (clobber (reg:CC FLAGS_REG))]
17895 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17896 [(set_attr "type" "multi")])
17898 (define_expand "stack_protect_test"
17899 [(match_operand 0 "memory_operand")
17900 (match_operand 1 "memory_operand")
17902 "!TARGET_HAS_BIONIC"
17904 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17906 rtx (*insn)(rtx, rtx, rtx);
17908 #ifdef TARGET_THREAD_SSP_OFFSET
17909 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17910 insn = (TARGET_LP64
17911 ? gen_stack_tls_protect_test_di
17912 : gen_stack_tls_protect_test_si);
17914 insn = (TARGET_LP64
17915 ? gen_stack_protect_test_di
17916 : gen_stack_protect_test_si);
17919 emit_insn (insn (flags, operands[0], operands[1]));
17921 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17922 flags, const0_rtx, operands[2]));
17926 (define_insn "stack_protect_test_<mode>"
17927 [(set (match_operand:CCZ 0 "flags_reg_operand")
17928 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17929 (match_operand:PTR 2 "memory_operand" "m")]
17931 (clobber (match_scratch:PTR 3 "=&r"))]
17932 "!TARGET_HAS_BIONIC"
17933 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17934 [(set_attr "type" "multi")])
17936 (define_insn "stack_tls_protect_test_<mode>"
17937 [(set (match_operand:CCZ 0 "flags_reg_operand")
17938 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17939 (match_operand:PTR 2 "const_int_operand" "i")]
17940 UNSPEC_SP_TLS_TEST))
17941 (clobber (match_scratch:PTR 3 "=r"))]
17943 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17944 [(set_attr "type" "multi")])
17946 (define_insn "sse4_2_crc32<mode>"
17947 [(set (match_operand:SI 0 "register_operand" "=r")
17949 [(match_operand:SI 1 "register_operand" "0")
17950 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17952 "TARGET_SSE4_2 || TARGET_CRC32"
17953 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17954 [(set_attr "type" "sselog1")
17955 (set_attr "prefix_rep" "1")
17956 (set_attr "prefix_extra" "1")
17957 (set (attr "prefix_data16")
17958 (if_then_else (match_operand:HI 2)
17960 (const_string "*")))
17961 (set (attr "prefix_rex")
17962 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17964 (const_string "*")))
17965 (set_attr "mode" "SI")])
17967 (define_insn "sse4_2_crc32di"
17968 [(set (match_operand:DI 0 "register_operand" "=r")
17970 [(match_operand:DI 1 "register_operand" "0")
17971 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17973 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17974 "crc32{q}\t{%2, %0|%0, %2}"
17975 [(set_attr "type" "sselog1")
17976 (set_attr "prefix_rep" "1")
17977 (set_attr "prefix_extra" "1")
17978 (set_attr "mode" "DI")])
17980 (define_insn "rdpmc"
17981 [(set (match_operand:DI 0 "register_operand" "=A")
17982 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17986 [(set_attr "type" "other")
17987 (set_attr "length" "2")])
17989 (define_insn "rdpmc_rex64"
17990 [(set (match_operand:DI 0 "register_operand" "=a")
17991 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17993 (set (match_operand:DI 1 "register_operand" "=d")
17994 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17997 [(set_attr "type" "other")
17998 (set_attr "length" "2")])
18000 (define_insn "rdtsc"
18001 [(set (match_operand:DI 0 "register_operand" "=A")
18002 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18005 [(set_attr "type" "other")
18006 (set_attr "length" "2")])
18008 (define_insn "rdtsc_rex64"
18009 [(set (match_operand:DI 0 "register_operand" "=a")
18010 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18011 (set (match_operand:DI 1 "register_operand" "=d")
18012 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18015 [(set_attr "type" "other")
18016 (set_attr "length" "2")])
18018 (define_insn "rdtscp"
18019 [(set (match_operand:DI 0 "register_operand" "=A")
18020 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18021 (set (match_operand:SI 1 "register_operand" "=c")
18022 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18025 [(set_attr "type" "other")
18026 (set_attr "length" "3")])
18028 (define_insn "rdtscp_rex64"
18029 [(set (match_operand:DI 0 "register_operand" "=a")
18030 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18031 (set (match_operand:DI 1 "register_operand" "=d")
18032 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18033 (set (match_operand:SI 2 "register_operand" "=c")
18034 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18037 [(set_attr "type" "other")
18038 (set_attr "length" "3")])
18040 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18042 ;; FXSR, XSAVE and XSAVEOPT instructions
18044 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18046 (define_insn "fxsave"
18047 [(set (match_operand:BLK 0 "memory_operand" "=m")
18048 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18051 [(set_attr "type" "other")
18052 (set_attr "memory" "store")
18053 (set (attr "length")
18054 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18056 (define_insn "fxsave64"
18057 [(set (match_operand:BLK 0 "memory_operand" "=m")
18058 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18059 "TARGET_64BIT && TARGET_FXSR"
18061 [(set_attr "type" "other")
18062 (set_attr "memory" "store")
18063 (set (attr "length")
18064 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18066 (define_insn "fxrstor"
18067 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18071 [(set_attr "type" "other")
18072 (set_attr "memory" "load")
18073 (set (attr "length")
18074 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18076 (define_insn "fxrstor64"
18077 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18078 UNSPECV_FXRSTOR64)]
18079 "TARGET_64BIT && TARGET_FXSR"
18081 [(set_attr "type" "other")
18082 (set_attr "memory" "load")
18083 (set (attr "length")
18084 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18086 (define_int_iterator ANY_XSAVE
18088 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
18090 (define_int_iterator ANY_XSAVE64
18092 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
18094 (define_int_attr xsave
18095 [(UNSPECV_XSAVE "xsave")
18096 (UNSPECV_XSAVE64 "xsave64")
18097 (UNSPECV_XSAVEOPT "xsaveopt")
18098 (UNSPECV_XSAVEOPT64 "xsaveopt64")])
18100 (define_insn "<xsave>"
18101 [(set (match_operand:BLK 0 "memory_operand" "=m")
18102 (unspec_volatile:BLK
18103 [(match_operand:DI 1 "register_operand" "A")]
18105 "!TARGET_64BIT && TARGET_XSAVE"
18107 [(set_attr "type" "other")
18108 (set_attr "memory" "store")
18109 (set (attr "length")
18110 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18112 (define_insn "<xsave>_rex64"
18113 [(set (match_operand:BLK 0 "memory_operand" "=m")
18114 (unspec_volatile:BLK
18115 [(match_operand:SI 1 "register_operand" "a")
18116 (match_operand:SI 2 "register_operand" "d")]
18118 "TARGET_64BIT && TARGET_XSAVE"
18120 [(set_attr "type" "other")
18121 (set_attr "memory" "store")
18122 (set (attr "length")
18123 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18125 (define_insn "<xsave>"
18126 [(set (match_operand:BLK 0 "memory_operand" "=m")
18127 (unspec_volatile:BLK
18128 [(match_operand:SI 1 "register_operand" "a")
18129 (match_operand:SI 2 "register_operand" "d")]
18131 "TARGET_64BIT && TARGET_XSAVE"
18133 [(set_attr "type" "other")
18134 (set_attr "memory" "store")
18135 (set (attr "length")
18136 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18138 (define_insn "xrstor"
18139 [(unspec_volatile:BLK
18140 [(match_operand:BLK 0 "memory_operand" "m")
18141 (match_operand:DI 1 "register_operand" "A")]
18143 "!TARGET_64BIT && TARGET_XSAVE"
18145 [(set_attr "type" "other")
18146 (set_attr "memory" "load")
18147 (set (attr "length")
18148 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18150 (define_insn "xrstor_rex64"
18151 [(unspec_volatile:BLK
18152 [(match_operand:BLK 0 "memory_operand" "m")
18153 (match_operand:SI 1 "register_operand" "a")
18154 (match_operand:SI 2 "register_operand" "d")]
18156 "TARGET_64BIT && TARGET_XSAVE"
18158 [(set_attr "type" "other")
18159 (set_attr "memory" "load")
18160 (set (attr "length")
18161 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18163 (define_insn "xrstor64"
18164 [(unspec_volatile:BLK
18165 [(match_operand:BLK 0 "memory_operand" "m")
18166 (match_operand:SI 1 "register_operand" "a")
18167 (match_operand:SI 2 "register_operand" "d")]
18169 "TARGET_64BIT && TARGET_XSAVE"
18171 [(set_attr "type" "other")
18172 (set_attr "memory" "load")
18173 (set (attr "length")
18174 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18176 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18178 ;; LWP instructions
18180 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18182 (define_expand "lwp_llwpcb"
18183 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18184 UNSPECV_LLWP_INTRINSIC)]
18187 (define_insn "*lwp_llwpcb<mode>1"
18188 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18189 UNSPECV_LLWP_INTRINSIC)]
18192 [(set_attr "type" "lwp")
18193 (set_attr "mode" "<MODE>")
18194 (set_attr "length" "5")])
18196 (define_expand "lwp_slwpcb"
18197 [(set (match_operand 0 "register_operand" "=r")
18198 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18203 insn = (Pmode == DImode
18205 : gen_lwp_slwpcbsi);
18207 emit_insn (insn (operands[0]));
18211 (define_insn "lwp_slwpcb<mode>"
18212 [(set (match_operand:P 0 "register_operand" "=r")
18213 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18216 [(set_attr "type" "lwp")
18217 (set_attr "mode" "<MODE>")
18218 (set_attr "length" "5")])
18220 (define_expand "lwp_lwpval<mode>3"
18221 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18222 (match_operand:SI 2 "nonimmediate_operand" "rm")
18223 (match_operand:SI 3 "const_int_operand" "i")]
18224 UNSPECV_LWPVAL_INTRINSIC)]
18226 ;; Avoid unused variable warning.
18227 "(void) operands[0];")
18229 (define_insn "*lwp_lwpval<mode>3_1"
18230 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18231 (match_operand:SI 1 "nonimmediate_operand" "rm")
18232 (match_operand:SI 2 "const_int_operand" "i")]
18233 UNSPECV_LWPVAL_INTRINSIC)]
18235 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18236 [(set_attr "type" "lwp")
18237 (set_attr "mode" "<MODE>")
18238 (set (attr "length")
18239 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18241 (define_expand "lwp_lwpins<mode>3"
18242 [(set (reg:CCC FLAGS_REG)
18243 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18244 (match_operand:SI 2 "nonimmediate_operand" "rm")
18245 (match_operand:SI 3 "const_int_operand" "i")]
18246 UNSPECV_LWPINS_INTRINSIC))
18247 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18248 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18251 (define_insn "*lwp_lwpins<mode>3_1"
18252 [(set (reg:CCC FLAGS_REG)
18253 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18254 (match_operand:SI 1 "nonimmediate_operand" "rm")
18255 (match_operand:SI 2 "const_int_operand" "i")]
18256 UNSPECV_LWPINS_INTRINSIC))]
18258 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18259 [(set_attr "type" "lwp")
18260 (set_attr "mode" "<MODE>")
18261 (set (attr "length")
18262 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18264 (define_int_iterator RDFSGSBASE
18268 (define_int_iterator WRFSGSBASE
18272 (define_int_attr fsgs
18273 [(UNSPECV_RDFSBASE "fs")
18274 (UNSPECV_RDGSBASE "gs")
18275 (UNSPECV_WRFSBASE "fs")
18276 (UNSPECV_WRGSBASE "gs")])
18278 (define_insn "rd<fsgs>base<mode>"
18279 [(set (match_operand:SWI48 0 "register_operand" "=r")
18280 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18281 "TARGET_64BIT && TARGET_FSGSBASE"
18283 [(set_attr "type" "other")
18284 (set_attr "prefix_extra" "2")])
18286 (define_insn "wr<fsgs>base<mode>"
18287 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18289 "TARGET_64BIT && TARGET_FSGSBASE"
18291 [(set_attr "type" "other")
18292 (set_attr "prefix_extra" "2")])
18294 (define_insn "rdrand<mode>_1"
18295 [(set (match_operand:SWI248 0 "register_operand" "=r")
18296 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18297 (set (reg:CCC FLAGS_REG)
18298 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18301 [(set_attr "type" "other")
18302 (set_attr "prefix_extra" "1")])
18304 (define_insn "rdseed<mode>_1"
18305 [(set (match_operand:SWI248 0 "register_operand" "=r")
18306 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18307 (set (reg:CCC FLAGS_REG)
18308 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18311 [(set_attr "type" "other")
18312 (set_attr "prefix_extra" "1")])
18314 (define_expand "pause"
18315 [(set (match_dup 0)
18316 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18319 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18320 MEM_VOLATILE_P (operands[0]) = 1;
18323 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18324 ;; They have the same encoding.
18325 (define_insn "*pause"
18326 [(set (match_operand:BLK 0)
18327 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18330 [(set_attr "length" "2")
18331 (set_attr "memory" "unknown")])
18333 (define_expand "xbegin"
18334 [(set (match_operand:SI 0 "register_operand")
18335 (unspec_volatile:SI [(match_dup 1)] UNSPECV_XBEGIN))]
18338 rtx label = gen_label_rtx ();
18340 operands[1] = force_reg (SImode, constm1_rtx);
18342 emit_jump_insn (gen_xbegin_1 (operands[1], label));
18344 emit_label (label);
18345 LABEL_NUSES (label) = 1;
18347 emit_move_insn (operands[0], operands[1]);
18352 (define_insn "xbegin_1"
18354 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18356 (label_ref (match_operand 1))
18358 (set (match_operand:SI 0 "register_operand" "+a")
18359 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18362 [(set_attr "type" "other")
18363 (set_attr "length" "6")])
18365 (define_insn "xend"
18366 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18369 [(set_attr "type" "other")
18370 (set_attr "length" "3")])
18372 (define_insn "xabort"
18373 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18377 [(set_attr "type" "other")
18378 (set_attr "length" "3")])
18380 (define_expand "xtest"
18381 [(set (match_operand:QI 0 "register_operand")
18382 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18385 emit_insn (gen_xtest_1 ());
18387 ix86_expand_setcc (operands[0], NE,
18388 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18392 (define_insn "xtest_1"
18393 [(set (reg:CCZ FLAGS_REG)
18394 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18397 [(set_attr "type" "other")
18398 (set_attr "length" "3")])
18402 (include "sync.md")