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
206 ;; For RDRAND support
209 ;; For RDSEED support
219 ;; Constants to represent rounding modes in the ROUND instruction
228 ;; Constants to represent pcomtrue/pcomfalse variants
238 ;; Constants used in the XOP pperm instruction
240 [(PPERM_SRC 0x00) /* copy source */
241 (PPERM_INVERT 0x20) /* invert source */
242 (PPERM_REVERSE 0x40) /* bit reverse source */
243 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
244 (PPERM_ZERO 0x80) /* all 0's */
245 (PPERM_ONES 0xa0) /* all 1's */
246 (PPERM_SIGN 0xc0) /* propagate sign bit */
247 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
248 (PPERM_SRC1 0x00) /* use first source byte */
249 (PPERM_SRC2 0x10) /* use second source byte */
252 ;; Registers by name.
305 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
308 ;; In C guard expressions, put expressions which may be compile-time
309 ;; constants first. This allows for better optimization. For
310 ;; example, write "TARGET_64BIT && reload_completed", not
311 ;; "reload_completed && TARGET_64BIT".
315 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
316 atom,generic64,amdfam10,bdver1,bdver2,btver1,btver2"
317 (const (symbol_ref "ix86_schedule")))
319 ;; A basic instruction type. Refinements due to arguments to be
320 ;; provided in other attributes.
323 alu,alu1,negnot,imov,imovx,lea,
324 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
325 icmp,test,ibr,setcc,icmov,
326 push,pop,call,callv,leave,
328 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
329 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
330 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
331 ssemuladd,sse4arg,lwp,
332 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
333 (const_string "other"))
335 ;; Main data type used by the insn
337 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
338 (const_string "unknown"))
340 ;; The CPU unit operations uses.
341 (define_attr "unit" "integer,i387,sse,mmx,unknown"
342 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
343 (const_string "i387")
344 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
345 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
346 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
348 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
350 (eq_attr "type" "other")
351 (const_string "unknown")]
352 (const_string "integer")))
354 ;; The (bounding maximum) length of an instruction immediate.
355 (define_attr "length_immediate" ""
356 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
359 (eq_attr "unit" "i387,sse,mmx")
361 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
362 rotate,rotatex,rotate1,imul,icmp,push,pop")
363 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
364 (eq_attr "type" "imov,test")
365 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
366 (eq_attr "type" "call")
367 (if_then_else (match_operand 0 "constant_call_address_operand")
370 (eq_attr "type" "callv")
371 (if_then_else (match_operand 1 "constant_call_address_operand")
374 ;; We don't know the size before shorten_branches. Expect
375 ;; the instruction to fit for better scheduling.
376 (eq_attr "type" "ibr")
379 (symbol_ref "/* Update immediate_length and other attributes! */
380 gcc_unreachable (),1")))
382 ;; The (bounding maximum) length of an instruction address.
383 (define_attr "length_address" ""
384 (cond [(eq_attr "type" "str,other,multi,fxch")
386 (and (eq_attr "type" "call")
387 (match_operand 0 "constant_call_address_operand"))
389 (and (eq_attr "type" "callv")
390 (match_operand 1 "constant_call_address_operand"))
393 (symbol_ref "ix86_attr_length_address_default (insn)")))
395 ;; Set when length prefix is used.
396 (define_attr "prefix_data16" ""
397 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
399 (eq_attr "mode" "HI")
401 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
406 ;; Set when string REP prefix is used.
407 (define_attr "prefix_rep" ""
408 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
410 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
415 ;; Set when 0f opcode prefix is used.
416 (define_attr "prefix_0f" ""
418 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
419 (eq_attr "unit" "sse,mmx"))
423 ;; Set when REX opcode prefix is used.
424 (define_attr "prefix_rex" ""
425 (cond [(not (match_test "TARGET_64BIT"))
427 (and (eq_attr "mode" "DI")
428 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
429 (eq_attr "unit" "!mmx")))
431 (and (eq_attr "mode" "QI")
432 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
434 (match_test "x86_extended_reg_mentioned_p (insn)")
436 (and (eq_attr "type" "imovx")
437 (match_operand:QI 1 "ext_QIreg_operand"))
442 ;; There are also additional prefixes in 3DNOW, SSSE3.
443 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
444 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
445 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
446 (define_attr "prefix_extra" ""
447 (cond [(eq_attr "type" "ssemuladd,sse4arg")
449 (eq_attr "type" "sseiadd1,ssecvt1")
454 ;; Prefix used: original, VEX or maybe VEX.
455 (define_attr "prefix" "orig,vex,maybe_vex"
456 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
458 (const_string "orig")))
460 ;; VEX W bit is used.
461 (define_attr "prefix_vex_w" "" (const_int 0))
463 ;; The length of VEX prefix
464 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
465 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
466 ;; still prefix_0f 1, with prefix_extra 1.
467 (define_attr "length_vex" ""
468 (if_then_else (and (eq_attr "prefix_0f" "1")
469 (eq_attr "prefix_extra" "0"))
470 (if_then_else (eq_attr "prefix_vex_w" "1")
471 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
472 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
473 (if_then_else (eq_attr "prefix_vex_w" "1")
474 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
475 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
477 ;; Set when modrm byte is used.
478 (define_attr "modrm" ""
479 (cond [(eq_attr "type" "str,leave")
481 (eq_attr "unit" "i387")
483 (and (eq_attr "type" "incdec")
484 (and (not (match_test "TARGET_64BIT"))
485 (ior (match_operand:SI 1 "register_operand")
486 (match_operand:HI 1 "register_operand"))))
488 (and (eq_attr "type" "push")
489 (not (match_operand 1 "memory_operand")))
491 (and (eq_attr "type" "pop")
492 (not (match_operand 0 "memory_operand")))
494 (and (eq_attr "type" "imov")
495 (and (not (eq_attr "mode" "DI"))
496 (ior (and (match_operand 0 "register_operand")
497 (match_operand 1 "immediate_operand"))
498 (ior (and (match_operand 0 "ax_reg_operand")
499 (match_operand 1 "memory_displacement_only_operand"))
500 (and (match_operand 0 "memory_displacement_only_operand")
501 (match_operand 1 "ax_reg_operand"))))))
503 (and (eq_attr "type" "call")
504 (match_operand 0 "constant_call_address_operand"))
506 (and (eq_attr "type" "callv")
507 (match_operand 1 "constant_call_address_operand"))
509 (and (eq_attr "type" "alu,alu1,icmp,test")
510 (match_operand 0 "ax_reg_operand"))
511 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
515 ;; The (bounding maximum) length of an instruction in bytes.
516 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
517 ;; Later we may want to split them and compute proper length as for
519 (define_attr "length" ""
520 (cond [(eq_attr "type" "other,multi,fistp,frndint")
522 (eq_attr "type" "fcmp")
524 (eq_attr "unit" "i387")
526 (plus (attr "prefix_data16")
527 (attr "length_address")))
528 (ior (eq_attr "prefix" "vex")
529 (and (eq_attr "prefix" "maybe_vex")
530 (match_test "TARGET_AVX")))
531 (plus (attr "length_vex")
532 (plus (attr "length_immediate")
534 (attr "length_address"))))]
535 (plus (plus (attr "modrm")
536 (plus (attr "prefix_0f")
537 (plus (attr "prefix_rex")
538 (plus (attr "prefix_extra")
540 (plus (attr "prefix_rep")
541 (plus (attr "prefix_data16")
542 (plus (attr "length_immediate")
543 (attr "length_address")))))))
545 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
546 ;; `store' if there is a simple memory reference therein, or `unknown'
547 ;; if the instruction is complex.
549 (define_attr "memory" "none,load,store,both,unknown"
550 (cond [(eq_attr "type" "other,multi,str,lwp")
551 (const_string "unknown")
552 (eq_attr "type" "lea,fcmov,fpspc")
553 (const_string "none")
554 (eq_attr "type" "fistp,leave")
555 (const_string "both")
556 (eq_attr "type" "frndint")
557 (const_string "load")
558 (eq_attr "type" "push")
559 (if_then_else (match_operand 1 "memory_operand")
560 (const_string "both")
561 (const_string "store"))
562 (eq_attr "type" "pop")
563 (if_then_else (match_operand 0 "memory_operand")
564 (const_string "both")
565 (const_string "load"))
566 (eq_attr "type" "setcc")
567 (if_then_else (match_operand 0 "memory_operand")
568 (const_string "store")
569 (const_string "none"))
570 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
571 (if_then_else (ior (match_operand 0 "memory_operand")
572 (match_operand 1 "memory_operand"))
573 (const_string "load")
574 (const_string "none"))
575 (eq_attr "type" "ibr")
576 (if_then_else (match_operand 0 "memory_operand")
577 (const_string "load")
578 (const_string "none"))
579 (eq_attr "type" "call")
580 (if_then_else (match_operand 0 "constant_call_address_operand")
581 (const_string "none")
582 (const_string "load"))
583 (eq_attr "type" "callv")
584 (if_then_else (match_operand 1 "constant_call_address_operand")
585 (const_string "none")
586 (const_string "load"))
587 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
588 (match_operand 1 "memory_operand"))
589 (const_string "both")
590 (and (match_operand 0 "memory_operand")
591 (match_operand 1 "memory_operand"))
592 (const_string "both")
593 (match_operand 0 "memory_operand")
594 (const_string "store")
595 (match_operand 1 "memory_operand")
596 (const_string "load")
598 "!alu1,negnot,ishift1,
599 imov,imovx,icmp,test,bitmanip,
601 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
602 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
603 (match_operand 2 "memory_operand"))
604 (const_string "load")
605 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
606 (match_operand 3 "memory_operand"))
607 (const_string "load")
609 (const_string "none")))
611 ;; Indicates if an instruction has both an immediate and a displacement.
613 (define_attr "imm_disp" "false,true,unknown"
614 (cond [(eq_attr "type" "other,multi")
615 (const_string "unknown")
616 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
617 (and (match_operand 0 "memory_displacement_operand")
618 (match_operand 1 "immediate_operand")))
619 (const_string "true")
620 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
621 (and (match_operand 0 "memory_displacement_operand")
622 (match_operand 2 "immediate_operand")))
623 (const_string "true")
625 (const_string "false")))
627 ;; Indicates if an FP operation has an integer source.
629 (define_attr "fp_int_src" "false,true"
630 (const_string "false"))
632 ;; Defines rounding mode of an FP operation.
634 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
635 (const_string "any"))
637 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
638 (define_attr "use_carry" "0,1" (const_string "0"))
640 ;; Define attribute to indicate unaligned ssemov insns
641 (define_attr "movu" "0,1" (const_string "0"))
643 ;; Used to control the "enabled" attribute on a per-instruction basis.
644 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,
645 avx2,noavx2,bmi2,fma,fma4"
646 (const_string "base"))
648 (define_attr "enabled" ""
649 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
650 (eq_attr "isa" "sse2_noavx")
651 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
652 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
653 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
654 (eq_attr "isa" "sse4_noavx")
655 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
656 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
657 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
658 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
659 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
660 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
661 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
662 ;; Disable generation of FMA4 instructions for generic code
663 ;; since FMA3 is preferred for targets that implement both
665 (eq_attr "isa" "fma4")
666 (symbol_ref "TARGET_FMA4 && !TARGET_FMA")
670 ;; Describe a user's asm statement.
671 (define_asm_attributes
672 [(set_attr "length" "128")
673 (set_attr "type" "multi")])
675 (define_code_iterator plusminus [plus minus])
677 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
679 ;; Base name for define_insn
680 (define_code_attr plusminus_insn
681 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
682 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
684 ;; Base name for insn mnemonic.
685 (define_code_attr plusminus_mnemonic
686 [(plus "add") (ss_plus "adds") (us_plus "addus")
687 (minus "sub") (ss_minus "subs") (us_minus "subus")])
688 (define_code_attr plusminus_carry_mnemonic
689 [(plus "adc") (minus "sbb")])
691 ;; Mark commutative operators as such in constraints.
692 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
693 (minus "") (ss_minus "") (us_minus "")])
695 ;; Mapping of max and min
696 (define_code_iterator maxmin [smax smin umax umin])
698 ;; Mapping of signed max and min
699 (define_code_iterator smaxmin [smax smin])
701 ;; Mapping of unsigned max and min
702 (define_code_iterator umaxmin [umax umin])
704 ;; Base name for integer and FP insn mnemonic
705 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
706 (umax "maxu") (umin "minu")])
707 (define_code_attr maxmin_float [(smax "max") (smin "min")])
709 ;; Mapping of logic operators
710 (define_code_iterator any_logic [and ior xor])
711 (define_code_iterator any_or [ior xor])
713 ;; Base name for insn mnemonic.
714 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
716 ;; Mapping of logic-shift operators
717 (define_code_iterator any_lshift [ashift lshiftrt])
719 ;; Mapping of shift-right operators
720 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
722 ;; Mapping of all shift operators
723 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
725 ;; Base name for define_insn
726 (define_code_attr shift_insn
727 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
729 ;; Base name for insn mnemonic.
730 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
731 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
733 ;; Mapping of rotate operators
734 (define_code_iterator any_rotate [rotate rotatert])
736 ;; Base name for define_insn
737 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
739 ;; Base name for insn mnemonic.
740 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
742 ;; Mapping of abs neg operators
743 (define_code_iterator absneg [abs neg])
745 ;; Base name for x87 insn mnemonic.
746 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
748 ;; Used in signed and unsigned widening multiplications.
749 (define_code_iterator any_extend [sign_extend zero_extend])
751 ;; Prefix for insn menmonic.
752 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
754 ;; Prefix for define_insn
755 (define_code_attr u [(sign_extend "") (zero_extend "u")])
756 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
757 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
759 ;; All integer modes.
760 (define_mode_iterator SWI1248x [QI HI SI DI])
762 ;; All integer modes without QImode.
763 (define_mode_iterator SWI248x [HI SI DI])
765 ;; All integer modes without QImode and HImode.
766 (define_mode_iterator SWI48x [SI DI])
768 ;; All integer modes without SImode and DImode.
769 (define_mode_iterator SWI12 [QI HI])
771 ;; All integer modes without DImode.
772 (define_mode_iterator SWI124 [QI HI SI])
774 ;; All integer modes without QImode and DImode.
775 (define_mode_iterator SWI24 [HI SI])
777 ;; Single word integer modes.
778 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
780 ;; Single word integer modes without QImode.
781 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
783 ;; Single word integer modes without QImode and HImode.
784 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
786 ;; All math-dependant single and double word integer modes.
787 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
788 (HI "TARGET_HIMODE_MATH")
789 SI DI (TI "TARGET_64BIT")])
791 ;; Math-dependant single word integer modes.
792 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
793 (HI "TARGET_HIMODE_MATH")
794 SI (DI "TARGET_64BIT")])
796 ;; Math-dependant integer modes without DImode.
797 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
798 (HI "TARGET_HIMODE_MATH")
801 ;; Math-dependant single word integer modes without QImode.
802 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
803 SI (DI "TARGET_64BIT")])
805 ;; Double word integer modes.
806 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
807 (TI "TARGET_64BIT")])
809 ;; Double word integer modes as mode attribute.
810 (define_mode_attr DWI [(SI "DI") (DI "TI")])
811 (define_mode_attr dwi [(SI "di") (DI "ti")])
813 ;; Half mode for double word integer modes.
814 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
815 (DI "TARGET_64BIT")])
817 ;; Instruction suffix for integer modes.
818 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
820 ;; Pointer size prefix for integer modes (Intel asm dialect)
821 (define_mode_attr iptrsize [(QI "BYTE")
826 ;; Register class for integer modes.
827 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
829 ;; Immediate operand constraint for integer modes.
830 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
832 ;; General operand constraint for word modes.
833 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
835 ;; Immediate operand constraint for double integer modes.
836 (define_mode_attr di [(SI "nF") (DI "e")])
838 ;; Immediate operand constraint for shifts.
839 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
841 ;; General operand predicate for integer modes.
842 (define_mode_attr general_operand
843 [(QI "general_operand")
844 (HI "general_operand")
845 (SI "x86_64_general_operand")
846 (DI "x86_64_general_operand")
847 (TI "x86_64_general_operand")])
849 ;; General sign/zero extend operand predicate for integer modes.
850 (define_mode_attr general_szext_operand
851 [(QI "general_operand")
852 (HI "general_operand")
853 (SI "x86_64_szext_general_operand")
854 (DI "x86_64_szext_general_operand")])
856 ;; Immediate operand predicate for integer modes.
857 (define_mode_attr immediate_operand
858 [(QI "immediate_operand")
859 (HI "immediate_operand")
860 (SI "x86_64_immediate_operand")
861 (DI "x86_64_immediate_operand")])
863 ;; Nonmemory operand predicate for integer modes.
864 (define_mode_attr nonmemory_operand
865 [(QI "nonmemory_operand")
866 (HI "nonmemory_operand")
867 (SI "x86_64_nonmemory_operand")
868 (DI "x86_64_nonmemory_operand")])
870 ;; Operand predicate for shifts.
871 (define_mode_attr shift_operand
872 [(QI "nonimmediate_operand")
873 (HI "nonimmediate_operand")
874 (SI "nonimmediate_operand")
875 (DI "shiftdi_operand")
876 (TI "register_operand")])
878 ;; Operand predicate for shift argument.
879 (define_mode_attr shift_immediate_operand
880 [(QI "const_1_to_31_operand")
881 (HI "const_1_to_31_operand")
882 (SI "const_1_to_31_operand")
883 (DI "const_1_to_63_operand")])
885 ;; Input operand predicate for arithmetic left shifts.
886 (define_mode_attr ashl_input_operand
887 [(QI "nonimmediate_operand")
888 (HI "nonimmediate_operand")
889 (SI "nonimmediate_operand")
890 (DI "ashldi_input_operand")
891 (TI "reg_or_pm1_operand")])
893 ;; SSE and x87 SFmode and DFmode floating point modes
894 (define_mode_iterator MODEF [SF DF])
896 ;; All x87 floating point modes
897 (define_mode_iterator X87MODEF [SF DF XF])
899 ;; SSE instruction suffix for various modes
900 (define_mode_attr ssemodesuffix
902 (V8SF "ps") (V4DF "pd")
903 (V4SF "ps") (V2DF "pd")
904 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
905 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
907 ;; SSE vector suffix for floating point modes
908 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
910 ;; SSE vector mode corresponding to a scalar mode
911 (define_mode_attr ssevecmode
912 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
914 ;; Instruction suffix for REX 64bit operators.
915 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
917 ;; This mode iterator allows :P to be used for patterns that operate on
918 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
919 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
921 ;; This mode iterator allows :W to be used for patterns that operate on
922 ;; word_mode sized quantities.
923 (define_mode_iterator W
924 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
926 ;; This mode iterator allows :PTR to be used for patterns that operate on
927 ;; ptr_mode sized quantities.
928 (define_mode_iterator PTR
929 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
931 ;; Scheduling descriptions
933 (include "pentium.md")
936 (include "athlon.md")
937 (include "bdver1.md")
943 ;; Operand and operator predicates and constraints
945 (include "predicates.md")
946 (include "constraints.md")
949 ;; Compare and branch/compare and store instructions.
951 (define_expand "cbranch<mode>4"
952 [(set (reg:CC FLAGS_REG)
953 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
954 (match_operand:SDWIM 2 "<general_operand>")))
955 (set (pc) (if_then_else
956 (match_operator 0 "ordered_comparison_operator"
957 [(reg:CC FLAGS_REG) (const_int 0)])
958 (label_ref (match_operand 3))
962 if (MEM_P (operands[1]) && MEM_P (operands[2]))
963 operands[1] = force_reg (<MODE>mode, operands[1]);
964 ix86_expand_branch (GET_CODE (operands[0]),
965 operands[1], operands[2], operands[3]);
969 (define_expand "cstore<mode>4"
970 [(set (reg:CC FLAGS_REG)
971 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
972 (match_operand:SWIM 3 "<general_operand>")))
973 (set (match_operand:QI 0 "register_operand")
974 (match_operator 1 "ordered_comparison_operator"
975 [(reg:CC FLAGS_REG) (const_int 0)]))]
978 if (MEM_P (operands[2]) && MEM_P (operands[3]))
979 operands[2] = force_reg (<MODE>mode, operands[2]);
980 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
981 operands[2], operands[3]);
985 (define_expand "cmp<mode>_1"
986 [(set (reg:CC FLAGS_REG)
987 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
988 (match_operand:SWI48 1 "<general_operand>")))])
990 (define_insn "*cmp<mode>_ccno_1"
991 [(set (reg FLAGS_REG)
992 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
993 (match_operand:SWI 1 "const0_operand")))]
994 "ix86_match_ccmode (insn, CCNOmode)"
996 test{<imodesuffix>}\t%0, %0
997 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
998 [(set_attr "type" "test,icmp")
999 (set_attr "length_immediate" "0,1")
1000 (set_attr "mode" "<MODE>")])
1002 (define_insn "*cmp<mode>_1"
1003 [(set (reg FLAGS_REG)
1004 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1005 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1006 "ix86_match_ccmode (insn, CCmode)"
1007 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1008 [(set_attr "type" "icmp")
1009 (set_attr "mode" "<MODE>")])
1011 (define_insn "*cmp<mode>_minus_1"
1012 [(set (reg FLAGS_REG)
1014 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1015 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1017 "ix86_match_ccmode (insn, CCGOCmode)"
1018 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1019 [(set_attr "type" "icmp")
1020 (set_attr "mode" "<MODE>")])
1022 (define_insn "*cmpqi_ext_1"
1023 [(set (reg FLAGS_REG)
1025 (match_operand:QI 0 "general_operand" "Qm")
1028 (match_operand 1 "ext_register_operand" "Q")
1030 (const_int 8)) 0)))]
1031 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1032 "cmp{b}\t{%h1, %0|%0, %h1}"
1033 [(set_attr "type" "icmp")
1034 (set_attr "mode" "QI")])
1036 (define_insn "*cmpqi_ext_1_rex64"
1037 [(set (reg FLAGS_REG)
1039 (match_operand:QI 0 "register_operand" "Q")
1042 (match_operand 1 "ext_register_operand" "Q")
1044 (const_int 8)) 0)))]
1045 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1046 "cmp{b}\t{%h1, %0|%0, %h1}"
1047 [(set_attr "type" "icmp")
1048 (set_attr "mode" "QI")])
1050 (define_insn "*cmpqi_ext_2"
1051 [(set (reg FLAGS_REG)
1055 (match_operand 0 "ext_register_operand" "Q")
1058 (match_operand:QI 1 "const0_operand")))]
1059 "ix86_match_ccmode (insn, CCNOmode)"
1061 [(set_attr "type" "test")
1062 (set_attr "length_immediate" "0")
1063 (set_attr "mode" "QI")])
1065 (define_expand "cmpqi_ext_3"
1066 [(set (reg:CC FLAGS_REG)
1070 (match_operand 0 "ext_register_operand")
1073 (match_operand:QI 1 "immediate_operand")))])
1075 (define_insn "*cmpqi_ext_3_insn"
1076 [(set (reg FLAGS_REG)
1080 (match_operand 0 "ext_register_operand" "Q")
1083 (match_operand:QI 1 "general_operand" "Qmn")))]
1084 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1085 "cmp{b}\t{%1, %h0|%h0, %1}"
1086 [(set_attr "type" "icmp")
1087 (set_attr "modrm" "1")
1088 (set_attr "mode" "QI")])
1090 (define_insn "*cmpqi_ext_3_insn_rex64"
1091 [(set (reg FLAGS_REG)
1095 (match_operand 0 "ext_register_operand" "Q")
1098 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1099 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1100 "cmp{b}\t{%1, %h0|%h0, %1}"
1101 [(set_attr "type" "icmp")
1102 (set_attr "modrm" "1")
1103 (set_attr "mode" "QI")])
1105 (define_insn "*cmpqi_ext_4"
1106 [(set (reg FLAGS_REG)
1110 (match_operand 0 "ext_register_operand" "Q")
1115 (match_operand 1 "ext_register_operand" "Q")
1117 (const_int 8)) 0)))]
1118 "ix86_match_ccmode (insn, CCmode)"
1119 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1120 [(set_attr "type" "icmp")
1121 (set_attr "mode" "QI")])
1123 ;; These implement float point compares.
1124 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1125 ;; which would allow mix and match FP modes on the compares. Which is what
1126 ;; the old patterns did, but with many more of them.
1128 (define_expand "cbranchxf4"
1129 [(set (reg:CC FLAGS_REG)
1130 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1131 (match_operand:XF 2 "nonmemory_operand")))
1132 (set (pc) (if_then_else
1133 (match_operator 0 "ix86_fp_comparison_operator"
1136 (label_ref (match_operand 3))
1140 ix86_expand_branch (GET_CODE (operands[0]),
1141 operands[1], operands[2], operands[3]);
1145 (define_expand "cstorexf4"
1146 [(set (reg:CC FLAGS_REG)
1147 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1148 (match_operand:XF 3 "nonmemory_operand")))
1149 (set (match_operand:QI 0 "register_operand")
1150 (match_operator 1 "ix86_fp_comparison_operator"
1155 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1156 operands[2], operands[3]);
1160 (define_expand "cbranch<mode>4"
1161 [(set (reg:CC FLAGS_REG)
1162 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1163 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1164 (set (pc) (if_then_else
1165 (match_operator 0 "ix86_fp_comparison_operator"
1168 (label_ref (match_operand 3))
1170 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1172 ix86_expand_branch (GET_CODE (operands[0]),
1173 operands[1], operands[2], operands[3]);
1177 (define_expand "cstore<mode>4"
1178 [(set (reg:CC FLAGS_REG)
1179 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1180 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1181 (set (match_operand:QI 0 "register_operand")
1182 (match_operator 1 "ix86_fp_comparison_operator"
1185 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1187 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1188 operands[2], operands[3]);
1192 (define_expand "cbranchcc4"
1193 [(set (pc) (if_then_else
1194 (match_operator 0 "comparison_operator"
1195 [(match_operand 1 "flags_reg_operand")
1196 (match_operand 2 "const0_operand")])
1197 (label_ref (match_operand 3))
1201 ix86_expand_branch (GET_CODE (operands[0]),
1202 operands[1], operands[2], operands[3]);
1206 (define_expand "cstorecc4"
1207 [(set (match_operand:QI 0 "register_operand")
1208 (match_operator 1 "comparison_operator"
1209 [(match_operand 2 "flags_reg_operand")
1210 (match_operand 3 "const0_operand")]))]
1213 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1214 operands[2], operands[3]);
1219 ;; FP compares, step 1:
1220 ;; Set the FP condition codes.
1222 ;; CCFPmode compare with exceptions
1223 ;; CCFPUmode compare with no exceptions
1225 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1226 ;; used to manage the reg stack popping would not be preserved.
1228 (define_insn "*cmpfp_0"
1229 [(set (match_operand:HI 0 "register_operand" "=a")
1232 (match_operand 1 "register_operand" "f")
1233 (match_operand 2 "const0_operand"))]
1235 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1236 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1237 "* return output_fp_compare (insn, operands, false, false);"
1238 [(set_attr "type" "multi")
1239 (set_attr "unit" "i387")
1241 (cond [(match_operand:SF 1)
1243 (match_operand:DF 1)
1246 (const_string "XF")))])
1248 (define_insn_and_split "*cmpfp_0_cc"
1249 [(set (reg:CCFP FLAGS_REG)
1251 (match_operand 1 "register_operand" "f")
1252 (match_operand 2 "const0_operand")))
1253 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1254 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1255 && TARGET_SAHF && !TARGET_CMOVE
1256 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1258 "&& reload_completed"
1261 [(compare:CCFP (match_dup 1)(match_dup 2))]
1263 (set (reg:CC FLAGS_REG)
1264 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1266 [(set_attr "type" "multi")
1267 (set_attr "unit" "i387")
1269 (cond [(match_operand:SF 1)
1271 (match_operand:DF 1)
1274 (const_string "XF")))])
1276 (define_insn "*cmpfp_xf"
1277 [(set (match_operand:HI 0 "register_operand" "=a")
1280 (match_operand:XF 1 "register_operand" "f")
1281 (match_operand:XF 2 "register_operand" "f"))]
1284 "* return output_fp_compare (insn, operands, false, false);"
1285 [(set_attr "type" "multi")
1286 (set_attr "unit" "i387")
1287 (set_attr "mode" "XF")])
1289 (define_insn_and_split "*cmpfp_xf_cc"
1290 [(set (reg:CCFP FLAGS_REG)
1292 (match_operand:XF 1 "register_operand" "f")
1293 (match_operand:XF 2 "register_operand" "f")))
1294 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1296 && TARGET_SAHF && !TARGET_CMOVE"
1298 "&& reload_completed"
1301 [(compare:CCFP (match_dup 1)(match_dup 2))]
1303 (set (reg:CC FLAGS_REG)
1304 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1306 [(set_attr "type" "multi")
1307 (set_attr "unit" "i387")
1308 (set_attr "mode" "XF")])
1310 (define_insn "*cmpfp_<mode>"
1311 [(set (match_operand:HI 0 "register_operand" "=a")
1314 (match_operand:MODEF 1 "register_operand" "f")
1315 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1318 "* return output_fp_compare (insn, operands, false, false);"
1319 [(set_attr "type" "multi")
1320 (set_attr "unit" "i387")
1321 (set_attr "mode" "<MODE>")])
1323 (define_insn_and_split "*cmpfp_<mode>_cc"
1324 [(set (reg:CCFP FLAGS_REG)
1326 (match_operand:MODEF 1 "register_operand" "f")
1327 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1328 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1330 && TARGET_SAHF && !TARGET_CMOVE"
1332 "&& reload_completed"
1335 [(compare:CCFP (match_dup 1)(match_dup 2))]
1337 (set (reg:CC FLAGS_REG)
1338 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1340 [(set_attr "type" "multi")
1341 (set_attr "unit" "i387")
1342 (set_attr "mode" "<MODE>")])
1344 (define_insn "*cmpfp_u"
1345 [(set (match_operand:HI 0 "register_operand" "=a")
1348 (match_operand 1 "register_operand" "f")
1349 (match_operand 2 "register_operand" "f"))]
1351 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1352 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1353 "* return output_fp_compare (insn, operands, false, true);"
1354 [(set_attr "type" "multi")
1355 (set_attr "unit" "i387")
1357 (cond [(match_operand:SF 1)
1359 (match_operand:DF 1)
1362 (const_string "XF")))])
1364 (define_insn_and_split "*cmpfp_u_cc"
1365 [(set (reg:CCFPU FLAGS_REG)
1367 (match_operand 1 "register_operand" "f")
1368 (match_operand 2 "register_operand" "f")))
1369 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1370 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1371 && TARGET_SAHF && !TARGET_CMOVE
1372 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1374 "&& reload_completed"
1377 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1379 (set (reg:CC FLAGS_REG)
1380 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1382 [(set_attr "type" "multi")
1383 (set_attr "unit" "i387")
1385 (cond [(match_operand:SF 1)
1387 (match_operand:DF 1)
1390 (const_string "XF")))])
1392 (define_insn "*cmpfp_<mode>"
1393 [(set (match_operand:HI 0 "register_operand" "=a")
1396 (match_operand 1 "register_operand" "f")
1397 (match_operator 3 "float_operator"
1398 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1400 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1401 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1402 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1403 "* return output_fp_compare (insn, operands, false, false);"
1404 [(set_attr "type" "multi")
1405 (set_attr "unit" "i387")
1406 (set_attr "fp_int_src" "true")
1407 (set_attr "mode" "<MODE>")])
1409 (define_insn_and_split "*cmpfp_<mode>_cc"
1410 [(set (reg:CCFP FLAGS_REG)
1412 (match_operand 1 "register_operand" "f")
1413 (match_operator 3 "float_operator"
1414 [(match_operand:SWI24 2 "memory_operand" "m")])))
1415 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1416 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1417 && TARGET_SAHF && !TARGET_CMOVE
1418 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1419 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1421 "&& reload_completed"
1426 (match_op_dup 3 [(match_dup 2)]))]
1428 (set (reg:CC FLAGS_REG)
1429 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1431 [(set_attr "type" "multi")
1432 (set_attr "unit" "i387")
1433 (set_attr "fp_int_src" "true")
1434 (set_attr "mode" "<MODE>")])
1436 ;; FP compares, step 2
1437 ;; Move the fpsw to ax.
1439 (define_insn "x86_fnstsw_1"
1440 [(set (match_operand:HI 0 "register_operand" "=a")
1441 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1444 [(set (attr "length")
1445 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1446 (set_attr "mode" "SI")
1447 (set_attr "unit" "i387")])
1449 ;; FP compares, step 3
1450 ;; Get ax into flags, general case.
1452 (define_insn "x86_sahf_1"
1453 [(set (reg:CC FLAGS_REG)
1454 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1458 #ifndef HAVE_AS_IX86_SAHF
1460 return ASM_BYTE "0x9e";
1465 [(set_attr "length" "1")
1466 (set_attr "athlon_decode" "vector")
1467 (set_attr "amdfam10_decode" "direct")
1468 (set_attr "bdver1_decode" "direct")
1469 (set_attr "mode" "SI")])
1471 ;; Pentium Pro can do steps 1 through 3 in one go.
1472 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1473 ;; (these i387 instructions set flags directly)
1474 (define_insn "*cmpfp_i_mixed"
1475 [(set (reg:CCFP FLAGS_REG)
1476 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1477 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1478 "TARGET_MIX_SSE_I387
1479 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1480 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1481 "* return output_fp_compare (insn, operands, true, false);"
1482 [(set_attr "type" "fcmp,ssecomi")
1483 (set_attr "prefix" "orig,maybe_vex")
1485 (if_then_else (match_operand:SF 1)
1487 (const_string "DF")))
1488 (set (attr "prefix_rep")
1489 (if_then_else (eq_attr "type" "ssecomi")
1491 (const_string "*")))
1492 (set (attr "prefix_data16")
1493 (cond [(eq_attr "type" "fcmp")
1495 (eq_attr "mode" "DF")
1498 (const_string "0")))
1499 (set_attr "athlon_decode" "vector")
1500 (set_attr "amdfam10_decode" "direct")
1501 (set_attr "bdver1_decode" "double")])
1503 (define_insn "*cmpfp_i_sse"
1504 [(set (reg:CCFP FLAGS_REG)
1505 (compare:CCFP (match_operand 0 "register_operand" "x")
1506 (match_operand 1 "nonimmediate_operand" "xm")))]
1508 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1509 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1510 "* return output_fp_compare (insn, operands, true, false);"
1511 [(set_attr "type" "ssecomi")
1512 (set_attr "prefix" "maybe_vex")
1514 (if_then_else (match_operand:SF 1)
1516 (const_string "DF")))
1517 (set_attr "prefix_rep" "0")
1518 (set (attr "prefix_data16")
1519 (if_then_else (eq_attr "mode" "DF")
1521 (const_string "0")))
1522 (set_attr "athlon_decode" "vector")
1523 (set_attr "amdfam10_decode" "direct")
1524 (set_attr "bdver1_decode" "double")])
1526 (define_insn "*cmpfp_i_i387"
1527 [(set (reg:CCFP FLAGS_REG)
1528 (compare:CCFP (match_operand 0 "register_operand" "f")
1529 (match_operand 1 "register_operand" "f")))]
1530 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1532 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1533 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1534 "* return output_fp_compare (insn, operands, true, false);"
1535 [(set_attr "type" "fcmp")
1537 (cond [(match_operand:SF 1)
1539 (match_operand:DF 1)
1542 (const_string "XF")))
1543 (set_attr "athlon_decode" "vector")
1544 (set_attr "amdfam10_decode" "direct")
1545 (set_attr "bdver1_decode" "double")])
1547 (define_insn "*cmpfp_iu_mixed"
1548 [(set (reg:CCFPU FLAGS_REG)
1549 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1550 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1551 "TARGET_MIX_SSE_I387
1552 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1553 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1554 "* return output_fp_compare (insn, operands, true, true);"
1555 [(set_attr "type" "fcmp,ssecomi")
1556 (set_attr "prefix" "orig,maybe_vex")
1558 (if_then_else (match_operand:SF 1)
1560 (const_string "DF")))
1561 (set (attr "prefix_rep")
1562 (if_then_else (eq_attr "type" "ssecomi")
1564 (const_string "*")))
1565 (set (attr "prefix_data16")
1566 (cond [(eq_attr "type" "fcmp")
1568 (eq_attr "mode" "DF")
1571 (const_string "0")))
1572 (set_attr "athlon_decode" "vector")
1573 (set_attr "amdfam10_decode" "direct")
1574 (set_attr "bdver1_decode" "double")])
1576 (define_insn "*cmpfp_iu_sse"
1577 [(set (reg:CCFPU FLAGS_REG)
1578 (compare:CCFPU (match_operand 0 "register_operand" "x")
1579 (match_operand 1 "nonimmediate_operand" "xm")))]
1581 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1582 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1583 "* return output_fp_compare (insn, operands, true, true);"
1584 [(set_attr "type" "ssecomi")
1585 (set_attr "prefix" "maybe_vex")
1587 (if_then_else (match_operand:SF 1)
1589 (const_string "DF")))
1590 (set_attr "prefix_rep" "0")
1591 (set (attr "prefix_data16")
1592 (if_then_else (eq_attr "mode" "DF")
1594 (const_string "0")))
1595 (set_attr "athlon_decode" "vector")
1596 (set_attr "amdfam10_decode" "direct")
1597 (set_attr "bdver1_decode" "double")])
1599 (define_insn "*cmpfp_iu_387"
1600 [(set (reg:CCFPU FLAGS_REG)
1601 (compare:CCFPU (match_operand 0 "register_operand" "f")
1602 (match_operand 1 "register_operand" "f")))]
1603 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1605 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1606 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1607 "* return output_fp_compare (insn, operands, true, true);"
1608 [(set_attr "type" "fcmp")
1610 (cond [(match_operand:SF 1)
1612 (match_operand:DF 1)
1615 (const_string "XF")))
1616 (set_attr "athlon_decode" "vector")
1617 (set_attr "amdfam10_decode" "direct")
1618 (set_attr "bdver1_decode" "direct")])
1620 ;; Push/pop instructions.
1622 (define_insn "*push<mode>2"
1623 [(set (match_operand:DWI 0 "push_operand" "=<")
1624 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1627 [(set_attr "type" "multi")
1628 (set_attr "mode" "<MODE>")])
1631 [(set (match_operand:TI 0 "push_operand")
1632 (match_operand:TI 1 "general_operand"))]
1633 "TARGET_64BIT && reload_completed
1634 && !SSE_REG_P (operands[1])"
1636 "ix86_split_long_move (operands); DONE;")
1638 (define_insn "*pushdi2_rex64"
1639 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1640 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1645 [(set_attr "type" "push,multi")
1646 (set_attr "mode" "DI")])
1648 ;; Convert impossible pushes of immediate to existing instructions.
1649 ;; First try to get scratch register and go through it. In case this
1650 ;; fails, push sign extended lower part first and then overwrite
1651 ;; upper part by 32bit move.
1653 [(match_scratch:DI 2 "r")
1654 (set (match_operand:DI 0 "push_operand")
1655 (match_operand:DI 1 "immediate_operand"))]
1656 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1657 && !x86_64_immediate_operand (operands[1], DImode)"
1658 [(set (match_dup 2) (match_dup 1))
1659 (set (match_dup 0) (match_dup 2))])
1661 ;; We need to define this as both peepholer and splitter for case
1662 ;; peephole2 pass is not run.
1663 ;; "&& 1" is needed to keep it from matching the previous pattern.
1665 [(set (match_operand:DI 0 "push_operand")
1666 (match_operand:DI 1 "immediate_operand"))]
1667 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1668 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1669 [(set (match_dup 0) (match_dup 1))
1670 (set (match_dup 2) (match_dup 3))]
1672 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1674 operands[1] = gen_lowpart (DImode, operands[2]);
1675 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1680 [(set (match_operand:DI 0 "push_operand")
1681 (match_operand:DI 1 "immediate_operand"))]
1682 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1683 ? epilogue_completed : reload_completed)
1684 && !symbolic_operand (operands[1], DImode)
1685 && !x86_64_immediate_operand (operands[1], DImode)"
1686 [(set (match_dup 0) (match_dup 1))
1687 (set (match_dup 2) (match_dup 3))]
1689 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1691 operands[1] = gen_lowpart (DImode, operands[2]);
1692 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1697 [(set (match_operand:DI 0 "push_operand")
1698 (match_operand:DI 1 "general_operand"))]
1699 "!TARGET_64BIT && reload_completed
1700 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1702 "ix86_split_long_move (operands); DONE;")
1704 (define_insn "*pushsi2"
1705 [(set (match_operand:SI 0 "push_operand" "=<")
1706 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1709 [(set_attr "type" "push")
1710 (set_attr "mode" "SI")])
1712 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1713 ;; "push a byte/word". But actually we use pushl, which has the effect
1714 ;; of rounding the amount pushed up to a word.
1716 ;; For TARGET_64BIT we always round up to 8 bytes.
1717 (define_insn "*push<mode>2_rex64"
1718 [(set (match_operand:SWI124 0 "push_operand" "=X")
1719 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1722 [(set_attr "type" "push")
1723 (set_attr "mode" "DI")])
1725 (define_insn "*push<mode>2"
1726 [(set (match_operand:SWI12 0 "push_operand" "=X")
1727 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1730 [(set_attr "type" "push")
1731 (set_attr "mode" "SI")])
1733 (define_insn "*push<mode>2_prologue"
1734 [(set (match_operand:W 0 "push_operand" "=<")
1735 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1736 (clobber (mem:BLK (scratch)))]
1738 "push{<imodesuffix>}\t%1"
1739 [(set_attr "type" "push")
1740 (set_attr "mode" "<MODE>")])
1742 (define_insn "*pop<mode>1"
1743 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1744 (match_operand:W 1 "pop_operand" ">"))]
1746 "pop{<imodesuffix>}\t%0"
1747 [(set_attr "type" "pop")
1748 (set_attr "mode" "<MODE>")])
1750 (define_insn "*pop<mode>1_epilogue"
1751 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1752 (match_operand:W 1 "pop_operand" ">"))
1753 (clobber (mem:BLK (scratch)))]
1755 "pop{<imodesuffix>}\t%0"
1756 [(set_attr "type" "pop")
1757 (set_attr "mode" "<MODE>")])
1759 ;; Move instructions.
1761 (define_expand "movoi"
1762 [(set (match_operand:OI 0 "nonimmediate_operand")
1763 (match_operand:OI 1 "general_operand"))]
1765 "ix86_expand_move (OImode, operands); DONE;")
1767 (define_expand "movti"
1768 [(set (match_operand:TI 0 "nonimmediate_operand")
1769 (match_operand:TI 1 "nonimmediate_operand"))]
1770 "TARGET_64BIT || TARGET_SSE"
1773 ix86_expand_move (TImode, operands);
1774 else if (push_operand (operands[0], TImode))
1775 ix86_expand_push (TImode, operands[1]);
1777 ix86_expand_vector_move (TImode, operands);
1781 ;; This expands to what emit_move_complex would generate if we didn't
1782 ;; have a movti pattern. Having this avoids problems with reload on
1783 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1784 ;; to have around all the time.
1785 (define_expand "movcdi"
1786 [(set (match_operand:CDI 0 "nonimmediate_operand")
1787 (match_operand:CDI 1 "general_operand"))]
1790 if (push_operand (operands[0], CDImode))
1791 emit_move_complex_push (CDImode, operands[0], operands[1]);
1793 emit_move_complex_parts (operands[0], operands[1]);
1797 (define_expand "mov<mode>"
1798 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1799 (match_operand:SWI1248x 1 "general_operand"))]
1801 "ix86_expand_move (<MODE>mode, operands); DONE;")
1803 (define_insn "*mov<mode>_xor"
1804 [(set (match_operand:SWI48 0 "register_operand" "=r")
1805 (match_operand:SWI48 1 "const0_operand"))
1806 (clobber (reg:CC FLAGS_REG))]
1809 [(set_attr "type" "alu1")
1810 (set_attr "mode" "SI")
1811 (set_attr "length_immediate" "0")])
1813 (define_insn "*mov<mode>_or"
1814 [(set (match_operand:SWI48 0 "register_operand" "=r")
1815 (match_operand:SWI48 1 "const_int_operand"))
1816 (clobber (reg:CC FLAGS_REG))]
1818 && operands[1] == constm1_rtx"
1819 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1820 [(set_attr "type" "alu1")
1821 (set_attr "mode" "<MODE>")
1822 (set_attr "length_immediate" "1")])
1824 (define_insn "*movoi_internal_avx"
1825 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1826 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1827 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1829 switch (which_alternative)
1832 return standard_sse_constant_opcode (insn, operands[1]);
1835 if (misaligned_operand (operands[0], OImode)
1836 || misaligned_operand (operands[1], OImode))
1838 if (get_attr_mode (insn) == MODE_V8SF)
1839 return "vmovups\t{%1, %0|%0, %1}";
1841 return "vmovdqu\t{%1, %0|%0, %1}";
1845 if (get_attr_mode (insn) == MODE_V8SF)
1846 return "vmovaps\t{%1, %0|%0, %1}";
1848 return "vmovdqa\t{%1, %0|%0, %1}";
1854 [(set_attr "type" "sselog1,ssemov,ssemov")
1855 (set_attr "prefix" "vex")
1857 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1858 (const_string "V8SF")
1859 (and (eq_attr "alternative" "2")
1860 (match_test "TARGET_SSE_TYPELESS_STORES"))
1861 (const_string "V8SF")
1863 (const_string "OI")))])
1865 (define_insn "*movti_internal_rex64"
1866 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1867 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1868 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1870 switch (which_alternative)
1876 return standard_sse_constant_opcode (insn, operands[1]);
1879 /* TDmode values are passed as TImode on the stack. Moving them
1880 to stack may result in unaligned memory access. */
1881 if (misaligned_operand (operands[0], TImode)
1882 || misaligned_operand (operands[1], TImode))
1884 if (get_attr_mode (insn) == MODE_V4SF)
1885 return "%vmovups\t{%1, %0|%0, %1}";
1887 return "%vmovdqu\t{%1, %0|%0, %1}";
1891 if (get_attr_mode (insn) == MODE_V4SF)
1892 return "%vmovaps\t{%1, %0|%0, %1}";
1894 return "%vmovdqa\t{%1, %0|%0, %1}";
1900 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1901 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1903 (cond [(eq_attr "alternative" "0,1")
1905 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1906 (const_string "V4SF")
1907 (and (eq_attr "alternative" "4")
1908 (match_test "TARGET_SSE_TYPELESS_STORES"))
1909 (const_string "V4SF")
1910 (match_test "TARGET_AVX")
1912 (match_test "optimize_function_for_size_p (cfun)")
1913 (const_string "V4SF")
1915 (const_string "TI")))])
1918 [(set (match_operand:TI 0 "nonimmediate_operand")
1919 (match_operand:TI 1 "general_operand"))]
1921 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1923 "ix86_split_long_move (operands); DONE;")
1925 (define_insn "*movti_internal_sse"
1926 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x ,m")
1927 (match_operand:TI 1 "vector_move_operand" "C ,xm,x"))]
1928 "TARGET_SSE && !TARGET_64BIT
1929 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1931 switch (which_alternative)
1934 return standard_sse_constant_opcode (insn, operands[1]);
1937 /* TDmode values are passed as TImode on the stack. Moving them
1938 to stack may result in unaligned memory access. */
1939 if (misaligned_operand (operands[0], TImode)
1940 || misaligned_operand (operands[1], TImode))
1942 if (get_attr_mode (insn) == MODE_V4SF)
1943 return "%vmovups\t{%1, %0|%0, %1}";
1945 return "%vmovdqu\t{%1, %0|%0, %1}";
1949 if (get_attr_mode (insn) == MODE_V4SF)
1950 return "%vmovaps\t{%1, %0|%0, %1}";
1952 return "%vmovdqa\t{%1, %0|%0, %1}";
1958 [(set_attr "type" "sselog1,ssemov,ssemov")
1959 (set_attr "prefix" "maybe_vex")
1961 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1962 (const_string "V4SF")
1963 (and (eq_attr "alternative" "2")
1964 (match_test "TARGET_SSE_TYPELESS_STORES"))
1965 (const_string "V4SF")
1966 (match_test "TARGET_AVX")
1968 (ior (not (match_test "TARGET_SSE2"))
1969 (match_test "optimize_function_for_size_p (cfun)"))
1970 (const_string "V4SF")
1972 (const_string "TI")))])
1974 (define_insn "*movdi_internal_rex64"
1975 [(set (match_operand:DI 0 "nonimmediate_operand"
1976 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1977 (match_operand:DI 1 "general_operand"
1978 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1979 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1981 switch (get_attr_type (insn))
1984 if (SSE_REG_P (operands[0]))
1985 return "movq2dq\t{%1, %0|%0, %1}";
1987 return "movdq2q\t{%1, %0|%0, %1}";
1990 if (get_attr_mode (insn) == MODE_V4SF)
1991 return "%vmovaps\t{%1, %0|%0, %1}";
1992 else if (get_attr_mode (insn) == MODE_TI)
1993 return "%vmovdqa\t{%1, %0|%0, %1}";
1995 /* Handle broken assemblers that require movd instead of movq. */
1996 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1997 return "%vmovd\t{%1, %0|%0, %1}";
1999 return "%vmovq\t{%1, %0|%0, %1}";
2002 /* Handle broken assemblers that require movd instead of movq. */
2003 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2004 return "movd\t{%1, %0|%0, %1}";
2006 return "movq\t{%1, %0|%0, %1}";
2009 return standard_sse_constant_opcode (insn, operands[1]);
2012 return "pxor\t%0, %0";
2018 return "lea{q}\t{%E1, %0|%0, %E1}";
2021 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2022 if (get_attr_mode (insn) == MODE_SI)
2023 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2024 else if (which_alternative == 2)
2025 return "movabs{q}\t{%1, %0|%0, %1}";
2026 else if (ix86_use_lea_for_mov (insn, operands))
2027 return "lea{q}\t{%E1, %0|%0, %E1}";
2029 return "mov{q}\t{%1, %0|%0, %1}";
2033 (cond [(eq_attr "alternative" "4")
2034 (const_string "multi")
2035 (eq_attr "alternative" "5")
2036 (const_string "mmx")
2037 (eq_attr "alternative" "6,7,8,9")
2038 (const_string "mmxmov")
2039 (eq_attr "alternative" "10")
2040 (const_string "sselog1")
2041 (eq_attr "alternative" "11,12,13,14,15")
2042 (const_string "ssemov")
2043 (eq_attr "alternative" "16,17")
2044 (const_string "ssecvt")
2045 (match_operand 1 "pic_32bit_operand")
2046 (const_string "lea")
2048 (const_string "imov")))
2051 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2053 (const_string "*")))
2054 (set (attr "length_immediate")
2056 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2058 (const_string "*")))
2059 (set (attr "prefix_rex")
2060 (if_then_else (eq_attr "alternative" "8,9")
2062 (const_string "*")))
2063 (set (attr "prefix_data16")
2064 (if_then_else (eq_attr "alternative" "11")
2066 (const_string "*")))
2067 (set (attr "prefix")
2068 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2069 (const_string "maybe_vex")
2070 (const_string "orig")))
2072 (cond [(eq_attr "alternative" "0,4")
2074 (eq_attr "alternative" "10,12")
2075 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2076 (const_string "V4SF")
2077 (match_test "TARGET_AVX")
2079 (match_test "optimize_function_for_size_p (cfun)")
2080 (const_string "V4SF")
2082 (const_string "TI"))
2084 (const_string "DI")))])
2086 ;; Reload patterns to support multi-word load/store
2087 ;; with non-offsetable address.
2088 (define_expand "reload_noff_store"
2089 [(parallel [(match_operand 0 "memory_operand" "=m")
2090 (match_operand 1 "register_operand" "r")
2091 (match_operand:DI 2 "register_operand" "=&r")])]
2094 rtx mem = operands[0];
2095 rtx addr = XEXP (mem, 0);
2097 emit_move_insn (operands[2], addr);
2098 mem = replace_equiv_address_nv (mem, operands[2]);
2100 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2104 (define_expand "reload_noff_load"
2105 [(parallel [(match_operand 0 "register_operand" "=r")
2106 (match_operand 1 "memory_operand" "m")
2107 (match_operand:DI 2 "register_operand" "=r")])]
2110 rtx mem = operands[1];
2111 rtx addr = XEXP (mem, 0);
2113 emit_move_insn (operands[2], addr);
2114 mem = replace_equiv_address_nv (mem, operands[2]);
2116 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2120 ;; Convert impossible stores of immediate to existing instructions.
2121 ;; First try to get scratch register and go through it. In case this
2122 ;; fails, move by 32bit parts.
2124 [(match_scratch:DI 2 "r")
2125 (set (match_operand:DI 0 "memory_operand")
2126 (match_operand:DI 1 "immediate_operand"))]
2127 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2128 && !x86_64_immediate_operand (operands[1], DImode)"
2129 [(set (match_dup 2) (match_dup 1))
2130 (set (match_dup 0) (match_dup 2))])
2132 ;; We need to define this as both peepholer and splitter for case
2133 ;; peephole2 pass is not run.
2134 ;; "&& 1" is needed to keep it from matching the previous pattern.
2136 [(set (match_operand:DI 0 "memory_operand")
2137 (match_operand:DI 1 "immediate_operand"))]
2138 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2139 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2140 [(set (match_dup 2) (match_dup 3))
2141 (set (match_dup 4) (match_dup 5))]
2142 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2145 [(set (match_operand:DI 0 "memory_operand")
2146 (match_operand:DI 1 "immediate_operand"))]
2147 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2148 ? epilogue_completed : reload_completed)
2149 && !symbolic_operand (operands[1], DImode)
2150 && !x86_64_immediate_operand (operands[1], DImode)"
2151 [(set (match_dup 2) (match_dup 3))
2152 (set (match_dup 4) (match_dup 5))]
2153 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2155 (define_insn "*movdi_internal"
2156 [(set (match_operand:DI 0 "nonimmediate_operand"
2157 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2158 (match_operand:DI 1 "general_operand"
2159 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2160 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2162 switch (get_attr_type (insn))
2165 if (SSE_REG_P (operands[0]))
2166 return "movq2dq\t{%1, %0|%0, %1}";
2168 return "movdq2q\t{%1, %0|%0, %1}";
2171 switch (get_attr_mode (insn))
2174 return "%vmovdqa\t{%1, %0|%0, %1}";
2176 return "%vmovq\t{%1, %0|%0, %1}";
2178 return "%vmovaps\t{%1, %0|%0, %1}";
2180 return "movlps\t{%1, %0|%0, %1}";
2186 return "movq\t{%1, %0|%0, %1}";
2189 return standard_sse_constant_opcode (insn, operands[1]);
2192 return "pxor\t%0, %0";
2202 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2203 (const_string "sse2")
2204 (eq_attr "alternative" "9,10,11,12")
2205 (const_string "noavx")
2207 (const_string "*")))
2209 (cond [(eq_attr "alternative" "0,1")
2210 (const_string "multi")
2211 (eq_attr "alternative" "2")
2212 (const_string "mmx")
2213 (eq_attr "alternative" "3,4")
2214 (const_string "mmxmov")
2215 (eq_attr "alternative" "5,9")
2216 (const_string "sselog1")
2217 (eq_attr "alternative" "13,14")
2218 (const_string "ssecvt")
2220 (const_string "ssemov")))
2221 (set (attr "prefix")
2222 (if_then_else (eq_attr "alternative" "5,6,7,8")
2223 (const_string "maybe_vex")
2224 (const_string "orig")))
2226 (cond [(eq_attr "alternative" "9,11")
2227 (const_string "V4SF")
2228 (eq_attr "alternative" "10,12")
2229 (const_string "V2SF")
2230 (eq_attr "alternative" "5,7")
2231 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2232 (const_string "V4SF")
2233 (match_test "TARGET_AVX")
2235 (match_test "optimize_function_for_size_p (cfun)")
2236 (const_string "V4SF")
2238 (const_string "TI"))
2240 (const_string "DI")))])
2243 [(set (match_operand:DI 0 "nonimmediate_operand")
2244 (match_operand:DI 1 "general_operand"))]
2245 "!TARGET_64BIT && reload_completed
2246 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2247 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2249 "ix86_split_long_move (operands); DONE;")
2251 (define_insn "*movsi_internal"
2252 [(set (match_operand:SI 0 "nonimmediate_operand"
2253 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2254 (match_operand:SI 1 "general_operand"
2255 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2256 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2258 switch (get_attr_type (insn))
2261 return standard_sse_constant_opcode (insn, operands[1]);
2264 switch (get_attr_mode (insn))
2267 return "%vmovdqa\t{%1, %0|%0, %1}";
2269 return "%vmovaps\t{%1, %0|%0, %1}";
2271 return "%vmovd\t{%1, %0|%0, %1}";
2273 return "%vmovss\t{%1, %0|%0, %1}";
2279 return "pxor\t%0, %0";
2282 if (get_attr_mode (insn) == MODE_DI)
2283 return "movq\t{%1, %0|%0, %1}";
2284 return "movd\t{%1, %0|%0, %1}";
2287 return "lea{l}\t{%E1, %0|%0, %E1}";
2290 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2291 if (ix86_use_lea_for_mov (insn, operands))
2292 return "lea{l}\t{%E1, %0|%0, %E1}";
2294 return "mov{l}\t{%1, %0|%0, %1}";
2298 (cond [(eq_attr "alternative" "2")
2299 (const_string "mmx")
2300 (eq_attr "alternative" "3,4,5")
2301 (const_string "mmxmov")
2302 (eq_attr "alternative" "6")
2303 (const_string "sselog1")
2304 (eq_attr "alternative" "7,8,9,10,11")
2305 (const_string "ssemov")
2306 (match_operand 1 "pic_32bit_operand")
2307 (const_string "lea")
2309 (const_string "imov")))
2310 (set (attr "prefix")
2311 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2312 (const_string "orig")
2313 (const_string "maybe_vex")))
2314 (set (attr "prefix_data16")
2315 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2317 (const_string "*")))
2319 (cond [(eq_attr "alternative" "2,3")
2321 (eq_attr "alternative" "6,7")
2322 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2323 (const_string "V4SF")
2324 (match_test "TARGET_AVX")
2326 (ior (not (match_test "TARGET_SSE2"))
2327 (match_test "optimize_function_for_size_p (cfun)"))
2328 (const_string "V4SF")
2330 (const_string "TI"))
2331 (and (eq_attr "alternative" "8,9,10,11")
2332 (not (match_test "TARGET_SSE2")))
2335 (const_string "SI")))])
2337 (define_insn "*movhi_internal"
2338 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2339 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2340 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2342 switch (get_attr_type (insn))
2345 /* movzwl is faster than movw on p2 due to partial word stalls,
2346 though not as fast as an aligned movl. */
2347 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2349 if (get_attr_mode (insn) == MODE_SI)
2350 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2352 return "mov{w}\t{%1, %0|%0, %1}";
2356 (cond [(match_test "optimize_function_for_size_p (cfun)")
2357 (const_string "imov")
2358 (and (eq_attr "alternative" "0")
2359 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2360 (not (match_test "TARGET_HIMODE_MATH"))))
2361 (const_string "imov")
2362 (and (eq_attr "alternative" "1,2")
2363 (match_operand:HI 1 "aligned_operand"))
2364 (const_string "imov")
2365 (and (match_test "TARGET_MOVX")
2366 (eq_attr "alternative" "0,2"))
2367 (const_string "imovx")
2369 (const_string "imov")))
2371 (cond [(eq_attr "type" "imovx")
2373 (and (eq_attr "alternative" "1,2")
2374 (match_operand:HI 1 "aligned_operand"))
2376 (and (eq_attr "alternative" "0")
2377 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2378 (not (match_test "TARGET_HIMODE_MATH"))))
2381 (const_string "HI")))])
2383 ;; Situation is quite tricky about when to choose full sized (SImode) move
2384 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2385 ;; partial register dependency machines (such as AMD Athlon), where QImode
2386 ;; moves issue extra dependency and for partial register stalls machines
2387 ;; that don't use QImode patterns (and QImode move cause stall on the next
2390 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2391 ;; register stall machines with, where we use QImode instructions, since
2392 ;; partial register stall can be caused there. Then we use movzx.
2393 (define_insn "*movqi_internal"
2394 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2395 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2396 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2398 switch (get_attr_type (insn))
2401 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2402 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2404 if (get_attr_mode (insn) == MODE_SI)
2405 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2407 return "mov{b}\t{%1, %0|%0, %1}";
2411 (cond [(and (eq_attr "alternative" "5")
2412 (not (match_operand:QI 1 "aligned_operand")))
2413 (const_string "imovx")
2414 (match_test "optimize_function_for_size_p (cfun)")
2415 (const_string "imov")
2416 (and (eq_attr "alternative" "3")
2417 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2418 (not (match_test "TARGET_QIMODE_MATH"))))
2419 (const_string "imov")
2420 (eq_attr "alternative" "3,5")
2421 (const_string "imovx")
2422 (and (match_test "TARGET_MOVX")
2423 (eq_attr "alternative" "2"))
2424 (const_string "imovx")
2426 (const_string "imov")))
2428 (cond [(eq_attr "alternative" "3,4,5")
2430 (eq_attr "alternative" "6")
2432 (eq_attr "type" "imovx")
2434 (and (eq_attr "type" "imov")
2435 (and (eq_attr "alternative" "0,1")
2436 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2437 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2438 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2440 ;; Avoid partial register stalls when not using QImode arithmetic
2441 (and (eq_attr "type" "imov")
2442 (and (eq_attr "alternative" "0,1")
2443 (and (match_test "TARGET_PARTIAL_REG_STALL")
2444 (not (match_test "TARGET_QIMODE_MATH")))))
2447 (const_string "QI")))])
2449 ;; Stores and loads of ax to arbitrary constant address.
2450 ;; We fake an second form of instruction to force reload to load address
2451 ;; into register when rax is not available
2452 (define_insn "*movabs<mode>_1"
2453 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2454 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2455 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2457 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2458 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2459 [(set_attr "type" "imov")
2460 (set_attr "modrm" "0,*")
2461 (set_attr "length_address" "8,0")
2462 (set_attr "length_immediate" "0,*")
2463 (set_attr "memory" "store")
2464 (set_attr "mode" "<MODE>")])
2466 (define_insn "*movabs<mode>_2"
2467 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2468 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2469 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2471 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2472 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2473 [(set_attr "type" "imov")
2474 (set_attr "modrm" "0,*")
2475 (set_attr "length_address" "8,0")
2476 (set_attr "length_immediate" "0")
2477 (set_attr "memory" "load")
2478 (set_attr "mode" "<MODE>")])
2480 (define_insn "swap<mode>"
2481 [(set (match_operand:SWI48 0 "register_operand" "+r")
2482 (match_operand:SWI48 1 "register_operand" "+r"))
2486 "xchg{<imodesuffix>}\t%1, %0"
2487 [(set_attr "type" "imov")
2488 (set_attr "mode" "<MODE>")
2489 (set_attr "pent_pair" "np")
2490 (set_attr "athlon_decode" "vector")
2491 (set_attr "amdfam10_decode" "double")
2492 (set_attr "bdver1_decode" "double")])
2494 (define_insn "*swap<mode>_1"
2495 [(set (match_operand:SWI12 0 "register_operand" "+r")
2496 (match_operand:SWI12 1 "register_operand" "+r"))
2499 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2501 [(set_attr "type" "imov")
2502 (set_attr "mode" "SI")
2503 (set_attr "pent_pair" "np")
2504 (set_attr "athlon_decode" "vector")
2505 (set_attr "amdfam10_decode" "double")
2506 (set_attr "bdver1_decode" "double")])
2508 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2509 ;; is disabled for AMDFAM10
2510 (define_insn "*swap<mode>_2"
2511 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2512 (match_operand:SWI12 1 "register_operand" "+<r>"))
2515 "TARGET_PARTIAL_REG_STALL"
2516 "xchg{<imodesuffix>}\t%1, %0"
2517 [(set_attr "type" "imov")
2518 (set_attr "mode" "<MODE>")
2519 (set_attr "pent_pair" "np")
2520 (set_attr "athlon_decode" "vector")])
2522 (define_expand "movstrict<mode>"
2523 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2524 (match_operand:SWI12 1 "general_operand"))]
2527 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2529 if (GET_CODE (operands[0]) == SUBREG
2530 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2532 /* Don't generate memory->memory moves, go through a register */
2533 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2534 operands[1] = force_reg (<MODE>mode, operands[1]);
2537 (define_insn "*movstrict<mode>_1"
2538 [(set (strict_low_part
2539 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2540 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2541 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2542 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2543 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2544 [(set_attr "type" "imov")
2545 (set_attr "mode" "<MODE>")])
2547 (define_insn "*movstrict<mode>_xor"
2548 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2549 (match_operand:SWI12 1 "const0_operand"))
2550 (clobber (reg:CC FLAGS_REG))]
2552 "xor{<imodesuffix>}\t%0, %0"
2553 [(set_attr "type" "alu1")
2554 (set_attr "mode" "<MODE>")
2555 (set_attr "length_immediate" "0")])
2557 (define_insn "*mov<mode>_extv_1"
2558 [(set (match_operand:SWI24 0 "register_operand" "=R")
2559 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2563 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2564 [(set_attr "type" "imovx")
2565 (set_attr "mode" "SI")])
2567 (define_insn "*movqi_extv_1_rex64"
2568 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2569 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2574 switch (get_attr_type (insn))
2577 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2579 return "mov{b}\t{%h1, %0|%0, %h1}";
2583 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2584 (match_test "TARGET_MOVX"))
2585 (const_string "imovx")
2586 (const_string "imov")))
2588 (if_then_else (eq_attr "type" "imovx")
2590 (const_string "QI")))])
2592 (define_insn "*movqi_extv_1"
2593 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2594 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2599 switch (get_attr_type (insn))
2602 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2604 return "mov{b}\t{%h1, %0|%0, %h1}";
2608 (if_then_else (and (match_operand:QI 0 "register_operand")
2609 (ior (not (match_operand:QI 0 "QIreg_operand"))
2610 (match_test "TARGET_MOVX")))
2611 (const_string "imovx")
2612 (const_string "imov")))
2614 (if_then_else (eq_attr "type" "imovx")
2616 (const_string "QI")))])
2618 (define_insn "*mov<mode>_extzv_1"
2619 [(set (match_operand:SWI48 0 "register_operand" "=R")
2620 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2624 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2625 [(set_attr "type" "imovx")
2626 (set_attr "mode" "SI")])
2628 (define_insn "*movqi_extzv_2_rex64"
2629 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2631 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2636 switch (get_attr_type (insn))
2639 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2641 return "mov{b}\t{%h1, %0|%0, %h1}";
2645 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2646 (match_test "TARGET_MOVX"))
2647 (const_string "imovx")
2648 (const_string "imov")))
2650 (if_then_else (eq_attr "type" "imovx")
2652 (const_string "QI")))])
2654 (define_insn "*movqi_extzv_2"
2655 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2657 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2662 switch (get_attr_type (insn))
2665 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2667 return "mov{b}\t{%h1, %0|%0, %h1}";
2671 (if_then_else (and (match_operand:QI 0 "register_operand")
2672 (ior (not (match_operand:QI 0 "QIreg_operand"))
2673 (match_test "TARGET_MOVX")))
2674 (const_string "imovx")
2675 (const_string "imov")))
2677 (if_then_else (eq_attr "type" "imovx")
2679 (const_string "QI")))])
2681 (define_expand "mov<mode>_insv_1"
2682 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2685 (match_operand:SWI48 1 "nonmemory_operand"))])
2687 (define_insn "*mov<mode>_insv_1_rex64"
2688 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2691 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2693 "mov{b}\t{%b1, %h0|%h0, %b1}"
2694 [(set_attr "type" "imov")
2695 (set_attr "mode" "QI")])
2697 (define_insn "*movsi_insv_1"
2698 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2701 (match_operand:SI 1 "general_operand" "Qmn"))]
2703 "mov{b}\t{%b1, %h0|%h0, %b1}"
2704 [(set_attr "type" "imov")
2705 (set_attr "mode" "QI")])
2707 (define_insn "*movqi_insv_2"
2708 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2711 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2714 "mov{b}\t{%h1, %h0|%h0, %h1}"
2715 [(set_attr "type" "imov")
2716 (set_attr "mode" "QI")])
2718 ;; Floating point push instructions.
2720 (define_insn "*pushtf"
2721 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2722 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2725 /* This insn should be already split before reg-stack. */
2728 [(set_attr "type" "multi")
2729 (set_attr "unit" "sse,*,*")
2730 (set_attr "mode" "TF,SI,SI")])
2732 ;; %%% Kill this when call knows how to work this out.
2734 [(set (match_operand:TF 0 "push_operand")
2735 (match_operand:TF 1 "sse_reg_operand"))]
2736 "TARGET_SSE && reload_completed"
2737 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2738 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2740 (define_insn "*pushxf"
2741 [(set (match_operand:XF 0 "push_operand" "=<,<")
2742 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2743 "optimize_function_for_speed_p (cfun)"
2745 /* This insn should be already split before reg-stack. */
2748 [(set_attr "type" "multi")
2749 (set_attr "unit" "i387,*")
2750 (set_attr "mode" "XF,SI")])
2752 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2753 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2754 ;; Pushing using integer instructions is longer except for constants
2755 ;; and direct memory references (assuming that any given constant is pushed
2756 ;; only once, but this ought to be handled elsewhere).
2758 (define_insn "*pushxf_nointeger"
2759 [(set (match_operand:XF 0 "push_operand" "=<,<")
2760 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2761 "optimize_function_for_size_p (cfun)"
2763 /* This insn should be already split before reg-stack. */
2766 [(set_attr "type" "multi")
2767 (set_attr "unit" "i387,*")
2768 (set_attr "mode" "XF,SI")])
2770 ;; %%% Kill this when call knows how to work this out.
2772 [(set (match_operand:XF 0 "push_operand")
2773 (match_operand:XF 1 "fp_register_operand"))]
2775 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2776 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2777 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2779 (define_insn "*pushdf_rex64"
2780 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2781 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2784 /* This insn should be already split before reg-stack. */
2787 [(set_attr "type" "multi")
2788 (set_attr "unit" "i387,*,*")
2789 (set_attr "mode" "DF,DI,DF")])
2791 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2792 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2793 ;; On the average, pushdf using integers can be still shorter.
2795 (define_insn "*pushdf"
2796 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2797 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2800 /* This insn should be already split before reg-stack. */
2803 [(set_attr "isa" "*,*,sse2")
2804 (set_attr "type" "multi")
2805 (set_attr "unit" "i387,*,*")
2806 (set_attr "mode" "DF,DI,DF")])
2808 ;; %%% Kill this when call knows how to work this out.
2810 [(set (match_operand:DF 0 "push_operand")
2811 (match_operand:DF 1 "any_fp_register_operand"))]
2813 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2814 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2816 (define_insn "*pushsf_rex64"
2817 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2818 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2821 /* Anything else should be already split before reg-stack. */
2822 gcc_assert (which_alternative == 1);
2823 return "push{q}\t%q1";
2825 [(set_attr "type" "multi,push,multi")
2826 (set_attr "unit" "i387,*,*")
2827 (set_attr "mode" "SF,DI,SF")])
2829 (define_insn "*pushsf"
2830 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2831 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2834 /* Anything else should be already split before reg-stack. */
2835 gcc_assert (which_alternative == 1);
2836 return "push{l}\t%1";
2838 [(set_attr "type" "multi,push,multi")
2839 (set_attr "unit" "i387,*,*")
2840 (set_attr "mode" "SF,SI,SF")])
2842 ;; %%% Kill this when call knows how to work this out.
2844 [(set (match_operand:SF 0 "push_operand")
2845 (match_operand:SF 1 "any_fp_register_operand"))]
2847 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2848 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2849 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2852 [(set (match_operand:SF 0 "push_operand")
2853 (match_operand:SF 1 "memory_operand"))]
2855 && (operands[2] = find_constant_src (insn))"
2856 [(set (match_dup 0) (match_dup 2))])
2859 [(set (match_operand 0 "push_operand")
2860 (match_operand 1 "general_operand"))]
2862 && (GET_MODE (operands[0]) == TFmode
2863 || GET_MODE (operands[0]) == XFmode
2864 || GET_MODE (operands[0]) == DFmode)
2865 && !ANY_FP_REG_P (operands[1])"
2867 "ix86_split_long_move (operands); DONE;")
2869 ;; Floating point move instructions.
2871 (define_expand "movtf"
2872 [(set (match_operand:TF 0 "nonimmediate_operand")
2873 (match_operand:TF 1 "nonimmediate_operand"))]
2876 ix86_expand_move (TFmode, operands);
2880 (define_expand "mov<mode>"
2881 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2882 (match_operand:X87MODEF 1 "general_operand"))]
2884 "ix86_expand_move (<MODE>mode, operands); DONE;")
2886 (define_insn "*movtf_internal"
2887 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2888 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,F*r"))]
2890 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2891 && (!can_create_pseudo_p ()
2892 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2893 || GET_CODE (operands[1]) != CONST_DOUBLE
2894 || (optimize_function_for_size_p (cfun)
2895 && standard_sse_constant_p (operands[1])
2896 && !memory_operand (operands[0], TFmode))
2897 || (!TARGET_MEMORY_MISMATCH_STALL
2898 && memory_operand (operands[0], TFmode)))"
2900 switch (which_alternative)
2903 return standard_sse_constant_opcode (insn, operands[1]);
2906 /* Handle misaligned load/store since we
2907 don't have movmisaligntf pattern. */
2908 if (misaligned_operand (operands[0], TFmode)
2909 || misaligned_operand (operands[1], TFmode))
2911 if (get_attr_mode (insn) == MODE_V4SF)
2912 return "%vmovups\t{%1, %0|%0, %1}";
2914 return "%vmovdqu\t{%1, %0|%0, %1}";
2918 if (get_attr_mode (insn) == MODE_V4SF)
2919 return "%vmovaps\t{%1, %0|%0, %1}";
2921 return "%vmovdqa\t{%1, %0|%0, %1}";
2932 [(set_attr "type" "sselog1,ssemov,ssemov,*,*")
2933 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2935 (cond [(eq_attr "alternative" "3,4")
2937 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2938 (const_string "V4SF")
2939 (and (eq_attr "alternative" "2")
2940 (match_test "TARGET_SSE_TYPELESS_STORES"))
2941 (const_string "V4SF")
2942 (match_test "TARGET_AVX")
2944 (ior (not (match_test "TARGET_SSE2"))
2945 (match_test "optimize_function_for_size_p (cfun)"))
2946 (const_string "V4SF")
2948 (const_string "TI")))])
2950 ;; Possible store forwarding (partial memory) stall in alternative 4.
2951 (define_insn "*movxf_internal"
2952 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2953 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2954 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2955 && (!can_create_pseudo_p ()
2956 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2957 || GET_CODE (operands[1]) != CONST_DOUBLE
2958 || (optimize_function_for_size_p (cfun)
2959 && standard_80387_constant_p (operands[1]) > 0
2960 && !memory_operand (operands[0], XFmode))
2961 || (!TARGET_MEMORY_MISMATCH_STALL
2962 && memory_operand (operands[0], XFmode)))"
2964 switch (which_alternative)
2968 return output_387_reg_move (insn, operands);
2971 return standard_80387_constant_opcode (operands[1]);
2981 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2982 (set_attr "mode" "XF,XF,XF,SI,SI")])
2984 (define_insn "*movdf_internal_rex64"
2985 [(set (match_operand:DF 0 "nonimmediate_operand"
2986 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2987 (match_operand:DF 1 "general_operand"
2988 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2989 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2990 && (!can_create_pseudo_p ()
2991 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2992 || GET_CODE (operands[1]) != CONST_DOUBLE
2993 || (optimize_function_for_size_p (cfun)
2994 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2995 && standard_80387_constant_p (operands[1]) > 0)
2996 || (TARGET_SSE2 && TARGET_SSE_MATH
2997 && standard_sse_constant_p (operands[1]))))
2998 || memory_operand (operands[0], DFmode))"
3000 switch (which_alternative)
3004 return output_387_reg_move (insn, operands);
3007 return standard_80387_constant_opcode (operands[1]);
3011 return "mov{q}\t{%1, %0|%0, %1}";
3014 return "movabs{q}\t{%1, %0|%0, %1}";
3020 return standard_sse_constant_opcode (insn, operands[1]);
3025 switch (get_attr_mode (insn))
3028 return "%vmovapd\t{%1, %0|%0, %1}";
3030 return "%vmovaps\t{%1, %0|%0, %1}";
3033 return "%vmovq\t{%1, %0|%0, %1}";
3035 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3036 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3037 return "%vmovsd\t{%1, %0|%0, %1}";
3039 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3041 return "%vmovlps\t{%1, %d0|%d0, %1}";
3048 /* Handle broken assemblers that require movd instead of movq. */
3049 return "%vmovd\t{%1, %0|%0, %1}";
3056 (cond [(eq_attr "alternative" "0,1,2")
3057 (const_string "fmov")
3058 (eq_attr "alternative" "3,4,5")
3059 (const_string "imov")
3060 (eq_attr "alternative" "6")
3061 (const_string "multi")
3062 (eq_attr "alternative" "7")
3063 (const_string "sselog1")
3065 (const_string "ssemov")))
3068 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3070 (const_string "*")))
3071 (set (attr "length_immediate")
3073 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3075 (const_string "*")))
3076 (set (attr "prefix")
3077 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3078 (const_string "orig")
3079 (const_string "maybe_vex")))
3080 (set (attr "prefix_data16")
3081 (if_then_else (eq_attr "mode" "V1DF")
3083 (const_string "*")))
3085 (cond [(eq_attr "alternative" "0,1,2")
3087 (eq_attr "alternative" "3,4,5,6,11,12")
3090 /* xorps is one byte shorter for !TARGET_AVX. */
3091 (eq_attr "alternative" "7")
3092 (cond [(match_test "TARGET_AVX")
3093 (const_string "V2DF")
3094 (match_test "optimize_function_for_size_p (cfun)")
3095 (const_string "V4SF")
3096 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3099 (const_string "V2DF"))
3101 /* For architectures resolving dependencies on
3102 whole SSE registers use APD move to break dependency
3103 chains, otherwise use short move to avoid extra work.
3105 movaps encodes one byte shorter for !TARGET_AVX. */
3106 (eq_attr "alternative" "8")
3107 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3108 (const_string "V4SF")
3109 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3110 (const_string "V2DF")
3111 (match_test "TARGET_AVX")
3113 (match_test "optimize_function_for_size_p (cfun)")
3114 (const_string "V4SF")
3116 (const_string "DF"))
3117 /* For architectures resolving dependencies on register
3118 parts we may avoid extra work to zero out upper part
3120 (eq_attr "alternative" "9")
3122 (match_test "TARGET_SSE_SPLIT_REGS")
3123 (const_string "V1DF")
3124 (const_string "DF"))
3126 (const_string "DF")))])
3128 ;; Possible store forwarding (partial memory) stall in alternative 4.
3129 (define_insn "*movdf_internal"
3130 [(set (match_operand:DF 0 "nonimmediate_operand"
3131 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3132 (match_operand:DF 1 "general_operand"
3133 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3134 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3135 && (!can_create_pseudo_p ()
3136 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3137 || GET_CODE (operands[1]) != CONST_DOUBLE
3138 || (optimize_function_for_size_p (cfun)
3139 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3140 && standard_80387_constant_p (operands[1]) > 0)
3141 || (TARGET_SSE2 && TARGET_SSE_MATH
3142 && standard_sse_constant_p (operands[1])))
3143 && !memory_operand (operands[0], DFmode))
3144 || (!TARGET_MEMORY_MISMATCH_STALL
3145 && memory_operand (operands[0], DFmode)))"
3147 switch (which_alternative)
3151 return output_387_reg_move (insn, operands);
3154 return standard_80387_constant_opcode (operands[1]);
3162 return standard_sse_constant_opcode (insn, operands[1]);
3170 switch (get_attr_mode (insn))
3173 return "%vmovapd\t{%1, %0|%0, %1}";
3175 return "%vmovaps\t{%1, %0|%0, %1}";
3178 return "%vmovq\t{%1, %0|%0, %1}";
3180 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3181 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3182 return "%vmovsd\t{%1, %0|%0, %1}";
3184 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3186 return "%vmovlps\t{%1, %d0|%d0, %1}";
3196 (if_then_else (eq_attr "alternative" "5,6,7,8")
3197 (const_string "sse2")
3198 (const_string "*")))
3200 (cond [(eq_attr "alternative" "0,1,2")
3201 (const_string "fmov")
3202 (eq_attr "alternative" "3,4")
3203 (const_string "multi")
3204 (eq_attr "alternative" "5,9")
3205 (const_string "sselog1")
3207 (const_string "ssemov")))
3208 (set (attr "prefix")
3209 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3210 (const_string "orig")
3211 (const_string "maybe_vex")))
3212 (set (attr "prefix_data16")
3213 (if_then_else (eq_attr "mode" "V1DF")
3215 (const_string "*")))
3217 (cond [(eq_attr "alternative" "0,1,2")
3219 (eq_attr "alternative" "3,4")
3222 /* For SSE1, we have many fewer alternatives. */
3223 (not (match_test "TARGET_SSE2"))
3225 (eq_attr "alternative" "5,6,9,10")
3226 (const_string "V4SF")
3227 (const_string "V2SF"))
3229 /* xorps is one byte shorter for !TARGET_AVX. */
3230 (eq_attr "alternative" "5,9")
3231 (cond [(match_test "TARGET_AVX")
3232 (const_string "V2DF")
3233 (match_test "optimize_function_for_size_p (cfun)")
3234 (const_string "V4SF")
3235 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3238 (const_string "V2DF"))
3240 /* For architectures resolving dependencies on
3241 whole SSE registers use APD move to break dependency
3242 chains, otherwise use short move to avoid extra work.
3244 movaps encodes one byte shorter for !TARGET_AVX. */
3245 (eq_attr "alternative" "6,10")
3246 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3247 (const_string "V4SF")
3248 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3249 (const_string "V2DF")
3250 (match_test "TARGET_AVX")
3252 (match_test "optimize_function_for_size_p (cfun)")
3253 (const_string "V4SF")
3255 (const_string "DF"))
3257 /* For architectures resolving dependencies on register
3258 parts we may avoid extra work to zero out upper part
3260 (eq_attr "alternative" "7,11")
3262 (match_test "TARGET_SSE_SPLIT_REGS")
3263 (const_string "V1DF")
3264 (const_string "DF"))
3266 (const_string "DF")))])
3268 (define_insn "*movsf_internal"
3269 [(set (match_operand:SF 0 "nonimmediate_operand"
3270 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3271 (match_operand:SF 1 "general_operand"
3272 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3273 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3274 && (!can_create_pseudo_p ()
3275 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3276 || GET_CODE (operands[1]) != CONST_DOUBLE
3277 || (optimize_function_for_size_p (cfun)
3278 && ((!TARGET_SSE_MATH
3279 && standard_80387_constant_p (operands[1]) > 0)
3281 && standard_sse_constant_p (operands[1]))))
3282 || memory_operand (operands[0], SFmode))"
3284 switch (which_alternative)
3288 return output_387_reg_move (insn, operands);
3291 return standard_80387_constant_opcode (operands[1]);
3295 return "mov{l}\t{%1, %0|%0, %1}";
3298 return standard_sse_constant_opcode (insn, operands[1]);
3301 if (get_attr_mode (insn) == MODE_V4SF)
3302 return "%vmovaps\t{%1, %0|%0, %1}";
3304 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3308 return "%vmovss\t{%1, %0|%0, %1}";
3314 return "movd\t{%1, %0|%0, %1}";
3317 return "movq\t{%1, %0|%0, %1}";
3321 return "%vmovd\t{%1, %0|%0, %1}";
3328 (cond [(eq_attr "alternative" "0,1,2")
3329 (const_string "fmov")
3330 (eq_attr "alternative" "3,4")
3331 (const_string "multi")
3332 (eq_attr "alternative" "5")
3333 (const_string "sselog1")
3334 (eq_attr "alternative" "9,10,11,14,15")
3335 (const_string "mmxmov")
3337 (const_string "ssemov")))
3338 (set (attr "prefix")
3339 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3340 (const_string "maybe_vex")
3341 (const_string "orig")))
3343 (cond [(eq_attr "alternative" "3,4,9,10")
3345 (eq_attr "alternative" "5")
3346 (cond [(match_test "TARGET_AVX")
3347 (const_string "V4SF")
3348 (ior (not (match_test "TARGET_SSE2"))
3349 (match_test "optimize_function_for_size_p (cfun)"))
3350 (const_string "V4SF")
3351 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3354 (const_string "V4SF"))
3356 /* For architectures resolving dependencies on
3357 whole SSE registers use APS move to break dependency
3358 chains, otherwise use short move to avoid extra work.
3360 Do the same for architectures resolving dependencies on
3361 the parts. While in DF mode it is better to always handle
3362 just register parts, the SF mode is different due to lack
3363 of instructions to load just part of the register. It is
3364 better to maintain the whole registers in single format
3365 to avoid problems on using packed logical operations. */
3366 (eq_attr "alternative" "6")
3368 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3369 (match_test "TARGET_SSE_SPLIT_REGS"))
3370 (const_string "V4SF")
3371 (const_string "SF"))
3372 (eq_attr "alternative" "11")
3373 (const_string "DI")]
3374 (const_string "SF")))])
3377 [(set (match_operand 0 "any_fp_register_operand")
3378 (match_operand 1 "memory_operand"))]
3380 && (GET_MODE (operands[0]) == TFmode
3381 || GET_MODE (operands[0]) == XFmode
3382 || GET_MODE (operands[0]) == DFmode
3383 || GET_MODE (operands[0]) == SFmode)
3384 && (operands[2] = find_constant_src (insn))"
3385 [(set (match_dup 0) (match_dup 2))]
3387 rtx c = operands[2];
3388 int r = REGNO (operands[0]);
3390 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3391 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3396 [(set (match_operand 0 "any_fp_register_operand")
3397 (float_extend (match_operand 1 "memory_operand")))]
3399 && (GET_MODE (operands[0]) == TFmode
3400 || GET_MODE (operands[0]) == XFmode
3401 || GET_MODE (operands[0]) == DFmode)
3402 && (operands[2] = find_constant_src (insn))"
3403 [(set (match_dup 0) (match_dup 2))]
3405 rtx c = operands[2];
3406 int r = REGNO (operands[0]);
3408 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3409 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3413 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3415 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3416 (match_operand:X87MODEF 1 "immediate_operand"))]
3418 && (standard_80387_constant_p (operands[1]) == 8
3419 || standard_80387_constant_p (operands[1]) == 9)"
3420 [(set (match_dup 0)(match_dup 1))
3422 (neg:X87MODEF (match_dup 0)))]
3426 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3427 if (real_isnegzero (&r))
3428 operands[1] = CONST0_RTX (<MODE>mode);
3430 operands[1] = CONST1_RTX (<MODE>mode);
3434 [(set (match_operand 0 "nonimmediate_operand")
3435 (match_operand 1 "general_operand"))]
3437 && (GET_MODE (operands[0]) == TFmode
3438 || GET_MODE (operands[0]) == XFmode
3439 || GET_MODE (operands[0]) == DFmode)
3440 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3442 "ix86_split_long_move (operands); DONE;")
3444 (define_insn "swapxf"
3445 [(set (match_operand:XF 0 "register_operand" "+f")
3446 (match_operand:XF 1 "register_operand" "+f"))
3451 if (STACK_TOP_P (operands[0]))
3456 [(set_attr "type" "fxch")
3457 (set_attr "mode" "XF")])
3459 (define_insn "*swap<mode>"
3460 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3461 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3464 "TARGET_80387 || reload_completed"
3466 if (STACK_TOP_P (operands[0]))
3471 [(set_attr "type" "fxch")
3472 (set_attr "mode" "<MODE>")])
3474 ;; Zero extension instructions
3476 (define_expand "zero_extendsidi2"
3477 [(set (match_operand:DI 0 "nonimmediate_operand")
3478 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3480 (define_insn "*zero_extendsidi2_rex64"
3481 [(set (match_operand:DI 0 "nonimmediate_operand"
3482 "=r ,o,?*Ym,?*y,?*Yi,?*x")
3484 (match_operand:SI 1 "x86_64_zext_general_operand"
3485 "rmWz,0,r ,m ,r ,m")))]
3488 switch (get_attr_type (insn))
3491 if (ix86_use_lea_for_mov (insn, operands))
3492 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3494 return "mov{l}\t{%1, %k0|%k0, %1}";
3500 return "movd\t{%1, %0|%0, %1}";
3503 return "%vmovd\t{%1, %0|%0, %1}";
3509 [(set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3510 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3511 (set_attr "prefix_0f" "0,*,*,*,*,*")
3512 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3514 (define_insn "*zero_extendsidi2"
3515 [(set (match_operand:DI 0 "nonimmediate_operand"
3516 "=ro,?r,?o,?*Ym,?*y,?*Yi,?*x")
3517 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3518 "0 ,rm,r ,r ,m ,r ,m")))]
3524 movd\t{%1, %0|%0, %1}
3525 movd\t{%1, %0|%0, %1}
3526 %vmovd\t{%1, %0|%0, %1}
3527 %vmovd\t{%1, %0|%0, %1}"
3528 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3529 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3530 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3531 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3534 [(set (match_operand:DI 0 "memory_operand")
3535 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3537 [(set (match_dup 4) (const_int 0))]
3538 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3541 [(set (match_operand:DI 0 "register_operand")
3542 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3543 "!TARGET_64BIT && reload_completed
3544 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3545 && true_regnum (operands[0]) == true_regnum (operands[1])"
3546 [(set (match_dup 4) (const_int 0))]
3547 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3550 [(set (match_operand:DI 0 "nonimmediate_operand")
3551 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3552 "!TARGET_64BIT && reload_completed
3553 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3554 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3555 [(set (match_dup 3) (match_dup 1))
3556 (set (match_dup 4) (const_int 0))]
3557 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3559 (define_insn "zero_extend<mode>di2"
3560 [(set (match_operand:DI 0 "register_operand" "=r")
3562 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3564 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3565 [(set_attr "type" "imovx")
3566 (set_attr "mode" "SI")])
3568 (define_expand "zero_extend<mode>si2"
3569 [(set (match_operand:SI 0 "register_operand")
3570 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3573 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3575 operands[1] = force_reg (<MODE>mode, operands[1]);
3576 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3581 (define_insn_and_split "zero_extend<mode>si2_and"
3582 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3584 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3585 (clobber (reg:CC FLAGS_REG))]
3586 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3588 "&& reload_completed"
3589 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3590 (clobber (reg:CC FLAGS_REG))])]
3592 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3594 ix86_expand_clear (operands[0]);
3596 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3597 emit_insn (gen_movstrict<mode>
3598 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3602 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3604 [(set_attr "type" "alu1")
3605 (set_attr "mode" "SI")])
3607 (define_insn "*zero_extend<mode>si2"
3608 [(set (match_operand:SI 0 "register_operand" "=r")
3610 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3611 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3612 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3613 [(set_attr "type" "imovx")
3614 (set_attr "mode" "SI")])
3616 (define_expand "zero_extendqihi2"
3617 [(set (match_operand:HI 0 "register_operand")
3618 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3621 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3623 operands[1] = force_reg (QImode, operands[1]);
3624 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3629 (define_insn_and_split "zero_extendqihi2_and"
3630 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3631 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3632 (clobber (reg:CC FLAGS_REG))]
3633 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3635 "&& reload_completed"
3636 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3637 (clobber (reg:CC FLAGS_REG))])]
3639 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3641 ix86_expand_clear (operands[0]);
3643 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3644 emit_insn (gen_movstrictqi
3645 (gen_lowpart (QImode, operands[0]), operands[1]));
3649 operands[0] = gen_lowpart (SImode, operands[0]);
3651 [(set_attr "type" "alu1")
3652 (set_attr "mode" "SI")])
3654 ; zero extend to SImode to avoid partial register stalls
3655 (define_insn "*zero_extendqihi2"
3656 [(set (match_operand:HI 0 "register_operand" "=r")
3657 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3658 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3659 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3660 [(set_attr "type" "imovx")
3661 (set_attr "mode" "SI")])
3663 ;; Sign extension instructions
3665 (define_expand "extendsidi2"
3666 [(set (match_operand:DI 0 "register_operand")
3667 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3672 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3677 (define_insn "*extendsidi2_rex64"
3678 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3679 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3683 movs{lq|x}\t{%1, %0|%0, %1}"
3684 [(set_attr "type" "imovx")
3685 (set_attr "mode" "DI")
3686 (set_attr "prefix_0f" "0")
3687 (set_attr "modrm" "0,1")])
3689 (define_insn "extendsidi2_1"
3690 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3691 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3692 (clobber (reg:CC FLAGS_REG))
3693 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3697 ;; Extend to memory case when source register does die.
3699 [(set (match_operand:DI 0 "memory_operand")
3700 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3701 (clobber (reg:CC FLAGS_REG))
3702 (clobber (match_operand:SI 2 "register_operand"))]
3704 && dead_or_set_p (insn, operands[1])
3705 && !reg_mentioned_p (operands[1], operands[0]))"
3706 [(set (match_dup 3) (match_dup 1))
3707 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3708 (clobber (reg:CC FLAGS_REG))])
3709 (set (match_dup 4) (match_dup 1))]
3710 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3712 ;; Extend to memory case when source register does not die.
3714 [(set (match_operand:DI 0 "memory_operand")
3715 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3716 (clobber (reg:CC FLAGS_REG))
3717 (clobber (match_operand:SI 2 "register_operand"))]
3721 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3723 emit_move_insn (operands[3], operands[1]);
3725 /* Generate a cltd if possible and doing so it profitable. */
3726 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3727 && true_regnum (operands[1]) == AX_REG
3728 && true_regnum (operands[2]) == DX_REG)
3730 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3734 emit_move_insn (operands[2], operands[1]);
3735 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3737 emit_move_insn (operands[4], operands[2]);
3741 ;; Extend to register case. Optimize case where source and destination
3742 ;; registers match and cases where we can use cltd.
3744 [(set (match_operand:DI 0 "register_operand")
3745 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3746 (clobber (reg:CC FLAGS_REG))
3747 (clobber (match_scratch:SI 2))]
3751 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3753 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3754 emit_move_insn (operands[3], operands[1]);
3756 /* Generate a cltd if possible and doing so it profitable. */
3757 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3758 && true_regnum (operands[3]) == AX_REG
3759 && true_regnum (operands[4]) == DX_REG)
3761 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3765 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3766 emit_move_insn (operands[4], operands[1]);
3768 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3772 (define_insn "extend<mode>di2"
3773 [(set (match_operand:DI 0 "register_operand" "=r")
3775 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3777 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3778 [(set_attr "type" "imovx")
3779 (set_attr "mode" "DI")])
3781 (define_insn "extendhisi2"
3782 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3783 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3786 switch (get_attr_prefix_0f (insn))
3789 return "{cwtl|cwde}";
3791 return "movs{wl|x}\t{%1, %0|%0, %1}";
3794 [(set_attr "type" "imovx")
3795 (set_attr "mode" "SI")
3796 (set (attr "prefix_0f")
3797 ;; movsx is short decodable while cwtl is vector decoded.
3798 (if_then_else (and (eq_attr "cpu" "!k6")
3799 (eq_attr "alternative" "0"))
3801 (const_string "1")))
3803 (if_then_else (eq_attr "prefix_0f" "0")
3805 (const_string "1")))])
3807 (define_insn "*extendhisi2_zext"
3808 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3811 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3814 switch (get_attr_prefix_0f (insn))
3817 return "{cwtl|cwde}";
3819 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3822 [(set_attr "type" "imovx")
3823 (set_attr "mode" "SI")
3824 (set (attr "prefix_0f")
3825 ;; movsx is short decodable while cwtl is vector decoded.
3826 (if_then_else (and (eq_attr "cpu" "!k6")
3827 (eq_attr "alternative" "0"))
3829 (const_string "1")))
3831 (if_then_else (eq_attr "prefix_0f" "0")
3833 (const_string "1")))])
3835 (define_insn "extendqisi2"
3836 [(set (match_operand:SI 0 "register_operand" "=r")
3837 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3839 "movs{bl|x}\t{%1, %0|%0, %1}"
3840 [(set_attr "type" "imovx")
3841 (set_attr "mode" "SI")])
3843 (define_insn "*extendqisi2_zext"
3844 [(set (match_operand:DI 0 "register_operand" "=r")
3846 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3848 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3849 [(set_attr "type" "imovx")
3850 (set_attr "mode" "SI")])
3852 (define_insn "extendqihi2"
3853 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3854 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3857 switch (get_attr_prefix_0f (insn))
3860 return "{cbtw|cbw}";
3862 return "movs{bw|x}\t{%1, %0|%0, %1}";
3865 [(set_attr "type" "imovx")
3866 (set_attr "mode" "HI")
3867 (set (attr "prefix_0f")
3868 ;; movsx is short decodable while cwtl is vector decoded.
3869 (if_then_else (and (eq_attr "cpu" "!k6")
3870 (eq_attr "alternative" "0"))
3872 (const_string "1")))
3874 (if_then_else (eq_attr "prefix_0f" "0")
3876 (const_string "1")))])
3878 ;; Conversions between float and double.
3880 ;; These are all no-ops in the model used for the 80387.
3881 ;; So just emit moves.
3883 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3885 [(set (match_operand:DF 0 "push_operand")
3886 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3888 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3889 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3892 [(set (match_operand:XF 0 "push_operand")
3893 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3895 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3896 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3897 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3899 (define_expand "extendsfdf2"
3900 [(set (match_operand:DF 0 "nonimmediate_operand")
3901 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3902 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3904 /* ??? Needed for compress_float_constant since all fp constants
3905 are TARGET_LEGITIMATE_CONSTANT_P. */
3906 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3908 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3909 && standard_80387_constant_p (operands[1]) > 0)
3911 operands[1] = simplify_const_unary_operation
3912 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3913 emit_move_insn_1 (operands[0], operands[1]);
3916 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3920 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3922 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3924 We do the conversion post reload to avoid producing of 128bit spills
3925 that might lead to ICE on 32bit target. The sequence unlikely combine
3928 [(set (match_operand:DF 0 "register_operand")
3930 (match_operand:SF 1 "nonimmediate_operand")))]
3931 "TARGET_USE_VECTOR_FP_CONVERTS
3932 && optimize_insn_for_speed_p ()
3933 && reload_completed && SSE_REG_P (operands[0])"
3938 (parallel [(const_int 0) (const_int 1)]))))]
3940 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3941 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3942 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3943 Try to avoid move when unpacking can be done in source. */
3944 if (REG_P (operands[1]))
3946 /* If it is unsafe to overwrite upper half of source, we need
3947 to move to destination and unpack there. */
3948 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3949 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3950 && true_regnum (operands[0]) != true_regnum (operands[1]))
3952 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3953 emit_move_insn (tmp, operands[1]);
3956 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3957 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3961 emit_insn (gen_vec_setv4sf_0 (operands[3],
3962 CONST0_RTX (V4SFmode), operands[1]));
3965 (define_insn "*extendsfdf2_mixed"
3966 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3968 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3969 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3971 switch (which_alternative)
3975 return output_387_reg_move (insn, operands);
3978 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3984 [(set_attr "type" "fmov,fmov,ssecvt")
3985 (set_attr "prefix" "orig,orig,maybe_vex")
3986 (set_attr "mode" "SF,XF,DF")])
3988 (define_insn "*extendsfdf2_sse"
3989 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3990 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3991 "TARGET_SSE2 && TARGET_SSE_MATH"
3992 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3993 [(set_attr "type" "ssecvt")
3994 (set_attr "prefix" "maybe_vex")
3995 (set_attr "mode" "DF")])
3997 (define_insn "*extendsfdf2_i387"
3998 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3999 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4001 "* return output_387_reg_move (insn, operands);"
4002 [(set_attr "type" "fmov")
4003 (set_attr "mode" "SF,XF")])
4005 (define_expand "extend<mode>xf2"
4006 [(set (match_operand:XF 0 "nonimmediate_operand")
4007 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4010 /* ??? Needed for compress_float_constant since all fp constants
4011 are TARGET_LEGITIMATE_CONSTANT_P. */
4012 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4014 if (standard_80387_constant_p (operands[1]) > 0)
4016 operands[1] = simplify_const_unary_operation
4017 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4018 emit_move_insn_1 (operands[0], operands[1]);
4021 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4025 (define_insn "*extend<mode>xf2_i387"
4026 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4028 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4030 "* return output_387_reg_move (insn, operands);"
4031 [(set_attr "type" "fmov")
4032 (set_attr "mode" "<MODE>,XF")])
4034 ;; %%% This seems bad bad news.
4035 ;; This cannot output into an f-reg because there is no way to be sure
4036 ;; of truncating in that case. Otherwise this is just like a simple move
4037 ;; insn. So we pretend we can output to a reg in order to get better
4038 ;; register preferencing, but we really use a stack slot.
4040 ;; Conversion from DFmode to SFmode.
4042 (define_expand "truncdfsf2"
4043 [(set (match_operand:SF 0 "nonimmediate_operand")
4045 (match_operand:DF 1 "nonimmediate_operand")))]
4046 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4048 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4050 else if (flag_unsafe_math_optimizations)
4054 enum ix86_stack_slot slot = (virtuals_instantiated
4057 rtx temp = assign_386_stack_local (SFmode, slot);
4058 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4063 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4065 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4067 We do the conversion post reload to avoid producing of 128bit spills
4068 that might lead to ICE on 32bit target. The sequence unlikely combine
4071 [(set (match_operand:SF 0 "register_operand")
4073 (match_operand:DF 1 "nonimmediate_operand")))]
4074 "TARGET_USE_VECTOR_FP_CONVERTS
4075 && optimize_insn_for_speed_p ()
4076 && reload_completed && SSE_REG_P (operands[0])"
4079 (float_truncate:V2SF
4083 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4084 operands[3] = CONST0_RTX (V2SFmode);
4085 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4086 /* Use movsd for loading from memory, unpcklpd for registers.
4087 Try to avoid move when unpacking can be done in source, or SSE3
4088 movddup is available. */
4089 if (REG_P (operands[1]))
4092 && true_regnum (operands[0]) != true_regnum (operands[1])
4093 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4094 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4096 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4097 emit_move_insn (tmp, operands[1]);
4100 else if (!TARGET_SSE3)
4101 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4102 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4105 emit_insn (gen_sse2_loadlpd (operands[4],
4106 CONST0_RTX (V2DFmode), operands[1]));
4109 (define_expand "truncdfsf2_with_temp"
4110 [(parallel [(set (match_operand:SF 0)
4111 (float_truncate:SF (match_operand:DF 1)))
4112 (clobber (match_operand:SF 2))])])
4114 (define_insn "*truncdfsf_fast_mixed"
4115 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4117 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4118 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4120 switch (which_alternative)
4123 return output_387_reg_move (insn, operands);
4125 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4130 [(set_attr "type" "fmov,ssecvt")
4131 (set_attr "prefix" "orig,maybe_vex")
4132 (set_attr "mode" "SF")])
4134 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4135 ;; because nothing we do here is unsafe.
4136 (define_insn "*truncdfsf_fast_sse"
4137 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4139 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4140 "TARGET_SSE2 && TARGET_SSE_MATH"
4141 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4142 [(set_attr "type" "ssecvt")
4143 (set_attr "prefix" "maybe_vex")
4144 (set_attr "mode" "SF")])
4146 (define_insn "*truncdfsf_fast_i387"
4147 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4149 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4150 "TARGET_80387 && flag_unsafe_math_optimizations"
4151 "* return output_387_reg_move (insn, operands);"
4152 [(set_attr "type" "fmov")
4153 (set_attr "mode" "SF")])
4155 (define_insn "*truncdfsf_mixed"
4156 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4158 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4159 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4160 "TARGET_MIX_SSE_I387"
4162 switch (which_alternative)
4165 return output_387_reg_move (insn, operands);
4167 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4173 [(set_attr "isa" "*,sse2,*,*,*")
4174 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4175 (set_attr "unit" "*,*,i387,i387,i387")
4176 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4177 (set_attr "mode" "SF")])
4179 (define_insn "*truncdfsf_i387"
4180 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4182 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4183 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4186 switch (which_alternative)
4189 return output_387_reg_move (insn, operands);
4195 [(set_attr "type" "fmov,multi,multi,multi")
4196 (set_attr "unit" "*,i387,i387,i387")
4197 (set_attr "mode" "SF")])
4199 (define_insn "*truncdfsf2_i387_1"
4200 [(set (match_operand:SF 0 "memory_operand" "=m")
4202 (match_operand:DF 1 "register_operand" "f")))]
4204 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4205 && !TARGET_MIX_SSE_I387"
4206 "* return output_387_reg_move (insn, operands);"
4207 [(set_attr "type" "fmov")
4208 (set_attr "mode" "SF")])
4211 [(set (match_operand:SF 0 "register_operand")
4213 (match_operand:DF 1 "fp_register_operand")))
4214 (clobber (match_operand 2))]
4216 [(set (match_dup 2) (match_dup 1))
4217 (set (match_dup 0) (match_dup 2))]
4218 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4220 ;; Conversion from XFmode to {SF,DF}mode
4222 (define_expand "truncxf<mode>2"
4223 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4224 (float_truncate:MODEF
4225 (match_operand:XF 1 "register_operand")))
4226 (clobber (match_dup 2))])]
4229 if (flag_unsafe_math_optimizations)
4231 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4232 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4233 if (reg != operands[0])
4234 emit_move_insn (operands[0], reg);
4239 enum ix86_stack_slot slot = (virtuals_instantiated
4242 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4246 (define_insn "*truncxfsf2_mixed"
4247 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4249 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4250 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4253 gcc_assert (!which_alternative);
4254 return output_387_reg_move (insn, operands);
4256 [(set_attr "type" "fmov,multi,multi,multi")
4257 (set_attr "unit" "*,i387,i387,i387")
4258 (set_attr "mode" "SF")])
4260 (define_insn "*truncxfdf2_mixed"
4261 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4263 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4264 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4267 gcc_assert (!which_alternative);
4268 return output_387_reg_move (insn, operands);
4270 [(set_attr "isa" "*,*,sse2,*")
4271 (set_attr "type" "fmov,multi,multi,multi")
4272 (set_attr "unit" "*,i387,i387,i387")
4273 (set_attr "mode" "DF")])
4275 (define_insn "truncxf<mode>2_i387_noop"
4276 [(set (match_operand:MODEF 0 "register_operand" "=f")
4277 (float_truncate:MODEF
4278 (match_operand:XF 1 "register_operand" "f")))]
4279 "TARGET_80387 && flag_unsafe_math_optimizations"
4280 "* return output_387_reg_move (insn, operands);"
4281 [(set_attr "type" "fmov")
4282 (set_attr "mode" "<MODE>")])
4284 (define_insn "*truncxf<mode>2_i387"
4285 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4286 (float_truncate:MODEF
4287 (match_operand:XF 1 "register_operand" "f")))]
4289 "* return output_387_reg_move (insn, operands);"
4290 [(set_attr "type" "fmov")
4291 (set_attr "mode" "<MODE>")])
4294 [(set (match_operand:MODEF 0 "register_operand")
4295 (float_truncate:MODEF
4296 (match_operand:XF 1 "register_operand")))
4297 (clobber (match_operand:MODEF 2 "memory_operand"))]
4298 "TARGET_80387 && reload_completed"
4299 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4300 (set (match_dup 0) (match_dup 2))])
4303 [(set (match_operand:MODEF 0 "memory_operand")
4304 (float_truncate:MODEF
4305 (match_operand:XF 1 "register_operand")))
4306 (clobber (match_operand:MODEF 2 "memory_operand"))]
4308 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4310 ;; Signed conversion to DImode.
4312 (define_expand "fix_truncxfdi2"
4313 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4314 (fix:DI (match_operand:XF 1 "register_operand")))
4315 (clobber (reg:CC FLAGS_REG))])]
4320 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4325 (define_expand "fix_trunc<mode>di2"
4326 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4327 (fix:DI (match_operand:MODEF 1 "register_operand")))
4328 (clobber (reg:CC FLAGS_REG))])]
4329 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4332 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4334 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4337 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4339 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4340 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4341 if (out != operands[0])
4342 emit_move_insn (operands[0], out);
4347 ;; Signed conversion to SImode.
4349 (define_expand "fix_truncxfsi2"
4350 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4351 (fix:SI (match_operand:XF 1 "register_operand")))
4352 (clobber (reg:CC FLAGS_REG))])]
4357 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4362 (define_expand "fix_trunc<mode>si2"
4363 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4364 (fix:SI (match_operand:MODEF 1 "register_operand")))
4365 (clobber (reg:CC FLAGS_REG))])]
4366 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4369 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4371 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4374 if (SSE_FLOAT_MODE_P (<MODE>mode))
4376 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4377 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4378 if (out != operands[0])
4379 emit_move_insn (operands[0], out);
4384 ;; Signed conversion to HImode.
4386 (define_expand "fix_trunc<mode>hi2"
4387 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4388 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4389 (clobber (reg:CC FLAGS_REG))])]
4391 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4395 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4400 ;; Unsigned conversion to SImode.
4402 (define_expand "fixuns_trunc<mode>si2"
4404 [(set (match_operand:SI 0 "register_operand")
4406 (match_operand:MODEF 1 "nonimmediate_operand")))
4408 (clobber (match_scratch:<ssevecmode> 3))
4409 (clobber (match_scratch:<ssevecmode> 4))])]
4410 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4412 enum machine_mode mode = <MODE>mode;
4413 enum machine_mode vecmode = <ssevecmode>mode;
4414 REAL_VALUE_TYPE TWO31r;
4417 if (optimize_insn_for_size_p ())
4420 real_ldexp (&TWO31r, &dconst1, 31);
4421 two31 = const_double_from_real_value (TWO31r, mode);
4422 two31 = ix86_build_const_vector (vecmode, true, two31);
4423 operands[2] = force_reg (vecmode, two31);
4426 (define_insn_and_split "*fixuns_trunc<mode>_1"
4427 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4429 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4430 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4431 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4432 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4433 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4434 && optimize_function_for_speed_p (cfun)"
4436 "&& reload_completed"
4439 ix86_split_convert_uns_si_sse (operands);
4443 ;; Unsigned conversion to HImode.
4444 ;; Without these patterns, we'll try the unsigned SI conversion which
4445 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4447 (define_expand "fixuns_trunc<mode>hi2"
4449 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4450 (set (match_operand:HI 0 "nonimmediate_operand")
4451 (subreg:HI (match_dup 2) 0))]
4452 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4453 "operands[2] = gen_reg_rtx (SImode);")
4455 ;; When SSE is available, it is always faster to use it!
4456 (define_insn "fix_trunc<mode>di_sse"
4457 [(set (match_operand:DI 0 "register_operand" "=r,r")
4458 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4459 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4460 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4461 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4462 [(set_attr "type" "sseicvt")
4463 (set_attr "prefix" "maybe_vex")
4464 (set_attr "prefix_rex" "1")
4465 (set_attr "mode" "<MODE>")
4466 (set_attr "athlon_decode" "double,vector")
4467 (set_attr "amdfam10_decode" "double,double")
4468 (set_attr "bdver1_decode" "double,double")])
4470 (define_insn "fix_trunc<mode>si_sse"
4471 [(set (match_operand:SI 0 "register_operand" "=r,r")
4472 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4473 "SSE_FLOAT_MODE_P (<MODE>mode)
4474 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4475 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4476 [(set_attr "type" "sseicvt")
4477 (set_attr "prefix" "maybe_vex")
4478 (set_attr "mode" "<MODE>")
4479 (set_attr "athlon_decode" "double,vector")
4480 (set_attr "amdfam10_decode" "double,double")
4481 (set_attr "bdver1_decode" "double,double")])
4483 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4485 [(set (match_operand:MODEF 0 "register_operand")
4486 (match_operand:MODEF 1 "memory_operand"))
4487 (set (match_operand:SWI48x 2 "register_operand")
4488 (fix:SWI48x (match_dup 0)))]
4489 "TARGET_SHORTEN_X87_SSE
4490 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4491 && peep2_reg_dead_p (2, operands[0])"
4492 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4494 ;; Avoid vector decoded forms of the instruction.
4496 [(match_scratch:DF 2 "x")
4497 (set (match_operand:SWI48x 0 "register_operand")
4498 (fix:SWI48x (match_operand:DF 1 "memory_operand")))]
4499 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4500 [(set (match_dup 2) (match_dup 1))
4501 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4504 [(match_scratch:SF 2 "x")
4505 (set (match_operand:SWI48x 0 "register_operand")
4506 (fix:SWI48x (match_operand:SF 1 "memory_operand")))]
4507 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4508 [(set (match_dup 2) (match_dup 1))
4509 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4511 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4512 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4513 (fix:SWI248x (match_operand 1 "register_operand")))]
4514 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4516 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4517 && (TARGET_64BIT || <MODE>mode != DImode))
4519 && can_create_pseudo_p ()"
4524 if (memory_operand (operands[0], VOIDmode))
4525 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4528 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4529 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4535 [(set_attr "type" "fisttp")
4536 (set_attr "mode" "<MODE>")])
4538 (define_insn "fix_trunc<mode>_i387_fisttp"
4539 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4540 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4541 (clobber (match_scratch:XF 2 "=&1f"))]
4542 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4544 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4545 && (TARGET_64BIT || <MODE>mode != DImode))
4546 && TARGET_SSE_MATH)"
4547 "* return output_fix_trunc (insn, operands, true);"
4548 [(set_attr "type" "fisttp")
4549 (set_attr "mode" "<MODE>")])
4551 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4552 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4553 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4554 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4555 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4556 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4558 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4559 && (TARGET_64BIT || <MODE>mode != DImode))
4560 && TARGET_SSE_MATH)"
4562 [(set_attr "type" "fisttp")
4563 (set_attr "mode" "<MODE>")])
4566 [(set (match_operand:SWI248x 0 "register_operand")
4567 (fix:SWI248x (match_operand 1 "register_operand")))
4568 (clobber (match_operand:SWI248x 2 "memory_operand"))
4569 (clobber (match_scratch 3))]
4571 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4572 (clobber (match_dup 3))])
4573 (set (match_dup 0) (match_dup 2))])
4576 [(set (match_operand:SWI248x 0 "memory_operand")
4577 (fix:SWI248x (match_operand 1 "register_operand")))
4578 (clobber (match_operand:SWI248x 2 "memory_operand"))
4579 (clobber (match_scratch 3))]
4581 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4582 (clobber (match_dup 3))])])
4584 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4585 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4586 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4587 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4588 ;; function in i386.c.
4589 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4590 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4591 (fix:SWI248x (match_operand 1 "register_operand")))
4592 (clobber (reg:CC FLAGS_REG))]
4593 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4595 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4596 && (TARGET_64BIT || <MODE>mode != DImode))
4597 && can_create_pseudo_p ()"
4602 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4604 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4605 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4606 if (memory_operand (operands[0], VOIDmode))
4607 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4608 operands[2], operands[3]));
4611 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4612 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4613 operands[2], operands[3],
4618 [(set_attr "type" "fistp")
4619 (set_attr "i387_cw" "trunc")
4620 (set_attr "mode" "<MODE>")])
4622 (define_insn "fix_truncdi_i387"
4623 [(set (match_operand:DI 0 "memory_operand" "=m")
4624 (fix:DI (match_operand 1 "register_operand" "f")))
4625 (use (match_operand:HI 2 "memory_operand" "m"))
4626 (use (match_operand:HI 3 "memory_operand" "m"))
4627 (clobber (match_scratch:XF 4 "=&1f"))]
4628 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4630 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4631 "* return output_fix_trunc (insn, operands, false);"
4632 [(set_attr "type" "fistp")
4633 (set_attr "i387_cw" "trunc")
4634 (set_attr "mode" "DI")])
4636 (define_insn "fix_truncdi_i387_with_temp"
4637 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4638 (fix:DI (match_operand 1 "register_operand" "f,f")))
4639 (use (match_operand:HI 2 "memory_operand" "m,m"))
4640 (use (match_operand:HI 3 "memory_operand" "m,m"))
4641 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4642 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4643 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4645 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4647 [(set_attr "type" "fistp")
4648 (set_attr "i387_cw" "trunc")
4649 (set_attr "mode" "DI")])
4652 [(set (match_operand:DI 0 "register_operand")
4653 (fix:DI (match_operand 1 "register_operand")))
4654 (use (match_operand:HI 2 "memory_operand"))
4655 (use (match_operand:HI 3 "memory_operand"))
4656 (clobber (match_operand:DI 4 "memory_operand"))
4657 (clobber (match_scratch 5))]
4659 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4662 (clobber (match_dup 5))])
4663 (set (match_dup 0) (match_dup 4))])
4666 [(set (match_operand:DI 0 "memory_operand")
4667 (fix:DI (match_operand 1 "register_operand")))
4668 (use (match_operand:HI 2 "memory_operand"))
4669 (use (match_operand:HI 3 "memory_operand"))
4670 (clobber (match_operand:DI 4 "memory_operand"))
4671 (clobber (match_scratch 5))]
4673 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4676 (clobber (match_dup 5))])])
4678 (define_insn "fix_trunc<mode>_i387"
4679 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4680 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4681 (use (match_operand:HI 2 "memory_operand" "m"))
4682 (use (match_operand:HI 3 "memory_operand" "m"))]
4683 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4685 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4686 "* return output_fix_trunc (insn, operands, false);"
4687 [(set_attr "type" "fistp")
4688 (set_attr "i387_cw" "trunc")
4689 (set_attr "mode" "<MODE>")])
4691 (define_insn "fix_trunc<mode>_i387_with_temp"
4692 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4693 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4694 (use (match_operand:HI 2 "memory_operand" "m,m"))
4695 (use (match_operand:HI 3 "memory_operand" "m,m"))
4696 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4697 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4699 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4701 [(set_attr "type" "fistp")
4702 (set_attr "i387_cw" "trunc")
4703 (set_attr "mode" "<MODE>")])
4706 [(set (match_operand:SWI24 0 "register_operand")
4707 (fix:SWI24 (match_operand 1 "register_operand")))
4708 (use (match_operand:HI 2 "memory_operand"))
4709 (use (match_operand:HI 3 "memory_operand"))
4710 (clobber (match_operand:SWI24 4 "memory_operand"))]
4712 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4714 (use (match_dup 3))])
4715 (set (match_dup 0) (match_dup 4))])
4718 [(set (match_operand:SWI24 0 "memory_operand")
4719 (fix:SWI24 (match_operand 1 "register_operand")))
4720 (use (match_operand:HI 2 "memory_operand"))
4721 (use (match_operand:HI 3 "memory_operand"))
4722 (clobber (match_operand:SWI24 4 "memory_operand"))]
4724 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4726 (use (match_dup 3))])])
4728 (define_insn "x86_fnstcw_1"
4729 [(set (match_operand:HI 0 "memory_operand" "=m")
4730 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4733 [(set (attr "length")
4734 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4735 (set_attr "mode" "HI")
4736 (set_attr "unit" "i387")
4737 (set_attr "bdver1_decode" "vector")])
4739 (define_insn "x86_fldcw_1"
4740 [(set (reg:HI FPCR_REG)
4741 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4744 [(set (attr "length")
4745 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4746 (set_attr "mode" "HI")
4747 (set_attr "unit" "i387")
4748 (set_attr "athlon_decode" "vector")
4749 (set_attr "amdfam10_decode" "vector")
4750 (set_attr "bdver1_decode" "vector")])
4752 ;; Conversion between fixed point and floating point.
4754 ;; Even though we only accept memory inputs, the backend _really_
4755 ;; wants to be able to do this between registers.
4757 (define_expand "floathi<mode>2"
4758 [(set (match_operand:X87MODEF 0 "register_operand")
4759 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4761 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4762 || TARGET_MIX_SSE_I387)")
4764 ;; Pre-reload splitter to add memory clobber to the pattern.
4765 (define_insn_and_split "*floathi<mode>2_1"
4766 [(set (match_operand:X87MODEF 0 "register_operand")
4767 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4769 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4770 || TARGET_MIX_SSE_I387)
4771 && can_create_pseudo_p ()"
4774 [(parallel [(set (match_dup 0)
4775 (float:X87MODEF (match_dup 1)))
4776 (clobber (match_dup 2))])]
4777 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4779 (define_insn "*floathi<mode>2_i387_with_temp"
4780 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4781 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4782 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4784 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4785 || TARGET_MIX_SSE_I387)"
4787 [(set_attr "type" "fmov,multi")
4788 (set_attr "mode" "<MODE>")
4789 (set_attr "unit" "*,i387")
4790 (set_attr "fp_int_src" "true")])
4792 (define_insn "*floathi<mode>2_i387"
4793 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4794 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4796 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4797 || TARGET_MIX_SSE_I387)"
4799 [(set_attr "type" "fmov")
4800 (set_attr "mode" "<MODE>")
4801 (set_attr "fp_int_src" "true")])
4804 [(set (match_operand:X87MODEF 0 "register_operand")
4805 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4806 (clobber (match_operand:HI 2 "memory_operand"))]
4808 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4809 || TARGET_MIX_SSE_I387)
4810 && reload_completed"
4811 [(set (match_dup 2) (match_dup 1))
4812 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4815 [(set (match_operand:X87MODEF 0 "register_operand")
4816 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4817 (clobber (match_operand:HI 2 "memory_operand"))]
4819 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4820 || TARGET_MIX_SSE_I387)
4821 && reload_completed"
4822 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4824 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4825 [(set (match_operand:X87MODEF 0 "register_operand")
4827 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4829 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4830 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4832 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4833 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4834 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4836 rtx reg = gen_reg_rtx (XFmode);
4837 rtx (*insn)(rtx, rtx);
4839 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4841 if (<X87MODEF:MODE>mode == SFmode)
4842 insn = gen_truncxfsf2;
4843 else if (<X87MODEF:MODE>mode == DFmode)
4844 insn = gen_truncxfdf2;
4848 emit_insn (insn (operands[0], reg));
4853 ;; Pre-reload splitter to add memory clobber to the pattern.
4854 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4855 [(set (match_operand:X87MODEF 0 "register_operand")
4856 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4858 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4859 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4860 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4861 || TARGET_MIX_SSE_I387))
4862 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4863 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4864 && ((<SWI48x:MODE>mode == SImode
4865 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4866 && optimize_function_for_speed_p (cfun)
4867 && flag_trapping_math)
4868 || !(TARGET_INTER_UNIT_CONVERSIONS
4869 || optimize_function_for_size_p (cfun)))))
4870 && can_create_pseudo_p ()"
4873 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4874 (clobber (match_dup 2))])]
4876 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4878 /* Avoid store forwarding (partial memory) stall penalty
4879 by passing DImode value through XMM registers. */
4880 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4881 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4882 && optimize_function_for_speed_p (cfun))
4884 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4891 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4892 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4894 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4895 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4896 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4897 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4899 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4900 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4901 (set_attr "unit" "*,i387,*,*,*")
4902 (set_attr "athlon_decode" "*,*,double,direct,double")
4903 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4904 (set_attr "bdver1_decode" "*,*,double,direct,double")
4905 (set_attr "fp_int_src" "true")])
4907 (define_insn "*floatsi<mode>2_vector_mixed"
4908 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4909 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4910 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4911 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4915 [(set_attr "type" "fmov,sseicvt")
4916 (set_attr "mode" "<MODE>,<ssevecmode>")
4917 (set_attr "unit" "i387,*")
4918 (set_attr "athlon_decode" "*,direct")
4919 (set_attr "amdfam10_decode" "*,double")
4920 (set_attr "bdver1_decode" "*,direct")
4921 (set_attr "fp_int_src" "true")])
4923 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4924 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4926 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4927 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4928 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4929 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4931 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4932 (set_attr "mode" "<MODEF:MODE>")
4933 (set_attr "unit" "*,i387,*,*")
4934 (set_attr "athlon_decode" "*,*,double,direct")
4935 (set_attr "amdfam10_decode" "*,*,vector,double")
4936 (set_attr "bdver1_decode" "*,*,double,direct")
4937 (set_attr "fp_int_src" "true")])
4940 [(set (match_operand:MODEF 0 "register_operand")
4941 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4942 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4943 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4944 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4945 && TARGET_INTER_UNIT_CONVERSIONS
4947 && (SSE_REG_P (operands[0])
4948 || (GET_CODE (operands[0]) == SUBREG
4949 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4950 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4953 [(set (match_operand:MODEF 0 "register_operand")
4954 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4955 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4956 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4957 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4958 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4960 && (SSE_REG_P (operands[0])
4961 || (GET_CODE (operands[0]) == SUBREG
4962 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4963 [(set (match_dup 2) (match_dup 1))
4964 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4966 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4967 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4969 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4970 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4971 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4972 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4975 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4976 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4977 [(set_attr "type" "fmov,sseicvt,sseicvt")
4978 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4979 (set_attr "mode" "<MODEF:MODE>")
4980 (set (attr "prefix_rex")
4982 (and (eq_attr "prefix" "maybe_vex")
4983 (match_test "<SWI48x:MODE>mode == DImode"))
4985 (const_string "*")))
4986 (set_attr "unit" "i387,*,*")
4987 (set_attr "athlon_decode" "*,double,direct")
4988 (set_attr "amdfam10_decode" "*,vector,double")
4989 (set_attr "bdver1_decode" "*,double,direct")
4990 (set_attr "fp_int_src" "true")])
4992 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4993 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4995 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4996 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4997 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4998 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5001 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5002 [(set_attr "type" "fmov,sseicvt")
5003 (set_attr "prefix" "orig,maybe_vex")
5004 (set_attr "mode" "<MODEF:MODE>")
5005 (set (attr "prefix_rex")
5007 (and (eq_attr "prefix" "maybe_vex")
5008 (match_test "<SWI48x:MODE>mode == DImode"))
5010 (const_string "*")))
5011 (set_attr "athlon_decode" "*,direct")
5012 (set_attr "amdfam10_decode" "*,double")
5013 (set_attr "bdver1_decode" "*,direct")
5014 (set_attr "fp_int_src" "true")])
5016 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5017 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5019 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5020 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5021 "TARGET_SSE2 && TARGET_SSE_MATH
5022 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5024 [(set_attr "type" "sseicvt")
5025 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5026 (set_attr "athlon_decode" "double,direct,double")
5027 (set_attr "amdfam10_decode" "vector,double,double")
5028 (set_attr "bdver1_decode" "double,direct,double")
5029 (set_attr "fp_int_src" "true")])
5031 (define_insn "*floatsi<mode>2_vector_sse"
5032 [(set (match_operand:MODEF 0 "register_operand" "=x")
5033 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5034 "TARGET_SSE2 && TARGET_SSE_MATH
5035 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5037 [(set_attr "type" "sseicvt")
5038 (set_attr "mode" "<MODE>")
5039 (set_attr "athlon_decode" "direct")
5040 (set_attr "amdfam10_decode" "double")
5041 (set_attr "bdver1_decode" "direct")
5042 (set_attr "fp_int_src" "true")])
5045 [(set (match_operand:MODEF 0 "register_operand")
5046 (float:MODEF (match_operand:SI 1 "register_operand")))
5047 (clobber (match_operand:SI 2 "memory_operand"))]
5048 "TARGET_SSE2 && TARGET_SSE_MATH
5049 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5051 && (SSE_REG_P (operands[0])
5052 || (GET_CODE (operands[0]) == SUBREG
5053 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5056 rtx op1 = operands[1];
5058 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5060 if (GET_CODE (op1) == SUBREG)
5061 op1 = SUBREG_REG (op1);
5063 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5065 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5066 emit_insn (gen_sse2_loadld (operands[4],
5067 CONST0_RTX (V4SImode), operands[1]));
5069 /* We can ignore possible trapping value in the
5070 high part of SSE register for non-trapping math. */
5071 else if (SSE_REG_P (op1) && !flag_trapping_math)
5072 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5075 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5076 emit_move_insn (operands[2], operands[1]);
5077 emit_insn (gen_sse2_loadld (operands[4],
5078 CONST0_RTX (V4SImode), operands[2]));
5080 if (<ssevecmode>mode == V4SFmode)
5081 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5083 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5088 [(set (match_operand:MODEF 0 "register_operand")
5089 (float:MODEF (match_operand:SI 1 "memory_operand")))
5090 (clobber (match_operand:SI 2 "memory_operand"))]
5091 "TARGET_SSE2 && TARGET_SSE_MATH
5092 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5094 && (SSE_REG_P (operands[0])
5095 || (GET_CODE (operands[0]) == SUBREG
5096 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5099 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5101 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5103 emit_insn (gen_sse2_loadld (operands[4],
5104 CONST0_RTX (V4SImode), operands[1]));
5105 if (<ssevecmode>mode == V4SFmode)
5106 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5108 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5113 [(set (match_operand:MODEF 0 "register_operand")
5114 (float:MODEF (match_operand:SI 1 "register_operand")))]
5115 "TARGET_SSE2 && TARGET_SSE_MATH
5116 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5118 && (SSE_REG_P (operands[0])
5119 || (GET_CODE (operands[0]) == SUBREG
5120 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5123 rtx op1 = operands[1];
5125 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5127 if (GET_CODE (op1) == SUBREG)
5128 op1 = SUBREG_REG (op1);
5130 if (GENERAL_REG_P (op1))
5132 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5133 if (TARGET_INTER_UNIT_MOVES)
5134 emit_insn (gen_sse2_loadld (operands[4],
5135 CONST0_RTX (V4SImode), operands[1]));
5138 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5140 emit_insn (gen_sse2_loadld (operands[4],
5141 CONST0_RTX (V4SImode), operands[5]));
5142 ix86_free_from_memory (GET_MODE (operands[1]));
5145 /* We can ignore possible trapping value in the
5146 high part of SSE register for non-trapping math. */
5147 else if (SSE_REG_P (op1) && !flag_trapping_math)
5148 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5151 if (<ssevecmode>mode == V4SFmode)
5152 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5154 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5159 [(set (match_operand:MODEF 0 "register_operand")
5160 (float:MODEF (match_operand:SI 1 "memory_operand")))]
5161 "TARGET_SSE2 && TARGET_SSE_MATH
5162 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5164 && (SSE_REG_P (operands[0])
5165 || (GET_CODE (operands[0]) == SUBREG
5166 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5169 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5171 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5173 emit_insn (gen_sse2_loadld (operands[4],
5174 CONST0_RTX (V4SImode), operands[1]));
5175 if (<ssevecmode>mode == V4SFmode)
5176 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5178 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5182 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5183 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5185 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5186 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5187 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5188 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5190 [(set_attr "type" "sseicvt")
5191 (set_attr "mode" "<MODEF:MODE>")
5192 (set_attr "athlon_decode" "double,direct")
5193 (set_attr "amdfam10_decode" "vector,double")
5194 (set_attr "bdver1_decode" "double,direct")
5195 (set_attr "fp_int_src" "true")])
5197 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5198 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5200 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5201 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5202 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5203 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5204 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5205 [(set_attr "type" "sseicvt")
5206 (set_attr "prefix" "maybe_vex")
5207 (set_attr "mode" "<MODEF:MODE>")
5208 (set (attr "prefix_rex")
5210 (and (eq_attr "prefix" "maybe_vex")
5211 (match_test "<SWI48x:MODE>mode == DImode"))
5213 (const_string "*")))
5214 (set_attr "athlon_decode" "double,direct")
5215 (set_attr "amdfam10_decode" "vector,double")
5216 (set_attr "bdver1_decode" "double,direct")
5217 (set_attr "fp_int_src" "true")])
5220 [(set (match_operand:MODEF 0 "register_operand")
5221 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))
5222 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5223 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5224 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5225 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5227 && (SSE_REG_P (operands[0])
5228 || (GET_CODE (operands[0]) == SUBREG
5229 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5230 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5232 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5233 [(set (match_operand:MODEF 0 "register_operand" "=x")
5235 (match_operand:SWI48x 1 "memory_operand" "m")))]
5236 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5237 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5238 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5239 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5240 [(set_attr "type" "sseicvt")
5241 (set_attr "prefix" "maybe_vex")
5242 (set_attr "mode" "<MODEF:MODE>")
5243 (set (attr "prefix_rex")
5245 (and (eq_attr "prefix" "maybe_vex")
5246 (match_test "<SWI48x:MODE>mode == DImode"))
5248 (const_string "*")))
5249 (set_attr "athlon_decode" "direct")
5250 (set_attr "amdfam10_decode" "double")
5251 (set_attr "bdver1_decode" "direct")
5252 (set_attr "fp_int_src" "true")])
5255 [(set (match_operand:MODEF 0 "register_operand")
5256 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
5257 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5258 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5259 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5260 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5262 && (SSE_REG_P (operands[0])
5263 || (GET_CODE (operands[0]) == SUBREG
5264 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5265 [(set (match_dup 2) (match_dup 1))
5266 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5269 [(set (match_operand:MODEF 0 "register_operand")
5270 (float:MODEF (match_operand:SWI48x 1 "memory_operand")))
5271 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5272 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5273 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5275 && (SSE_REG_P (operands[0])
5276 || (GET_CODE (operands[0]) == SUBREG
5277 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5278 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5280 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5281 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5283 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5284 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5286 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5290 [(set_attr "type" "fmov,multi")
5291 (set_attr "mode" "<X87MODEF:MODE>")
5292 (set_attr "unit" "*,i387")
5293 (set_attr "fp_int_src" "true")])
5295 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5296 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5298 (match_operand:SWI48x 1 "memory_operand" "m")))]
5300 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5302 [(set_attr "type" "fmov")
5303 (set_attr "mode" "<X87MODEF:MODE>")
5304 (set_attr "fp_int_src" "true")])
5307 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5308 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5309 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5311 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5312 && reload_completed"
5313 [(set (match_dup 2) (match_dup 1))
5314 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5317 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5318 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5319 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5321 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5322 && reload_completed"
5323 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5325 ;; Avoid store forwarding (partial memory) stall penalty
5326 ;; by passing DImode value through XMM registers. */
5328 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5329 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5331 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5332 (clobber (match_scratch:V4SI 3 "=X,x"))
5333 (clobber (match_scratch:V4SI 4 "=X,x"))
5334 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5335 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5336 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5337 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5339 [(set_attr "type" "multi")
5340 (set_attr "mode" "<X87MODEF:MODE>")
5341 (set_attr "unit" "i387")
5342 (set_attr "fp_int_src" "true")])
5345 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5346 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5347 (clobber (match_scratch:V4SI 3))
5348 (clobber (match_scratch:V4SI 4))
5349 (clobber (match_operand:DI 2 "memory_operand"))]
5350 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5351 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5352 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5353 && reload_completed"
5354 [(set (match_dup 2) (match_dup 3))
5355 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5357 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5358 Assemble the 64-bit DImode value in an xmm register. */
5359 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5360 gen_rtx_SUBREG (SImode, operands[1], 0)));
5361 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5362 gen_rtx_SUBREG (SImode, operands[1], 4)));
5363 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5366 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5370 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5371 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5372 (clobber (match_scratch:V4SI 3))
5373 (clobber (match_scratch:V4SI 4))
5374 (clobber (match_operand:DI 2 "memory_operand"))]
5375 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5376 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5377 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5378 && reload_completed"
5379 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5381 ;; Avoid store forwarding (partial memory) stall penalty by extending
5382 ;; SImode value to DImode through XMM register instead of pushing two
5383 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5384 ;; targets benefit from this optimization. Also note that fild
5385 ;; loads from memory only.
5387 (define_insn "*floatunssi<mode>2_1"
5388 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5389 (unsigned_float:X87MODEF
5390 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5391 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5392 (clobber (match_scratch:SI 3 "=X,x"))]
5394 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5397 [(set_attr "type" "multi")
5398 (set_attr "mode" "<MODE>")])
5401 [(set (match_operand:X87MODEF 0 "register_operand")
5402 (unsigned_float:X87MODEF
5403 (match_operand:SI 1 "register_operand")))
5404 (clobber (match_operand:DI 2 "memory_operand"))
5405 (clobber (match_scratch:SI 3))]
5407 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5409 && reload_completed"
5410 [(set (match_dup 2) (match_dup 1))
5412 (float:X87MODEF (match_dup 2)))]
5413 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5416 [(set (match_operand:X87MODEF 0 "register_operand")
5417 (unsigned_float:X87MODEF
5418 (match_operand:SI 1 "memory_operand")))
5419 (clobber (match_operand:DI 2 "memory_operand"))
5420 (clobber (match_scratch:SI 3))]
5422 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5424 && reload_completed"
5425 [(set (match_dup 2) (match_dup 3))
5427 (float:X87MODEF (match_dup 2)))]
5429 emit_move_insn (operands[3], operands[1]);
5430 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5433 (define_expand "floatunssi<mode>2"
5435 [(set (match_operand:X87MODEF 0 "register_operand")
5436 (unsigned_float:X87MODEF
5437 (match_operand:SI 1 "nonimmediate_operand")))
5438 (clobber (match_dup 2))
5439 (clobber (match_scratch:SI 3))])]
5441 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5443 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5445 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5447 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5452 enum ix86_stack_slot slot = (virtuals_instantiated
5455 operands[2] = assign_386_stack_local (DImode, slot);
5459 (define_expand "floatunsdisf2"
5460 [(use (match_operand:SF 0 "register_operand"))
5461 (use (match_operand:DI 1 "nonimmediate_operand"))]
5462 "TARGET_64BIT && TARGET_SSE_MATH"
5463 "x86_emit_floatuns (operands); DONE;")
5465 (define_expand "floatunsdidf2"
5466 [(use (match_operand:DF 0 "register_operand"))
5467 (use (match_operand:DI 1 "nonimmediate_operand"))]
5468 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5469 && TARGET_SSE2 && TARGET_SSE_MATH"
5472 x86_emit_floatuns (operands);
5474 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5478 ;; Load effective address instructions
5480 (define_insn_and_split "*lea<mode>"
5481 [(set (match_operand:SWI48 0 "register_operand" "=r")
5482 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5485 rtx addr = operands[1];
5487 if (GET_CODE (addr) == SUBREG)
5489 gcc_assert (TARGET_64BIT);
5490 gcc_assert (<MODE>mode == SImode);
5491 gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
5492 return "lea{l}\t{%E1, %0|%0, %E1}";
5494 else if (GET_CODE (addr) == ZERO_EXTEND
5495 || GET_CODE (addr) == AND)
5497 gcc_assert (TARGET_64BIT);
5498 gcc_assert (<MODE>mode == DImode);
5499 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5502 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5504 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5507 enum machine_mode mode = <MODE>mode;
5510 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5511 change operands[] array behind our back. */
5512 pat = PATTERN (curr_insn);
5514 operands[0] = SET_DEST (pat);
5515 operands[1] = SET_SRC (pat);
5517 /* Emit all operations in SImode for zero-extended addresses. Recall
5518 that x86_64 inheretly zero-extends SImode operations to DImode. */
5519 if (GET_CODE (operands[1]) == ZERO_EXTEND
5520 || GET_CODE (operands[1]) == AND)
5523 ix86_split_lea_for_addr (curr_insn, operands, mode);
5526 [(set_attr "type" "lea")
5527 (set_attr "mode" "<MODE>")])
5531 (define_expand "add<mode>3"
5532 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5533 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5534 (match_operand:SDWIM 2 "<general_operand>")))]
5536 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5538 (define_insn_and_split "*add<dwi>3_doubleword"
5539 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5541 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5542 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5543 (clobber (reg:CC FLAGS_REG))]
5544 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5547 [(parallel [(set (reg:CC FLAGS_REG)
5548 (unspec:CC [(match_dup 1) (match_dup 2)]
5551 (plus:DWIH (match_dup 1) (match_dup 2)))])
5552 (parallel [(set (match_dup 3)
5556 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5558 (clobber (reg:CC FLAGS_REG))])]
5559 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5561 (define_insn "*add<mode>3_cc"
5562 [(set (reg:CC FLAGS_REG)
5564 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5565 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5567 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5568 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5569 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5570 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5571 [(set_attr "type" "alu")
5572 (set_attr "mode" "<MODE>")])
5574 (define_insn "addqi3_cc"
5575 [(set (reg:CC FLAGS_REG)
5577 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5578 (match_operand:QI 2 "general_operand" "qn,qm")]
5580 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5581 (plus:QI (match_dup 1) (match_dup 2)))]
5582 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5583 "add{b}\t{%2, %0|%0, %2}"
5584 [(set_attr "type" "alu")
5585 (set_attr "mode" "QI")])
5587 (define_insn "*add<mode>_1"
5588 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5590 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5591 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5592 (clobber (reg:CC FLAGS_REG))]
5593 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5595 switch (get_attr_type (insn))
5601 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5602 if (operands[2] == const1_rtx)
5603 return "inc{<imodesuffix>}\t%0";
5606 gcc_assert (operands[2] == constm1_rtx);
5607 return "dec{<imodesuffix>}\t%0";
5611 /* For most processors, ADD is faster than LEA. This alternative
5612 was added to use ADD as much as possible. */
5613 if (which_alternative == 2)
5616 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5619 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5620 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5621 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5623 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5627 (cond [(eq_attr "alternative" "3")
5628 (const_string "lea")
5629 (match_operand:SWI48 2 "incdec_operand")
5630 (const_string "incdec")
5632 (const_string "alu")))
5633 (set (attr "length_immediate")
5635 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5637 (const_string "*")))
5638 (set_attr "mode" "<MODE>")])
5640 ;; It may seem that nonimmediate operand is proper one for operand 1.
5641 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5642 ;; we take care in ix86_binary_operator_ok to not allow two memory
5643 ;; operands so proper swapping will be done in reload. This allow
5644 ;; patterns constructed from addsi_1 to match.
5646 (define_insn "addsi_1_zext"
5647 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5649 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5650 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5651 (clobber (reg:CC FLAGS_REG))]
5652 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5654 switch (get_attr_type (insn))
5660 if (operands[2] == const1_rtx)
5661 return "inc{l}\t%k0";
5664 gcc_assert (operands[2] == constm1_rtx);
5665 return "dec{l}\t%k0";
5669 /* For most processors, ADD is faster than LEA. This alternative
5670 was added to use ADD as much as possible. */
5671 if (which_alternative == 1)
5674 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5677 if (x86_maybe_negate_const_int (&operands[2], SImode))
5678 return "sub{l}\t{%2, %k0|%k0, %2}";
5680 return "add{l}\t{%2, %k0|%k0, %2}";
5684 (cond [(eq_attr "alternative" "2")
5685 (const_string "lea")
5686 (match_operand:SI 2 "incdec_operand")
5687 (const_string "incdec")
5689 (const_string "alu")))
5690 (set (attr "length_immediate")
5692 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5694 (const_string "*")))
5695 (set_attr "mode" "SI")])
5697 (define_insn "*addhi_1"
5698 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5699 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5700 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5701 (clobber (reg:CC FLAGS_REG))]
5702 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5704 switch (get_attr_type (insn))
5710 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5711 if (operands[2] == const1_rtx)
5712 return "inc{w}\t%0";
5715 gcc_assert (operands[2] == constm1_rtx);
5716 return "dec{w}\t%0";
5720 /* For most processors, ADD is faster than LEA. This alternative
5721 was added to use ADD as much as possible. */
5722 if (which_alternative == 2)
5725 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5728 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5729 if (x86_maybe_negate_const_int (&operands[2], HImode))
5730 return "sub{w}\t{%2, %0|%0, %2}";
5732 return "add{w}\t{%2, %0|%0, %2}";
5736 (cond [(eq_attr "alternative" "3")
5737 (const_string "lea")
5738 (match_operand:HI 2 "incdec_operand")
5739 (const_string "incdec")
5741 (const_string "alu")))
5742 (set (attr "length_immediate")
5744 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5746 (const_string "*")))
5747 (set_attr "mode" "HI,HI,HI,SI")])
5749 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5750 (define_insn "*addqi_1"
5751 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5752 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5753 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5754 (clobber (reg:CC FLAGS_REG))]
5755 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5757 bool widen = (which_alternative == 3 || which_alternative == 4);
5759 switch (get_attr_type (insn))
5765 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5766 if (operands[2] == const1_rtx)
5767 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5770 gcc_assert (operands[2] == constm1_rtx);
5771 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5775 /* For most processors, ADD is faster than LEA. These alternatives
5776 were added to use ADD as much as possible. */
5777 if (which_alternative == 2 || which_alternative == 4)
5780 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5783 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5784 if (x86_maybe_negate_const_int (&operands[2], QImode))
5787 return "sub{l}\t{%2, %k0|%k0, %2}";
5789 return "sub{b}\t{%2, %0|%0, %2}";
5792 return "add{l}\t{%k2, %k0|%k0, %k2}";
5794 return "add{b}\t{%2, %0|%0, %2}";
5798 (cond [(eq_attr "alternative" "5")
5799 (const_string "lea")
5800 (match_operand:QI 2 "incdec_operand")
5801 (const_string "incdec")
5803 (const_string "alu")))
5804 (set (attr "length_immediate")
5806 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5808 (const_string "*")))
5809 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5811 (define_insn "*addqi_1_slp"
5812 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5813 (plus:QI (match_dup 0)
5814 (match_operand:QI 1 "general_operand" "qn,qm")))
5815 (clobber (reg:CC FLAGS_REG))]
5816 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5817 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5819 switch (get_attr_type (insn))
5822 if (operands[1] == const1_rtx)
5823 return "inc{b}\t%0";
5826 gcc_assert (operands[1] == constm1_rtx);
5827 return "dec{b}\t%0";
5831 if (x86_maybe_negate_const_int (&operands[1], QImode))
5832 return "sub{b}\t{%1, %0|%0, %1}";
5834 return "add{b}\t{%1, %0|%0, %1}";
5838 (if_then_else (match_operand:QI 1 "incdec_operand")
5839 (const_string "incdec")
5840 (const_string "alu1")))
5841 (set (attr "memory")
5842 (if_then_else (match_operand 1 "memory_operand")
5843 (const_string "load")
5844 (const_string "none")))
5845 (set_attr "mode" "QI")])
5847 ;; Split non destructive adds if we cannot use lea.
5849 [(set (match_operand:SWI48 0 "register_operand")
5850 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5851 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5852 (clobber (reg:CC FLAGS_REG))]
5853 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5854 [(set (match_dup 0) (match_dup 1))
5855 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5856 (clobber (reg:CC FLAGS_REG))])])
5858 ;; Convert add to the lea pattern to avoid flags dependency.
5860 [(set (match_operand:SWI 0 "register_operand")
5861 (plus:SWI (match_operand:SWI 1 "register_operand")
5862 (match_operand:SWI 2 "<nonmemory_operand>")))
5863 (clobber (reg:CC FLAGS_REG))]
5864 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5867 enum machine_mode mode = <MODE>mode;
5870 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5873 operands[0] = gen_lowpart (mode, operands[0]);
5874 operands[1] = gen_lowpart (mode, operands[1]);
5875 operands[2] = gen_lowpart (mode, operands[2]);
5878 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5880 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5884 ;; Split non destructive adds if we cannot use lea.
5886 [(set (match_operand:DI 0 "register_operand")
5888 (plus:SI (match_operand:SI 1 "register_operand")
5889 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5890 (clobber (reg:CC FLAGS_REG))]
5892 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5893 [(set (match_dup 3) (match_dup 1))
5894 (parallel [(set (match_dup 0)
5895 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5896 (clobber (reg:CC FLAGS_REG))])]
5897 "operands[3] = gen_lowpart (SImode, operands[0]);")
5899 ;; Convert add to the lea pattern to avoid flags dependency.
5901 [(set (match_operand:DI 0 "register_operand")
5903 (plus:SI (match_operand:SI 1 "register_operand")
5904 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5905 (clobber (reg:CC FLAGS_REG))]
5906 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5908 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5910 (define_insn "*add<mode>_2"
5911 [(set (reg FLAGS_REG)
5914 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5915 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5917 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5918 (plus:SWI (match_dup 1) (match_dup 2)))]
5919 "ix86_match_ccmode (insn, CCGOCmode)
5920 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5922 switch (get_attr_type (insn))
5925 if (operands[2] == const1_rtx)
5926 return "inc{<imodesuffix>}\t%0";
5929 gcc_assert (operands[2] == constm1_rtx);
5930 return "dec{<imodesuffix>}\t%0";
5934 if (which_alternative == 2)
5937 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5940 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5941 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5942 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5944 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5948 (if_then_else (match_operand:SWI 2 "incdec_operand")
5949 (const_string "incdec")
5950 (const_string "alu")))
5951 (set (attr "length_immediate")
5953 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5955 (const_string "*")))
5956 (set_attr "mode" "<MODE>")])
5958 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5959 (define_insn "*addsi_2_zext"
5960 [(set (reg FLAGS_REG)
5962 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5963 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5965 (set (match_operand:DI 0 "register_operand" "=r,r")
5966 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5967 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5968 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5970 switch (get_attr_type (insn))
5973 if (operands[2] == const1_rtx)
5974 return "inc{l}\t%k0";
5977 gcc_assert (operands[2] == constm1_rtx);
5978 return "dec{l}\t%k0";
5982 if (which_alternative == 1)
5985 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5988 if (x86_maybe_negate_const_int (&operands[2], SImode))
5989 return "sub{l}\t{%2, %k0|%k0, %2}";
5991 return "add{l}\t{%2, %k0|%k0, %2}";
5995 (if_then_else (match_operand:SI 2 "incdec_operand")
5996 (const_string "incdec")
5997 (const_string "alu")))
5998 (set (attr "length_immediate")
6000 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6002 (const_string "*")))
6003 (set_attr "mode" "SI")])
6005 (define_insn "*add<mode>_3"
6006 [(set (reg FLAGS_REG)
6008 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6009 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6010 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6011 "ix86_match_ccmode (insn, CCZmode)
6012 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6014 switch (get_attr_type (insn))
6017 if (operands[2] == const1_rtx)
6018 return "inc{<imodesuffix>}\t%0";
6021 gcc_assert (operands[2] == constm1_rtx);
6022 return "dec{<imodesuffix>}\t%0";
6026 if (which_alternative == 1)
6029 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6032 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6033 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6034 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6036 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6040 (if_then_else (match_operand:SWI 2 "incdec_operand")
6041 (const_string "incdec")
6042 (const_string "alu")))
6043 (set (attr "length_immediate")
6045 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6047 (const_string "*")))
6048 (set_attr "mode" "<MODE>")])
6050 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6051 (define_insn "*addsi_3_zext"
6052 [(set (reg FLAGS_REG)
6054 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6055 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6056 (set (match_operand:DI 0 "register_operand" "=r,r")
6057 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6058 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6059 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6061 switch (get_attr_type (insn))
6064 if (operands[2] == const1_rtx)
6065 return "inc{l}\t%k0";
6068 gcc_assert (operands[2] == constm1_rtx);
6069 return "dec{l}\t%k0";
6073 if (which_alternative == 1)
6076 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6079 if (x86_maybe_negate_const_int (&operands[2], SImode))
6080 return "sub{l}\t{%2, %k0|%k0, %2}";
6082 return "add{l}\t{%2, %k0|%k0, %2}";
6086 (if_then_else (match_operand:SI 2 "incdec_operand")
6087 (const_string "incdec")
6088 (const_string "alu")))
6089 (set (attr "length_immediate")
6091 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6093 (const_string "*")))
6094 (set_attr "mode" "SI")])
6096 ; For comparisons against 1, -1 and 128, we may generate better code
6097 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6098 ; is matched then. We can't accept general immediate, because for
6099 ; case of overflows, the result is messed up.
6100 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6101 ; only for comparisons not depending on it.
6103 (define_insn "*adddi_4"
6104 [(set (reg FLAGS_REG)
6106 (match_operand:DI 1 "nonimmediate_operand" "0")
6107 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6108 (clobber (match_scratch:DI 0 "=rm"))]
6110 && ix86_match_ccmode (insn, CCGCmode)"
6112 switch (get_attr_type (insn))
6115 if (operands[2] == constm1_rtx)
6116 return "inc{q}\t%0";
6119 gcc_assert (operands[2] == const1_rtx);
6120 return "dec{q}\t%0";
6124 if (x86_maybe_negate_const_int (&operands[2], DImode))
6125 return "add{q}\t{%2, %0|%0, %2}";
6127 return "sub{q}\t{%2, %0|%0, %2}";
6131 (if_then_else (match_operand:DI 2 "incdec_operand")
6132 (const_string "incdec")
6133 (const_string "alu")))
6134 (set (attr "length_immediate")
6136 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6138 (const_string "*")))
6139 (set_attr "mode" "DI")])
6141 ; For comparisons against 1, -1 and 128, we may generate better code
6142 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6143 ; is matched then. We can't accept general immediate, because for
6144 ; case of overflows, the result is messed up.
6145 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6146 ; only for comparisons not depending on it.
6148 (define_insn "*add<mode>_4"
6149 [(set (reg FLAGS_REG)
6151 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6152 (match_operand:SWI124 2 "const_int_operand" "n")))
6153 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6154 "ix86_match_ccmode (insn, CCGCmode)"
6156 switch (get_attr_type (insn))
6159 if (operands[2] == constm1_rtx)
6160 return "inc{<imodesuffix>}\t%0";
6163 gcc_assert (operands[2] == const1_rtx);
6164 return "dec{<imodesuffix>}\t%0";
6168 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6169 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6171 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6175 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6176 (const_string "incdec")
6177 (const_string "alu")))
6178 (set (attr "length_immediate")
6180 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6182 (const_string "*")))
6183 (set_attr "mode" "<MODE>")])
6185 (define_insn "*add<mode>_5"
6186 [(set (reg FLAGS_REG)
6189 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6190 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6192 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6193 "ix86_match_ccmode (insn, CCGOCmode)
6194 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6196 switch (get_attr_type (insn))
6199 if (operands[2] == const1_rtx)
6200 return "inc{<imodesuffix>}\t%0";
6203 gcc_assert (operands[2] == constm1_rtx);
6204 return "dec{<imodesuffix>}\t%0";
6208 if (which_alternative == 1)
6211 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6214 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6215 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6216 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6218 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6222 (if_then_else (match_operand:SWI 2 "incdec_operand")
6223 (const_string "incdec")
6224 (const_string "alu")))
6225 (set (attr "length_immediate")
6227 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6229 (const_string "*")))
6230 (set_attr "mode" "<MODE>")])
6232 (define_insn "*addqi_ext_1_rex64"
6233 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6238 (match_operand 1 "ext_register_operand" "0")
6241 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6242 (clobber (reg:CC FLAGS_REG))]
6245 switch (get_attr_type (insn))
6248 if (operands[2] == const1_rtx)
6249 return "inc{b}\t%h0";
6252 gcc_assert (operands[2] == constm1_rtx);
6253 return "dec{b}\t%h0";
6257 return "add{b}\t{%2, %h0|%h0, %2}";
6261 (if_then_else (match_operand:QI 2 "incdec_operand")
6262 (const_string "incdec")
6263 (const_string "alu")))
6264 (set_attr "modrm" "1")
6265 (set_attr "mode" "QI")])
6267 (define_insn "addqi_ext_1"
6268 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6273 (match_operand 1 "ext_register_operand" "0")
6276 (match_operand:QI 2 "general_operand" "Qmn")))
6277 (clobber (reg:CC FLAGS_REG))]
6280 switch (get_attr_type (insn))
6283 if (operands[2] == const1_rtx)
6284 return "inc{b}\t%h0";
6287 gcc_assert (operands[2] == constm1_rtx);
6288 return "dec{b}\t%h0";
6292 return "add{b}\t{%2, %h0|%h0, %2}";
6296 (if_then_else (match_operand:QI 2 "incdec_operand")
6297 (const_string "incdec")
6298 (const_string "alu")))
6299 (set_attr "modrm" "1")
6300 (set_attr "mode" "QI")])
6302 (define_insn "*addqi_ext_2"
6303 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6308 (match_operand 1 "ext_register_operand" "%0")
6312 (match_operand 2 "ext_register_operand" "Q")
6315 (clobber (reg:CC FLAGS_REG))]
6317 "add{b}\t{%h2, %h0|%h0, %h2}"
6318 [(set_attr "type" "alu")
6319 (set_attr "mode" "QI")])
6321 ;; The lea patterns for modes less than 32 bits need to be matched by
6322 ;; several insns converted to real lea by splitters.
6324 (define_insn_and_split "*lea_general_1"
6325 [(set (match_operand 0 "register_operand" "=r")
6326 (plus (plus (match_operand 1 "index_register_operand" "l")
6327 (match_operand 2 "register_operand" "r"))
6328 (match_operand 3 "immediate_operand" "i")))]
6329 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6330 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6331 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6332 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6333 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6334 || GET_MODE (operands[3]) == VOIDmode)"
6336 "&& reload_completed"
6339 enum machine_mode mode = SImode;
6342 operands[0] = gen_lowpart (mode, operands[0]);
6343 operands[1] = gen_lowpart (mode, operands[1]);
6344 operands[2] = gen_lowpart (mode, operands[2]);
6345 operands[3] = gen_lowpart (mode, operands[3]);
6347 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6350 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6353 [(set_attr "type" "lea")
6354 (set_attr "mode" "SI")])
6356 (define_insn_and_split "*lea_general_2"
6357 [(set (match_operand 0 "register_operand" "=r")
6358 (plus (mult (match_operand 1 "index_register_operand" "l")
6359 (match_operand 2 "const248_operand" "n"))
6360 (match_operand 3 "nonmemory_operand" "ri")))]
6361 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6362 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6363 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6364 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6365 || GET_MODE (operands[3]) == VOIDmode)"
6367 "&& reload_completed"
6370 enum machine_mode mode = SImode;
6373 operands[0] = gen_lowpart (mode, operands[0]);
6374 operands[1] = gen_lowpart (mode, operands[1]);
6375 operands[3] = gen_lowpart (mode, operands[3]);
6377 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6380 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6383 [(set_attr "type" "lea")
6384 (set_attr "mode" "SI")])
6386 (define_insn_and_split "*lea_general_3"
6387 [(set (match_operand 0 "register_operand" "=r")
6388 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6389 (match_operand 2 "const248_operand" "n"))
6390 (match_operand 3 "register_operand" "r"))
6391 (match_operand 4 "immediate_operand" "i")))]
6392 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6393 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6394 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6395 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6397 "&& reload_completed"
6400 enum machine_mode mode = SImode;
6403 operands[0] = gen_lowpart (mode, operands[0]);
6404 operands[1] = gen_lowpart (mode, operands[1]);
6405 operands[3] = gen_lowpart (mode, operands[3]);
6406 operands[4] = gen_lowpart (mode, operands[4]);
6408 pat = gen_rtx_PLUS (mode,
6410 gen_rtx_MULT (mode, operands[1],
6415 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6418 [(set_attr "type" "lea")
6419 (set_attr "mode" "SI")])
6421 (define_insn_and_split "*lea_general_4"
6422 [(set (match_operand 0 "register_operand" "=r")
6424 (match_operand 1 "index_register_operand" "l")
6425 (match_operand 2 "const_int_operand" "n"))
6426 (match_operand 3 "const_int_operand" "n")))]
6427 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6428 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6429 || GET_MODE (operands[0]) == SImode
6430 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6431 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6432 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6433 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6434 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6436 "&& reload_completed"
6439 enum machine_mode mode = GET_MODE (operands[0]);
6442 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6445 operands[0] = gen_lowpart (mode, operands[0]);
6446 operands[1] = gen_lowpart (mode, operands[1]);
6449 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6451 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6452 INTVAL (operands[3]));
6454 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6457 [(set_attr "type" "lea")
6459 (if_then_else (match_operand:DI 0)
6461 (const_string "SI")))])
6463 ;; Subtract instructions
6465 (define_expand "sub<mode>3"
6466 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6467 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6468 (match_operand:SDWIM 2 "<general_operand>")))]
6470 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6472 (define_insn_and_split "*sub<dwi>3_doubleword"
6473 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6475 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6476 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6477 (clobber (reg:CC FLAGS_REG))]
6478 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6481 [(parallel [(set (reg:CC FLAGS_REG)
6482 (compare:CC (match_dup 1) (match_dup 2)))
6484 (minus:DWIH (match_dup 1) (match_dup 2)))])
6485 (parallel [(set (match_dup 3)
6489 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6491 (clobber (reg:CC FLAGS_REG))])]
6492 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6494 (define_insn "*sub<mode>_1"
6495 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6497 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6498 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6499 (clobber (reg:CC FLAGS_REG))]
6500 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6501 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6502 [(set_attr "type" "alu")
6503 (set_attr "mode" "<MODE>")])
6505 (define_insn "*subsi_1_zext"
6506 [(set (match_operand:DI 0 "register_operand" "=r")
6508 (minus:SI (match_operand:SI 1 "register_operand" "0")
6509 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6510 (clobber (reg:CC FLAGS_REG))]
6511 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6512 "sub{l}\t{%2, %k0|%k0, %2}"
6513 [(set_attr "type" "alu")
6514 (set_attr "mode" "SI")])
6516 (define_insn "*subqi_1_slp"
6517 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6518 (minus:QI (match_dup 0)
6519 (match_operand:QI 1 "general_operand" "qn,qm")))
6520 (clobber (reg:CC FLAGS_REG))]
6521 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6522 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6523 "sub{b}\t{%1, %0|%0, %1}"
6524 [(set_attr "type" "alu1")
6525 (set_attr "mode" "QI")])
6527 (define_insn "*sub<mode>_2"
6528 [(set (reg FLAGS_REG)
6531 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6532 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6534 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6535 (minus:SWI (match_dup 1) (match_dup 2)))]
6536 "ix86_match_ccmode (insn, CCGOCmode)
6537 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6538 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6539 [(set_attr "type" "alu")
6540 (set_attr "mode" "<MODE>")])
6542 (define_insn "*subsi_2_zext"
6543 [(set (reg FLAGS_REG)
6545 (minus:SI (match_operand:SI 1 "register_operand" "0")
6546 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6548 (set (match_operand:DI 0 "register_operand" "=r")
6550 (minus:SI (match_dup 1)
6552 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6553 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6554 "sub{l}\t{%2, %k0|%k0, %2}"
6555 [(set_attr "type" "alu")
6556 (set_attr "mode" "SI")])
6558 (define_insn "*sub<mode>_3"
6559 [(set (reg FLAGS_REG)
6560 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6561 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6562 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6563 (minus:SWI (match_dup 1) (match_dup 2)))]
6564 "ix86_match_ccmode (insn, CCmode)
6565 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6566 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6567 [(set_attr "type" "alu")
6568 (set_attr "mode" "<MODE>")])
6570 (define_insn "*subsi_3_zext"
6571 [(set (reg FLAGS_REG)
6572 (compare (match_operand:SI 1 "register_operand" "0")
6573 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6574 (set (match_operand:DI 0 "register_operand" "=r")
6576 (minus:SI (match_dup 1)
6578 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6579 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6580 "sub{l}\t{%2, %1|%1, %2}"
6581 [(set_attr "type" "alu")
6582 (set_attr "mode" "SI")])
6584 ;; Add with carry and subtract with borrow
6586 (define_expand "<plusminus_insn><mode>3_carry"
6588 [(set (match_operand:SWI 0 "nonimmediate_operand")
6590 (match_operand:SWI 1 "nonimmediate_operand")
6591 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6592 [(match_operand 3 "flags_reg_operand")
6594 (match_operand:SWI 2 "<general_operand>"))))
6595 (clobber (reg:CC FLAGS_REG))])]
6596 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6598 (define_insn "*<plusminus_insn><mode>3_carry"
6599 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6601 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6603 (match_operator 3 "ix86_carry_flag_operator"
6604 [(reg FLAGS_REG) (const_int 0)])
6605 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6606 (clobber (reg:CC FLAGS_REG))]
6607 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6608 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6609 [(set_attr "type" "alu")
6610 (set_attr "use_carry" "1")
6611 (set_attr "pent_pair" "pu")
6612 (set_attr "mode" "<MODE>")])
6614 (define_insn "*addsi3_carry_zext"
6615 [(set (match_operand:DI 0 "register_operand" "=r")
6617 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6618 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6619 [(reg FLAGS_REG) (const_int 0)])
6620 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6621 (clobber (reg:CC FLAGS_REG))]
6622 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6623 "adc{l}\t{%2, %k0|%k0, %2}"
6624 [(set_attr "type" "alu")
6625 (set_attr "use_carry" "1")
6626 (set_attr "pent_pair" "pu")
6627 (set_attr "mode" "SI")])
6629 (define_insn "*subsi3_carry_zext"
6630 [(set (match_operand:DI 0 "register_operand" "=r")
6632 (minus:SI (match_operand:SI 1 "register_operand" "0")
6633 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6634 [(reg FLAGS_REG) (const_int 0)])
6635 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6636 (clobber (reg:CC FLAGS_REG))]
6637 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6638 "sbb{l}\t{%2, %k0|%k0, %2}"
6639 [(set_attr "type" "alu")
6640 (set_attr "pent_pair" "pu")
6641 (set_attr "mode" "SI")])
6645 (define_insn "adcx<mode>3"
6646 [(set (reg:CCC FLAGS_REG)
6649 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6651 (match_operator 4 "ix86_carry_flag_operator"
6652 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6653 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6655 (set (match_operand:SWI48 0 "register_operand" "=r")
6656 (plus:SWI48 (match_dup 1)
6657 (plus:SWI48 (match_op_dup 4
6658 [(match_dup 3) (const_int 0)])
6660 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6661 "adcx\t{%2, %0|%0, %2}"
6662 [(set_attr "type" "alu")
6663 (set_attr "use_carry" "1")
6664 (set_attr "mode" "<MODE>")])
6666 ;; Overflow setting add and subtract instructions
6668 (define_insn "*add<mode>3_cconly_overflow"
6669 [(set (reg:CCC FLAGS_REG)
6672 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6673 (match_operand:SWI 2 "<general_operand>" "<g>"))
6675 (clobber (match_scratch:SWI 0 "=<r>"))]
6676 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6677 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6678 [(set_attr "type" "alu")
6679 (set_attr "mode" "<MODE>")])
6681 (define_insn "*sub<mode>3_cconly_overflow"
6682 [(set (reg:CCC FLAGS_REG)
6685 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6686 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6689 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6690 [(set_attr "type" "icmp")
6691 (set_attr "mode" "<MODE>")])
6693 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6694 [(set (reg:CCC FLAGS_REG)
6697 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6698 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6700 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6701 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6702 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6703 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6704 [(set_attr "type" "alu")
6705 (set_attr "mode" "<MODE>")])
6707 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6708 [(set (reg:CCC FLAGS_REG)
6711 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6712 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6714 (set (match_operand:DI 0 "register_operand" "=r")
6715 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6716 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6717 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6718 [(set_attr "type" "alu")
6719 (set_attr "mode" "SI")])
6721 ;; The patterns that match these are at the end of this file.
6723 (define_expand "<plusminus_insn>xf3"
6724 [(set (match_operand:XF 0 "register_operand")
6726 (match_operand:XF 1 "register_operand")
6727 (match_operand:XF 2 "register_operand")))]
6730 (define_expand "<plusminus_insn><mode>3"
6731 [(set (match_operand:MODEF 0 "register_operand")
6733 (match_operand:MODEF 1 "register_operand")
6734 (match_operand:MODEF 2 "nonimmediate_operand")))]
6735 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6736 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6738 ;; Multiply instructions
6740 (define_expand "mul<mode>3"
6741 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6743 (match_operand:SWIM248 1 "register_operand")
6744 (match_operand:SWIM248 2 "<general_operand>")))
6745 (clobber (reg:CC FLAGS_REG))])])
6747 (define_expand "mulqi3"
6748 [(parallel [(set (match_operand:QI 0 "register_operand")
6750 (match_operand:QI 1 "register_operand")
6751 (match_operand:QI 2 "nonimmediate_operand")))
6752 (clobber (reg:CC FLAGS_REG))])]
6753 "TARGET_QIMODE_MATH")
6756 ;; IMUL reg32/64, reg32/64, imm8 Direct
6757 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6758 ;; IMUL reg32/64, reg32/64, imm32 Direct
6759 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6760 ;; IMUL reg32/64, reg32/64 Direct
6761 ;; IMUL reg32/64, mem32/64 Direct
6763 ;; On BDVER1, all above IMULs use DirectPath
6765 (define_insn "*mul<mode>3_1"
6766 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6768 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6769 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6770 (clobber (reg:CC FLAGS_REG))]
6771 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6773 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6774 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6775 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6776 [(set_attr "type" "imul")
6777 (set_attr "prefix_0f" "0,0,1")
6778 (set (attr "athlon_decode")
6779 (cond [(eq_attr "cpu" "athlon")
6780 (const_string "vector")
6781 (eq_attr "alternative" "1")
6782 (const_string "vector")
6783 (and (eq_attr "alternative" "2")
6784 (match_operand 1 "memory_operand"))
6785 (const_string "vector")]
6786 (const_string "direct")))
6787 (set (attr "amdfam10_decode")
6788 (cond [(and (eq_attr "alternative" "0,1")
6789 (match_operand 1 "memory_operand"))
6790 (const_string "vector")]
6791 (const_string "direct")))
6792 (set_attr "bdver1_decode" "direct")
6793 (set_attr "mode" "<MODE>")])
6795 (define_insn "*mulsi3_1_zext"
6796 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6798 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6799 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6800 (clobber (reg:CC FLAGS_REG))]
6802 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6804 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6805 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6806 imul{l}\t{%2, %k0|%k0, %2}"
6807 [(set_attr "type" "imul")
6808 (set_attr "prefix_0f" "0,0,1")
6809 (set (attr "athlon_decode")
6810 (cond [(eq_attr "cpu" "athlon")
6811 (const_string "vector")
6812 (eq_attr "alternative" "1")
6813 (const_string "vector")
6814 (and (eq_attr "alternative" "2")
6815 (match_operand 1 "memory_operand"))
6816 (const_string "vector")]
6817 (const_string "direct")))
6818 (set (attr "amdfam10_decode")
6819 (cond [(and (eq_attr "alternative" "0,1")
6820 (match_operand 1 "memory_operand"))
6821 (const_string "vector")]
6822 (const_string "direct")))
6823 (set_attr "bdver1_decode" "direct")
6824 (set_attr "mode" "SI")])
6827 ;; IMUL reg16, reg16, imm8 VectorPath
6828 ;; IMUL reg16, mem16, imm8 VectorPath
6829 ;; IMUL reg16, reg16, imm16 VectorPath
6830 ;; IMUL reg16, mem16, imm16 VectorPath
6831 ;; IMUL reg16, reg16 Direct
6832 ;; IMUL reg16, mem16 Direct
6834 ;; On BDVER1, all HI MULs use DoublePath
6836 (define_insn "*mulhi3_1"
6837 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6838 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6839 (match_operand:HI 2 "general_operand" "K,n,mr")))
6840 (clobber (reg:CC FLAGS_REG))]
6842 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6844 imul{w}\t{%2, %1, %0|%0, %1, %2}
6845 imul{w}\t{%2, %1, %0|%0, %1, %2}
6846 imul{w}\t{%2, %0|%0, %2}"
6847 [(set_attr "type" "imul")
6848 (set_attr "prefix_0f" "0,0,1")
6849 (set (attr "athlon_decode")
6850 (cond [(eq_attr "cpu" "athlon")
6851 (const_string "vector")
6852 (eq_attr "alternative" "1,2")
6853 (const_string "vector")]
6854 (const_string "direct")))
6855 (set (attr "amdfam10_decode")
6856 (cond [(eq_attr "alternative" "0,1")
6857 (const_string "vector")]
6858 (const_string "direct")))
6859 (set_attr "bdver1_decode" "double")
6860 (set_attr "mode" "HI")])
6862 ;;On AMDFAM10 and BDVER1
6866 (define_insn "*mulqi3_1"
6867 [(set (match_operand:QI 0 "register_operand" "=a")
6868 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6869 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6870 (clobber (reg:CC FLAGS_REG))]
6872 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6874 [(set_attr "type" "imul")
6875 (set_attr "length_immediate" "0")
6876 (set (attr "athlon_decode")
6877 (if_then_else (eq_attr "cpu" "athlon")
6878 (const_string "vector")
6879 (const_string "direct")))
6880 (set_attr "amdfam10_decode" "direct")
6881 (set_attr "bdver1_decode" "direct")
6882 (set_attr "mode" "QI")])
6884 (define_expand "<u>mul<mode><dwi>3"
6885 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6888 (match_operand:DWIH 1 "nonimmediate_operand"))
6890 (match_operand:DWIH 2 "register_operand"))))
6891 (clobber (reg:CC FLAGS_REG))])])
6893 (define_expand "<u>mulqihi3"
6894 [(parallel [(set (match_operand:HI 0 "register_operand")
6897 (match_operand:QI 1 "nonimmediate_operand"))
6899 (match_operand:QI 2 "register_operand"))))
6900 (clobber (reg:CC FLAGS_REG))])]
6901 "TARGET_QIMODE_MATH")
6903 (define_insn "*bmi2_umulditi3_1"
6904 [(set (match_operand:DI 0 "register_operand" "=r")
6906 (match_operand:DI 2 "nonimmediate_operand" "%d")
6907 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6908 (set (match_operand:DI 1 "register_operand" "=r")
6911 (mult:TI (zero_extend:TI (match_dup 2))
6912 (zero_extend:TI (match_dup 3)))
6914 "TARGET_64BIT && TARGET_BMI2
6915 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6916 "mulx\t{%3, %0, %1|%1, %0, %3}"
6917 [(set_attr "type" "imulx")
6918 (set_attr "prefix" "vex")
6919 (set_attr "mode" "DI")])
6921 (define_insn "*bmi2_umulsidi3_1"
6922 [(set (match_operand:SI 0 "register_operand" "=r")
6924 (match_operand:SI 2 "nonimmediate_operand" "%d")
6925 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6926 (set (match_operand:SI 1 "register_operand" "=r")
6929 (mult:DI (zero_extend:DI (match_dup 2))
6930 (zero_extend:DI (match_dup 3)))
6932 "!TARGET_64BIT && TARGET_BMI2
6933 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6934 "mulx\t{%3, %0, %1|%1, %0, %3}"
6935 [(set_attr "type" "imulx")
6936 (set_attr "prefix" "vex")
6937 (set_attr "mode" "SI")])
6939 (define_insn "*umul<mode><dwi>3_1"
6940 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6943 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6945 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6946 (clobber (reg:CC FLAGS_REG))]
6947 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6950 mul{<imodesuffix>}\t%2"
6951 [(set_attr "isa" "bmi2,*")
6952 (set_attr "type" "imulx,imul")
6953 (set_attr "length_immediate" "*,0")
6954 (set (attr "athlon_decode")
6955 (cond [(eq_attr "alternative" "1")
6956 (if_then_else (eq_attr "cpu" "athlon")
6957 (const_string "vector")
6958 (const_string "double"))]
6959 (const_string "*")))
6960 (set_attr "amdfam10_decode" "*,double")
6961 (set_attr "bdver1_decode" "*,direct")
6962 (set_attr "prefix" "vex,orig")
6963 (set_attr "mode" "<MODE>")])
6965 ;; Convert mul to the mulx pattern to avoid flags dependency.
6967 [(set (match_operand:<DWI> 0 "register_operand")
6970 (match_operand:DWIH 1 "register_operand"))
6972 (match_operand:DWIH 2 "nonimmediate_operand"))))
6973 (clobber (reg:CC FLAGS_REG))]
6974 "TARGET_BMI2 && reload_completed
6975 && true_regnum (operands[1]) == DX_REG"
6976 [(parallel [(set (match_dup 3)
6977 (mult:DWIH (match_dup 1) (match_dup 2)))
6981 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6982 (zero_extend:<DWI> (match_dup 2)))
6985 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6987 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6990 (define_insn "*mul<mode><dwi>3_1"
6991 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6994 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6996 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6997 (clobber (reg:CC FLAGS_REG))]
6998 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6999 "imul{<imodesuffix>}\t%2"
7000 [(set_attr "type" "imul")
7001 (set_attr "length_immediate" "0")
7002 (set (attr "athlon_decode")
7003 (if_then_else (eq_attr "cpu" "athlon")
7004 (const_string "vector")
7005 (const_string "double")))
7006 (set_attr "amdfam10_decode" "double")
7007 (set_attr "bdver1_decode" "direct")
7008 (set_attr "mode" "<MODE>")])
7010 (define_insn "*<u>mulqihi3_1"
7011 [(set (match_operand:HI 0 "register_operand" "=a")
7014 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7016 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7017 (clobber (reg:CC FLAGS_REG))]
7019 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7020 "<sgnprefix>mul{b}\t%2"
7021 [(set_attr "type" "imul")
7022 (set_attr "length_immediate" "0")
7023 (set (attr "athlon_decode")
7024 (if_then_else (eq_attr "cpu" "athlon")
7025 (const_string "vector")
7026 (const_string "direct")))
7027 (set_attr "amdfam10_decode" "direct")
7028 (set_attr "bdver1_decode" "direct")
7029 (set_attr "mode" "QI")])
7031 (define_expand "<s>mul<mode>3_highpart"
7032 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7037 (match_operand:SWI48 1 "nonimmediate_operand"))
7039 (match_operand:SWI48 2 "register_operand")))
7041 (clobber (match_scratch:SWI48 3))
7042 (clobber (reg:CC FLAGS_REG))])]
7044 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7046 (define_insn "*<s>muldi3_highpart_1"
7047 [(set (match_operand:DI 0 "register_operand" "=d")
7052 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7054 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7056 (clobber (match_scratch:DI 3 "=1"))
7057 (clobber (reg:CC FLAGS_REG))]
7059 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7060 "<sgnprefix>mul{q}\t%2"
7061 [(set_attr "type" "imul")
7062 (set_attr "length_immediate" "0")
7063 (set (attr "athlon_decode")
7064 (if_then_else (eq_attr "cpu" "athlon")
7065 (const_string "vector")
7066 (const_string "double")))
7067 (set_attr "amdfam10_decode" "double")
7068 (set_attr "bdver1_decode" "direct")
7069 (set_attr "mode" "DI")])
7071 (define_insn "*<s>mulsi3_highpart_1"
7072 [(set (match_operand:SI 0 "register_operand" "=d")
7077 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7079 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7081 (clobber (match_scratch:SI 3 "=1"))
7082 (clobber (reg:CC FLAGS_REG))]
7083 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7084 "<sgnprefix>mul{l}\t%2"
7085 [(set_attr "type" "imul")
7086 (set_attr "length_immediate" "0")
7087 (set (attr "athlon_decode")
7088 (if_then_else (eq_attr "cpu" "athlon")
7089 (const_string "vector")
7090 (const_string "double")))
7091 (set_attr "amdfam10_decode" "double")
7092 (set_attr "bdver1_decode" "direct")
7093 (set_attr "mode" "SI")])
7095 (define_insn "*<s>mulsi3_highpart_zext"
7096 [(set (match_operand:DI 0 "register_operand" "=d")
7097 (zero_extend:DI (truncate:SI
7099 (mult:DI (any_extend:DI
7100 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7102 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7104 (clobber (match_scratch:SI 3 "=1"))
7105 (clobber (reg:CC FLAGS_REG))]
7107 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7108 "<sgnprefix>mul{l}\t%2"
7109 [(set_attr "type" "imul")
7110 (set_attr "length_immediate" "0")
7111 (set (attr "athlon_decode")
7112 (if_then_else (eq_attr "cpu" "athlon")
7113 (const_string "vector")
7114 (const_string "double")))
7115 (set_attr "amdfam10_decode" "double")
7116 (set_attr "bdver1_decode" "direct")
7117 (set_attr "mode" "SI")])
7119 ;; The patterns that match these are at the end of this file.
7121 (define_expand "mulxf3"
7122 [(set (match_operand:XF 0 "register_operand")
7123 (mult:XF (match_operand:XF 1 "register_operand")
7124 (match_operand:XF 2 "register_operand")))]
7127 (define_expand "mul<mode>3"
7128 [(set (match_operand:MODEF 0 "register_operand")
7129 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7130 (match_operand:MODEF 2 "nonimmediate_operand")))]
7131 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7132 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7134 ;; Divide instructions
7136 ;; The patterns that match these are at the end of this file.
7138 (define_expand "divxf3"
7139 [(set (match_operand:XF 0 "register_operand")
7140 (div:XF (match_operand:XF 1 "register_operand")
7141 (match_operand:XF 2 "register_operand")))]
7144 (define_expand "divdf3"
7145 [(set (match_operand:DF 0 "register_operand")
7146 (div:DF (match_operand:DF 1 "register_operand")
7147 (match_operand:DF 2 "nonimmediate_operand")))]
7148 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7149 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7151 (define_expand "divsf3"
7152 [(set (match_operand:SF 0 "register_operand")
7153 (div:SF (match_operand:SF 1 "register_operand")
7154 (match_operand:SF 2 "nonimmediate_operand")))]
7155 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7160 && optimize_insn_for_speed_p ()
7161 && flag_finite_math_only && !flag_trapping_math
7162 && flag_unsafe_math_optimizations)
7164 ix86_emit_swdivsf (operands[0], operands[1],
7165 operands[2], SFmode);
7170 ;; Divmod instructions.
7172 (define_expand "divmod<mode>4"
7173 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7175 (match_operand:SWIM248 1 "register_operand")
7176 (match_operand:SWIM248 2 "nonimmediate_operand")))
7177 (set (match_operand:SWIM248 3 "register_operand")
7178 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7179 (clobber (reg:CC FLAGS_REG))])])
7181 ;; Split with 8bit unsigned divide:
7182 ;; if (dividend an divisor are in [0-255])
7183 ;; use 8bit unsigned integer divide
7185 ;; use original integer divide
7187 [(set (match_operand:SWI48 0 "register_operand")
7188 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7189 (match_operand:SWI48 3 "nonimmediate_operand")))
7190 (set (match_operand:SWI48 1 "register_operand")
7191 (mod:SWI48 (match_dup 2) (match_dup 3)))
7192 (clobber (reg:CC FLAGS_REG))]
7193 "TARGET_USE_8BIT_IDIV
7194 && TARGET_QIMODE_MATH
7195 && can_create_pseudo_p ()
7196 && !optimize_insn_for_size_p ()"
7198 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7200 (define_insn_and_split "divmod<mode>4_1"
7201 [(set (match_operand:SWI48 0 "register_operand" "=a")
7202 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7203 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7204 (set (match_operand:SWI48 1 "register_operand" "=&d")
7205 (mod:SWI48 (match_dup 2) (match_dup 3)))
7206 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7207 (clobber (reg:CC FLAGS_REG))]
7211 [(parallel [(set (match_dup 1)
7212 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7213 (clobber (reg:CC FLAGS_REG))])
7214 (parallel [(set (match_dup 0)
7215 (div:SWI48 (match_dup 2) (match_dup 3)))
7217 (mod:SWI48 (match_dup 2) (match_dup 3)))
7219 (clobber (reg:CC FLAGS_REG))])]
7221 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7223 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7224 operands[4] = operands[2];
7227 /* Avoid use of cltd in favor of a mov+shift. */
7228 emit_move_insn (operands[1], operands[2]);
7229 operands[4] = operands[1];
7232 [(set_attr "type" "multi")
7233 (set_attr "mode" "<MODE>")])
7235 (define_insn_and_split "*divmod<mode>4"
7236 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7237 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7238 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7239 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7240 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7241 (clobber (reg:CC FLAGS_REG))]
7245 [(parallel [(set (match_dup 1)
7246 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7247 (clobber (reg:CC FLAGS_REG))])
7248 (parallel [(set (match_dup 0)
7249 (div:SWIM248 (match_dup 2) (match_dup 3)))
7251 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7253 (clobber (reg:CC FLAGS_REG))])]
7255 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7257 if (<MODE>mode != HImode
7258 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7259 operands[4] = operands[2];
7262 /* Avoid use of cltd in favor of a mov+shift. */
7263 emit_move_insn (operands[1], operands[2]);
7264 operands[4] = operands[1];
7267 [(set_attr "type" "multi")
7268 (set_attr "mode" "<MODE>")])
7270 (define_insn "*divmod<mode>4_noext"
7271 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7272 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7273 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7274 (set (match_operand:SWIM248 1 "register_operand" "=d")
7275 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7276 (use (match_operand:SWIM248 4 "register_operand" "1"))
7277 (clobber (reg:CC FLAGS_REG))]
7279 "idiv{<imodesuffix>}\t%3"
7280 [(set_attr "type" "idiv")
7281 (set_attr "mode" "<MODE>")])
7283 (define_expand "divmodqi4"
7284 [(parallel [(set (match_operand:QI 0 "register_operand")
7286 (match_operand:QI 1 "register_operand")
7287 (match_operand:QI 2 "nonimmediate_operand")))
7288 (set (match_operand:QI 3 "register_operand")
7289 (mod:QI (match_dup 1) (match_dup 2)))
7290 (clobber (reg:CC FLAGS_REG))])]
7291 "TARGET_QIMODE_MATH"
7296 tmp0 = gen_reg_rtx (HImode);
7297 tmp1 = gen_reg_rtx (HImode);
7299 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7301 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7302 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7304 /* Extract remainder from AH. */
7305 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7306 insn = emit_move_insn (operands[3], tmp1);
7308 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7309 set_unique_reg_note (insn, REG_EQUAL, mod);
7311 /* Extract quotient from AL. */
7312 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7314 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7315 set_unique_reg_note (insn, REG_EQUAL, div);
7320 ;; Divide AX by r/m8, with result stored in
7323 ;; Change div/mod to HImode and extend the second argument to HImode
7324 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7325 ;; combine may fail.
7326 (define_insn "divmodhiqi3"
7327 [(set (match_operand:HI 0 "register_operand" "=a")
7332 (mod:HI (match_operand:HI 1 "register_operand" "0")
7334 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7338 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7339 (clobber (reg:CC FLAGS_REG))]
7340 "TARGET_QIMODE_MATH"
7342 [(set_attr "type" "idiv")
7343 (set_attr "mode" "QI")])
7345 (define_expand "udivmod<mode>4"
7346 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7348 (match_operand:SWIM248 1 "register_operand")
7349 (match_operand:SWIM248 2 "nonimmediate_operand")))
7350 (set (match_operand:SWIM248 3 "register_operand")
7351 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7352 (clobber (reg:CC FLAGS_REG))])])
7354 ;; Split with 8bit unsigned divide:
7355 ;; if (dividend an divisor are in [0-255])
7356 ;; use 8bit unsigned integer divide
7358 ;; use original integer divide
7360 [(set (match_operand:SWI48 0 "register_operand")
7361 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7362 (match_operand:SWI48 3 "nonimmediate_operand")))
7363 (set (match_operand:SWI48 1 "register_operand")
7364 (umod:SWI48 (match_dup 2) (match_dup 3)))
7365 (clobber (reg:CC FLAGS_REG))]
7366 "TARGET_USE_8BIT_IDIV
7367 && TARGET_QIMODE_MATH
7368 && can_create_pseudo_p ()
7369 && !optimize_insn_for_size_p ()"
7371 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7373 (define_insn_and_split "udivmod<mode>4_1"
7374 [(set (match_operand:SWI48 0 "register_operand" "=a")
7375 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7376 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7377 (set (match_operand:SWI48 1 "register_operand" "=&d")
7378 (umod:SWI48 (match_dup 2) (match_dup 3)))
7379 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7380 (clobber (reg:CC FLAGS_REG))]
7384 [(set (match_dup 1) (const_int 0))
7385 (parallel [(set (match_dup 0)
7386 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7388 (umod:SWI48 (match_dup 2) (match_dup 3)))
7390 (clobber (reg:CC FLAGS_REG))])]
7392 [(set_attr "type" "multi")
7393 (set_attr "mode" "<MODE>")])
7395 (define_insn_and_split "*udivmod<mode>4"
7396 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7397 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7398 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7399 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7400 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7401 (clobber (reg:CC FLAGS_REG))]
7405 [(set (match_dup 1) (const_int 0))
7406 (parallel [(set (match_dup 0)
7407 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7409 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7411 (clobber (reg:CC FLAGS_REG))])]
7413 [(set_attr "type" "multi")
7414 (set_attr "mode" "<MODE>")])
7416 (define_insn "*udivmod<mode>4_noext"
7417 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7418 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7419 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7420 (set (match_operand:SWIM248 1 "register_operand" "=d")
7421 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7422 (use (match_operand:SWIM248 4 "register_operand" "1"))
7423 (clobber (reg:CC FLAGS_REG))]
7425 "div{<imodesuffix>}\t%3"
7426 [(set_attr "type" "idiv")
7427 (set_attr "mode" "<MODE>")])
7429 (define_expand "udivmodqi4"
7430 [(parallel [(set (match_operand:QI 0 "register_operand")
7432 (match_operand:QI 1 "register_operand")
7433 (match_operand:QI 2 "nonimmediate_operand")))
7434 (set (match_operand:QI 3 "register_operand")
7435 (umod:QI (match_dup 1) (match_dup 2)))
7436 (clobber (reg:CC FLAGS_REG))])]
7437 "TARGET_QIMODE_MATH"
7442 tmp0 = gen_reg_rtx (HImode);
7443 tmp1 = gen_reg_rtx (HImode);
7445 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7447 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7448 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7450 /* Extract remainder from AH. */
7451 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7452 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7453 insn = emit_move_insn (operands[3], tmp1);
7455 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7456 set_unique_reg_note (insn, REG_EQUAL, mod);
7458 /* Extract quotient from AL. */
7459 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7461 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7462 set_unique_reg_note (insn, REG_EQUAL, div);
7467 (define_insn "udivmodhiqi3"
7468 [(set (match_operand:HI 0 "register_operand" "=a")
7473 (mod:HI (match_operand:HI 1 "register_operand" "0")
7475 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7479 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7480 (clobber (reg:CC FLAGS_REG))]
7481 "TARGET_QIMODE_MATH"
7483 [(set_attr "type" "idiv")
7484 (set_attr "mode" "QI")])
7486 ;; We cannot use div/idiv for double division, because it causes
7487 ;; "division by zero" on the overflow and that's not what we expect
7488 ;; from truncate. Because true (non truncating) double division is
7489 ;; never generated, we can't create this insn anyway.
7492 ; [(set (match_operand:SI 0 "register_operand" "=a")
7494 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7496 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7497 ; (set (match_operand:SI 3 "register_operand" "=d")
7499 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7500 ; (clobber (reg:CC FLAGS_REG))]
7502 ; "div{l}\t{%2, %0|%0, %2}"
7503 ; [(set_attr "type" "idiv")])
7505 ;;- Logical AND instructions
7507 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7508 ;; Note that this excludes ah.
7510 (define_expand "testsi_ccno_1"
7511 [(set (reg:CCNO FLAGS_REG)
7513 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7514 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7517 (define_expand "testqi_ccz_1"
7518 [(set (reg:CCZ FLAGS_REG)
7519 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7520 (match_operand:QI 1 "nonmemory_operand"))
7523 (define_expand "testdi_ccno_1"
7524 [(set (reg:CCNO FLAGS_REG)
7526 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7527 (match_operand:DI 1 "x86_64_szext_general_operand"))
7529 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7531 (define_insn "*testdi_1"
7532 [(set (reg FLAGS_REG)
7535 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7536 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7538 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7539 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7541 test{l}\t{%k1, %k0|%k0, %k1}
7542 test{l}\t{%k1, %k0|%k0, %k1}
7543 test{q}\t{%1, %0|%0, %1}
7544 test{q}\t{%1, %0|%0, %1}
7545 test{q}\t{%1, %0|%0, %1}"
7546 [(set_attr "type" "test")
7547 (set_attr "modrm" "0,1,0,1,1")
7548 (set_attr "mode" "SI,SI,DI,DI,DI")])
7550 (define_insn "*testqi_1_maybe_si"
7551 [(set (reg FLAGS_REG)
7554 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7555 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7557 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7558 && ix86_match_ccmode (insn,
7559 CONST_INT_P (operands[1])
7560 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7562 if (which_alternative == 3)
7564 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7565 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7566 return "test{l}\t{%1, %k0|%k0, %1}";
7568 return "test{b}\t{%1, %0|%0, %1}";
7570 [(set_attr "type" "test")
7571 (set_attr "modrm" "0,1,1,1")
7572 (set_attr "mode" "QI,QI,QI,SI")
7573 (set_attr "pent_pair" "uv,np,uv,np")])
7575 (define_insn "*test<mode>_1"
7576 [(set (reg FLAGS_REG)
7579 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7580 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7582 "ix86_match_ccmode (insn, CCNOmode)
7583 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7584 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7585 [(set_attr "type" "test")
7586 (set_attr "modrm" "0,1,1")
7587 (set_attr "mode" "<MODE>")
7588 (set_attr "pent_pair" "uv,np,uv")])
7590 (define_expand "testqi_ext_ccno_0"
7591 [(set (reg:CCNO FLAGS_REG)
7595 (match_operand 0 "ext_register_operand")
7598 (match_operand 1 "const_int_operand"))
7601 (define_insn "*testqi_ext_0"
7602 [(set (reg FLAGS_REG)
7606 (match_operand 0 "ext_register_operand" "Q")
7609 (match_operand 1 "const_int_operand" "n"))
7611 "ix86_match_ccmode (insn, CCNOmode)"
7612 "test{b}\t{%1, %h0|%h0, %1}"
7613 [(set_attr "type" "test")
7614 (set_attr "mode" "QI")
7615 (set_attr "length_immediate" "1")
7616 (set_attr "modrm" "1")
7617 (set_attr "pent_pair" "np")])
7619 (define_insn "*testqi_ext_1_rex64"
7620 [(set (reg FLAGS_REG)
7624 (match_operand 0 "ext_register_operand" "Q")
7628 (match_operand:QI 1 "register_operand" "Q")))
7630 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7631 "test{b}\t{%1, %h0|%h0, %1}"
7632 [(set_attr "type" "test")
7633 (set_attr "mode" "QI")])
7635 (define_insn "*testqi_ext_1"
7636 [(set (reg FLAGS_REG)
7640 (match_operand 0 "ext_register_operand" "Q")
7644 (match_operand:QI 1 "general_operand" "Qm")))
7646 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7647 "test{b}\t{%1, %h0|%h0, %1}"
7648 [(set_attr "type" "test")
7649 (set_attr "mode" "QI")])
7651 (define_insn "*testqi_ext_2"
7652 [(set (reg FLAGS_REG)
7656 (match_operand 0 "ext_register_operand" "Q")
7660 (match_operand 1 "ext_register_operand" "Q")
7664 "ix86_match_ccmode (insn, CCNOmode)"
7665 "test{b}\t{%h1, %h0|%h0, %h1}"
7666 [(set_attr "type" "test")
7667 (set_attr "mode" "QI")])
7669 (define_insn "*testqi_ext_3_rex64"
7670 [(set (reg FLAGS_REG)
7671 (compare (zero_extract:DI
7672 (match_operand 0 "nonimmediate_operand" "rm")
7673 (match_operand:DI 1 "const_int_operand")
7674 (match_operand:DI 2 "const_int_operand"))
7677 && ix86_match_ccmode (insn, CCNOmode)
7678 && INTVAL (operands[1]) > 0
7679 && INTVAL (operands[2]) >= 0
7680 /* Ensure that resulting mask is zero or sign extended operand. */
7681 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7682 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7683 && INTVAL (operands[1]) > 32))
7684 && (GET_MODE (operands[0]) == SImode
7685 || GET_MODE (operands[0]) == DImode
7686 || GET_MODE (operands[0]) == HImode
7687 || GET_MODE (operands[0]) == QImode)"
7690 ;; Combine likes to form bit extractions for some tests. Humor it.
7691 (define_insn "*testqi_ext_3"
7692 [(set (reg FLAGS_REG)
7693 (compare (zero_extract:SI
7694 (match_operand 0 "nonimmediate_operand" "rm")
7695 (match_operand:SI 1 "const_int_operand")
7696 (match_operand:SI 2 "const_int_operand"))
7698 "ix86_match_ccmode (insn, CCNOmode)
7699 && INTVAL (operands[1]) > 0
7700 && INTVAL (operands[2]) >= 0
7701 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7702 && (GET_MODE (operands[0]) == SImode
7703 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7704 || GET_MODE (operands[0]) == HImode
7705 || GET_MODE (operands[0]) == QImode)"
7709 [(set (match_operand 0 "flags_reg_operand")
7710 (match_operator 1 "compare_operator"
7712 (match_operand 2 "nonimmediate_operand")
7713 (match_operand 3 "const_int_operand")
7714 (match_operand 4 "const_int_operand"))
7716 "ix86_match_ccmode (insn, CCNOmode)"
7717 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7719 rtx val = operands[2];
7720 HOST_WIDE_INT len = INTVAL (operands[3]);
7721 HOST_WIDE_INT pos = INTVAL (operands[4]);
7723 enum machine_mode mode, submode;
7725 mode = GET_MODE (val);
7728 /* ??? Combine likes to put non-volatile mem extractions in QImode
7729 no matter the size of the test. So find a mode that works. */
7730 if (! MEM_VOLATILE_P (val))
7732 mode = smallest_mode_for_size (pos + len, MODE_INT);
7733 val = adjust_address (val, mode, 0);
7736 else if (GET_CODE (val) == SUBREG
7737 && (submode = GET_MODE (SUBREG_REG (val)),
7738 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7739 && pos + len <= GET_MODE_BITSIZE (submode)
7740 && GET_MODE_CLASS (submode) == MODE_INT)
7742 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7744 val = SUBREG_REG (val);
7746 else if (mode == HImode && pos + len <= 8)
7748 /* Small HImode tests can be converted to QImode. */
7750 val = gen_lowpart (QImode, val);
7753 if (len == HOST_BITS_PER_WIDE_INT)
7756 mask = ((HOST_WIDE_INT)1 << len) - 1;
7759 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7762 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7763 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7764 ;; this is relatively important trick.
7765 ;; Do the conversion only post-reload to avoid limiting of the register class
7768 [(set (match_operand 0 "flags_reg_operand")
7769 (match_operator 1 "compare_operator"
7770 [(and (match_operand 2 "register_operand")
7771 (match_operand 3 "const_int_operand"))
7774 && QI_REG_P (operands[2])
7775 && GET_MODE (operands[2]) != QImode
7776 && ((ix86_match_ccmode (insn, CCZmode)
7777 && !(INTVAL (operands[3]) & ~(255 << 8)))
7778 || (ix86_match_ccmode (insn, CCNOmode)
7779 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7782 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7786 operands[2] = gen_lowpart (SImode, operands[2]);
7787 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7791 [(set (match_operand 0 "flags_reg_operand")
7792 (match_operator 1 "compare_operator"
7793 [(and (match_operand 2 "nonimmediate_operand")
7794 (match_operand 3 "const_int_operand"))
7797 && GET_MODE (operands[2]) != QImode
7798 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7799 && ((ix86_match_ccmode (insn, CCZmode)
7800 && !(INTVAL (operands[3]) & ~255))
7801 || (ix86_match_ccmode (insn, CCNOmode)
7802 && !(INTVAL (operands[3]) & ~127)))"
7804 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7807 operands[2] = gen_lowpart (QImode, operands[2]);
7808 operands[3] = gen_lowpart (QImode, operands[3]);
7811 ;; %%% This used to optimize known byte-wide and operations to memory,
7812 ;; and sometimes to QImode registers. If this is considered useful,
7813 ;; it should be done with splitters.
7815 (define_expand "and<mode>3"
7816 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7817 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7818 (match_operand:SWIM 2 "<general_szext_operand>")))]
7821 enum machine_mode mode = <MODE>mode;
7822 rtx (*insn) (rtx, rtx);
7824 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7826 HOST_WIDE_INT ival = INTVAL (operands[2]);
7828 if (ival == (HOST_WIDE_INT) 0xffffffff)
7830 else if (ival == 0xffff)
7832 else if (ival == 0xff)
7836 if (mode == <MODE>mode)
7838 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7842 if (<MODE>mode == DImode)
7843 insn = (mode == SImode)
7844 ? gen_zero_extendsidi2
7846 ? gen_zero_extendhidi2
7847 : gen_zero_extendqidi2;
7848 else if (<MODE>mode == SImode)
7849 insn = (mode == HImode)
7850 ? gen_zero_extendhisi2
7851 : gen_zero_extendqisi2;
7852 else if (<MODE>mode == HImode)
7853 insn = gen_zero_extendqihi2;
7857 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7861 (define_insn "*anddi_1"
7862 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7864 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7865 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7866 (clobber (reg:CC FLAGS_REG))]
7867 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7869 switch (get_attr_type (insn))
7875 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7876 if (get_attr_mode (insn) == MODE_SI)
7877 return "and{l}\t{%k2, %k0|%k0, %k2}";
7879 return "and{q}\t{%2, %0|%0, %2}";
7882 [(set_attr "type" "alu,alu,alu,imovx")
7883 (set_attr "length_immediate" "*,*,*,0")
7884 (set (attr "prefix_rex")
7886 (and (eq_attr "type" "imovx")
7887 (and (match_test "INTVAL (operands[2]) == 0xff")
7888 (match_operand 1 "ext_QIreg_operand")))
7890 (const_string "*")))
7891 (set_attr "mode" "SI,DI,DI,SI")])
7893 (define_insn "*andsi_1"
7894 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7895 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7896 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7897 (clobber (reg:CC FLAGS_REG))]
7898 "ix86_binary_operator_ok (AND, SImode, operands)"
7900 switch (get_attr_type (insn))
7906 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7907 return "and{l}\t{%2, %0|%0, %2}";
7910 [(set_attr "type" "alu,alu,imovx")
7911 (set (attr "prefix_rex")
7913 (and (eq_attr "type" "imovx")
7914 (and (match_test "INTVAL (operands[2]) == 0xff")
7915 (match_operand 1 "ext_QIreg_operand")))
7917 (const_string "*")))
7918 (set_attr "length_immediate" "*,*,0")
7919 (set_attr "mode" "SI")])
7921 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7922 (define_insn "*andsi_1_zext"
7923 [(set (match_operand:DI 0 "register_operand" "=r")
7925 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7926 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7927 (clobber (reg:CC FLAGS_REG))]
7928 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7929 "and{l}\t{%2, %k0|%k0, %2}"
7930 [(set_attr "type" "alu")
7931 (set_attr "mode" "SI")])
7933 (define_insn "*andhi_1"
7934 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7935 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7936 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7937 (clobber (reg:CC FLAGS_REG))]
7938 "ix86_binary_operator_ok (AND, HImode, operands)"
7940 switch (get_attr_type (insn))
7946 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7947 return "and{w}\t{%2, %0|%0, %2}";
7950 [(set_attr "type" "alu,alu,imovx")
7951 (set_attr "length_immediate" "*,*,0")
7952 (set (attr "prefix_rex")
7954 (and (eq_attr "type" "imovx")
7955 (match_operand 1 "ext_QIreg_operand"))
7957 (const_string "*")))
7958 (set_attr "mode" "HI,HI,SI")])
7960 ;; %%% Potential partial reg stall on alternative 2. What to do?
7961 (define_insn "*andqi_1"
7962 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7963 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7964 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7965 (clobber (reg:CC FLAGS_REG))]
7966 "ix86_binary_operator_ok (AND, QImode, operands)"
7968 and{b}\t{%2, %0|%0, %2}
7969 and{b}\t{%2, %0|%0, %2}
7970 and{l}\t{%k2, %k0|%k0, %k2}"
7971 [(set_attr "type" "alu")
7972 (set_attr "mode" "QI,QI,SI")])
7974 (define_insn "*andqi_1_slp"
7975 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7976 (and:QI (match_dup 0)
7977 (match_operand:QI 1 "general_operand" "qn,qmn")))
7978 (clobber (reg:CC FLAGS_REG))]
7979 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7980 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7981 "and{b}\t{%1, %0|%0, %1}"
7982 [(set_attr "type" "alu1")
7983 (set_attr "mode" "QI")])
7985 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7987 [(set (match_operand:DI 0 "register_operand")
7988 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7989 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7990 (clobber (reg:CC FLAGS_REG))]
7992 [(parallel [(set (match_dup 0)
7993 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7994 (clobber (reg:CC FLAGS_REG))])]
7995 "operands[2] = gen_lowpart (SImode, operands[2]);")
7998 [(set (match_operand:SWI248 0 "register_operand")
7999 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8000 (match_operand:SWI248 2 "const_int_operand")))
8001 (clobber (reg:CC FLAGS_REG))]
8003 && true_regnum (operands[0]) != true_regnum (operands[1])"
8006 HOST_WIDE_INT ival = INTVAL (operands[2]);
8007 enum machine_mode mode;
8008 rtx (*insn) (rtx, rtx);
8010 if (ival == (HOST_WIDE_INT) 0xffffffff)
8012 else if (ival == 0xffff)
8016 gcc_assert (ival == 0xff);
8020 if (<MODE>mode == DImode)
8021 insn = (mode == SImode)
8022 ? gen_zero_extendsidi2
8024 ? gen_zero_extendhidi2
8025 : gen_zero_extendqidi2;
8028 if (<MODE>mode != SImode)
8029 /* Zero extend to SImode to avoid partial register stalls. */
8030 operands[0] = gen_lowpart (SImode, operands[0]);
8032 insn = (mode == HImode)
8033 ? gen_zero_extendhisi2
8034 : gen_zero_extendqisi2;
8036 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8041 [(set (match_operand 0 "register_operand")
8043 (const_int -65536)))
8044 (clobber (reg:CC FLAGS_REG))]
8045 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8046 || optimize_function_for_size_p (cfun)"
8047 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8048 "operands[1] = gen_lowpart (HImode, operands[0]);")
8051 [(set (match_operand 0 "ext_register_operand")
8054 (clobber (reg:CC FLAGS_REG))]
8055 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8056 && reload_completed"
8057 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8058 "operands[1] = gen_lowpart (QImode, operands[0]);")
8061 [(set (match_operand 0 "ext_register_operand")
8063 (const_int -65281)))
8064 (clobber (reg:CC FLAGS_REG))]
8065 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8066 && reload_completed"
8067 [(parallel [(set (zero_extract:SI (match_dup 0)
8071 (zero_extract:SI (match_dup 0)
8074 (zero_extract:SI (match_dup 0)
8077 (clobber (reg:CC FLAGS_REG))])]
8078 "operands[0] = gen_lowpart (SImode, operands[0]);")
8080 (define_insn "*anddi_2"
8081 [(set (reg FLAGS_REG)
8084 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8085 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8087 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8088 (and:DI (match_dup 1) (match_dup 2)))]
8089 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8090 && ix86_binary_operator_ok (AND, DImode, operands)"
8092 and{l}\t{%k2, %k0|%k0, %k2}
8093 and{q}\t{%2, %0|%0, %2}
8094 and{q}\t{%2, %0|%0, %2}"
8095 [(set_attr "type" "alu")
8096 (set_attr "mode" "SI,DI,DI")])
8098 (define_insn "*andqi_2_maybe_si"
8099 [(set (reg FLAGS_REG)
8101 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8102 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8104 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8105 (and:QI (match_dup 1) (match_dup 2)))]
8106 "ix86_binary_operator_ok (AND, QImode, operands)
8107 && ix86_match_ccmode (insn,
8108 CONST_INT_P (operands[2])
8109 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8111 if (which_alternative == 2)
8113 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8114 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8115 return "and{l}\t{%2, %k0|%k0, %2}";
8117 return "and{b}\t{%2, %0|%0, %2}";
8119 [(set_attr "type" "alu")
8120 (set_attr "mode" "QI,QI,SI")])
8122 (define_insn "*and<mode>_2"
8123 [(set (reg FLAGS_REG)
8124 (compare (and:SWI124
8125 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8126 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8128 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8129 (and:SWI124 (match_dup 1) (match_dup 2)))]
8130 "ix86_match_ccmode (insn, CCNOmode)
8131 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8132 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8133 [(set_attr "type" "alu")
8134 (set_attr "mode" "<MODE>")])
8136 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8137 (define_insn "*andsi_2_zext"
8138 [(set (reg FLAGS_REG)
8140 (match_operand:SI 1 "nonimmediate_operand" "%0")
8141 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8143 (set (match_operand:DI 0 "register_operand" "=r")
8144 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8145 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8146 && ix86_binary_operator_ok (AND, SImode, operands)"
8147 "and{l}\t{%2, %k0|%k0, %2}"
8148 [(set_attr "type" "alu")
8149 (set_attr "mode" "SI")])
8151 (define_insn "*andqi_2_slp"
8152 [(set (reg FLAGS_REG)
8154 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8155 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8157 (set (strict_low_part (match_dup 0))
8158 (and:QI (match_dup 0) (match_dup 1)))]
8159 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8160 && ix86_match_ccmode (insn, CCNOmode)
8161 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8162 "and{b}\t{%1, %0|%0, %1}"
8163 [(set_attr "type" "alu1")
8164 (set_attr "mode" "QI")])
8166 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8167 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8168 ;; for a QImode operand, which of course failed.
8169 (define_insn "andqi_ext_0"
8170 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8175 (match_operand 1 "ext_register_operand" "0")
8178 (match_operand 2 "const_int_operand" "n")))
8179 (clobber (reg:CC FLAGS_REG))]
8181 "and{b}\t{%2, %h0|%h0, %2}"
8182 [(set_attr "type" "alu")
8183 (set_attr "length_immediate" "1")
8184 (set_attr "modrm" "1")
8185 (set_attr "mode" "QI")])
8187 ;; Generated by peephole translating test to and. This shows up
8188 ;; often in fp comparisons.
8189 (define_insn "*andqi_ext_0_cc"
8190 [(set (reg FLAGS_REG)
8194 (match_operand 1 "ext_register_operand" "0")
8197 (match_operand 2 "const_int_operand" "n"))
8199 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8208 "ix86_match_ccmode (insn, CCNOmode)"
8209 "and{b}\t{%2, %h0|%h0, %2}"
8210 [(set_attr "type" "alu")
8211 (set_attr "length_immediate" "1")
8212 (set_attr "modrm" "1")
8213 (set_attr "mode" "QI")])
8215 (define_insn "*andqi_ext_1_rex64"
8216 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8221 (match_operand 1 "ext_register_operand" "0")
8225 (match_operand 2 "ext_register_operand" "Q"))))
8226 (clobber (reg:CC FLAGS_REG))]
8228 "and{b}\t{%2, %h0|%h0, %2}"
8229 [(set_attr "type" "alu")
8230 (set_attr "length_immediate" "0")
8231 (set_attr "mode" "QI")])
8233 (define_insn "*andqi_ext_1"
8234 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8239 (match_operand 1 "ext_register_operand" "0")
8243 (match_operand:QI 2 "general_operand" "Qm"))))
8244 (clobber (reg:CC FLAGS_REG))]
8246 "and{b}\t{%2, %h0|%h0, %2}"
8247 [(set_attr "type" "alu")
8248 (set_attr "length_immediate" "0")
8249 (set_attr "mode" "QI")])
8251 (define_insn "*andqi_ext_2"
8252 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8257 (match_operand 1 "ext_register_operand" "%0")
8261 (match_operand 2 "ext_register_operand" "Q")
8264 (clobber (reg:CC FLAGS_REG))]
8266 "and{b}\t{%h2, %h0|%h0, %h2}"
8267 [(set_attr "type" "alu")
8268 (set_attr "length_immediate" "0")
8269 (set_attr "mode" "QI")])
8271 ;; Convert wide AND instructions with immediate operand to shorter QImode
8272 ;; equivalents when possible.
8273 ;; Don't do the splitting with memory operands, since it introduces risk
8274 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8275 ;; for size, but that can (should?) be handled by generic code instead.
8277 [(set (match_operand 0 "register_operand")
8278 (and (match_operand 1 "register_operand")
8279 (match_operand 2 "const_int_operand")))
8280 (clobber (reg:CC FLAGS_REG))]
8282 && QI_REG_P (operands[0])
8283 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8284 && !(~INTVAL (operands[2]) & ~(255 << 8))
8285 && GET_MODE (operands[0]) != QImode"
8286 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8287 (and:SI (zero_extract:SI (match_dup 1)
8288 (const_int 8) (const_int 8))
8290 (clobber (reg:CC FLAGS_REG))])]
8292 operands[0] = gen_lowpart (SImode, operands[0]);
8293 operands[1] = gen_lowpart (SImode, operands[1]);
8294 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8297 ;; Since AND can be encoded with sign extended immediate, this is only
8298 ;; profitable when 7th bit is not set.
8300 [(set (match_operand 0 "register_operand")
8301 (and (match_operand 1 "general_operand")
8302 (match_operand 2 "const_int_operand")))
8303 (clobber (reg:CC FLAGS_REG))]
8305 && ANY_QI_REG_P (operands[0])
8306 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8307 && !(~INTVAL (operands[2]) & ~255)
8308 && !(INTVAL (operands[2]) & 128)
8309 && GET_MODE (operands[0]) != QImode"
8310 [(parallel [(set (strict_low_part (match_dup 0))
8311 (and:QI (match_dup 1)
8313 (clobber (reg:CC FLAGS_REG))])]
8315 operands[0] = gen_lowpart (QImode, operands[0]);
8316 operands[1] = gen_lowpart (QImode, operands[1]);
8317 operands[2] = gen_lowpart (QImode, operands[2]);
8320 ;; Logical inclusive and exclusive OR instructions
8322 ;; %%% This used to optimize known byte-wide and operations to memory.
8323 ;; If this is considered useful, it should be done with splitters.
8325 (define_expand "<code><mode>3"
8326 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8327 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8328 (match_operand:SWIM 2 "<general_operand>")))]
8330 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8332 (define_insn "*<code><mode>_1"
8333 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8335 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8336 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8337 (clobber (reg:CC FLAGS_REG))]
8338 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8339 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8340 [(set_attr "type" "alu")
8341 (set_attr "mode" "<MODE>")])
8343 ;; %%% Potential partial reg stall on alternative 2. What to do?
8344 (define_insn "*<code>qi_1"
8345 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8346 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8347 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8348 (clobber (reg:CC FLAGS_REG))]
8349 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8351 <logic>{b}\t{%2, %0|%0, %2}
8352 <logic>{b}\t{%2, %0|%0, %2}
8353 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8354 [(set_attr "type" "alu")
8355 (set_attr "mode" "QI,QI,SI")])
8357 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8358 (define_insn "*<code>si_1_zext"
8359 [(set (match_operand:DI 0 "register_operand" "=r")
8361 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8362 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8363 (clobber (reg:CC FLAGS_REG))]
8364 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8365 "<logic>{l}\t{%2, %k0|%k0, %2}"
8366 [(set_attr "type" "alu")
8367 (set_attr "mode" "SI")])
8369 (define_insn "*<code>si_1_zext_imm"
8370 [(set (match_operand:DI 0 "register_operand" "=r")
8372 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8373 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8374 (clobber (reg:CC FLAGS_REG))]
8375 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8376 "<logic>{l}\t{%2, %k0|%k0, %2}"
8377 [(set_attr "type" "alu")
8378 (set_attr "mode" "SI")])
8380 (define_insn "*<code>qi_1_slp"
8381 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8382 (any_or:QI (match_dup 0)
8383 (match_operand:QI 1 "general_operand" "qmn,qn")))
8384 (clobber (reg:CC FLAGS_REG))]
8385 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8386 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8387 "<logic>{b}\t{%1, %0|%0, %1}"
8388 [(set_attr "type" "alu1")
8389 (set_attr "mode" "QI")])
8391 (define_insn "*<code><mode>_2"
8392 [(set (reg FLAGS_REG)
8393 (compare (any_or:SWI
8394 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8395 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8397 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8398 (any_or:SWI (match_dup 1) (match_dup 2)))]
8399 "ix86_match_ccmode (insn, CCNOmode)
8400 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8401 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8402 [(set_attr "type" "alu")
8403 (set_attr "mode" "<MODE>")])
8405 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8406 ;; ??? Special case for immediate operand is missing - it is tricky.
8407 (define_insn "*<code>si_2_zext"
8408 [(set (reg FLAGS_REG)
8409 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8410 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8412 (set (match_operand:DI 0 "register_operand" "=r")
8413 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8414 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8415 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8416 "<logic>{l}\t{%2, %k0|%k0, %2}"
8417 [(set_attr "type" "alu")
8418 (set_attr "mode" "SI")])
8420 (define_insn "*<code>si_2_zext_imm"
8421 [(set (reg FLAGS_REG)
8423 (match_operand:SI 1 "nonimmediate_operand" "%0")
8424 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8426 (set (match_operand:DI 0 "register_operand" "=r")
8427 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8428 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8429 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8430 "<logic>{l}\t{%2, %k0|%k0, %2}"
8431 [(set_attr "type" "alu")
8432 (set_attr "mode" "SI")])
8434 (define_insn "*<code>qi_2_slp"
8435 [(set (reg FLAGS_REG)
8436 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8437 (match_operand:QI 1 "general_operand" "qmn,qn"))
8439 (set (strict_low_part (match_dup 0))
8440 (any_or:QI (match_dup 0) (match_dup 1)))]
8441 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8442 && ix86_match_ccmode (insn, CCNOmode)
8443 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8444 "<logic>{b}\t{%1, %0|%0, %1}"
8445 [(set_attr "type" "alu1")
8446 (set_attr "mode" "QI")])
8448 (define_insn "*<code><mode>_3"
8449 [(set (reg FLAGS_REG)
8450 (compare (any_or:SWI
8451 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8452 (match_operand:SWI 2 "<general_operand>" "<g>"))
8454 (clobber (match_scratch:SWI 0 "=<r>"))]
8455 "ix86_match_ccmode (insn, CCNOmode)
8456 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8457 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8458 [(set_attr "type" "alu")
8459 (set_attr "mode" "<MODE>")])
8461 (define_insn "*<code>qi_ext_0"
8462 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8467 (match_operand 1 "ext_register_operand" "0")
8470 (match_operand 2 "const_int_operand" "n")))
8471 (clobber (reg:CC FLAGS_REG))]
8472 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8473 "<logic>{b}\t{%2, %h0|%h0, %2}"
8474 [(set_attr "type" "alu")
8475 (set_attr "length_immediate" "1")
8476 (set_attr "modrm" "1")
8477 (set_attr "mode" "QI")])
8479 (define_insn "*<code>qi_ext_1_rex64"
8480 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8485 (match_operand 1 "ext_register_operand" "0")
8489 (match_operand 2 "ext_register_operand" "Q"))))
8490 (clobber (reg:CC FLAGS_REG))]
8492 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8493 "<logic>{b}\t{%2, %h0|%h0, %2}"
8494 [(set_attr "type" "alu")
8495 (set_attr "length_immediate" "0")
8496 (set_attr "mode" "QI")])
8498 (define_insn "*<code>qi_ext_1"
8499 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8504 (match_operand 1 "ext_register_operand" "0")
8508 (match_operand:QI 2 "general_operand" "Qm"))))
8509 (clobber (reg:CC FLAGS_REG))]
8511 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8512 "<logic>{b}\t{%2, %h0|%h0, %2}"
8513 [(set_attr "type" "alu")
8514 (set_attr "length_immediate" "0")
8515 (set_attr "mode" "QI")])
8517 (define_insn "*<code>qi_ext_2"
8518 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8522 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8525 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8528 (clobber (reg:CC FLAGS_REG))]
8529 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8530 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8531 [(set_attr "type" "alu")
8532 (set_attr "length_immediate" "0")
8533 (set_attr "mode" "QI")])
8536 [(set (match_operand 0 "register_operand")
8537 (any_or (match_operand 1 "register_operand")
8538 (match_operand 2 "const_int_operand")))
8539 (clobber (reg:CC FLAGS_REG))]
8541 && QI_REG_P (operands[0])
8542 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8543 && !(INTVAL (operands[2]) & ~(255 << 8))
8544 && GET_MODE (operands[0]) != QImode"
8545 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8546 (any_or:SI (zero_extract:SI (match_dup 1)
8547 (const_int 8) (const_int 8))
8549 (clobber (reg:CC FLAGS_REG))])]
8551 operands[0] = gen_lowpart (SImode, operands[0]);
8552 operands[1] = gen_lowpart (SImode, operands[1]);
8553 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8556 ;; Since OR can be encoded with sign extended immediate, this is only
8557 ;; profitable when 7th bit is set.
8559 [(set (match_operand 0 "register_operand")
8560 (any_or (match_operand 1 "general_operand")
8561 (match_operand 2 "const_int_operand")))
8562 (clobber (reg:CC FLAGS_REG))]
8564 && ANY_QI_REG_P (operands[0])
8565 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8566 && !(INTVAL (operands[2]) & ~255)
8567 && (INTVAL (operands[2]) & 128)
8568 && GET_MODE (operands[0]) != QImode"
8569 [(parallel [(set (strict_low_part (match_dup 0))
8570 (any_or:QI (match_dup 1)
8572 (clobber (reg:CC FLAGS_REG))])]
8574 operands[0] = gen_lowpart (QImode, operands[0]);
8575 operands[1] = gen_lowpart (QImode, operands[1]);
8576 operands[2] = gen_lowpart (QImode, operands[2]);
8579 (define_expand "xorqi_cc_ext_1"
8581 (set (reg:CCNO FLAGS_REG)
8585 (match_operand 1 "ext_register_operand")
8588 (match_operand:QI 2 "general_operand"))
8590 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8600 (define_insn "*xorqi_cc_ext_1_rex64"
8601 [(set (reg FLAGS_REG)
8605 (match_operand 1 "ext_register_operand" "0")
8608 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8610 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8619 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8620 "xor{b}\t{%2, %h0|%h0, %2}"
8621 [(set_attr "type" "alu")
8622 (set_attr "modrm" "1")
8623 (set_attr "mode" "QI")])
8625 (define_insn "*xorqi_cc_ext_1"
8626 [(set (reg FLAGS_REG)
8630 (match_operand 1 "ext_register_operand" "0")
8633 (match_operand:QI 2 "general_operand" "qmn"))
8635 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8644 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8645 "xor{b}\t{%2, %h0|%h0, %2}"
8646 [(set_attr "type" "alu")
8647 (set_attr "modrm" "1")
8648 (set_attr "mode" "QI")])
8650 ;; Negation instructions
8652 (define_expand "neg<mode>2"
8653 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8654 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8656 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8658 (define_insn_and_split "*neg<dwi>2_doubleword"
8659 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8660 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8661 (clobber (reg:CC FLAGS_REG))]
8662 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8666 [(set (reg:CCZ FLAGS_REG)
8667 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8668 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8671 (plus:DWIH (match_dup 3)
8672 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8674 (clobber (reg:CC FLAGS_REG))])
8677 (neg:DWIH (match_dup 2)))
8678 (clobber (reg:CC FLAGS_REG))])]
8679 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8681 (define_insn "*neg<mode>2_1"
8682 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8683 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8684 (clobber (reg:CC FLAGS_REG))]
8685 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8686 "neg{<imodesuffix>}\t%0"
8687 [(set_attr "type" "negnot")
8688 (set_attr "mode" "<MODE>")])
8690 ;; Combine is quite creative about this pattern.
8691 (define_insn "*negsi2_1_zext"
8692 [(set (match_operand:DI 0 "register_operand" "=r")
8694 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8697 (clobber (reg:CC FLAGS_REG))]
8698 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8700 [(set_attr "type" "negnot")
8701 (set_attr "mode" "SI")])
8703 ;; The problem with neg is that it does not perform (compare x 0),
8704 ;; it really performs (compare 0 x), which leaves us with the zero
8705 ;; flag being the only useful item.
8707 (define_insn "*neg<mode>2_cmpz"
8708 [(set (reg:CCZ FLAGS_REG)
8710 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8712 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8713 (neg:SWI (match_dup 1)))]
8714 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8715 "neg{<imodesuffix>}\t%0"
8716 [(set_attr "type" "negnot")
8717 (set_attr "mode" "<MODE>")])
8719 (define_insn "*negsi2_cmpz_zext"
8720 [(set (reg:CCZ FLAGS_REG)
8724 (match_operand:DI 1 "register_operand" "0")
8728 (set (match_operand:DI 0 "register_operand" "=r")
8729 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8732 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8734 [(set_attr "type" "negnot")
8735 (set_attr "mode" "SI")])
8737 ;; Changing of sign for FP values is doable using integer unit too.
8739 (define_expand "<code><mode>2"
8740 [(set (match_operand:X87MODEF 0 "register_operand")
8741 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8742 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8743 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8745 (define_insn "*absneg<mode>2_mixed"
8746 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8747 (match_operator:MODEF 3 "absneg_operator"
8748 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8749 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8750 (clobber (reg:CC FLAGS_REG))]
8751 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8754 (define_insn "*absneg<mode>2_sse"
8755 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8756 (match_operator:MODEF 3 "absneg_operator"
8757 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8758 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8759 (clobber (reg:CC FLAGS_REG))]
8760 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8763 (define_insn "*absneg<mode>2_i387"
8764 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8765 (match_operator:X87MODEF 3 "absneg_operator"
8766 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8767 (use (match_operand 2))
8768 (clobber (reg:CC FLAGS_REG))]
8769 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8772 (define_expand "<code>tf2"
8773 [(set (match_operand:TF 0 "register_operand")
8774 (absneg:TF (match_operand:TF 1 "register_operand")))]
8776 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8778 (define_insn "*absnegtf2_sse"
8779 [(set (match_operand:TF 0 "register_operand" "=x,x")
8780 (match_operator:TF 3 "absneg_operator"
8781 [(match_operand:TF 1 "register_operand" "0,x")]))
8782 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8783 (clobber (reg:CC FLAGS_REG))]
8787 ;; Splitters for fp abs and neg.
8790 [(set (match_operand 0 "fp_register_operand")
8791 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8792 (use (match_operand 2))
8793 (clobber (reg:CC FLAGS_REG))]
8795 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8798 [(set (match_operand 0 "register_operand")
8799 (match_operator 3 "absneg_operator"
8800 [(match_operand 1 "register_operand")]))
8801 (use (match_operand 2 "nonimmediate_operand"))
8802 (clobber (reg:CC FLAGS_REG))]
8803 "reload_completed && SSE_REG_P (operands[0])"
8804 [(set (match_dup 0) (match_dup 3))]
8806 enum machine_mode mode = GET_MODE (operands[0]);
8807 enum machine_mode vmode = GET_MODE (operands[2]);
8810 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8811 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8812 if (operands_match_p (operands[0], operands[2]))
8815 operands[1] = operands[2];
8818 if (GET_CODE (operands[3]) == ABS)
8819 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8821 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8826 [(set (match_operand:SF 0 "register_operand")
8827 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8828 (use (match_operand:V4SF 2))
8829 (clobber (reg:CC FLAGS_REG))]
8831 [(parallel [(set (match_dup 0) (match_dup 1))
8832 (clobber (reg:CC FLAGS_REG))])]
8835 operands[0] = gen_lowpart (SImode, operands[0]);
8836 if (GET_CODE (operands[1]) == ABS)
8838 tmp = gen_int_mode (0x7fffffff, SImode);
8839 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8843 tmp = gen_int_mode (0x80000000, SImode);
8844 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8850 [(set (match_operand:DF 0 "register_operand")
8851 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8852 (use (match_operand 2))
8853 (clobber (reg:CC FLAGS_REG))]
8855 [(parallel [(set (match_dup 0) (match_dup 1))
8856 (clobber (reg:CC FLAGS_REG))])]
8861 tmp = gen_lowpart (DImode, operands[0]);
8862 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8865 if (GET_CODE (operands[1]) == ABS)
8868 tmp = gen_rtx_NOT (DImode, tmp);
8872 operands[0] = gen_highpart (SImode, operands[0]);
8873 if (GET_CODE (operands[1]) == ABS)
8875 tmp = gen_int_mode (0x7fffffff, SImode);
8876 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8880 tmp = gen_int_mode (0x80000000, SImode);
8881 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8888 [(set (match_operand:XF 0 "register_operand")
8889 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8890 (use (match_operand 2))
8891 (clobber (reg:CC FLAGS_REG))]
8893 [(parallel [(set (match_dup 0) (match_dup 1))
8894 (clobber (reg:CC FLAGS_REG))])]
8897 operands[0] = gen_rtx_REG (SImode,
8898 true_regnum (operands[0])
8899 + (TARGET_64BIT ? 1 : 2));
8900 if (GET_CODE (operands[1]) == ABS)
8902 tmp = GEN_INT (0x7fff);
8903 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8907 tmp = GEN_INT (0x8000);
8908 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8913 ;; Conditionalize these after reload. If they match before reload, we
8914 ;; lose the clobber and ability to use integer instructions.
8916 (define_insn "*<code><mode>2_1"
8917 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8918 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8920 && (reload_completed
8921 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8922 "f<absneg_mnemonic>"
8923 [(set_attr "type" "fsgn")
8924 (set_attr "mode" "<MODE>")])
8926 (define_insn "*<code>extendsfdf2"
8927 [(set (match_operand:DF 0 "register_operand" "=f")
8928 (absneg:DF (float_extend:DF
8929 (match_operand:SF 1 "register_operand" "0"))))]
8930 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8931 "f<absneg_mnemonic>"
8932 [(set_attr "type" "fsgn")
8933 (set_attr "mode" "DF")])
8935 (define_insn "*<code>extendsfxf2"
8936 [(set (match_operand:XF 0 "register_operand" "=f")
8937 (absneg:XF (float_extend:XF
8938 (match_operand:SF 1 "register_operand" "0"))))]
8940 "f<absneg_mnemonic>"
8941 [(set_attr "type" "fsgn")
8942 (set_attr "mode" "XF")])
8944 (define_insn "*<code>extenddfxf2"
8945 [(set (match_operand:XF 0 "register_operand" "=f")
8946 (absneg:XF (float_extend:XF
8947 (match_operand:DF 1 "register_operand" "0"))))]
8949 "f<absneg_mnemonic>"
8950 [(set_attr "type" "fsgn")
8951 (set_attr "mode" "XF")])
8953 ;; Copysign instructions
8955 (define_mode_iterator CSGNMODE [SF DF TF])
8956 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8958 (define_expand "copysign<mode>3"
8959 [(match_operand:CSGNMODE 0 "register_operand")
8960 (match_operand:CSGNMODE 1 "nonmemory_operand")
8961 (match_operand:CSGNMODE 2 "register_operand")]
8962 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8963 || (TARGET_SSE && (<MODE>mode == TFmode))"
8964 "ix86_expand_copysign (operands); DONE;")
8966 (define_insn_and_split "copysign<mode>3_const"
8967 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8969 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8970 (match_operand:CSGNMODE 2 "register_operand" "0")
8971 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8973 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8974 || (TARGET_SSE && (<MODE>mode == TFmode))"
8976 "&& reload_completed"
8978 "ix86_split_copysign_const (operands); DONE;")
8980 (define_insn "copysign<mode>3_var"
8981 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8983 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8984 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8985 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8986 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8988 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8989 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8990 || (TARGET_SSE && (<MODE>mode == TFmode))"
8994 [(set (match_operand:CSGNMODE 0 "register_operand")
8996 [(match_operand:CSGNMODE 2 "register_operand")
8997 (match_operand:CSGNMODE 3 "register_operand")
8998 (match_operand:<CSGNVMODE> 4)
8999 (match_operand:<CSGNVMODE> 5)]
9001 (clobber (match_scratch:<CSGNVMODE> 1))]
9002 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9003 || (TARGET_SSE && (<MODE>mode == TFmode)))
9004 && reload_completed"
9006 "ix86_split_copysign_var (operands); DONE;")
9008 ;; One complement instructions
9010 (define_expand "one_cmpl<mode>2"
9011 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9012 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9014 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9016 (define_insn "*one_cmpl<mode>2_1"
9017 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9018 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9019 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9020 "not{<imodesuffix>}\t%0"
9021 [(set_attr "type" "negnot")
9022 (set_attr "mode" "<MODE>")])
9024 ;; %%% Potential partial reg stall on alternative 1. What to do?
9025 (define_insn "*one_cmplqi2_1"
9026 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9027 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9028 "ix86_unary_operator_ok (NOT, QImode, operands)"
9032 [(set_attr "type" "negnot")
9033 (set_attr "mode" "QI,SI")])
9035 ;; ??? Currently never generated - xor is used instead.
9036 (define_insn "*one_cmplsi2_1_zext"
9037 [(set (match_operand:DI 0 "register_operand" "=r")
9039 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9040 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9042 [(set_attr "type" "negnot")
9043 (set_attr "mode" "SI")])
9045 (define_insn "*one_cmpl<mode>2_2"
9046 [(set (reg FLAGS_REG)
9047 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9049 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9050 (not:SWI (match_dup 1)))]
9051 "ix86_match_ccmode (insn, CCNOmode)
9052 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9054 [(set_attr "type" "alu1")
9055 (set_attr "mode" "<MODE>")])
9058 [(set (match_operand 0 "flags_reg_operand")
9059 (match_operator 2 "compare_operator"
9060 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9062 (set (match_operand:SWI 1 "nonimmediate_operand")
9063 (not:SWI (match_dup 3)))]
9064 "ix86_match_ccmode (insn, CCNOmode)"
9065 [(parallel [(set (match_dup 0)
9066 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9069 (xor:SWI (match_dup 3) (const_int -1)))])])
9071 ;; ??? Currently never generated - xor is used instead.
9072 (define_insn "*one_cmplsi2_2_zext"
9073 [(set (reg FLAGS_REG)
9074 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9076 (set (match_operand:DI 0 "register_operand" "=r")
9077 (zero_extend:DI (not:SI (match_dup 1))))]
9078 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9079 && ix86_unary_operator_ok (NOT, SImode, operands)"
9081 [(set_attr "type" "alu1")
9082 (set_attr "mode" "SI")])
9085 [(set (match_operand 0 "flags_reg_operand")
9086 (match_operator 2 "compare_operator"
9087 [(not:SI (match_operand:SI 3 "register_operand"))
9089 (set (match_operand:DI 1 "register_operand")
9090 (zero_extend:DI (not:SI (match_dup 3))))]
9091 "ix86_match_ccmode (insn, CCNOmode)"
9092 [(parallel [(set (match_dup 0)
9093 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9096 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9098 ;; Shift instructions
9100 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9101 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9102 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9103 ;; from the assembler input.
9105 ;; This instruction shifts the target reg/mem as usual, but instead of
9106 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9107 ;; is a left shift double, bits are taken from the high order bits of
9108 ;; reg, else if the insn is a shift right double, bits are taken from the
9109 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9110 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9112 ;; Since sh[lr]d does not change the `reg' operand, that is done
9113 ;; separately, making all shifts emit pairs of shift double and normal
9114 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9115 ;; support a 63 bit shift, each shift where the count is in a reg expands
9116 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9118 ;; If the shift count is a constant, we need never emit more than one
9119 ;; shift pair, instead using moves and sign extension for counts greater
9122 (define_expand "ashl<mode>3"
9123 [(set (match_operand:SDWIM 0 "<shift_operand>")
9124 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9125 (match_operand:QI 2 "nonmemory_operand")))]
9127 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9129 (define_insn "*ashl<mode>3_doubleword"
9130 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9131 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9132 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9133 (clobber (reg:CC FLAGS_REG))]
9136 [(set_attr "type" "multi")])
9139 [(set (match_operand:DWI 0 "register_operand")
9140 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9141 (match_operand:QI 2 "nonmemory_operand")))
9142 (clobber (reg:CC FLAGS_REG))]
9143 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9145 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9147 ;; By default we don't ask for a scratch register, because when DWImode
9148 ;; values are manipulated, registers are already at a premium. But if
9149 ;; we have one handy, we won't turn it away.
9152 [(match_scratch:DWIH 3 "r")
9153 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9155 (match_operand:<DWI> 1 "nonmemory_operand")
9156 (match_operand:QI 2 "nonmemory_operand")))
9157 (clobber (reg:CC FLAGS_REG))])
9161 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9163 (define_insn "x86_64_shld"
9164 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9165 (ior:DI (ashift:DI (match_dup 0)
9166 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9167 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9168 (minus:QI (const_int 64) (match_dup 2)))))
9169 (clobber (reg:CC FLAGS_REG))]
9171 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9172 [(set_attr "type" "ishift")
9173 (set_attr "prefix_0f" "1")
9174 (set_attr "mode" "DI")
9175 (set_attr "athlon_decode" "vector")
9176 (set_attr "amdfam10_decode" "vector")
9177 (set_attr "bdver1_decode" "vector")])
9179 (define_insn "x86_shld"
9180 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9181 (ior:SI (ashift:SI (match_dup 0)
9182 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9183 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9184 (minus:QI (const_int 32) (match_dup 2)))))
9185 (clobber (reg:CC FLAGS_REG))]
9187 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9188 [(set_attr "type" "ishift")
9189 (set_attr "prefix_0f" "1")
9190 (set_attr "mode" "SI")
9191 (set_attr "pent_pair" "np")
9192 (set_attr "athlon_decode" "vector")
9193 (set_attr "amdfam10_decode" "vector")
9194 (set_attr "bdver1_decode" "vector")])
9196 (define_expand "x86_shift<mode>_adj_1"
9197 [(set (reg:CCZ FLAGS_REG)
9198 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9201 (set (match_operand:SWI48 0 "register_operand")
9202 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9203 (match_operand:SWI48 1 "register_operand")
9206 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9207 (match_operand:SWI48 3 "register_operand")
9210 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9212 (define_expand "x86_shift<mode>_adj_2"
9213 [(use (match_operand:SWI48 0 "register_operand"))
9214 (use (match_operand:SWI48 1 "register_operand"))
9215 (use (match_operand:QI 2 "register_operand"))]
9218 rtx label = gen_label_rtx ();
9221 emit_insn (gen_testqi_ccz_1 (operands[2],
9222 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9224 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9225 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9226 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9227 gen_rtx_LABEL_REF (VOIDmode, label),
9229 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9230 JUMP_LABEL (tmp) = label;
9232 emit_move_insn (operands[0], operands[1]);
9233 ix86_expand_clear (operands[1]);
9236 LABEL_NUSES (label) = 1;
9241 ;; Avoid useless masking of count operand.
9242 (define_insn_and_split "*ashl<mode>3_mask"
9243 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9245 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9248 (match_operand:SI 2 "nonimmediate_operand" "c")
9249 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9250 (clobber (reg:CC FLAGS_REG))]
9251 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9252 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9253 == GET_MODE_BITSIZE (<MODE>mode)-1"
9256 [(parallel [(set (match_dup 0)
9257 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9258 (clobber (reg:CC FLAGS_REG))])]
9260 if (can_create_pseudo_p ())
9261 operands [2] = force_reg (SImode, operands[2]);
9263 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9265 [(set_attr "type" "ishift")
9266 (set_attr "mode" "<MODE>")])
9268 (define_insn "*bmi2_ashl<mode>3_1"
9269 [(set (match_operand:SWI48 0 "register_operand" "=r")
9270 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9271 (match_operand:SWI48 2 "register_operand" "r")))]
9273 "shlx\t{%2, %1, %0|%0, %1, %2}"
9274 [(set_attr "type" "ishiftx")
9275 (set_attr "mode" "<MODE>")])
9277 (define_insn "*ashl<mode>3_1"
9278 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9279 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9280 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9281 (clobber (reg:CC FLAGS_REG))]
9282 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9284 switch (get_attr_type (insn))
9291 gcc_assert (operands[2] == const1_rtx);
9292 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9293 return "add{<imodesuffix>}\t%0, %0";
9296 if (operands[2] == const1_rtx
9297 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9298 return "sal{<imodesuffix>}\t%0";
9300 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9303 [(set_attr "isa" "*,*,bmi2")
9305 (cond [(eq_attr "alternative" "1")
9306 (const_string "lea")
9307 (eq_attr "alternative" "2")
9308 (const_string "ishiftx")
9309 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9310 (match_operand 0 "register_operand"))
9311 (match_operand 2 "const1_operand"))
9312 (const_string "alu")
9314 (const_string "ishift")))
9315 (set (attr "length_immediate")
9317 (ior (eq_attr "type" "alu")
9318 (and (eq_attr "type" "ishift")
9319 (and (match_operand 2 "const1_operand")
9320 (ior (match_test "TARGET_SHIFT1")
9321 (match_test "optimize_function_for_size_p (cfun)")))))
9323 (const_string "*")))
9324 (set_attr "mode" "<MODE>")])
9326 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9328 [(set (match_operand:SWI48 0 "register_operand")
9329 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9330 (match_operand:QI 2 "register_operand")))
9331 (clobber (reg:CC FLAGS_REG))]
9332 "TARGET_BMI2 && reload_completed"
9334 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9335 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9337 (define_insn "*bmi2_ashlsi3_1_zext"
9338 [(set (match_operand:DI 0 "register_operand" "=r")
9340 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9341 (match_operand:SI 2 "register_operand" "r"))))]
9342 "TARGET_64BIT && TARGET_BMI2"
9343 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9344 [(set_attr "type" "ishiftx")
9345 (set_attr "mode" "SI")])
9347 (define_insn "*ashlsi3_1_zext"
9348 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9350 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9351 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9352 (clobber (reg:CC FLAGS_REG))]
9353 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9355 switch (get_attr_type (insn))
9362 gcc_assert (operands[2] == const1_rtx);
9363 return "add{l}\t%k0, %k0";
9366 if (operands[2] == const1_rtx
9367 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9368 return "sal{l}\t%k0";
9370 return "sal{l}\t{%2, %k0|%k0, %2}";
9373 [(set_attr "isa" "*,*,bmi2")
9375 (cond [(eq_attr "alternative" "1")
9376 (const_string "lea")
9377 (eq_attr "alternative" "2")
9378 (const_string "ishiftx")
9379 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9380 (match_operand 2 "const1_operand"))
9381 (const_string "alu")
9383 (const_string "ishift")))
9384 (set (attr "length_immediate")
9386 (ior (eq_attr "type" "alu")
9387 (and (eq_attr "type" "ishift")
9388 (and (match_operand 2 "const1_operand")
9389 (ior (match_test "TARGET_SHIFT1")
9390 (match_test "optimize_function_for_size_p (cfun)")))))
9392 (const_string "*")))
9393 (set_attr "mode" "SI")])
9395 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9397 [(set (match_operand:DI 0 "register_operand")
9399 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9400 (match_operand:QI 2 "register_operand"))))
9401 (clobber (reg:CC FLAGS_REG))]
9402 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9404 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9405 "operands[2] = gen_lowpart (SImode, operands[2]);")
9407 (define_insn "*ashlhi3_1"
9408 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9409 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9410 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9411 (clobber (reg:CC FLAGS_REG))]
9412 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9414 switch (get_attr_type (insn))
9420 gcc_assert (operands[2] == const1_rtx);
9421 return "add{w}\t%0, %0";
9424 if (operands[2] == const1_rtx
9425 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9426 return "sal{w}\t%0";
9428 return "sal{w}\t{%2, %0|%0, %2}";
9432 (cond [(eq_attr "alternative" "1")
9433 (const_string "lea")
9434 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9435 (match_operand 0 "register_operand"))
9436 (match_operand 2 "const1_operand"))
9437 (const_string "alu")
9439 (const_string "ishift")))
9440 (set (attr "length_immediate")
9442 (ior (eq_attr "type" "alu")
9443 (and (eq_attr "type" "ishift")
9444 (and (match_operand 2 "const1_operand")
9445 (ior (match_test "TARGET_SHIFT1")
9446 (match_test "optimize_function_for_size_p (cfun)")))))
9448 (const_string "*")))
9449 (set_attr "mode" "HI,SI")])
9451 ;; %%% Potential partial reg stall on alternative 1. What to do?
9452 (define_insn "*ashlqi3_1"
9453 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9454 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9455 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9456 (clobber (reg:CC FLAGS_REG))]
9457 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9459 switch (get_attr_type (insn))
9465 gcc_assert (operands[2] == const1_rtx);
9466 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9467 return "add{l}\t%k0, %k0";
9469 return "add{b}\t%0, %0";
9472 if (operands[2] == const1_rtx
9473 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9475 if (get_attr_mode (insn) == MODE_SI)
9476 return "sal{l}\t%k0";
9478 return "sal{b}\t%0";
9482 if (get_attr_mode (insn) == MODE_SI)
9483 return "sal{l}\t{%2, %k0|%k0, %2}";
9485 return "sal{b}\t{%2, %0|%0, %2}";
9490 (cond [(eq_attr "alternative" "2")
9491 (const_string "lea")
9492 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9493 (match_operand 0 "register_operand"))
9494 (match_operand 2 "const1_operand"))
9495 (const_string "alu")
9497 (const_string "ishift")))
9498 (set (attr "length_immediate")
9500 (ior (eq_attr "type" "alu")
9501 (and (eq_attr "type" "ishift")
9502 (and (match_operand 2 "const1_operand")
9503 (ior (match_test "TARGET_SHIFT1")
9504 (match_test "optimize_function_for_size_p (cfun)")))))
9506 (const_string "*")))
9507 (set_attr "mode" "QI,SI,SI")])
9509 (define_insn "*ashlqi3_1_slp"
9510 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9511 (ashift:QI (match_dup 0)
9512 (match_operand:QI 1 "nonmemory_operand" "cI")))
9513 (clobber (reg:CC FLAGS_REG))]
9514 "(optimize_function_for_size_p (cfun)
9515 || !TARGET_PARTIAL_FLAG_REG_STALL
9516 || (operands[1] == const1_rtx
9518 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9520 switch (get_attr_type (insn))
9523 gcc_assert (operands[1] == const1_rtx);
9524 return "add{b}\t%0, %0";
9527 if (operands[1] == const1_rtx
9528 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9529 return "sal{b}\t%0";
9531 return "sal{b}\t{%1, %0|%0, %1}";
9535 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9536 (match_operand 0 "register_operand"))
9537 (match_operand 1 "const1_operand"))
9538 (const_string "alu")
9540 (const_string "ishift1")))
9541 (set (attr "length_immediate")
9543 (ior (eq_attr "type" "alu")
9544 (and (eq_attr "type" "ishift1")
9545 (and (match_operand 1 "const1_operand")
9546 (ior (match_test "TARGET_SHIFT1")
9547 (match_test "optimize_function_for_size_p (cfun)")))))
9549 (const_string "*")))
9550 (set_attr "mode" "QI")])
9552 ;; Convert ashift to the lea pattern to avoid flags dependency.
9554 [(set (match_operand 0 "register_operand")
9555 (ashift (match_operand 1 "index_register_operand")
9556 (match_operand:QI 2 "const_int_operand")))
9557 (clobber (reg:CC FLAGS_REG))]
9558 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9560 && true_regnum (operands[0]) != true_regnum (operands[1])"
9563 enum machine_mode mode = GET_MODE (operands[0]);
9566 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9569 operands[0] = gen_lowpart (mode, operands[0]);
9570 operands[1] = gen_lowpart (mode, operands[1]);
9573 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9575 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9577 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9581 ;; Convert ashift to the lea pattern to avoid flags dependency.
9583 [(set (match_operand:DI 0 "register_operand")
9585 (ashift:SI (match_operand:SI 1 "index_register_operand")
9586 (match_operand:QI 2 "const_int_operand"))))
9587 (clobber (reg:CC FLAGS_REG))]
9588 "TARGET_64BIT && reload_completed
9589 && true_regnum (operands[0]) != true_regnum (operands[1])"
9591 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9593 operands[1] = gen_lowpart (DImode, operands[1]);
9594 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9597 ;; This pattern can't accept a variable shift count, since shifts by
9598 ;; zero don't affect the flags. We assume that shifts by constant
9599 ;; zero are optimized away.
9600 (define_insn "*ashl<mode>3_cmp"
9601 [(set (reg FLAGS_REG)
9603 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9604 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9606 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9607 (ashift:SWI (match_dup 1) (match_dup 2)))]
9608 "(optimize_function_for_size_p (cfun)
9609 || !TARGET_PARTIAL_FLAG_REG_STALL
9610 || (operands[2] == const1_rtx
9612 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9613 && ix86_match_ccmode (insn, CCGOCmode)
9614 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9616 switch (get_attr_type (insn))
9619 gcc_assert (operands[2] == const1_rtx);
9620 return "add{<imodesuffix>}\t%0, %0";
9623 if (operands[2] == const1_rtx
9624 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9625 return "sal{<imodesuffix>}\t%0";
9627 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9631 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9632 (match_operand 0 "register_operand"))
9633 (match_operand 2 "const1_operand"))
9634 (const_string "alu")
9636 (const_string "ishift")))
9637 (set (attr "length_immediate")
9639 (ior (eq_attr "type" "alu")
9640 (and (eq_attr "type" "ishift")
9641 (and (match_operand 2 "const1_operand")
9642 (ior (match_test "TARGET_SHIFT1")
9643 (match_test "optimize_function_for_size_p (cfun)")))))
9645 (const_string "*")))
9646 (set_attr "mode" "<MODE>")])
9648 (define_insn "*ashlsi3_cmp_zext"
9649 [(set (reg FLAGS_REG)
9651 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9652 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9654 (set (match_operand:DI 0 "register_operand" "=r")
9655 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9657 && (optimize_function_for_size_p (cfun)
9658 || !TARGET_PARTIAL_FLAG_REG_STALL
9659 || (operands[2] == const1_rtx
9661 || TARGET_DOUBLE_WITH_ADD)))
9662 && ix86_match_ccmode (insn, CCGOCmode)
9663 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9665 switch (get_attr_type (insn))
9668 gcc_assert (operands[2] == const1_rtx);
9669 return "add{l}\t%k0, %k0";
9672 if (operands[2] == const1_rtx
9673 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9674 return "sal{l}\t%k0";
9676 return "sal{l}\t{%2, %k0|%k0, %2}";
9680 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9681 (match_operand 2 "const1_operand"))
9682 (const_string "alu")
9684 (const_string "ishift")))
9685 (set (attr "length_immediate")
9687 (ior (eq_attr "type" "alu")
9688 (and (eq_attr "type" "ishift")
9689 (and (match_operand 2 "const1_operand")
9690 (ior (match_test "TARGET_SHIFT1")
9691 (match_test "optimize_function_for_size_p (cfun)")))))
9693 (const_string "*")))
9694 (set_attr "mode" "SI")])
9696 (define_insn "*ashl<mode>3_cconly"
9697 [(set (reg FLAGS_REG)
9699 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9700 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9702 (clobber (match_scratch:SWI 0 "=<r>"))]
9703 "(optimize_function_for_size_p (cfun)
9704 || !TARGET_PARTIAL_FLAG_REG_STALL
9705 || (operands[2] == const1_rtx
9707 || TARGET_DOUBLE_WITH_ADD)))
9708 && ix86_match_ccmode (insn, CCGOCmode)"
9710 switch (get_attr_type (insn))
9713 gcc_assert (operands[2] == const1_rtx);
9714 return "add{<imodesuffix>}\t%0, %0";
9717 if (operands[2] == const1_rtx
9718 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9719 return "sal{<imodesuffix>}\t%0";
9721 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9725 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9726 (match_operand 0 "register_operand"))
9727 (match_operand 2 "const1_operand"))
9728 (const_string "alu")
9730 (const_string "ishift")))
9731 (set (attr "length_immediate")
9733 (ior (eq_attr "type" "alu")
9734 (and (eq_attr "type" "ishift")
9735 (and (match_operand 2 "const1_operand")
9736 (ior (match_test "TARGET_SHIFT1")
9737 (match_test "optimize_function_for_size_p (cfun)")))))
9739 (const_string "*")))
9740 (set_attr "mode" "<MODE>")])
9742 ;; See comment above `ashl<mode>3' about how this works.
9744 (define_expand "<shift_insn><mode>3"
9745 [(set (match_operand:SDWIM 0 "<shift_operand>")
9746 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9747 (match_operand:QI 2 "nonmemory_operand")))]
9749 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9751 ;; Avoid useless masking of count operand.
9752 (define_insn_and_split "*<shift_insn><mode>3_mask"
9753 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9755 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9758 (match_operand:SI 2 "nonimmediate_operand" "c")
9759 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9760 (clobber (reg:CC FLAGS_REG))]
9761 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9762 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9763 == GET_MODE_BITSIZE (<MODE>mode)-1"
9766 [(parallel [(set (match_dup 0)
9767 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9768 (clobber (reg:CC FLAGS_REG))])]
9770 if (can_create_pseudo_p ())
9771 operands [2] = force_reg (SImode, operands[2]);
9773 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9775 [(set_attr "type" "ishift")
9776 (set_attr "mode" "<MODE>")])
9778 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9779 [(set (match_operand:DWI 0 "register_operand" "=r")
9780 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9781 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9782 (clobber (reg:CC FLAGS_REG))]
9785 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9787 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9788 [(set_attr "type" "multi")])
9790 ;; By default we don't ask for a scratch register, because when DWImode
9791 ;; values are manipulated, registers are already at a premium. But if
9792 ;; we have one handy, we won't turn it away.
9795 [(match_scratch:DWIH 3 "r")
9796 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9798 (match_operand:<DWI> 1 "register_operand")
9799 (match_operand:QI 2 "nonmemory_operand")))
9800 (clobber (reg:CC FLAGS_REG))])
9804 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9806 (define_insn "x86_64_shrd"
9807 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9808 (ior:DI (ashiftrt:DI (match_dup 0)
9809 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9810 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9811 (minus:QI (const_int 64) (match_dup 2)))))
9812 (clobber (reg:CC FLAGS_REG))]
9814 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9815 [(set_attr "type" "ishift")
9816 (set_attr "prefix_0f" "1")
9817 (set_attr "mode" "DI")
9818 (set_attr "athlon_decode" "vector")
9819 (set_attr "amdfam10_decode" "vector")
9820 (set_attr "bdver1_decode" "vector")])
9822 (define_insn "x86_shrd"
9823 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9824 (ior:SI (ashiftrt:SI (match_dup 0)
9825 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9826 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9827 (minus:QI (const_int 32) (match_dup 2)))))
9828 (clobber (reg:CC FLAGS_REG))]
9830 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9831 [(set_attr "type" "ishift")
9832 (set_attr "prefix_0f" "1")
9833 (set_attr "mode" "SI")
9834 (set_attr "pent_pair" "np")
9835 (set_attr "athlon_decode" "vector")
9836 (set_attr "amdfam10_decode" "vector")
9837 (set_attr "bdver1_decode" "vector")])
9839 (define_insn "ashrdi3_cvt"
9840 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9841 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9842 (match_operand:QI 2 "const_int_operand")))
9843 (clobber (reg:CC FLAGS_REG))]
9844 "TARGET_64BIT && INTVAL (operands[2]) == 63
9845 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9846 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9849 sar{q}\t{%2, %0|%0, %2}"
9850 [(set_attr "type" "imovx,ishift")
9851 (set_attr "prefix_0f" "0,*")
9852 (set_attr "length_immediate" "0,*")
9853 (set_attr "modrm" "0,1")
9854 (set_attr "mode" "DI")])
9856 (define_insn "ashrsi3_cvt"
9857 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9858 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9859 (match_operand:QI 2 "const_int_operand")))
9860 (clobber (reg:CC FLAGS_REG))]
9861 "INTVAL (operands[2]) == 31
9862 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9863 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9866 sar{l}\t{%2, %0|%0, %2}"
9867 [(set_attr "type" "imovx,ishift")
9868 (set_attr "prefix_0f" "0,*")
9869 (set_attr "length_immediate" "0,*")
9870 (set_attr "modrm" "0,1")
9871 (set_attr "mode" "SI")])
9873 (define_insn "*ashrsi3_cvt_zext"
9874 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9876 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9877 (match_operand:QI 2 "const_int_operand"))))
9878 (clobber (reg:CC FLAGS_REG))]
9879 "TARGET_64BIT && INTVAL (operands[2]) == 31
9880 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9881 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9884 sar{l}\t{%2, %k0|%k0, %2}"
9885 [(set_attr "type" "imovx,ishift")
9886 (set_attr "prefix_0f" "0,*")
9887 (set_attr "length_immediate" "0,*")
9888 (set_attr "modrm" "0,1")
9889 (set_attr "mode" "SI")])
9891 (define_expand "x86_shift<mode>_adj_3"
9892 [(use (match_operand:SWI48 0 "register_operand"))
9893 (use (match_operand:SWI48 1 "register_operand"))
9894 (use (match_operand:QI 2 "register_operand"))]
9897 rtx label = gen_label_rtx ();
9900 emit_insn (gen_testqi_ccz_1 (operands[2],
9901 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9903 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9904 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9905 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9906 gen_rtx_LABEL_REF (VOIDmode, label),
9908 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9909 JUMP_LABEL (tmp) = label;
9911 emit_move_insn (operands[0], operands[1]);
9912 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9913 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9915 LABEL_NUSES (label) = 1;
9920 (define_insn "*bmi2_<shift_insn><mode>3_1"
9921 [(set (match_operand:SWI48 0 "register_operand" "=r")
9922 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9923 (match_operand:SWI48 2 "register_operand" "r")))]
9925 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9926 [(set_attr "type" "ishiftx")
9927 (set_attr "mode" "<MODE>")])
9929 (define_insn "*<shift_insn><mode>3_1"
9930 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9932 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9933 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9934 (clobber (reg:CC FLAGS_REG))]
9935 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9937 switch (get_attr_type (insn))
9943 if (operands[2] == const1_rtx
9944 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9945 return "<shift>{<imodesuffix>}\t%0";
9947 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9950 [(set_attr "isa" "*,bmi2")
9951 (set_attr "type" "ishift,ishiftx")
9952 (set (attr "length_immediate")
9954 (and (match_operand 2 "const1_operand")
9955 (ior (match_test "TARGET_SHIFT1")
9956 (match_test "optimize_function_for_size_p (cfun)")))
9958 (const_string "*")))
9959 (set_attr "mode" "<MODE>")])
9961 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9963 [(set (match_operand:SWI48 0 "register_operand")
9964 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9965 (match_operand:QI 2 "register_operand")))
9966 (clobber (reg:CC FLAGS_REG))]
9967 "TARGET_BMI2 && reload_completed"
9969 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9970 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9972 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9973 [(set (match_operand:DI 0 "register_operand" "=r")
9975 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9976 (match_operand:SI 2 "register_operand" "r"))))]
9977 "TARGET_64BIT && TARGET_BMI2"
9978 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9979 [(set_attr "type" "ishiftx")
9980 (set_attr "mode" "SI")])
9982 (define_insn "*<shift_insn>si3_1_zext"
9983 [(set (match_operand:DI 0 "register_operand" "=r,r")
9985 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9986 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9987 (clobber (reg:CC FLAGS_REG))]
9988 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9990 switch (get_attr_type (insn))
9996 if (operands[2] == const1_rtx
9997 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9998 return "<shift>{l}\t%k0";
10000 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10003 [(set_attr "isa" "*,bmi2")
10004 (set_attr "type" "ishift,ishiftx")
10005 (set (attr "length_immediate")
10007 (and (match_operand 2 "const1_operand")
10008 (ior (match_test "TARGET_SHIFT1")
10009 (match_test "optimize_function_for_size_p (cfun)")))
10011 (const_string "*")))
10012 (set_attr "mode" "SI")])
10014 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10016 [(set (match_operand:DI 0 "register_operand")
10018 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10019 (match_operand:QI 2 "register_operand"))))
10020 (clobber (reg:CC FLAGS_REG))]
10021 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10022 [(set (match_dup 0)
10023 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10024 "operands[2] = gen_lowpart (SImode, operands[2]);")
10026 (define_insn "*<shift_insn><mode>3_1"
10027 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10029 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10030 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10031 (clobber (reg:CC FLAGS_REG))]
10032 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10034 if (operands[2] == const1_rtx
10035 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10036 return "<shift>{<imodesuffix>}\t%0";
10038 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10040 [(set_attr "type" "ishift")
10041 (set (attr "length_immediate")
10043 (and (match_operand 2 "const1_operand")
10044 (ior (match_test "TARGET_SHIFT1")
10045 (match_test "optimize_function_for_size_p (cfun)")))
10047 (const_string "*")))
10048 (set_attr "mode" "<MODE>")])
10050 (define_insn "*<shift_insn>qi3_1_slp"
10051 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10052 (any_shiftrt:QI (match_dup 0)
10053 (match_operand:QI 1 "nonmemory_operand" "cI")))
10054 (clobber (reg:CC FLAGS_REG))]
10055 "(optimize_function_for_size_p (cfun)
10056 || !TARGET_PARTIAL_REG_STALL
10057 || (operands[1] == const1_rtx
10058 && TARGET_SHIFT1))"
10060 if (operands[1] == const1_rtx
10061 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10062 return "<shift>{b}\t%0";
10064 return "<shift>{b}\t{%1, %0|%0, %1}";
10066 [(set_attr "type" "ishift1")
10067 (set (attr "length_immediate")
10069 (and (match_operand 1 "const1_operand")
10070 (ior (match_test "TARGET_SHIFT1")
10071 (match_test "optimize_function_for_size_p (cfun)")))
10073 (const_string "*")))
10074 (set_attr "mode" "QI")])
10076 ;; This pattern can't accept a variable shift count, since shifts by
10077 ;; zero don't affect the flags. We assume that shifts by constant
10078 ;; zero are optimized away.
10079 (define_insn "*<shift_insn><mode>3_cmp"
10080 [(set (reg FLAGS_REG)
10083 (match_operand:SWI 1 "nonimmediate_operand" "0")
10084 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10086 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10087 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10088 "(optimize_function_for_size_p (cfun)
10089 || !TARGET_PARTIAL_FLAG_REG_STALL
10090 || (operands[2] == const1_rtx
10092 && ix86_match_ccmode (insn, CCGOCmode)
10093 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10095 if (operands[2] == const1_rtx
10096 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10097 return "<shift>{<imodesuffix>}\t%0";
10099 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10101 [(set_attr "type" "ishift")
10102 (set (attr "length_immediate")
10104 (and (match_operand 2 "const1_operand")
10105 (ior (match_test "TARGET_SHIFT1")
10106 (match_test "optimize_function_for_size_p (cfun)")))
10108 (const_string "*")))
10109 (set_attr "mode" "<MODE>")])
10111 (define_insn "*<shift_insn>si3_cmp_zext"
10112 [(set (reg FLAGS_REG)
10114 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10115 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10117 (set (match_operand:DI 0 "register_operand" "=r")
10118 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10120 && (optimize_function_for_size_p (cfun)
10121 || !TARGET_PARTIAL_FLAG_REG_STALL
10122 || (operands[2] == const1_rtx
10124 && ix86_match_ccmode (insn, CCGOCmode)
10125 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10127 if (operands[2] == const1_rtx
10128 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10129 return "<shift>{l}\t%k0";
10131 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10133 [(set_attr "type" "ishift")
10134 (set (attr "length_immediate")
10136 (and (match_operand 2 "const1_operand")
10137 (ior (match_test "TARGET_SHIFT1")
10138 (match_test "optimize_function_for_size_p (cfun)")))
10140 (const_string "*")))
10141 (set_attr "mode" "SI")])
10143 (define_insn "*<shift_insn><mode>3_cconly"
10144 [(set (reg FLAGS_REG)
10147 (match_operand:SWI 1 "register_operand" "0")
10148 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10150 (clobber (match_scratch:SWI 0 "=<r>"))]
10151 "(optimize_function_for_size_p (cfun)
10152 || !TARGET_PARTIAL_FLAG_REG_STALL
10153 || (operands[2] == const1_rtx
10155 && ix86_match_ccmode (insn, CCGOCmode)"
10157 if (operands[2] == const1_rtx
10158 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10159 return "<shift>{<imodesuffix>}\t%0";
10161 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10163 [(set_attr "type" "ishift")
10164 (set (attr "length_immediate")
10166 (and (match_operand 2 "const1_operand")
10167 (ior (match_test "TARGET_SHIFT1")
10168 (match_test "optimize_function_for_size_p (cfun)")))
10170 (const_string "*")))
10171 (set_attr "mode" "<MODE>")])
10173 ;; Rotate instructions
10175 (define_expand "<rotate_insn>ti3"
10176 [(set (match_operand:TI 0 "register_operand")
10177 (any_rotate:TI (match_operand:TI 1 "register_operand")
10178 (match_operand:QI 2 "nonmemory_operand")))]
10181 if (const_1_to_63_operand (operands[2], VOIDmode))
10182 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10183 (operands[0], operands[1], operands[2]));
10190 (define_expand "<rotate_insn>di3"
10191 [(set (match_operand:DI 0 "shiftdi_operand")
10192 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10193 (match_operand:QI 2 "nonmemory_operand")))]
10197 ix86_expand_binary_operator (<CODE>, DImode, operands);
10198 else if (const_1_to_31_operand (operands[2], VOIDmode))
10199 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10200 (operands[0], operands[1], operands[2]));
10207 (define_expand "<rotate_insn><mode>3"
10208 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10209 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10210 (match_operand:QI 2 "nonmemory_operand")))]
10212 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10214 ;; Avoid useless masking of count operand.
10215 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10216 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10218 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10221 (match_operand:SI 2 "nonimmediate_operand" "c")
10222 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10223 (clobber (reg:CC FLAGS_REG))]
10224 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10225 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10226 == GET_MODE_BITSIZE (<MODE>mode)-1"
10229 [(parallel [(set (match_dup 0)
10230 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10231 (clobber (reg:CC FLAGS_REG))])]
10233 if (can_create_pseudo_p ())
10234 operands [2] = force_reg (SImode, operands[2]);
10236 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10238 [(set_attr "type" "rotate")
10239 (set_attr "mode" "<MODE>")])
10241 ;; Implement rotation using two double-precision
10242 ;; shift instructions and a scratch register.
10244 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10245 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10246 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10247 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10248 (clobber (reg:CC FLAGS_REG))
10249 (clobber (match_scratch:DWIH 3 "=&r"))]
10253 [(set (match_dup 3) (match_dup 4))
10255 [(set (match_dup 4)
10256 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10257 (lshiftrt:DWIH (match_dup 5)
10258 (minus:QI (match_dup 6) (match_dup 2)))))
10259 (clobber (reg:CC FLAGS_REG))])
10261 [(set (match_dup 5)
10262 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10263 (lshiftrt:DWIH (match_dup 3)
10264 (minus:QI (match_dup 6) (match_dup 2)))))
10265 (clobber (reg:CC FLAGS_REG))])]
10267 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10269 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10272 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10273 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10274 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10275 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10276 (clobber (reg:CC FLAGS_REG))
10277 (clobber (match_scratch:DWIH 3 "=&r"))]
10281 [(set (match_dup 3) (match_dup 4))
10283 [(set (match_dup 4)
10284 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10285 (ashift:DWIH (match_dup 5)
10286 (minus:QI (match_dup 6) (match_dup 2)))))
10287 (clobber (reg:CC FLAGS_REG))])
10289 [(set (match_dup 5)
10290 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10291 (ashift:DWIH (match_dup 3)
10292 (minus:QI (match_dup 6) (match_dup 2)))))
10293 (clobber (reg:CC FLAGS_REG))])]
10295 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10297 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10300 (define_insn "*bmi2_rorx<mode>3_1"
10301 [(set (match_operand:SWI48 0 "register_operand" "=r")
10302 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10303 (match_operand:QI 2 "immediate_operand" "<S>")))]
10305 "rorx\t{%2, %1, %0|%0, %1, %2}"
10306 [(set_attr "type" "rotatex")
10307 (set_attr "mode" "<MODE>")])
10309 (define_insn "*<rotate_insn><mode>3_1"
10310 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10312 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10313 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10314 (clobber (reg:CC FLAGS_REG))]
10315 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10317 switch (get_attr_type (insn))
10323 if (operands[2] == const1_rtx
10324 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10325 return "<rotate>{<imodesuffix>}\t%0";
10327 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10330 [(set_attr "isa" "*,bmi2")
10331 (set_attr "type" "rotate,rotatex")
10332 (set (attr "length_immediate")
10334 (and (eq_attr "type" "rotate")
10335 (and (match_operand 2 "const1_operand")
10336 (ior (match_test "TARGET_SHIFT1")
10337 (match_test "optimize_function_for_size_p (cfun)"))))
10339 (const_string "*")))
10340 (set_attr "mode" "<MODE>")])
10342 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10344 [(set (match_operand:SWI48 0 "register_operand")
10345 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10346 (match_operand:QI 2 "immediate_operand")))
10347 (clobber (reg:CC FLAGS_REG))]
10348 "TARGET_BMI2 && reload_completed"
10349 [(set (match_dup 0)
10350 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10353 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10357 [(set (match_operand:SWI48 0 "register_operand")
10358 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10359 (match_operand:QI 2 "immediate_operand")))
10360 (clobber (reg:CC FLAGS_REG))]
10361 "TARGET_BMI2 && reload_completed"
10362 [(set (match_dup 0)
10363 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10365 (define_insn "*bmi2_rorxsi3_1_zext"
10366 [(set (match_operand:DI 0 "register_operand" "=r")
10368 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10369 (match_operand:QI 2 "immediate_operand" "I"))))]
10370 "TARGET_64BIT && TARGET_BMI2"
10371 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10372 [(set_attr "type" "rotatex")
10373 (set_attr "mode" "SI")])
10375 (define_insn "*<rotate_insn>si3_1_zext"
10376 [(set (match_operand:DI 0 "register_operand" "=r,r")
10378 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10379 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10380 (clobber (reg:CC FLAGS_REG))]
10381 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10383 switch (get_attr_type (insn))
10389 if (operands[2] == const1_rtx
10390 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10391 return "<rotate>{l}\t%k0";
10393 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10396 [(set_attr "isa" "*,bmi2")
10397 (set_attr "type" "rotate,rotatex")
10398 (set (attr "length_immediate")
10400 (and (eq_attr "type" "rotate")
10401 (and (match_operand 2 "const1_operand")
10402 (ior (match_test "TARGET_SHIFT1")
10403 (match_test "optimize_function_for_size_p (cfun)"))))
10405 (const_string "*")))
10406 (set_attr "mode" "SI")])
10408 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10410 [(set (match_operand:DI 0 "register_operand")
10412 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10413 (match_operand:QI 2 "immediate_operand"))))
10414 (clobber (reg:CC FLAGS_REG))]
10415 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10416 [(set (match_dup 0)
10417 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10420 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10424 [(set (match_operand:DI 0 "register_operand")
10426 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10427 (match_operand:QI 2 "immediate_operand"))))
10428 (clobber (reg:CC FLAGS_REG))]
10429 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10430 [(set (match_dup 0)
10431 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10433 (define_insn "*<rotate_insn><mode>3_1"
10434 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10435 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10436 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10437 (clobber (reg:CC FLAGS_REG))]
10438 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10440 if (operands[2] == const1_rtx
10441 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10442 return "<rotate>{<imodesuffix>}\t%0";
10444 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10446 [(set_attr "type" "rotate")
10447 (set (attr "length_immediate")
10449 (and (match_operand 2 "const1_operand")
10450 (ior (match_test "TARGET_SHIFT1")
10451 (match_test "optimize_function_for_size_p (cfun)")))
10453 (const_string "*")))
10454 (set_attr "mode" "<MODE>")])
10456 (define_insn "*<rotate_insn>qi3_1_slp"
10457 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10458 (any_rotate:QI (match_dup 0)
10459 (match_operand:QI 1 "nonmemory_operand" "cI")))
10460 (clobber (reg:CC FLAGS_REG))]
10461 "(optimize_function_for_size_p (cfun)
10462 || !TARGET_PARTIAL_REG_STALL
10463 || (operands[1] == const1_rtx
10464 && TARGET_SHIFT1))"
10466 if (operands[1] == const1_rtx
10467 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10468 return "<rotate>{b}\t%0";
10470 return "<rotate>{b}\t{%1, %0|%0, %1}";
10472 [(set_attr "type" "rotate1")
10473 (set (attr "length_immediate")
10475 (and (match_operand 1 "const1_operand")
10476 (ior (match_test "TARGET_SHIFT1")
10477 (match_test "optimize_function_for_size_p (cfun)")))
10479 (const_string "*")))
10480 (set_attr "mode" "QI")])
10483 [(set (match_operand:HI 0 "register_operand")
10484 (any_rotate:HI (match_dup 0) (const_int 8)))
10485 (clobber (reg:CC FLAGS_REG))]
10487 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10488 [(parallel [(set (strict_low_part (match_dup 0))
10489 (bswap:HI (match_dup 0)))
10490 (clobber (reg:CC FLAGS_REG))])])
10492 ;; Bit set / bit test instructions
10494 (define_expand "extv"
10495 [(set (match_operand:SI 0 "register_operand")
10496 (sign_extract:SI (match_operand:SI 1 "register_operand")
10497 (match_operand:SI 2 "const8_operand")
10498 (match_operand:SI 3 "const8_operand")))]
10501 /* Handle extractions from %ah et al. */
10502 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10505 /* From mips.md: extract_bit_field doesn't verify that our source
10506 matches the predicate, so check it again here. */
10507 if (! ext_register_operand (operands[1], VOIDmode))
10511 (define_expand "extzv"
10512 [(set (match_operand:SI 0 "register_operand")
10513 (zero_extract:SI (match_operand 1 "ext_register_operand")
10514 (match_operand:SI 2 "const8_operand")
10515 (match_operand:SI 3 "const8_operand")))]
10518 /* Handle extractions from %ah et al. */
10519 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10522 /* From mips.md: extract_bit_field doesn't verify that our source
10523 matches the predicate, so check it again here. */
10524 if (! ext_register_operand (operands[1], VOIDmode))
10528 (define_expand "insv"
10529 [(set (zero_extract (match_operand 0 "register_operand")
10530 (match_operand 1 "const_int_operand")
10531 (match_operand 2 "const_int_operand"))
10532 (match_operand 3 "register_operand"))]
10535 rtx (*gen_mov_insv_1) (rtx, rtx);
10537 if (ix86_expand_pinsr (operands))
10540 /* Handle insertions to %ah et al. */
10541 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10544 /* From mips.md: insert_bit_field doesn't verify that our source
10545 matches the predicate, so check it again here. */
10546 if (! ext_register_operand (operands[0], VOIDmode))
10549 gen_mov_insv_1 = (TARGET_64BIT
10550 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10552 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10556 ;; %%% bts, btr, btc, bt.
10557 ;; In general these instructions are *slow* when applied to memory,
10558 ;; since they enforce atomic operation. When applied to registers,
10559 ;; it depends on the cpu implementation. They're never faster than
10560 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10561 ;; no point. But in 64-bit, we can't hold the relevant immediates
10562 ;; within the instruction itself, so operating on bits in the high
10563 ;; 32-bits of a register becomes easier.
10565 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10566 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10567 ;; negdf respectively, so they can never be disabled entirely.
10569 (define_insn "*btsq"
10570 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10572 (match_operand:DI 1 "const_0_to_63_operand"))
10574 (clobber (reg:CC FLAGS_REG))]
10575 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10576 "bts{q}\t{%1, %0|%0, %1}"
10577 [(set_attr "type" "alu1")
10578 (set_attr "prefix_0f" "1")
10579 (set_attr "mode" "DI")])
10581 (define_insn "*btrq"
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 "btr{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 "*btcq"
10594 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10596 (match_operand:DI 1 "const_0_to_63_operand"))
10597 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10598 (clobber (reg:CC FLAGS_REG))]
10599 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10600 "btc{q}\t{%1, %0|%0, %1}"
10601 [(set_attr "type" "alu1")
10602 (set_attr "prefix_0f" "1")
10603 (set_attr "mode" "DI")])
10605 ;; Allow Nocona to avoid these instructions if a register is available.
10608 [(match_scratch:DI 2 "r")
10609 (parallel [(set (zero_extract:DI
10610 (match_operand:DI 0 "register_operand")
10612 (match_operand:DI 1 "const_0_to_63_operand"))
10614 (clobber (reg:CC FLAGS_REG))])]
10615 "TARGET_64BIT && !TARGET_USE_BT"
10618 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10621 if (HOST_BITS_PER_WIDE_INT >= 64)
10622 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10623 else if (i < HOST_BITS_PER_WIDE_INT)
10624 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10626 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10628 op1 = immed_double_const (lo, hi, DImode);
10631 emit_move_insn (operands[2], op1);
10635 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10640 [(match_scratch:DI 2 "r")
10641 (parallel [(set (zero_extract:DI
10642 (match_operand:DI 0 "register_operand")
10644 (match_operand:DI 1 "const_0_to_63_operand"))
10646 (clobber (reg:CC FLAGS_REG))])]
10647 "TARGET_64BIT && !TARGET_USE_BT"
10650 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10653 if (HOST_BITS_PER_WIDE_INT >= 64)
10654 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10655 else if (i < HOST_BITS_PER_WIDE_INT)
10656 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10658 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10660 op1 = immed_double_const (~lo, ~hi, DImode);
10663 emit_move_insn (operands[2], op1);
10667 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10672 [(match_scratch:DI 2 "r")
10673 (parallel [(set (zero_extract:DI
10674 (match_operand:DI 0 "register_operand")
10676 (match_operand:DI 1 "const_0_to_63_operand"))
10677 (not:DI (zero_extract:DI
10678 (match_dup 0) (const_int 1) (match_dup 1))))
10679 (clobber (reg:CC FLAGS_REG))])]
10680 "TARGET_64BIT && !TARGET_USE_BT"
10683 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10686 if (HOST_BITS_PER_WIDE_INT >= 64)
10687 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10688 else if (i < HOST_BITS_PER_WIDE_INT)
10689 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10691 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10693 op1 = immed_double_const (lo, hi, DImode);
10696 emit_move_insn (operands[2], op1);
10700 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10704 (define_insn "*bt<mode>"
10705 [(set (reg:CCC FLAGS_REG)
10707 (zero_extract:SWI48
10708 (match_operand:SWI48 0 "register_operand" "r")
10710 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10712 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10713 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10714 [(set_attr "type" "alu1")
10715 (set_attr "prefix_0f" "1")
10716 (set_attr "mode" "<MODE>")])
10718 ;; Store-flag instructions.
10720 ;; For all sCOND expanders, also expand the compare or test insn that
10721 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10723 (define_insn_and_split "*setcc_di_1"
10724 [(set (match_operand:DI 0 "register_operand" "=q")
10725 (match_operator:DI 1 "ix86_comparison_operator"
10726 [(reg FLAGS_REG) (const_int 0)]))]
10727 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10729 "&& reload_completed"
10730 [(set (match_dup 2) (match_dup 1))
10731 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10733 PUT_MODE (operands[1], QImode);
10734 operands[2] = gen_lowpart (QImode, operands[0]);
10737 (define_insn_and_split "*setcc_si_1_and"
10738 [(set (match_operand:SI 0 "register_operand" "=q")
10739 (match_operator:SI 1 "ix86_comparison_operator"
10740 [(reg FLAGS_REG) (const_int 0)]))
10741 (clobber (reg:CC FLAGS_REG))]
10742 "!TARGET_PARTIAL_REG_STALL
10743 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10745 "&& reload_completed"
10746 [(set (match_dup 2) (match_dup 1))
10747 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10748 (clobber (reg:CC FLAGS_REG))])]
10750 PUT_MODE (operands[1], QImode);
10751 operands[2] = gen_lowpart (QImode, operands[0]);
10754 (define_insn_and_split "*setcc_si_1_movzbl"
10755 [(set (match_operand:SI 0 "register_operand" "=q")
10756 (match_operator:SI 1 "ix86_comparison_operator"
10757 [(reg FLAGS_REG) (const_int 0)]))]
10758 "!TARGET_PARTIAL_REG_STALL
10759 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10761 "&& reload_completed"
10762 [(set (match_dup 2) (match_dup 1))
10763 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10765 PUT_MODE (operands[1], QImode);
10766 operands[2] = gen_lowpart (QImode, operands[0]);
10769 (define_insn "*setcc_qi"
10770 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10771 (match_operator:QI 1 "ix86_comparison_operator"
10772 [(reg FLAGS_REG) (const_int 0)]))]
10775 [(set_attr "type" "setcc")
10776 (set_attr "mode" "QI")])
10778 (define_insn "*setcc_qi_slp"
10779 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10780 (match_operator:QI 1 "ix86_comparison_operator"
10781 [(reg FLAGS_REG) (const_int 0)]))]
10784 [(set_attr "type" "setcc")
10785 (set_attr "mode" "QI")])
10787 ;; In general it is not safe to assume too much about CCmode registers,
10788 ;; so simplify-rtx stops when it sees a second one. Under certain
10789 ;; conditions this is safe on x86, so help combine not create
10796 [(set (match_operand:QI 0 "nonimmediate_operand")
10797 (ne:QI (match_operator 1 "ix86_comparison_operator"
10798 [(reg FLAGS_REG) (const_int 0)])
10801 [(set (match_dup 0) (match_dup 1))]
10802 "PUT_MODE (operands[1], QImode);")
10805 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10806 (ne:QI (match_operator 1 "ix86_comparison_operator"
10807 [(reg FLAGS_REG) (const_int 0)])
10810 [(set (match_dup 0) (match_dup 1))]
10811 "PUT_MODE (operands[1], QImode);")
10814 [(set (match_operand:QI 0 "nonimmediate_operand")
10815 (eq:QI (match_operator 1 "ix86_comparison_operator"
10816 [(reg FLAGS_REG) (const_int 0)])
10819 [(set (match_dup 0) (match_dup 1))]
10821 rtx new_op1 = copy_rtx (operands[1]);
10822 operands[1] = new_op1;
10823 PUT_MODE (new_op1, QImode);
10824 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10825 GET_MODE (XEXP (new_op1, 0))));
10827 /* Make sure that (a) the CCmode we have for the flags is strong
10828 enough for the reversed compare or (b) we have a valid FP compare. */
10829 if (! ix86_comparison_operator (new_op1, VOIDmode))
10834 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10835 (eq:QI (match_operator 1 "ix86_comparison_operator"
10836 [(reg FLAGS_REG) (const_int 0)])
10839 [(set (match_dup 0) (match_dup 1))]
10841 rtx new_op1 = copy_rtx (operands[1]);
10842 operands[1] = new_op1;
10843 PUT_MODE (new_op1, QImode);
10844 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10845 GET_MODE (XEXP (new_op1, 0))));
10847 /* Make sure that (a) the CCmode we have for the flags is strong
10848 enough for the reversed compare or (b) we have a valid FP compare. */
10849 if (! ix86_comparison_operator (new_op1, VOIDmode))
10853 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10854 ;; subsequent logical operations are used to imitate conditional moves.
10855 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10858 (define_insn "setcc_<mode>_sse"
10859 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10860 (match_operator:MODEF 3 "sse_comparison_operator"
10861 [(match_operand:MODEF 1 "register_operand" "0,x")
10862 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10863 "SSE_FLOAT_MODE_P (<MODE>mode)"
10865 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10866 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10867 [(set_attr "isa" "noavx,avx")
10868 (set_attr "type" "ssecmp")
10869 (set_attr "length_immediate" "1")
10870 (set_attr "prefix" "orig,vex")
10871 (set_attr "mode" "<MODE>")])
10873 ;; Basic conditional jump instructions.
10874 ;; We ignore the overflow flag for signed branch instructions.
10876 (define_insn "*jcc_1"
10878 (if_then_else (match_operator 1 "ix86_comparison_operator"
10879 [(reg FLAGS_REG) (const_int 0)])
10880 (label_ref (match_operand 0))
10884 [(set_attr "type" "ibr")
10885 (set_attr "modrm" "0")
10886 (set (attr "length")
10887 (if_then_else (and (ge (minus (match_dup 0) (pc))
10889 (lt (minus (match_dup 0) (pc))
10894 (define_insn "*jcc_2"
10896 (if_then_else (match_operator 1 "ix86_comparison_operator"
10897 [(reg FLAGS_REG) (const_int 0)])
10899 (label_ref (match_operand 0))))]
10902 [(set_attr "type" "ibr")
10903 (set_attr "modrm" "0")
10904 (set (attr "length")
10905 (if_then_else (and (ge (minus (match_dup 0) (pc))
10907 (lt (minus (match_dup 0) (pc))
10912 ;; In general it is not safe to assume too much about CCmode registers,
10913 ;; so simplify-rtx stops when it sees a second one. Under certain
10914 ;; conditions this is safe on x86, so help combine not create
10922 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10923 [(reg FLAGS_REG) (const_int 0)])
10925 (label_ref (match_operand 1))
10929 (if_then_else (match_dup 0)
10930 (label_ref (match_dup 1))
10932 "PUT_MODE (operands[0], VOIDmode);")
10936 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10937 [(reg FLAGS_REG) (const_int 0)])
10939 (label_ref (match_operand 1))
10943 (if_then_else (match_dup 0)
10944 (label_ref (match_dup 1))
10947 rtx new_op0 = copy_rtx (operands[0]);
10948 operands[0] = new_op0;
10949 PUT_MODE (new_op0, VOIDmode);
10950 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10951 GET_MODE (XEXP (new_op0, 0))));
10953 /* Make sure that (a) the CCmode we have for the flags is strong
10954 enough for the reversed compare or (b) we have a valid FP compare. */
10955 if (! ix86_comparison_operator (new_op0, VOIDmode))
10959 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10960 ;; pass generates from shift insn with QImode operand. Actually, the mode
10961 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10962 ;; appropriate modulo of the bit offset value.
10964 (define_insn_and_split "*jcc_bt<mode>"
10966 (if_then_else (match_operator 0 "bt_comparison_operator"
10967 [(zero_extract:SWI48
10968 (match_operand:SWI48 1 "register_operand" "r")
10971 (match_operand:QI 2 "register_operand" "r")))
10973 (label_ref (match_operand 3))
10975 (clobber (reg:CC FLAGS_REG))]
10976 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10979 [(set (reg:CCC FLAGS_REG)
10981 (zero_extract:SWI48
10987 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10988 (label_ref (match_dup 3))
10991 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10993 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10996 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10997 ;; also for DImode, this is what combine produces.
10998 (define_insn_and_split "*jcc_bt<mode>_mask"
11000 (if_then_else (match_operator 0 "bt_comparison_operator"
11001 [(zero_extract:SWI48
11002 (match_operand:SWI48 1 "register_operand" "r")
11005 (match_operand:SI 2 "register_operand" "r")
11006 (match_operand:SI 3 "const_int_operand" "n")))])
11007 (label_ref (match_operand 4))
11009 (clobber (reg:CC FLAGS_REG))]
11010 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11011 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11012 == GET_MODE_BITSIZE (<MODE>mode)-1"
11015 [(set (reg:CCC FLAGS_REG)
11017 (zero_extract:SWI48
11023 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11024 (label_ref (match_dup 4))
11027 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11029 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11032 (define_insn_and_split "*jcc_btsi_1"
11034 (if_then_else (match_operator 0 "bt_comparison_operator"
11037 (match_operand:SI 1 "register_operand" "r")
11038 (match_operand:QI 2 "register_operand" "r"))
11041 (label_ref (match_operand 3))
11043 (clobber (reg:CC FLAGS_REG))]
11044 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11047 [(set (reg:CCC FLAGS_REG)
11055 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11056 (label_ref (match_dup 3))
11059 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11061 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11064 ;; avoid useless masking of bit offset operand
11065 (define_insn_and_split "*jcc_btsi_mask_1"
11068 (match_operator 0 "bt_comparison_operator"
11071 (match_operand:SI 1 "register_operand" "r")
11074 (match_operand:SI 2 "register_operand" "r")
11075 (match_operand:SI 3 "const_int_operand" "n")) 0))
11078 (label_ref (match_operand 4))
11080 (clobber (reg:CC FLAGS_REG))]
11081 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11082 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11085 [(set (reg:CCC FLAGS_REG)
11093 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11094 (label_ref (match_dup 4))
11096 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11098 ;; Define combination compare-and-branch fp compare instructions to help
11101 (define_insn "*fp_jcc_1_387"
11103 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11104 [(match_operand 1 "register_operand" "f")
11105 (match_operand 2 "nonimmediate_operand" "fm")])
11106 (label_ref (match_operand 3))
11108 (clobber (reg:CCFP FPSR_REG))
11109 (clobber (reg:CCFP FLAGS_REG))
11110 (clobber (match_scratch:HI 4 "=a"))]
11112 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11113 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11114 && SELECT_CC_MODE (GET_CODE (operands[0]),
11115 operands[1], operands[2]) == CCFPmode
11119 (define_insn "*fp_jcc_1r_387"
11121 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11122 [(match_operand 1 "register_operand" "f")
11123 (match_operand 2 "nonimmediate_operand" "fm")])
11125 (label_ref (match_operand 3))))
11126 (clobber (reg:CCFP FPSR_REG))
11127 (clobber (reg:CCFP FLAGS_REG))
11128 (clobber (match_scratch:HI 4 "=a"))]
11130 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11131 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11132 && SELECT_CC_MODE (GET_CODE (operands[0]),
11133 operands[1], operands[2]) == CCFPmode
11137 (define_insn "*fp_jcc_2_387"
11139 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11140 [(match_operand 1 "register_operand" "f")
11141 (match_operand 2 "register_operand" "f")])
11142 (label_ref (match_operand 3))
11144 (clobber (reg:CCFP FPSR_REG))
11145 (clobber (reg:CCFP FLAGS_REG))
11146 (clobber (match_scratch:HI 4 "=a"))]
11147 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11148 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11152 (define_insn "*fp_jcc_2r_387"
11154 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11155 [(match_operand 1 "register_operand" "f")
11156 (match_operand 2 "register_operand" "f")])
11158 (label_ref (match_operand 3))))
11159 (clobber (reg:CCFP FPSR_REG))
11160 (clobber (reg:CCFP FLAGS_REG))
11161 (clobber (match_scratch:HI 4 "=a"))]
11162 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11163 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11167 (define_insn "*fp_jcc_3_387"
11169 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11170 [(match_operand 1 "register_operand" "f")
11171 (match_operand 2 "const0_operand")])
11172 (label_ref (match_operand 3))
11174 (clobber (reg:CCFP FPSR_REG))
11175 (clobber (reg:CCFP FLAGS_REG))
11176 (clobber (match_scratch:HI 4 "=a"))]
11177 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11178 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11179 && SELECT_CC_MODE (GET_CODE (operands[0]),
11180 operands[1], operands[2]) == CCFPmode
11186 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11187 [(match_operand 1 "register_operand")
11188 (match_operand 2 "nonimmediate_operand")])
11190 (match_operand 4)))
11191 (clobber (reg:CCFP FPSR_REG))
11192 (clobber (reg:CCFP FLAGS_REG))]
11196 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11197 operands[3], operands[4], NULL_RTX, NULL_RTX);
11203 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11204 [(match_operand 1 "register_operand")
11205 (match_operand 2 "general_operand")])
11207 (match_operand 4)))
11208 (clobber (reg:CCFP FPSR_REG))
11209 (clobber (reg:CCFP FLAGS_REG))
11210 (clobber (match_scratch:HI 5 "=a"))]
11214 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11215 operands[3], operands[4], operands[5], NULL_RTX);
11219 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11220 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11221 ;; with a precedence over other operators and is always put in the first
11222 ;; place. Swap condition and operands to match ficom instruction.
11224 (define_insn "*fp_jcc_4_<mode>_387"
11227 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11228 [(match_operator 1 "float_operator"
11229 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11230 (match_operand 3 "register_operand" "f,f")])
11231 (label_ref (match_operand 4))
11233 (clobber (reg:CCFP FPSR_REG))
11234 (clobber (reg:CCFP FLAGS_REG))
11235 (clobber (match_scratch:HI 5 "=a,a"))]
11236 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11237 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11238 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11239 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11246 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11247 [(match_operator 1 "float_operator"
11248 [(match_operand:SWI24 2 "memory_operand")])
11249 (match_operand 3 "register_operand")])
11251 (match_operand 5)))
11252 (clobber (reg:CCFP FPSR_REG))
11253 (clobber (reg:CCFP FLAGS_REG))
11254 (clobber (match_scratch:HI 6 "=a"))]
11258 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11260 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11261 operands[3], operands[7],
11262 operands[4], operands[5], operands[6], NULL_RTX);
11266 ;; %%% Kill this when reload knows how to do it.
11270 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11271 [(match_operator 1 "float_operator"
11272 [(match_operand:SWI24 2 "register_operand")])
11273 (match_operand 3 "register_operand")])
11275 (match_operand 5)))
11276 (clobber (reg:CCFP FPSR_REG))
11277 (clobber (reg:CCFP FLAGS_REG))
11278 (clobber (match_scratch:HI 6 "=a"))]
11282 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11283 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11285 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11286 operands[3], operands[7],
11287 operands[4], operands[5], operands[6], operands[2]);
11291 ;; Unconditional and other jump instructions
11293 (define_insn "jump"
11295 (label_ref (match_operand 0)))]
11298 [(set_attr "type" "ibr")
11299 (set (attr "length")
11300 (if_then_else (and (ge (minus (match_dup 0) (pc))
11302 (lt (minus (match_dup 0) (pc))
11306 (set_attr "modrm" "0")])
11308 (define_expand "indirect_jump"
11309 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11313 operands[0] = convert_memory_address (word_mode, operands[0]);
11316 (define_insn "*indirect_jump"
11317 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11320 [(set_attr "type" "ibr")
11321 (set_attr "length_immediate" "0")])
11323 (define_expand "tablejump"
11324 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11325 (use (label_ref (match_operand 1)))])]
11328 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11329 relative. Convert the relative address to an absolute address. */
11333 enum rtx_code code;
11335 /* We can't use @GOTOFF for text labels on VxWorks;
11336 see gotoff_operand. */
11337 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11341 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11343 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11347 op1 = pic_offset_table_rtx;
11352 op0 = pic_offset_table_rtx;
11356 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11361 operands[0] = convert_memory_address (word_mode, operands[0]);
11364 (define_insn "*tablejump_1"
11365 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11366 (use (label_ref (match_operand 1)))]
11369 [(set_attr "type" "ibr")
11370 (set_attr "length_immediate" "0")])
11372 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11375 [(set (reg FLAGS_REG) (match_operand 0))
11376 (set (match_operand:QI 1 "register_operand")
11377 (match_operator:QI 2 "ix86_comparison_operator"
11378 [(reg FLAGS_REG) (const_int 0)]))
11379 (set (match_operand 3 "q_regs_operand")
11380 (zero_extend (match_dup 1)))]
11381 "(peep2_reg_dead_p (3, operands[1])
11382 || operands_match_p (operands[1], operands[3]))
11383 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11384 [(set (match_dup 4) (match_dup 0))
11385 (set (strict_low_part (match_dup 5))
11388 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11389 operands[5] = gen_lowpart (QImode, operands[3]);
11390 ix86_expand_clear (operands[3]);
11394 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11395 (match_operand 4)])
11396 (set (match_operand:QI 1 "register_operand")
11397 (match_operator:QI 2 "ix86_comparison_operator"
11398 [(reg FLAGS_REG) (const_int 0)]))
11399 (set (match_operand 3 "q_regs_operand")
11400 (zero_extend (match_dup 1)))]
11401 "(peep2_reg_dead_p (3, operands[1])
11402 || operands_match_p (operands[1], operands[3]))
11403 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11404 [(parallel [(set (match_dup 5) (match_dup 0))
11406 (set (strict_low_part (match_dup 6))
11409 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11410 operands[6] = gen_lowpart (QImode, operands[3]);
11411 ix86_expand_clear (operands[3]);
11414 ;; Similar, but match zero extend with andsi3.
11417 [(set (reg FLAGS_REG) (match_operand 0))
11418 (set (match_operand:QI 1 "register_operand")
11419 (match_operator:QI 2 "ix86_comparison_operator"
11420 [(reg FLAGS_REG) (const_int 0)]))
11421 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11422 (and:SI (match_dup 3) (const_int 255)))
11423 (clobber (reg:CC FLAGS_REG))])]
11424 "REGNO (operands[1]) == REGNO (operands[3])
11425 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11426 [(set (match_dup 4) (match_dup 0))
11427 (set (strict_low_part (match_dup 5))
11430 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11431 operands[5] = gen_lowpart (QImode, operands[3]);
11432 ix86_expand_clear (operands[3]);
11436 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11437 (match_operand 4)])
11438 (set (match_operand:QI 1 "register_operand")
11439 (match_operator:QI 2 "ix86_comparison_operator"
11440 [(reg FLAGS_REG) (const_int 0)]))
11441 (parallel [(set (match_operand 3 "q_regs_operand")
11442 (zero_extend (match_dup 1)))
11443 (clobber (reg:CC FLAGS_REG))])]
11444 "(peep2_reg_dead_p (3, operands[1])
11445 || operands_match_p (operands[1], operands[3]))
11446 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11447 [(parallel [(set (match_dup 5) (match_dup 0))
11449 (set (strict_low_part (match_dup 6))
11452 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11453 operands[6] = gen_lowpart (QImode, operands[3]);
11454 ix86_expand_clear (operands[3]);
11457 ;; Call instructions.
11459 ;; The predicates normally associated with named expanders are not properly
11460 ;; checked for calls. This is a bug in the generic code, but it isn't that
11461 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11463 ;; P6 processors will jump to the address after the decrement when %esp
11464 ;; is used as a call operand, so they will execute return address as a code.
11465 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11467 ;; Register constraint for call instruction.
11468 (define_mode_attr c [(SI "l") (DI "r")])
11470 ;; Call subroutine returning no value.
11472 (define_expand "call"
11473 [(call (match_operand:QI 0)
11475 (use (match_operand 2))]
11478 ix86_expand_call (NULL, operands[0], operands[1],
11479 operands[2], NULL, false);
11483 (define_expand "sibcall"
11484 [(call (match_operand:QI 0)
11486 (use (match_operand 2))]
11489 ix86_expand_call (NULL, operands[0], operands[1],
11490 operands[2], NULL, true);
11494 (define_insn_and_split "*call_vzeroupper"
11495 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11497 (unspec [(match_operand 2 "const_int_operand")]
11498 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11499 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11501 "&& reload_completed"
11503 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11504 [(set_attr "type" "call")])
11506 (define_insn "*call"
11507 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11508 (match_operand 1))]
11509 "!SIBLING_CALL_P (insn)"
11510 "* return ix86_output_call_insn (insn, operands[0]);"
11511 [(set_attr "type" "call")])
11513 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11514 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11516 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11517 (clobber (reg:TI XMM6_REG))
11518 (clobber (reg:TI XMM7_REG))
11519 (clobber (reg:TI XMM8_REG))
11520 (clobber (reg:TI XMM9_REG))
11521 (clobber (reg:TI XMM10_REG))
11522 (clobber (reg:TI XMM11_REG))
11523 (clobber (reg:TI XMM12_REG))
11524 (clobber (reg:TI XMM13_REG))
11525 (clobber (reg:TI XMM14_REG))
11526 (clobber (reg:TI XMM15_REG))
11527 (clobber (reg:DI SI_REG))
11528 (clobber (reg:DI DI_REG))
11529 (unspec [(match_operand 2 "const_int_operand")]
11530 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11531 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11533 "&& reload_completed"
11535 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11536 [(set_attr "type" "call")])
11538 (define_insn "*call_rex64_ms_sysv"
11539 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11541 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11542 (clobber (reg:TI XMM6_REG))
11543 (clobber (reg:TI XMM7_REG))
11544 (clobber (reg:TI XMM8_REG))
11545 (clobber (reg:TI XMM9_REG))
11546 (clobber (reg:TI XMM10_REG))
11547 (clobber (reg:TI XMM11_REG))
11548 (clobber (reg:TI XMM12_REG))
11549 (clobber (reg:TI XMM13_REG))
11550 (clobber (reg:TI XMM14_REG))
11551 (clobber (reg:TI XMM15_REG))
11552 (clobber (reg:DI SI_REG))
11553 (clobber (reg:DI DI_REG))]
11554 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11555 "* return ix86_output_call_insn (insn, operands[0]);"
11556 [(set_attr "type" "call")])
11558 (define_insn_and_split "*sibcall_vzeroupper"
11559 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11561 (unspec [(match_operand 2 "const_int_operand")]
11562 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11563 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11565 "&& reload_completed"
11567 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11568 [(set_attr "type" "call")])
11570 (define_insn "*sibcall"
11571 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11572 (match_operand 1))]
11573 "SIBLING_CALL_P (insn)"
11574 "* return ix86_output_call_insn (insn, operands[0]);"
11575 [(set_attr "type" "call")])
11577 (define_expand "call_pop"
11578 [(parallel [(call (match_operand:QI 0)
11579 (match_operand:SI 1))
11580 (set (reg:SI SP_REG)
11581 (plus:SI (reg:SI SP_REG)
11582 (match_operand:SI 3)))])]
11585 ix86_expand_call (NULL, operands[0], operands[1],
11586 operands[2], operands[3], false);
11590 (define_insn_and_split "*call_pop_vzeroupper"
11591 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11593 (set (reg:SI SP_REG)
11594 (plus:SI (reg:SI SP_REG)
11595 (match_operand:SI 2 "immediate_operand" "i")))
11596 (unspec [(match_operand 3 "const_int_operand")]
11597 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11598 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11600 "&& reload_completed"
11602 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11603 [(set_attr "type" "call")])
11605 (define_insn "*call_pop"
11606 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11608 (set (reg:SI SP_REG)
11609 (plus:SI (reg:SI SP_REG)
11610 (match_operand:SI 2 "immediate_operand" "i")))]
11611 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11612 "* return ix86_output_call_insn (insn, operands[0]);"
11613 [(set_attr "type" "call")])
11615 (define_insn_and_split "*sibcall_pop_vzeroupper"
11616 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11618 (set (reg:SI SP_REG)
11619 (plus:SI (reg:SI SP_REG)
11620 (match_operand:SI 2 "immediate_operand" "i")))
11621 (unspec [(match_operand 3 "const_int_operand")]
11622 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11623 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11625 "&& reload_completed"
11627 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11628 [(set_attr "type" "call")])
11630 (define_insn "*sibcall_pop"
11631 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11633 (set (reg:SI SP_REG)
11634 (plus:SI (reg:SI SP_REG)
11635 (match_operand:SI 2 "immediate_operand" "i")))]
11636 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11637 "* return ix86_output_call_insn (insn, operands[0]);"
11638 [(set_attr "type" "call")])
11640 ;; Call subroutine, returning value in operand 0
11642 (define_expand "call_value"
11643 [(set (match_operand 0)
11644 (call (match_operand:QI 1)
11645 (match_operand 2)))
11646 (use (match_operand 3))]
11649 ix86_expand_call (operands[0], operands[1], operands[2],
11650 operands[3], NULL, false);
11654 (define_expand "sibcall_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, true);
11666 (define_insn_and_split "*call_value_vzeroupper"
11667 [(set (match_operand 0)
11668 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11669 (match_operand 2)))
11670 (unspec [(match_operand 3 "const_int_operand")]
11671 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11672 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11674 "&& reload_completed"
11676 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11677 [(set_attr "type" "callv")])
11679 (define_insn "*call_value"
11680 [(set (match_operand 0)
11681 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11682 (match_operand 2)))]
11683 "!SIBLING_CALL_P (insn)"
11684 "* return ix86_output_call_insn (insn, operands[1]);"
11685 [(set_attr "type" "callv")])
11687 (define_insn_and_split "*sibcall_value_vzeroupper"
11688 [(set (match_operand 0)
11689 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11690 (match_operand 2)))
11691 (unspec [(match_operand 3 "const_int_operand")]
11692 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11693 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11695 "&& reload_completed"
11697 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11698 [(set_attr "type" "callv")])
11700 (define_insn "*sibcall_value"
11701 [(set (match_operand 0)
11702 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11703 (match_operand 2)))]
11704 "SIBLING_CALL_P (insn)"
11705 "* return ix86_output_call_insn (insn, operands[1]);"
11706 [(set_attr "type" "callv")])
11708 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11709 [(set (match_operand 0)
11710 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11711 (match_operand 2)))
11712 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11713 (clobber (reg:TI XMM6_REG))
11714 (clobber (reg:TI XMM7_REG))
11715 (clobber (reg:TI XMM8_REG))
11716 (clobber (reg:TI XMM9_REG))
11717 (clobber (reg:TI XMM10_REG))
11718 (clobber (reg:TI XMM11_REG))
11719 (clobber (reg:TI XMM12_REG))
11720 (clobber (reg:TI XMM13_REG))
11721 (clobber (reg:TI XMM14_REG))
11722 (clobber (reg:TI XMM15_REG))
11723 (clobber (reg:DI SI_REG))
11724 (clobber (reg:DI DI_REG))
11725 (unspec [(match_operand 3 "const_int_operand")]
11726 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11727 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11729 "&& reload_completed"
11731 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11732 [(set_attr "type" "callv")])
11734 (define_insn "*call_value_rex64_ms_sysv"
11735 [(set (match_operand 0)
11736 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11737 (match_operand 2)))
11738 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11739 (clobber (reg:TI XMM6_REG))
11740 (clobber (reg:TI XMM7_REG))
11741 (clobber (reg:TI XMM8_REG))
11742 (clobber (reg:TI XMM9_REG))
11743 (clobber (reg:TI XMM10_REG))
11744 (clobber (reg:TI XMM11_REG))
11745 (clobber (reg:TI XMM12_REG))
11746 (clobber (reg:TI XMM13_REG))
11747 (clobber (reg:TI XMM14_REG))
11748 (clobber (reg:TI XMM15_REG))
11749 (clobber (reg:DI SI_REG))
11750 (clobber (reg:DI DI_REG))]
11751 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11752 "* return ix86_output_call_insn (insn, operands[1]);"
11753 [(set_attr "type" "callv")])
11755 (define_expand "call_value_pop"
11756 [(parallel [(set (match_operand 0)
11757 (call (match_operand:QI 1)
11758 (match_operand:SI 2)))
11759 (set (reg:SI SP_REG)
11760 (plus:SI (reg:SI SP_REG)
11761 (match_operand:SI 4)))])]
11764 ix86_expand_call (operands[0], operands[1], operands[2],
11765 operands[3], operands[4], false);
11769 (define_insn_and_split "*call_value_pop_vzeroupper"
11770 [(set (match_operand 0)
11771 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11772 (match_operand 2)))
11773 (set (reg:SI SP_REG)
11774 (plus:SI (reg:SI SP_REG)
11775 (match_operand:SI 3 "immediate_operand" "i")))
11776 (unspec [(match_operand 4 "const_int_operand")]
11777 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11778 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11780 "&& reload_completed"
11782 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11783 [(set_attr "type" "callv")])
11785 (define_insn "*call_value_pop"
11786 [(set (match_operand 0)
11787 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11788 (match_operand 2)))
11789 (set (reg:SI SP_REG)
11790 (plus:SI (reg:SI SP_REG)
11791 (match_operand:SI 3 "immediate_operand" "i")))]
11792 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11793 "* return ix86_output_call_insn (insn, operands[1]);"
11794 [(set_attr "type" "callv")])
11796 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11797 [(set (match_operand 0)
11798 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11799 (match_operand 2)))
11800 (set (reg:SI SP_REG)
11801 (plus:SI (reg:SI SP_REG)
11802 (match_operand:SI 3 "immediate_operand" "i")))
11803 (unspec [(match_operand 4 "const_int_operand")]
11804 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11805 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11807 "&& reload_completed"
11809 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11810 [(set_attr "type" "callv")])
11812 (define_insn "*sibcall_value_pop"
11813 [(set (match_operand 0)
11814 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11815 (match_operand 2)))
11816 (set (reg:SI SP_REG)
11817 (plus:SI (reg:SI SP_REG)
11818 (match_operand:SI 3 "immediate_operand" "i")))]
11819 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11820 "* return ix86_output_call_insn (insn, operands[1]);"
11821 [(set_attr "type" "callv")])
11823 ;; Call subroutine returning any type.
11825 (define_expand "untyped_call"
11826 [(parallel [(call (match_operand 0)
11829 (match_operand 2)])]
11834 /* In order to give reg-stack an easier job in validating two
11835 coprocessor registers as containing a possible return value,
11836 simply pretend the untyped call returns a complex long double
11839 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11840 and should have the default ABI. */
11842 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11843 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11844 operands[0], const0_rtx,
11845 GEN_INT ((TARGET_64BIT
11846 ? (ix86_abi == SYSV_ABI
11847 ? X86_64_SSE_REGPARM_MAX
11848 : X86_64_MS_SSE_REGPARM_MAX)
11849 : X86_32_SSE_REGPARM_MAX)
11853 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11855 rtx set = XVECEXP (operands[2], 0, i);
11856 emit_move_insn (SET_DEST (set), SET_SRC (set));
11859 /* The optimizer does not know that the call sets the function value
11860 registers we stored in the result block. We avoid problems by
11861 claiming that all hard registers are used and clobbered at this
11863 emit_insn (gen_blockage ());
11868 ;; Prologue and epilogue instructions
11870 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11871 ;; all of memory. This blocks insns from being moved across this point.
11873 (define_insn "blockage"
11874 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11877 [(set_attr "length" "0")])
11879 ;; Do not schedule instructions accessing memory across this point.
11881 (define_expand "memory_blockage"
11882 [(set (match_dup 0)
11883 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11886 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11887 MEM_VOLATILE_P (operands[0]) = 1;
11890 (define_insn "*memory_blockage"
11891 [(set (match_operand:BLK 0)
11892 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11895 [(set_attr "length" "0")])
11897 ;; As USE insns aren't meaningful after reload, this is used instead
11898 ;; to prevent deleting instructions setting registers for PIC code
11899 (define_insn "prologue_use"
11900 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11903 [(set_attr "length" "0")])
11905 ;; Insn emitted into the body of a function to return from a function.
11906 ;; This is only done if the function's epilogue is known to be simple.
11907 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11909 (define_expand "return"
11911 "ix86_can_use_return_insn_p ()"
11913 ix86_maybe_emit_epilogue_vzeroupper ();
11914 if (crtl->args.pops_args)
11916 rtx popc = GEN_INT (crtl->args.pops_args);
11917 emit_jump_insn (gen_simple_return_pop_internal (popc));
11922 ;; We need to disable this for TARGET_SEH, as otherwise
11923 ;; shrink-wrapped prologue gets enabled too. This might exceed
11924 ;; the maximum size of prologue in unwind information.
11926 (define_expand "simple_return"
11930 ix86_maybe_emit_epilogue_vzeroupper ();
11931 if (crtl->args.pops_args)
11933 rtx popc = GEN_INT (crtl->args.pops_args);
11934 emit_jump_insn (gen_simple_return_pop_internal (popc));
11939 (define_insn "simple_return_internal"
11943 [(set_attr "length" "1")
11944 (set_attr "atom_unit" "jeu")
11945 (set_attr "length_immediate" "0")
11946 (set_attr "modrm" "0")])
11948 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11949 ;; instruction Athlon and K8 have.
11951 (define_insn "simple_return_internal_long"
11953 (unspec [(const_int 0)] UNSPEC_REP)]
11956 [(set_attr "length" "2")
11957 (set_attr "atom_unit" "jeu")
11958 (set_attr "length_immediate" "0")
11959 (set_attr "prefix_rep" "1")
11960 (set_attr "modrm" "0")])
11962 (define_insn "simple_return_pop_internal"
11964 (use (match_operand:SI 0 "const_int_operand"))]
11967 [(set_attr "length" "3")
11968 (set_attr "atom_unit" "jeu")
11969 (set_attr "length_immediate" "2")
11970 (set_attr "modrm" "0")])
11972 (define_insn "simple_return_indirect_internal"
11974 (use (match_operand:SI 0 "register_operand" "r"))]
11977 [(set_attr "type" "ibr")
11978 (set_attr "length_immediate" "0")])
11984 [(set_attr "length" "1")
11985 (set_attr "length_immediate" "0")
11986 (set_attr "modrm" "0")])
11988 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11989 (define_insn "nops"
11990 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11994 int num = INTVAL (operands[0]);
11996 gcc_assert (IN_RANGE (num, 1, 8));
11999 fputs ("\tnop\n", asm_out_file);
12003 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12004 (set_attr "length_immediate" "0")
12005 (set_attr "modrm" "0")])
12007 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12008 ;; branch prediction penalty for the third jump in a 16-byte
12012 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12015 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12016 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12018 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12019 The align insn is used to avoid 3 jump instructions in the row to improve
12020 branch prediction and the benefits hardly outweigh the cost of extra 8
12021 nops on the average inserted by full alignment pseudo operation. */
12025 [(set_attr "length" "16")])
12027 (define_expand "prologue"
12030 "ix86_expand_prologue (); DONE;")
12032 (define_insn "set_got"
12033 [(set (match_operand:SI 0 "register_operand" "=r")
12034 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12035 (clobber (reg:CC FLAGS_REG))]
12037 "* return output_set_got (operands[0], NULL_RTX);"
12038 [(set_attr "type" "multi")
12039 (set_attr "length" "12")])
12041 (define_insn "set_got_labelled"
12042 [(set (match_operand:SI 0 "register_operand" "=r")
12043 (unspec:SI [(label_ref (match_operand 1))]
12045 (clobber (reg:CC FLAGS_REG))]
12047 "* return output_set_got (operands[0], operands[1]);"
12048 [(set_attr "type" "multi")
12049 (set_attr "length" "12")])
12051 (define_insn "set_got_rex64"
12052 [(set (match_operand:DI 0 "register_operand" "=r")
12053 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12055 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12056 [(set_attr "type" "lea")
12057 (set_attr "length_address" "4")
12058 (set_attr "mode" "DI")])
12060 (define_insn "set_rip_rex64"
12061 [(set (match_operand:DI 0 "register_operand" "=r")
12062 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12064 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12065 [(set_attr "type" "lea")
12066 (set_attr "length_address" "4")
12067 (set_attr "mode" "DI")])
12069 (define_insn "set_got_offset_rex64"
12070 [(set (match_operand:DI 0 "register_operand" "=r")
12072 [(label_ref (match_operand 1))]
12073 UNSPEC_SET_GOT_OFFSET))]
12075 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12076 [(set_attr "type" "imov")
12077 (set_attr "length_immediate" "0")
12078 (set_attr "length_address" "8")
12079 (set_attr "mode" "DI")])
12081 (define_expand "epilogue"
12084 "ix86_expand_epilogue (1); DONE;")
12086 (define_expand "sibcall_epilogue"
12089 "ix86_expand_epilogue (0); DONE;")
12091 (define_expand "eh_return"
12092 [(use (match_operand 0 "register_operand"))]
12095 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12097 /* Tricky bit: we write the address of the handler to which we will
12098 be returning into someone else's stack frame, one word below the
12099 stack address we wish to restore. */
12100 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12101 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12102 tmp = gen_rtx_MEM (Pmode, tmp);
12103 emit_move_insn (tmp, ra);
12105 emit_jump_insn (gen_eh_return_internal ());
12110 (define_insn_and_split "eh_return_internal"
12114 "epilogue_completed"
12116 "ix86_expand_epilogue (2); DONE;")
12118 (define_insn "leave"
12119 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12120 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12121 (clobber (mem:BLK (scratch)))]
12124 [(set_attr "type" "leave")])
12126 (define_insn "leave_rex64"
12127 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12128 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12129 (clobber (mem:BLK (scratch)))]
12132 [(set_attr "type" "leave")])
12134 ;; Handle -fsplit-stack.
12136 (define_expand "split_stack_prologue"
12140 ix86_expand_split_stack_prologue ();
12144 ;; In order to support the call/return predictor, we use a return
12145 ;; instruction which the middle-end doesn't see.
12146 (define_insn "split_stack_return"
12147 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12148 UNSPECV_SPLIT_STACK_RETURN)]
12151 if (operands[0] == const0_rtx)
12156 [(set_attr "atom_unit" "jeu")
12157 (set_attr "modrm" "0")
12158 (set (attr "length")
12159 (if_then_else (match_operand:SI 0 "const0_operand")
12162 (set (attr "length_immediate")
12163 (if_then_else (match_operand:SI 0 "const0_operand")
12167 ;; If there are operand 0 bytes available on the stack, jump to
12170 (define_expand "split_stack_space_check"
12171 [(set (pc) (if_then_else
12172 (ltu (minus (reg SP_REG)
12173 (match_operand 0 "register_operand"))
12174 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12175 (label_ref (match_operand 1))
12179 rtx reg, size, limit;
12181 reg = gen_reg_rtx (Pmode);
12182 size = force_reg (Pmode, operands[0]);
12183 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12184 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12185 UNSPEC_STACK_CHECK);
12186 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12187 ix86_expand_branch (GEU, reg, limit, operands[1]);
12192 ;; Bit manipulation instructions.
12194 (define_expand "ffs<mode>2"
12195 [(set (match_dup 2) (const_int -1))
12196 (parallel [(set (match_dup 3) (match_dup 4))
12197 (set (match_operand:SWI48 0 "register_operand")
12199 (match_operand:SWI48 1 "nonimmediate_operand")))])
12200 (set (match_dup 0) (if_then_else:SWI48
12201 (eq (match_dup 3) (const_int 0))
12204 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12205 (clobber (reg:CC FLAGS_REG))])]
12208 enum machine_mode flags_mode;
12210 if (<MODE>mode == SImode && !TARGET_CMOVE)
12212 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12216 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12218 operands[2] = gen_reg_rtx (<MODE>mode);
12219 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12220 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12223 (define_insn_and_split "ffssi2_no_cmove"
12224 [(set (match_operand:SI 0 "register_operand" "=r")
12225 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12226 (clobber (match_scratch:SI 2 "=&q"))
12227 (clobber (reg:CC FLAGS_REG))]
12230 "&& reload_completed"
12231 [(parallel [(set (match_dup 4) (match_dup 5))
12232 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12233 (set (strict_low_part (match_dup 3))
12234 (eq:QI (match_dup 4) (const_int 0)))
12235 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12236 (clobber (reg:CC FLAGS_REG))])
12237 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12238 (clobber (reg:CC FLAGS_REG))])
12239 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12240 (clobber (reg:CC FLAGS_REG))])]
12242 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12244 operands[3] = gen_lowpart (QImode, operands[2]);
12245 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12246 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12248 ix86_expand_clear (operands[2]);
12251 (define_insn "*tzcnt<mode>_1"
12252 [(set (reg:CCC FLAGS_REG)
12253 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12255 (set (match_operand:SWI48 0 "register_operand" "=r")
12256 (ctz:SWI48 (match_dup 1)))]
12258 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12259 [(set_attr "type" "alu1")
12260 (set_attr "prefix_0f" "1")
12261 (set_attr "prefix_rep" "1")
12262 (set_attr "mode" "<MODE>")])
12264 (define_insn "*bsf<mode>_1"
12265 [(set (reg:CCZ FLAGS_REG)
12266 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12268 (set (match_operand:SWI48 0 "register_operand" "=r")
12269 (ctz:SWI48 (match_dup 1)))]
12271 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12272 [(set_attr "type" "alu1")
12273 (set_attr "prefix_0f" "1")
12274 (set_attr "mode" "<MODE>")])
12276 (define_insn "ctz<mode>2"
12277 [(set (match_operand:SWI248 0 "register_operand" "=r")
12278 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12279 (clobber (reg:CC FLAGS_REG))]
12283 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12284 else if (optimize_function_for_size_p (cfun))
12286 else if (TARGET_GENERIC)
12287 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12288 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12290 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12292 [(set_attr "type" "alu1")
12293 (set_attr "prefix_0f" "1")
12294 (set (attr "prefix_rep")
12296 (ior (match_test "TARGET_BMI")
12297 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12298 (match_test "TARGET_GENERIC")))
12300 (const_string "0")))
12301 (set_attr "mode" "<MODE>")])
12303 (define_expand "clz<mode>2"
12305 [(set (match_operand:SWI248 0 "register_operand")
12308 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12309 (clobber (reg:CC FLAGS_REG))])
12311 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12312 (clobber (reg:CC FLAGS_REG))])]
12317 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12320 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12323 (define_insn "clz<mode>2_lzcnt"
12324 [(set (match_operand:SWI248 0 "register_operand" "=r")
12325 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12326 (clobber (reg:CC FLAGS_REG))]
12328 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12329 [(set_attr "prefix_rep" "1")
12330 (set_attr "type" "bitmanip")
12331 (set_attr "mode" "<MODE>")])
12333 ;; BMI instructions.
12334 (define_insn "*bmi_andn_<mode>"
12335 [(set (match_operand:SWI48 0 "register_operand" "=r")
12338 (match_operand:SWI48 1 "register_operand" "r"))
12339 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12340 (clobber (reg:CC FLAGS_REG))]
12342 "andn\t{%2, %1, %0|%0, %1, %2}"
12343 [(set_attr "type" "bitmanip")
12344 (set_attr "mode" "<MODE>")])
12346 (define_insn "bmi_bextr_<mode>"
12347 [(set (match_operand:SWI48 0 "register_operand" "=r")
12348 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12349 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12351 (clobber (reg:CC FLAGS_REG))]
12353 "bextr\t{%2, %1, %0|%0, %1, %2}"
12354 [(set_attr "type" "bitmanip")
12355 (set_attr "mode" "<MODE>")])
12357 (define_insn "*bmi_blsi_<mode>"
12358 [(set (match_operand:SWI48 0 "register_operand" "=r")
12361 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12363 (clobber (reg:CC FLAGS_REG))]
12365 "blsi\t{%1, %0|%0, %1}"
12366 [(set_attr "type" "bitmanip")
12367 (set_attr "mode" "<MODE>")])
12369 (define_insn "*bmi_blsmsk_<mode>"
12370 [(set (match_operand:SWI48 0 "register_operand" "=r")
12373 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12376 (clobber (reg:CC FLAGS_REG))]
12378 "blsmsk\t{%1, %0|%0, %1}"
12379 [(set_attr "type" "bitmanip")
12380 (set_attr "mode" "<MODE>")])
12382 (define_insn "*bmi_blsr_<mode>"
12383 [(set (match_operand:SWI48 0 "register_operand" "=r")
12386 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12389 (clobber (reg:CC FLAGS_REG))]
12391 "blsr\t{%1, %0|%0, %1}"
12392 [(set_attr "type" "bitmanip")
12393 (set_attr "mode" "<MODE>")])
12395 ;; BMI2 instructions.
12396 (define_insn "bmi2_bzhi_<mode>3"
12397 [(set (match_operand:SWI48 0 "register_operand" "=r")
12398 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12399 (lshiftrt:SWI48 (const_int -1)
12400 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12401 (clobber (reg:CC FLAGS_REG))]
12403 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12404 [(set_attr "type" "bitmanip")
12405 (set_attr "prefix" "vex")
12406 (set_attr "mode" "<MODE>")])
12408 (define_insn "bmi2_pdep_<mode>3"
12409 [(set (match_operand:SWI48 0 "register_operand" "=r")
12410 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12411 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12414 "pdep\t{%2, %1, %0|%0, %1, %2}"
12415 [(set_attr "type" "bitmanip")
12416 (set_attr "prefix" "vex")
12417 (set_attr "mode" "<MODE>")])
12419 (define_insn "bmi2_pext_<mode>3"
12420 [(set (match_operand:SWI48 0 "register_operand" "=r")
12421 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12422 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12425 "pext\t{%2, %1, %0|%0, %1, %2}"
12426 [(set_attr "type" "bitmanip")
12427 (set_attr "prefix" "vex")
12428 (set_attr "mode" "<MODE>")])
12430 ;; TBM instructions.
12431 (define_insn "tbm_bextri_<mode>"
12432 [(set (match_operand:SWI48 0 "register_operand" "=r")
12433 (zero_extract:SWI48
12434 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12435 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12436 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12437 (clobber (reg:CC FLAGS_REG))]
12440 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12441 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12443 [(set_attr "type" "bitmanip")
12444 (set_attr "mode" "<MODE>")])
12446 (define_insn "*tbm_blcfill_<mode>"
12447 [(set (match_operand:SWI48 0 "register_operand" "=r")
12450 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12453 (clobber (reg:CC FLAGS_REG))]
12455 "blcfill\t{%1, %0|%0, %1}"
12456 [(set_attr "type" "bitmanip")
12457 (set_attr "mode" "<MODE>")])
12459 (define_insn "*tbm_blci_<mode>"
12460 [(set (match_operand:SWI48 0 "register_operand" "=r")
12464 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12467 (clobber (reg:CC FLAGS_REG))]
12469 "blci\t{%1, %0|%0, %1}"
12470 [(set_attr "type" "bitmanip")
12471 (set_attr "mode" "<MODE>")])
12473 (define_insn "*tbm_blcic_<mode>"
12474 [(set (match_operand:SWI48 0 "register_operand" "=r")
12477 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12481 (clobber (reg:CC FLAGS_REG))]
12483 "blcic\t{%1, %0|%0, %1}"
12484 [(set_attr "type" "bitmanip")
12485 (set_attr "mode" "<MODE>")])
12487 (define_insn "*tbm_blcmsk_<mode>"
12488 [(set (match_operand:SWI48 0 "register_operand" "=r")
12491 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12494 (clobber (reg:CC FLAGS_REG))]
12496 "blcmsk\t{%1, %0|%0, %1}"
12497 [(set_attr "type" "bitmanip")
12498 (set_attr "mode" "<MODE>")])
12500 (define_insn "*tbm_blcs_<mode>"
12501 [(set (match_operand:SWI48 0 "register_operand" "=r")
12504 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12507 (clobber (reg:CC FLAGS_REG))]
12509 "blcs\t{%1, %0|%0, %1}"
12510 [(set_attr "type" "bitmanip")
12511 (set_attr "mode" "<MODE>")])
12513 (define_insn "*tbm_blsfill_<mode>"
12514 [(set (match_operand:SWI48 0 "register_operand" "=r")
12517 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12520 (clobber (reg:CC FLAGS_REG))]
12522 "blsfill\t{%1, %0|%0, %1}"
12523 [(set_attr "type" "bitmanip")
12524 (set_attr "mode" "<MODE>")])
12526 (define_insn "*tbm_blsic_<mode>"
12527 [(set (match_operand:SWI48 0 "register_operand" "=r")
12530 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12534 (clobber (reg:CC FLAGS_REG))]
12536 "blsic\t{%1, %0|%0, %1}"
12537 [(set_attr "type" "bitmanip")
12538 (set_attr "mode" "<MODE>")])
12540 (define_insn "*tbm_t1mskc_<mode>"
12541 [(set (match_operand:SWI48 0 "register_operand" "=r")
12544 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12548 (clobber (reg:CC FLAGS_REG))]
12550 "t1mskc\t{%1, %0|%0, %1}"
12551 [(set_attr "type" "bitmanip")
12552 (set_attr "mode" "<MODE>")])
12554 (define_insn "*tbm_tzmsk_<mode>"
12555 [(set (match_operand:SWI48 0 "register_operand" "=r")
12558 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12562 (clobber (reg:CC FLAGS_REG))]
12564 "tzmsk\t{%1, %0|%0, %1}"
12565 [(set_attr "type" "bitmanip")
12566 (set_attr "mode" "<MODE>")])
12568 (define_insn "bsr_rex64"
12569 [(set (match_operand:DI 0 "register_operand" "=r")
12570 (minus:DI (const_int 63)
12571 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12572 (clobber (reg:CC FLAGS_REG))]
12574 "bsr{q}\t{%1, %0|%0, %1}"
12575 [(set_attr "type" "alu1")
12576 (set_attr "prefix_0f" "1")
12577 (set_attr "mode" "DI")])
12580 [(set (match_operand:SI 0 "register_operand" "=r")
12581 (minus:SI (const_int 31)
12582 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12583 (clobber (reg:CC FLAGS_REG))]
12585 "bsr{l}\t{%1, %0|%0, %1}"
12586 [(set_attr "type" "alu1")
12587 (set_attr "prefix_0f" "1")
12588 (set_attr "mode" "SI")])
12590 (define_insn "*bsrhi"
12591 [(set (match_operand:HI 0 "register_operand" "=r")
12592 (minus:HI (const_int 15)
12593 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12594 (clobber (reg:CC FLAGS_REG))]
12596 "bsr{w}\t{%1, %0|%0, %1}"
12597 [(set_attr "type" "alu1")
12598 (set_attr "prefix_0f" "1")
12599 (set_attr "mode" "HI")])
12601 (define_insn "popcount<mode>2"
12602 [(set (match_operand:SWI248 0 "register_operand" "=r")
12604 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12605 (clobber (reg:CC FLAGS_REG))]
12609 return "popcnt\t{%1, %0|%0, %1}";
12611 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12614 [(set_attr "prefix_rep" "1")
12615 (set_attr "type" "bitmanip")
12616 (set_attr "mode" "<MODE>")])
12618 (define_insn "*popcount<mode>2_cmp"
12619 [(set (reg FLAGS_REG)
12622 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12624 (set (match_operand:SWI248 0 "register_operand" "=r")
12625 (popcount:SWI248 (match_dup 1)))]
12626 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12629 return "popcnt\t{%1, %0|%0, %1}";
12631 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12634 [(set_attr "prefix_rep" "1")
12635 (set_attr "type" "bitmanip")
12636 (set_attr "mode" "<MODE>")])
12638 (define_insn "*popcountsi2_cmp_zext"
12639 [(set (reg FLAGS_REG)
12641 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12643 (set (match_operand:DI 0 "register_operand" "=r")
12644 (zero_extend:DI(popcount:SI (match_dup 1))))]
12645 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12648 return "popcnt\t{%1, %0|%0, %1}";
12650 return "popcnt{l}\t{%1, %0|%0, %1}";
12653 [(set_attr "prefix_rep" "1")
12654 (set_attr "type" "bitmanip")
12655 (set_attr "mode" "SI")])
12657 (define_expand "bswapdi2"
12658 [(set (match_operand:DI 0 "register_operand")
12659 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12662 if (TARGET_64BIT && !TARGET_MOVBE)
12663 operands[1] = force_reg (DImode, operands[1]);
12666 (define_insn_and_split "*bswapdi2_doubleword"
12667 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12669 (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12671 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12673 "&& reload_completed"
12674 [(set (match_dup 2)
12675 (bswap:SI (match_dup 1)))
12677 (bswap:SI (match_dup 3)))]
12679 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
12681 if (REG_P (operands[0]) && REG_P (operands[1]))
12683 emit_insn (gen_swapsi (operands[0], operands[2]));
12684 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12685 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12691 if (MEM_P (operands[0]))
12693 emit_insn (gen_bswapsi2 (operands[3], operands[3]));
12694 emit_insn (gen_bswapsi2 (operands[1], operands[1]));
12696 emit_move_insn (operands[0], operands[3]);
12697 emit_move_insn (operands[2], operands[1]);
12699 if (MEM_P (operands[1]))
12701 emit_move_insn (operands[2], operands[1]);
12702 emit_move_insn (operands[0], operands[3]);
12704 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12705 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12711 (define_expand "bswapsi2"
12712 [(set (match_operand:SI 0 "register_operand")
12713 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12718 else if (TARGET_BSWAP)
12719 operands[1] = force_reg (SImode, operands[1]);
12722 rtx x = operands[0];
12724 emit_move_insn (x, operands[1]);
12725 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12726 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12727 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12732 (define_insn "*bswap<mode>2_movbe"
12733 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12734 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12736 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12739 movbe\t{%1, %0|%0, %1}
12740 movbe\t{%1, %0|%0, %1}"
12741 [(set_attr "type" "bitmanip,imov,imov")
12742 (set_attr "modrm" "0,1,1")
12743 (set_attr "prefix_0f" "*,1,1")
12744 (set_attr "prefix_extra" "*,1,1")
12745 (set_attr "mode" "<MODE>")])
12747 (define_insn "*bswap<mode>2"
12748 [(set (match_operand:SWI48 0 "register_operand" "=r")
12749 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12752 [(set_attr "type" "bitmanip")
12753 (set_attr "modrm" "0")
12754 (set_attr "mode" "<MODE>")])
12756 (define_insn "*bswaphi_lowpart_1"
12757 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12758 (bswap:HI (match_dup 0)))
12759 (clobber (reg:CC FLAGS_REG))]
12760 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12762 xchg{b}\t{%h0, %b0|%b0, %h0}
12763 rol{w}\t{$8, %0|%0, 8}"
12764 [(set_attr "length" "2,4")
12765 (set_attr "mode" "QI,HI")])
12767 (define_insn "bswaphi_lowpart"
12768 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12769 (bswap:HI (match_dup 0)))
12770 (clobber (reg:CC FLAGS_REG))]
12772 "rol{w}\t{$8, %0|%0, 8}"
12773 [(set_attr "length" "4")
12774 (set_attr "mode" "HI")])
12776 (define_expand "paritydi2"
12777 [(set (match_operand:DI 0 "register_operand")
12778 (parity:DI (match_operand:DI 1 "register_operand")))]
12781 rtx scratch = gen_reg_rtx (QImode);
12784 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12785 NULL_RTX, operands[1]));
12787 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12788 gen_rtx_REG (CCmode, FLAGS_REG),
12790 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12793 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12796 rtx tmp = gen_reg_rtx (SImode);
12798 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12799 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12804 (define_expand "paritysi2"
12805 [(set (match_operand:SI 0 "register_operand")
12806 (parity:SI (match_operand:SI 1 "register_operand")))]
12809 rtx scratch = gen_reg_rtx (QImode);
12812 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12814 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12815 gen_rtx_REG (CCmode, FLAGS_REG),
12817 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12819 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12823 (define_insn_and_split "paritydi2_cmp"
12824 [(set (reg:CC FLAGS_REG)
12825 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12827 (clobber (match_scratch:DI 0 "=r"))
12828 (clobber (match_scratch:SI 1 "=&r"))
12829 (clobber (match_scratch:HI 2 "=Q"))]
12832 "&& reload_completed"
12834 [(set (match_dup 1)
12835 (xor:SI (match_dup 1) (match_dup 4)))
12836 (clobber (reg:CC FLAGS_REG))])
12838 [(set (reg:CC FLAGS_REG)
12839 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12840 (clobber (match_dup 1))
12841 (clobber (match_dup 2))])]
12843 operands[4] = gen_lowpart (SImode, operands[3]);
12847 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12848 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12851 operands[1] = gen_highpart (SImode, operands[3]);
12854 (define_insn_and_split "paritysi2_cmp"
12855 [(set (reg:CC FLAGS_REG)
12856 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12858 (clobber (match_scratch:SI 0 "=r"))
12859 (clobber (match_scratch:HI 1 "=&Q"))]
12862 "&& reload_completed"
12864 [(set (match_dup 1)
12865 (xor:HI (match_dup 1) (match_dup 3)))
12866 (clobber (reg:CC FLAGS_REG))])
12868 [(set (reg:CC FLAGS_REG)
12869 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12870 (clobber (match_dup 1))])]
12872 operands[3] = gen_lowpart (HImode, operands[2]);
12874 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12875 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12878 (define_insn "*parityhi2_cmp"
12879 [(set (reg:CC FLAGS_REG)
12880 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12882 (clobber (match_scratch:HI 0 "=Q"))]
12884 "xor{b}\t{%h0, %b0|%b0, %h0}"
12885 [(set_attr "length" "2")
12886 (set_attr "mode" "HI")])
12889 ;; Thread-local storage patterns for ELF.
12891 ;; Note that these code sequences must appear exactly as shown
12892 ;; in order to allow linker relaxation.
12894 (define_insn "*tls_global_dynamic_32_gnu"
12895 [(set (match_operand:SI 0 "register_operand" "=a")
12897 [(match_operand:SI 1 "register_operand" "b")
12898 (match_operand 2 "tls_symbolic_operand")
12899 (match_operand 3 "constant_call_address_operand" "z")]
12901 (clobber (match_scratch:SI 4 "=d"))
12902 (clobber (match_scratch:SI 5 "=c"))
12903 (clobber (reg:CC FLAGS_REG))]
12904 "!TARGET_64BIT && TARGET_GNU_TLS"
12907 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12908 if (TARGET_SUN_TLS)
12909 #ifdef HAVE_AS_IX86_TLSGDPLT
12910 return "call\t%a2@tlsgdplt";
12912 return "call\t%p3@plt";
12914 return "call\t%P3";
12916 [(set_attr "type" "multi")
12917 (set_attr "length" "12")])
12919 (define_expand "tls_global_dynamic_32"
12921 [(set (match_operand:SI 0 "register_operand")
12922 (unspec:SI [(match_operand:SI 2 "register_operand")
12923 (match_operand 1 "tls_symbolic_operand")
12924 (match_operand 3 "constant_call_address_operand")]
12926 (clobber (match_scratch:SI 4))
12927 (clobber (match_scratch:SI 5))
12928 (clobber (reg:CC FLAGS_REG))])])
12930 (define_insn "*tls_global_dynamic_64_<mode>"
12931 [(set (match_operand:P 0 "register_operand" "=a")
12933 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12934 (match_operand 3)))
12935 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12940 fputs (ASM_BYTE "0x66\n", asm_out_file);
12942 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12943 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12944 fputs ("\trex64\n", asm_out_file);
12945 if (TARGET_SUN_TLS)
12946 return "call\t%p2@plt";
12947 return "call\t%P2";
12949 [(set_attr "type" "multi")
12950 (set (attr "length")
12951 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12953 (define_expand "tls_global_dynamic_64_<mode>"
12955 [(set (match_operand:P 0 "register_operand")
12957 (mem:QI (match_operand 2 "constant_call_address_operand"))
12959 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12963 (define_insn "*tls_local_dynamic_base_32_gnu"
12964 [(set (match_operand:SI 0 "register_operand" "=a")
12966 [(match_operand:SI 1 "register_operand" "b")
12967 (match_operand 2 "constant_call_address_operand" "z")]
12968 UNSPEC_TLS_LD_BASE))
12969 (clobber (match_scratch:SI 3 "=d"))
12970 (clobber (match_scratch:SI 4 "=c"))
12971 (clobber (reg:CC FLAGS_REG))]
12972 "!TARGET_64BIT && TARGET_GNU_TLS"
12975 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12976 if (TARGET_SUN_TLS)
12977 #ifdef HAVE_AS_IX86_TLSLDMPLT
12978 return "call\t%&@tlsldmplt";
12980 return "call\t%p2@plt";
12982 return "call\t%P2";
12984 [(set_attr "type" "multi")
12985 (set_attr "length" "11")])
12987 (define_expand "tls_local_dynamic_base_32"
12989 [(set (match_operand:SI 0 "register_operand")
12991 [(match_operand:SI 1 "register_operand")
12992 (match_operand 2 "constant_call_address_operand")]
12993 UNSPEC_TLS_LD_BASE))
12994 (clobber (match_scratch:SI 3))
12995 (clobber (match_scratch:SI 4))
12996 (clobber (reg:CC FLAGS_REG))])])
12998 (define_insn "*tls_local_dynamic_base_64_<mode>"
12999 [(set (match_operand:P 0 "register_operand" "=a")
13001 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
13002 (match_operand 2)))
13003 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13007 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13008 if (TARGET_SUN_TLS)
13009 return "call\t%p1@plt";
13010 return "call\t%P1";
13012 [(set_attr "type" "multi")
13013 (set_attr "length" "12")])
13015 (define_expand "tls_local_dynamic_base_64_<mode>"
13017 [(set (match_operand:P 0 "register_operand")
13019 (mem:QI (match_operand 1 "constant_call_address_operand"))
13021 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13024 ;; Local dynamic of a single variable is a lose. Show combine how
13025 ;; to convert that back to global dynamic.
13027 (define_insn_and_split "*tls_local_dynamic_32_once"
13028 [(set (match_operand:SI 0 "register_operand" "=a")
13030 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13031 (match_operand 2 "constant_call_address_operand" "z")]
13032 UNSPEC_TLS_LD_BASE)
13033 (const:SI (unspec:SI
13034 [(match_operand 3 "tls_symbolic_operand")]
13036 (clobber (match_scratch:SI 4 "=d"))
13037 (clobber (match_scratch:SI 5 "=c"))
13038 (clobber (reg:CC FLAGS_REG))]
13043 [(set (match_dup 0)
13044 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13046 (clobber (match_dup 4))
13047 (clobber (match_dup 5))
13048 (clobber (reg:CC FLAGS_REG))])])
13050 ;; Segment register for the thread base ptr load
13051 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13053 ;; Load and add the thread base pointer from %<tp_seg>:0.
13054 (define_insn "*load_tp_x32"
13055 [(set (match_operand:SI 0 "register_operand" "=r")
13056 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13058 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13059 [(set_attr "type" "imov")
13060 (set_attr "modrm" "0")
13061 (set_attr "length" "7")
13062 (set_attr "memory" "load")
13063 (set_attr "imm_disp" "false")])
13065 (define_insn "*load_tp_x32_zext"
13066 [(set (match_operand:DI 0 "register_operand" "=r")
13067 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13069 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13070 [(set_attr "type" "imov")
13071 (set_attr "modrm" "0")
13072 (set_attr "length" "7")
13073 (set_attr "memory" "load")
13074 (set_attr "imm_disp" "false")])
13076 (define_insn "*load_tp_<mode>"
13077 [(set (match_operand:P 0 "register_operand" "=r")
13078 (unspec:P [(const_int 0)] UNSPEC_TP))]
13080 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13081 [(set_attr "type" "imov")
13082 (set_attr "modrm" "0")
13083 (set_attr "length" "7")
13084 (set_attr "memory" "load")
13085 (set_attr "imm_disp" "false")])
13087 (define_insn "*add_tp_x32"
13088 [(set (match_operand:SI 0 "register_operand" "=r")
13089 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13090 (match_operand:SI 1 "register_operand" "0")))
13091 (clobber (reg:CC FLAGS_REG))]
13093 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13094 [(set_attr "type" "alu")
13095 (set_attr "modrm" "0")
13096 (set_attr "length" "7")
13097 (set_attr "memory" "load")
13098 (set_attr "imm_disp" "false")])
13100 (define_insn "*add_tp_x32_zext"
13101 [(set (match_operand:DI 0 "register_operand" "=r")
13103 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13104 (match_operand:SI 1 "register_operand" "0"))))
13105 (clobber (reg:CC FLAGS_REG))]
13107 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13108 [(set_attr "type" "alu")
13109 (set_attr "modrm" "0")
13110 (set_attr "length" "7")
13111 (set_attr "memory" "load")
13112 (set_attr "imm_disp" "false")])
13114 (define_insn "*add_tp_<mode>"
13115 [(set (match_operand:P 0 "register_operand" "=r")
13116 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13117 (match_operand:P 1 "register_operand" "0")))
13118 (clobber (reg:CC FLAGS_REG))]
13120 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13121 [(set_attr "type" "alu")
13122 (set_attr "modrm" "0")
13123 (set_attr "length" "7")
13124 (set_attr "memory" "load")
13125 (set_attr "imm_disp" "false")])
13127 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13128 ;; %rax as destination of the initial executable code sequence.
13129 (define_insn "tls_initial_exec_64_sun"
13130 [(set (match_operand:DI 0 "register_operand" "=a")
13132 [(match_operand 1 "tls_symbolic_operand")]
13133 UNSPEC_TLS_IE_SUN))
13134 (clobber (reg:CC FLAGS_REG))]
13135 "TARGET_64BIT && TARGET_SUN_TLS"
13138 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13139 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13141 [(set_attr "type" "multi")])
13143 ;; GNU2 TLS patterns can be split.
13145 (define_expand "tls_dynamic_gnu2_32"
13146 [(set (match_dup 3)
13147 (plus:SI (match_operand:SI 2 "register_operand")
13149 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13152 [(set (match_operand:SI 0 "register_operand")
13153 (unspec:SI [(match_dup 1) (match_dup 3)
13154 (match_dup 2) (reg:SI SP_REG)]
13156 (clobber (reg:CC FLAGS_REG))])]
13157 "!TARGET_64BIT && TARGET_GNU2_TLS"
13159 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13160 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13163 (define_insn "*tls_dynamic_gnu2_lea_32"
13164 [(set (match_operand:SI 0 "register_operand" "=r")
13165 (plus:SI (match_operand:SI 1 "register_operand" "b")
13167 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13168 UNSPEC_TLSDESC))))]
13169 "!TARGET_64BIT && TARGET_GNU2_TLS"
13170 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13171 [(set_attr "type" "lea")
13172 (set_attr "mode" "SI")
13173 (set_attr "length" "6")
13174 (set_attr "length_address" "4")])
13176 (define_insn "*tls_dynamic_gnu2_call_32"
13177 [(set (match_operand:SI 0 "register_operand" "=a")
13178 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13179 (match_operand:SI 2 "register_operand" "0")
13180 ;; we have to make sure %ebx still points to the GOT
13181 (match_operand:SI 3 "register_operand" "b")
13184 (clobber (reg:CC FLAGS_REG))]
13185 "!TARGET_64BIT && TARGET_GNU2_TLS"
13186 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13187 [(set_attr "type" "call")
13188 (set_attr "length" "2")
13189 (set_attr "length_address" "0")])
13191 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13192 [(set (match_operand:SI 0 "register_operand" "=&a")
13194 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13195 (match_operand:SI 4)
13196 (match_operand:SI 2 "register_operand" "b")
13199 (const:SI (unspec:SI
13200 [(match_operand 1 "tls_symbolic_operand")]
13202 (clobber (reg:CC FLAGS_REG))]
13203 "!TARGET_64BIT && TARGET_GNU2_TLS"
13206 [(set (match_dup 0) (match_dup 5))]
13208 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13209 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13212 (define_expand "tls_dynamic_gnu2_64"
13213 [(set (match_dup 2)
13214 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13217 [(set (match_operand:DI 0 "register_operand")
13218 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13220 (clobber (reg:CC FLAGS_REG))])]
13221 "TARGET_64BIT && TARGET_GNU2_TLS"
13223 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13224 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13227 (define_insn "*tls_dynamic_gnu2_lea_64"
13228 [(set (match_operand:DI 0 "register_operand" "=r")
13229 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13231 "TARGET_64BIT && TARGET_GNU2_TLS"
13232 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13233 [(set_attr "type" "lea")
13234 (set_attr "mode" "DI")
13235 (set_attr "length" "7")
13236 (set_attr "length_address" "4")])
13238 (define_insn "*tls_dynamic_gnu2_call_64"
13239 [(set (match_operand:DI 0 "register_operand" "=a")
13240 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13241 (match_operand:DI 2 "register_operand" "0")
13244 (clobber (reg:CC FLAGS_REG))]
13245 "TARGET_64BIT && TARGET_GNU2_TLS"
13246 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13247 [(set_attr "type" "call")
13248 (set_attr "length" "2")
13249 (set_attr "length_address" "0")])
13251 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13252 [(set (match_operand:DI 0 "register_operand" "=&a")
13254 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13255 (match_operand:DI 3)
13258 (const:DI (unspec:DI
13259 [(match_operand 1 "tls_symbolic_operand")]
13261 (clobber (reg:CC FLAGS_REG))]
13262 "TARGET_64BIT && TARGET_GNU2_TLS"
13265 [(set (match_dup 0) (match_dup 4))]
13267 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13268 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13271 ;; These patterns match the binary 387 instructions for addM3, subM3,
13272 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13273 ;; SFmode. The first is the normal insn, the second the same insn but
13274 ;; with one operand a conversion, and the third the same insn but with
13275 ;; the other operand a conversion. The conversion may be SFmode or
13276 ;; SImode if the target mode DFmode, but only SImode if the target mode
13279 ;; Gcc is slightly more smart about handling normal two address instructions
13280 ;; so use special patterns for add and mull.
13282 (define_insn "*fop_<mode>_comm_mixed"
13283 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13284 (match_operator:MODEF 3 "binary_fp_operator"
13285 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13286 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13287 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13288 && COMMUTATIVE_ARITH_P (operands[3])
13289 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13290 "* return output_387_binary_op (insn, operands);"
13291 [(set (attr "type")
13292 (if_then_else (eq_attr "alternative" "1,2")
13293 (if_then_else (match_operand:MODEF 3 "mult_operator")
13294 (const_string "ssemul")
13295 (const_string "sseadd"))
13296 (if_then_else (match_operand:MODEF 3 "mult_operator")
13297 (const_string "fmul")
13298 (const_string "fop"))))
13299 (set_attr "isa" "*,noavx,avx")
13300 (set_attr "prefix" "orig,orig,vex")
13301 (set_attr "mode" "<MODE>")])
13303 (define_insn "*fop_<mode>_comm_sse"
13304 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13305 (match_operator:MODEF 3 "binary_fp_operator"
13306 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13307 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13308 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13309 && COMMUTATIVE_ARITH_P (operands[3])
13310 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13311 "* return output_387_binary_op (insn, operands);"
13312 [(set (attr "type")
13313 (if_then_else (match_operand:MODEF 3 "mult_operator")
13314 (const_string "ssemul")
13315 (const_string "sseadd")))
13316 (set_attr "isa" "noavx,avx")
13317 (set_attr "prefix" "orig,vex")
13318 (set_attr "mode" "<MODE>")])
13320 (define_insn "*fop_<mode>_comm_i387"
13321 [(set (match_operand:MODEF 0 "register_operand" "=f")
13322 (match_operator:MODEF 3 "binary_fp_operator"
13323 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13324 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13325 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13326 && COMMUTATIVE_ARITH_P (operands[3])
13327 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13328 "* return output_387_binary_op (insn, operands);"
13329 [(set (attr "type")
13330 (if_then_else (match_operand:MODEF 3 "mult_operator")
13331 (const_string "fmul")
13332 (const_string "fop")))
13333 (set_attr "mode" "<MODE>")])
13335 (define_insn "*fop_<mode>_1_mixed"
13336 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13337 (match_operator:MODEF 3 "binary_fp_operator"
13338 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13339 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13340 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13341 && !COMMUTATIVE_ARITH_P (operands[3])
13342 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13343 "* return output_387_binary_op (insn, operands);"
13344 [(set (attr "type")
13345 (cond [(and (eq_attr "alternative" "2,3")
13346 (match_operand:MODEF 3 "mult_operator"))
13347 (const_string "ssemul")
13348 (and (eq_attr "alternative" "2,3")
13349 (match_operand:MODEF 3 "div_operator"))
13350 (const_string "ssediv")
13351 (eq_attr "alternative" "2,3")
13352 (const_string "sseadd")
13353 (match_operand:MODEF 3 "mult_operator")
13354 (const_string "fmul")
13355 (match_operand:MODEF 3 "div_operator")
13356 (const_string "fdiv")
13358 (const_string "fop")))
13359 (set_attr "isa" "*,*,noavx,avx")
13360 (set_attr "prefix" "orig,orig,orig,vex")
13361 (set_attr "mode" "<MODE>")])
13363 (define_insn "*rcpsf2_sse"
13364 [(set (match_operand:SF 0 "register_operand" "=x")
13365 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13368 "%vrcpss\t{%1, %d0|%d0, %1}"
13369 [(set_attr "type" "sse")
13370 (set_attr "atom_sse_attr" "rcp")
13371 (set_attr "prefix" "maybe_vex")
13372 (set_attr "mode" "SF")])
13374 (define_insn "*fop_<mode>_1_sse"
13375 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13376 (match_operator:MODEF 3 "binary_fp_operator"
13377 [(match_operand:MODEF 1 "register_operand" "0,x")
13378 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13379 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13380 && !COMMUTATIVE_ARITH_P (operands[3])"
13381 "* return output_387_binary_op (insn, operands);"
13382 [(set (attr "type")
13383 (cond [(match_operand:MODEF 3 "mult_operator")
13384 (const_string "ssemul")
13385 (match_operand:MODEF 3 "div_operator")
13386 (const_string "ssediv")
13388 (const_string "sseadd")))
13389 (set_attr "isa" "noavx,avx")
13390 (set_attr "prefix" "orig,vex")
13391 (set_attr "mode" "<MODE>")])
13393 ;; This pattern is not fully shadowed by the pattern above.
13394 (define_insn "*fop_<mode>_1_i387"
13395 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13396 (match_operator:MODEF 3 "binary_fp_operator"
13397 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13398 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13399 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13400 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13401 && !COMMUTATIVE_ARITH_P (operands[3])
13402 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13403 "* return output_387_binary_op (insn, operands);"
13404 [(set (attr "type")
13405 (cond [(match_operand:MODEF 3 "mult_operator")
13406 (const_string "fmul")
13407 (match_operand:MODEF 3 "div_operator")
13408 (const_string "fdiv")
13410 (const_string "fop")))
13411 (set_attr "mode" "<MODE>")])
13413 ;; ??? Add SSE splitters for these!
13414 (define_insn "*fop_<MODEF:mode>_2_i387"
13415 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13416 (match_operator:MODEF 3 "binary_fp_operator"
13418 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13419 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13420 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13421 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13422 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13423 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13424 [(set (attr "type")
13425 (cond [(match_operand:MODEF 3 "mult_operator")
13426 (const_string "fmul")
13427 (match_operand:MODEF 3 "div_operator")
13428 (const_string "fdiv")
13430 (const_string "fop")))
13431 (set_attr "fp_int_src" "true")
13432 (set_attr "mode" "<SWI24:MODE>")])
13434 (define_insn "*fop_<MODEF:mode>_3_i387"
13435 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13436 (match_operator:MODEF 3 "binary_fp_operator"
13437 [(match_operand:MODEF 1 "register_operand" "0,0")
13439 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13440 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13441 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13442 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13443 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13444 [(set (attr "type")
13445 (cond [(match_operand:MODEF 3 "mult_operator")
13446 (const_string "fmul")
13447 (match_operand:MODEF 3 "div_operator")
13448 (const_string "fdiv")
13450 (const_string "fop")))
13451 (set_attr "fp_int_src" "true")
13452 (set_attr "mode" "<MODE>")])
13454 (define_insn "*fop_df_4_i387"
13455 [(set (match_operand:DF 0 "register_operand" "=f,f")
13456 (match_operator:DF 3 "binary_fp_operator"
13458 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13459 (match_operand:DF 2 "register_operand" "0,f")]))]
13460 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13461 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13462 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13463 "* return output_387_binary_op (insn, operands);"
13464 [(set (attr "type")
13465 (cond [(match_operand:DF 3 "mult_operator")
13466 (const_string "fmul")
13467 (match_operand:DF 3 "div_operator")
13468 (const_string "fdiv")
13470 (const_string "fop")))
13471 (set_attr "mode" "SF")])
13473 (define_insn "*fop_df_5_i387"
13474 [(set (match_operand:DF 0 "register_operand" "=f,f")
13475 (match_operator:DF 3 "binary_fp_operator"
13476 [(match_operand:DF 1 "register_operand" "0,f")
13478 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13479 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13480 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13481 "* return output_387_binary_op (insn, operands);"
13482 [(set (attr "type")
13483 (cond [(match_operand:DF 3 "mult_operator")
13484 (const_string "fmul")
13485 (match_operand:DF 3 "div_operator")
13486 (const_string "fdiv")
13488 (const_string "fop")))
13489 (set_attr "mode" "SF")])
13491 (define_insn "*fop_df_6_i387"
13492 [(set (match_operand:DF 0 "register_operand" "=f,f")
13493 (match_operator:DF 3 "binary_fp_operator"
13495 (match_operand:SF 1 "register_operand" "0,f"))
13497 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13498 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13499 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13500 "* return output_387_binary_op (insn, operands);"
13501 [(set (attr "type")
13502 (cond [(match_operand:DF 3 "mult_operator")
13503 (const_string "fmul")
13504 (match_operand:DF 3 "div_operator")
13505 (const_string "fdiv")
13507 (const_string "fop")))
13508 (set_attr "mode" "SF")])
13510 (define_insn "*fop_xf_comm_i387"
13511 [(set (match_operand:XF 0 "register_operand" "=f")
13512 (match_operator:XF 3 "binary_fp_operator"
13513 [(match_operand:XF 1 "register_operand" "%0")
13514 (match_operand:XF 2 "register_operand" "f")]))]
13516 && COMMUTATIVE_ARITH_P (operands[3])"
13517 "* return output_387_binary_op (insn, operands);"
13518 [(set (attr "type")
13519 (if_then_else (match_operand:XF 3 "mult_operator")
13520 (const_string "fmul")
13521 (const_string "fop")))
13522 (set_attr "mode" "XF")])
13524 (define_insn "*fop_xf_1_i387"
13525 [(set (match_operand:XF 0 "register_operand" "=f,f")
13526 (match_operator:XF 3 "binary_fp_operator"
13527 [(match_operand:XF 1 "register_operand" "0,f")
13528 (match_operand:XF 2 "register_operand" "f,0")]))]
13530 && !COMMUTATIVE_ARITH_P (operands[3])"
13531 "* return output_387_binary_op (insn, operands);"
13532 [(set (attr "type")
13533 (cond [(match_operand:XF 3 "mult_operator")
13534 (const_string "fmul")
13535 (match_operand:XF 3 "div_operator")
13536 (const_string "fdiv")
13538 (const_string "fop")))
13539 (set_attr "mode" "XF")])
13541 (define_insn "*fop_xf_2_i387"
13542 [(set (match_operand:XF 0 "register_operand" "=f,f")
13543 (match_operator:XF 3 "binary_fp_operator"
13545 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13546 (match_operand:XF 2 "register_operand" "0,0")]))]
13547 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13548 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13549 [(set (attr "type")
13550 (cond [(match_operand:XF 3 "mult_operator")
13551 (const_string "fmul")
13552 (match_operand:XF 3 "div_operator")
13553 (const_string "fdiv")
13555 (const_string "fop")))
13556 (set_attr "fp_int_src" "true")
13557 (set_attr "mode" "<MODE>")])
13559 (define_insn "*fop_xf_3_i387"
13560 [(set (match_operand:XF 0 "register_operand" "=f,f")
13561 (match_operator:XF 3 "binary_fp_operator"
13562 [(match_operand:XF 1 "register_operand" "0,0")
13564 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13565 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13566 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13567 [(set (attr "type")
13568 (cond [(match_operand:XF 3 "mult_operator")
13569 (const_string "fmul")
13570 (match_operand:XF 3 "div_operator")
13571 (const_string "fdiv")
13573 (const_string "fop")))
13574 (set_attr "fp_int_src" "true")
13575 (set_attr "mode" "<MODE>")])
13577 (define_insn "*fop_xf_4_i387"
13578 [(set (match_operand:XF 0 "register_operand" "=f,f")
13579 (match_operator:XF 3 "binary_fp_operator"
13581 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13582 (match_operand:XF 2 "register_operand" "0,f")]))]
13584 "* return output_387_binary_op (insn, operands);"
13585 [(set (attr "type")
13586 (cond [(match_operand:XF 3 "mult_operator")
13587 (const_string "fmul")
13588 (match_operand:XF 3 "div_operator")
13589 (const_string "fdiv")
13591 (const_string "fop")))
13592 (set_attr "mode" "<MODE>")])
13594 (define_insn "*fop_xf_5_i387"
13595 [(set (match_operand:XF 0 "register_operand" "=f,f")
13596 (match_operator:XF 3 "binary_fp_operator"
13597 [(match_operand:XF 1 "register_operand" "0,f")
13599 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13601 "* return output_387_binary_op (insn, operands);"
13602 [(set (attr "type")
13603 (cond [(match_operand:XF 3 "mult_operator")
13604 (const_string "fmul")
13605 (match_operand:XF 3 "div_operator")
13606 (const_string "fdiv")
13608 (const_string "fop")))
13609 (set_attr "mode" "<MODE>")])
13611 (define_insn "*fop_xf_6_i387"
13612 [(set (match_operand:XF 0 "register_operand" "=f,f")
13613 (match_operator:XF 3 "binary_fp_operator"
13615 (match_operand:MODEF 1 "register_operand" "0,f"))
13617 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13619 "* return output_387_binary_op (insn, operands);"
13620 [(set (attr "type")
13621 (cond [(match_operand:XF 3 "mult_operator")
13622 (const_string "fmul")
13623 (match_operand:XF 3 "div_operator")
13624 (const_string "fdiv")
13626 (const_string "fop")))
13627 (set_attr "mode" "<MODE>")])
13630 [(set (match_operand 0 "register_operand")
13631 (match_operator 3 "binary_fp_operator"
13632 [(float (match_operand:SWI24 1 "register_operand"))
13633 (match_operand 2 "register_operand")]))]
13635 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13636 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13639 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13640 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13641 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13642 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13643 GET_MODE (operands[3]),
13646 ix86_free_from_memory (GET_MODE (operands[1]));
13651 [(set (match_operand 0 "register_operand")
13652 (match_operator 3 "binary_fp_operator"
13653 [(match_operand 1 "register_operand")
13654 (float (match_operand:SWI24 2 "register_operand"))]))]
13656 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13657 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13660 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13661 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13662 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13663 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13664 GET_MODE (operands[3]),
13667 ix86_free_from_memory (GET_MODE (operands[2]));
13671 ;; FPU special functions.
13673 ;; This pattern implements a no-op XFmode truncation for
13674 ;; all fancy i386 XFmode math functions.
13676 (define_insn "truncxf<mode>2_i387_noop_unspec"
13677 [(set (match_operand:MODEF 0 "register_operand" "=f")
13678 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13679 UNSPEC_TRUNC_NOOP))]
13680 "TARGET_USE_FANCY_MATH_387"
13681 "* return output_387_reg_move (insn, operands);"
13682 [(set_attr "type" "fmov")
13683 (set_attr "mode" "<MODE>")])
13685 (define_insn "sqrtxf2"
13686 [(set (match_operand:XF 0 "register_operand" "=f")
13687 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13688 "TARGET_USE_FANCY_MATH_387"
13690 [(set_attr "type" "fpspc")
13691 (set_attr "mode" "XF")
13692 (set_attr "athlon_decode" "direct")
13693 (set_attr "amdfam10_decode" "direct")
13694 (set_attr "bdver1_decode" "direct")])
13696 (define_insn "sqrt_extend<mode>xf2_i387"
13697 [(set (match_operand:XF 0 "register_operand" "=f")
13700 (match_operand:MODEF 1 "register_operand" "0"))))]
13701 "TARGET_USE_FANCY_MATH_387"
13703 [(set_attr "type" "fpspc")
13704 (set_attr "mode" "XF")
13705 (set_attr "athlon_decode" "direct")
13706 (set_attr "amdfam10_decode" "direct")
13707 (set_attr "bdver1_decode" "direct")])
13709 (define_insn "*rsqrtsf2_sse"
13710 [(set (match_operand:SF 0 "register_operand" "=x")
13711 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13714 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13715 [(set_attr "type" "sse")
13716 (set_attr "atom_sse_attr" "rcp")
13717 (set_attr "prefix" "maybe_vex")
13718 (set_attr "mode" "SF")])
13720 (define_expand "rsqrtsf2"
13721 [(set (match_operand:SF 0 "register_operand")
13722 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13726 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13730 (define_insn "*sqrt<mode>2_sse"
13731 [(set (match_operand:MODEF 0 "register_operand" "=x")
13733 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13734 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13735 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13736 [(set_attr "type" "sse")
13737 (set_attr "atom_sse_attr" "sqrt")
13738 (set_attr "prefix" "maybe_vex")
13739 (set_attr "mode" "<MODE>")
13740 (set_attr "athlon_decode" "*")
13741 (set_attr "amdfam10_decode" "*")
13742 (set_attr "bdver1_decode" "*")])
13744 (define_expand "sqrt<mode>2"
13745 [(set (match_operand:MODEF 0 "register_operand")
13747 (match_operand:MODEF 1 "nonimmediate_operand")))]
13748 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13749 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13751 if (<MODE>mode == SFmode
13753 && TARGET_RECIP_SQRT
13754 && !optimize_function_for_size_p (cfun)
13755 && flag_finite_math_only && !flag_trapping_math
13756 && flag_unsafe_math_optimizations)
13758 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13762 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13764 rtx op0 = gen_reg_rtx (XFmode);
13765 rtx op1 = force_reg (<MODE>mode, operands[1]);
13767 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13768 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13773 (define_insn "fpremxf4_i387"
13774 [(set (match_operand:XF 0 "register_operand" "=f")
13775 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13776 (match_operand:XF 3 "register_operand" "1")]
13778 (set (match_operand:XF 1 "register_operand" "=u")
13779 (unspec:XF [(match_dup 2) (match_dup 3)]
13781 (set (reg:CCFP FPSR_REG)
13782 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13784 "TARGET_USE_FANCY_MATH_387"
13786 [(set_attr "type" "fpspc")
13787 (set_attr "mode" "XF")])
13789 (define_expand "fmodxf3"
13790 [(use (match_operand:XF 0 "register_operand"))
13791 (use (match_operand:XF 1 "general_operand"))
13792 (use (match_operand:XF 2 "general_operand"))]
13793 "TARGET_USE_FANCY_MATH_387"
13795 rtx label = gen_label_rtx ();
13797 rtx op1 = gen_reg_rtx (XFmode);
13798 rtx op2 = gen_reg_rtx (XFmode);
13800 emit_move_insn (op2, operands[2]);
13801 emit_move_insn (op1, operands[1]);
13803 emit_label (label);
13804 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13805 ix86_emit_fp_unordered_jump (label);
13806 LABEL_NUSES (label) = 1;
13808 emit_move_insn (operands[0], op1);
13812 (define_expand "fmod<mode>3"
13813 [(use (match_operand:MODEF 0 "register_operand"))
13814 (use (match_operand:MODEF 1 "general_operand"))
13815 (use (match_operand:MODEF 2 "general_operand"))]
13816 "TARGET_USE_FANCY_MATH_387"
13818 rtx (*gen_truncxf) (rtx, rtx);
13820 rtx label = gen_label_rtx ();
13822 rtx op1 = gen_reg_rtx (XFmode);
13823 rtx op2 = gen_reg_rtx (XFmode);
13825 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13826 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13828 emit_label (label);
13829 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13830 ix86_emit_fp_unordered_jump (label);
13831 LABEL_NUSES (label) = 1;
13833 /* Truncate the result properly for strict SSE math. */
13834 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13835 && !TARGET_MIX_SSE_I387)
13836 gen_truncxf = gen_truncxf<mode>2;
13838 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13840 emit_insn (gen_truncxf (operands[0], op1));
13844 (define_insn "fprem1xf4_i387"
13845 [(set (match_operand:XF 0 "register_operand" "=f")
13846 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13847 (match_operand:XF 3 "register_operand" "1")]
13849 (set (match_operand:XF 1 "register_operand" "=u")
13850 (unspec:XF [(match_dup 2) (match_dup 3)]
13852 (set (reg:CCFP FPSR_REG)
13853 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13855 "TARGET_USE_FANCY_MATH_387"
13857 [(set_attr "type" "fpspc")
13858 (set_attr "mode" "XF")])
13860 (define_expand "remainderxf3"
13861 [(use (match_operand:XF 0 "register_operand"))
13862 (use (match_operand:XF 1 "general_operand"))
13863 (use (match_operand:XF 2 "general_operand"))]
13864 "TARGET_USE_FANCY_MATH_387"
13866 rtx label = gen_label_rtx ();
13868 rtx op1 = gen_reg_rtx (XFmode);
13869 rtx op2 = gen_reg_rtx (XFmode);
13871 emit_move_insn (op2, operands[2]);
13872 emit_move_insn (op1, operands[1]);
13874 emit_label (label);
13875 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13876 ix86_emit_fp_unordered_jump (label);
13877 LABEL_NUSES (label) = 1;
13879 emit_move_insn (operands[0], op1);
13883 (define_expand "remainder<mode>3"
13884 [(use (match_operand:MODEF 0 "register_operand"))
13885 (use (match_operand:MODEF 1 "general_operand"))
13886 (use (match_operand:MODEF 2 "general_operand"))]
13887 "TARGET_USE_FANCY_MATH_387"
13889 rtx (*gen_truncxf) (rtx, rtx);
13891 rtx label = gen_label_rtx ();
13893 rtx op1 = gen_reg_rtx (XFmode);
13894 rtx op2 = gen_reg_rtx (XFmode);
13896 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13897 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13899 emit_label (label);
13901 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13902 ix86_emit_fp_unordered_jump (label);
13903 LABEL_NUSES (label) = 1;
13905 /* Truncate the result properly for strict SSE math. */
13906 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13907 && !TARGET_MIX_SSE_I387)
13908 gen_truncxf = gen_truncxf<mode>2;
13910 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13912 emit_insn (gen_truncxf (operands[0], op1));
13916 (define_int_iterator SINCOS
13920 (define_int_attr sincos
13921 [(UNSPEC_SIN "sin")
13922 (UNSPEC_COS "cos")])
13924 (define_insn "*<sincos>xf2_i387"
13925 [(set (match_operand:XF 0 "register_operand" "=f")
13926 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13928 "TARGET_USE_FANCY_MATH_387
13929 && flag_unsafe_math_optimizations"
13931 [(set_attr "type" "fpspc")
13932 (set_attr "mode" "XF")])
13934 (define_insn "*<sincos>_extend<mode>xf2_i387"
13935 [(set (match_operand:XF 0 "register_operand" "=f")
13936 (unspec:XF [(float_extend:XF
13937 (match_operand:MODEF 1 "register_operand" "0"))]
13939 "TARGET_USE_FANCY_MATH_387
13940 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13941 || TARGET_MIX_SSE_I387)
13942 && flag_unsafe_math_optimizations"
13944 [(set_attr "type" "fpspc")
13945 (set_attr "mode" "XF")])
13947 ;; When sincos pattern is defined, sin and cos builtin functions will be
13948 ;; expanded to sincos pattern with one of its outputs left unused.
13949 ;; CSE pass will figure out if two sincos patterns can be combined,
13950 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13951 ;; depending on the unused output.
13953 (define_insn "sincosxf3"
13954 [(set (match_operand:XF 0 "register_operand" "=f")
13955 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13956 UNSPEC_SINCOS_COS))
13957 (set (match_operand:XF 1 "register_operand" "=u")
13958 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13959 "TARGET_USE_FANCY_MATH_387
13960 && flag_unsafe_math_optimizations"
13962 [(set_attr "type" "fpspc")
13963 (set_attr "mode" "XF")])
13966 [(set (match_operand:XF 0 "register_operand")
13967 (unspec:XF [(match_operand:XF 2 "register_operand")]
13968 UNSPEC_SINCOS_COS))
13969 (set (match_operand:XF 1 "register_operand")
13970 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13971 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13972 && can_create_pseudo_p ()"
13973 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13976 [(set (match_operand:XF 0 "register_operand")
13977 (unspec:XF [(match_operand:XF 2 "register_operand")]
13978 UNSPEC_SINCOS_COS))
13979 (set (match_operand:XF 1 "register_operand")
13980 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13981 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13982 && can_create_pseudo_p ()"
13983 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13985 (define_insn "sincos_extend<mode>xf3_i387"
13986 [(set (match_operand:XF 0 "register_operand" "=f")
13987 (unspec:XF [(float_extend:XF
13988 (match_operand:MODEF 2 "register_operand" "0"))]
13989 UNSPEC_SINCOS_COS))
13990 (set (match_operand:XF 1 "register_operand" "=u")
13991 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13992 "TARGET_USE_FANCY_MATH_387
13993 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13994 || TARGET_MIX_SSE_I387)
13995 && flag_unsafe_math_optimizations"
13997 [(set_attr "type" "fpspc")
13998 (set_attr "mode" "XF")])
14001 [(set (match_operand:XF 0 "register_operand")
14002 (unspec:XF [(float_extend:XF
14003 (match_operand:MODEF 2 "register_operand"))]
14004 UNSPEC_SINCOS_COS))
14005 (set (match_operand:XF 1 "register_operand")
14006 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14007 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14008 && can_create_pseudo_p ()"
14009 [(set (match_dup 1)
14010 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
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[1]))
14020 && can_create_pseudo_p ()"
14021 [(set (match_dup 0)
14022 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14024 (define_expand "sincos<mode>3"
14025 [(use (match_operand:MODEF 0 "register_operand"))
14026 (use (match_operand:MODEF 1 "register_operand"))
14027 (use (match_operand:MODEF 2 "register_operand"))]
14028 "TARGET_USE_FANCY_MATH_387
14029 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14030 || TARGET_MIX_SSE_I387)
14031 && flag_unsafe_math_optimizations"
14033 rtx op0 = gen_reg_rtx (XFmode);
14034 rtx op1 = gen_reg_rtx (XFmode);
14036 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14037 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14038 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14042 (define_insn "fptanxf4_i387"
14043 [(set (match_operand:XF 0 "register_operand" "=f")
14044 (match_operand:XF 3 "const_double_operand" "F"))
14045 (set (match_operand:XF 1 "register_operand" "=u")
14046 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14048 "TARGET_USE_FANCY_MATH_387
14049 && flag_unsafe_math_optimizations
14050 && standard_80387_constant_p (operands[3]) == 2"
14052 [(set_attr "type" "fpspc")
14053 (set_attr "mode" "XF")])
14055 (define_insn "fptan_extend<mode>xf4_i387"
14056 [(set (match_operand:MODEF 0 "register_operand" "=f")
14057 (match_operand:MODEF 3 "const_double_operand" "F"))
14058 (set (match_operand:XF 1 "register_operand" "=u")
14059 (unspec:XF [(float_extend:XF
14060 (match_operand:MODEF 2 "register_operand" "0"))]
14062 "TARGET_USE_FANCY_MATH_387
14063 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14064 || TARGET_MIX_SSE_I387)
14065 && flag_unsafe_math_optimizations
14066 && standard_80387_constant_p (operands[3]) == 2"
14068 [(set_attr "type" "fpspc")
14069 (set_attr "mode" "XF")])
14071 (define_expand "tanxf2"
14072 [(use (match_operand:XF 0 "register_operand"))
14073 (use (match_operand:XF 1 "register_operand"))]
14074 "TARGET_USE_FANCY_MATH_387
14075 && flag_unsafe_math_optimizations"
14077 rtx one = gen_reg_rtx (XFmode);
14078 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14080 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14084 (define_expand "tan<mode>2"
14085 [(use (match_operand:MODEF 0 "register_operand"))
14086 (use (match_operand:MODEF 1 "register_operand"))]
14087 "TARGET_USE_FANCY_MATH_387
14088 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14089 || TARGET_MIX_SSE_I387)
14090 && flag_unsafe_math_optimizations"
14092 rtx op0 = gen_reg_rtx (XFmode);
14094 rtx one = gen_reg_rtx (<MODE>mode);
14095 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14097 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14098 operands[1], op2));
14099 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14103 (define_insn "*fpatanxf3_i387"
14104 [(set (match_operand:XF 0 "register_operand" "=f")
14105 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14106 (match_operand:XF 2 "register_operand" "u")]
14108 (clobber (match_scratch:XF 3 "=2"))]
14109 "TARGET_USE_FANCY_MATH_387
14110 && flag_unsafe_math_optimizations"
14112 [(set_attr "type" "fpspc")
14113 (set_attr "mode" "XF")])
14115 (define_insn "fpatan_extend<mode>xf3_i387"
14116 [(set (match_operand:XF 0 "register_operand" "=f")
14117 (unspec:XF [(float_extend:XF
14118 (match_operand:MODEF 1 "register_operand" "0"))
14120 (match_operand:MODEF 2 "register_operand" "u"))]
14122 (clobber (match_scratch:XF 3 "=2"))]
14123 "TARGET_USE_FANCY_MATH_387
14124 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14125 || TARGET_MIX_SSE_I387)
14126 && flag_unsafe_math_optimizations"
14128 [(set_attr "type" "fpspc")
14129 (set_attr "mode" "XF")])
14131 (define_expand "atan2xf3"
14132 [(parallel [(set (match_operand:XF 0 "register_operand")
14133 (unspec:XF [(match_operand:XF 2 "register_operand")
14134 (match_operand:XF 1 "register_operand")]
14136 (clobber (match_scratch:XF 3))])]
14137 "TARGET_USE_FANCY_MATH_387
14138 && flag_unsafe_math_optimizations")
14140 (define_expand "atan2<mode>3"
14141 [(use (match_operand:MODEF 0 "register_operand"))
14142 (use (match_operand:MODEF 1 "register_operand"))
14143 (use (match_operand:MODEF 2 "register_operand"))]
14144 "TARGET_USE_FANCY_MATH_387
14145 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14146 || TARGET_MIX_SSE_I387)
14147 && flag_unsafe_math_optimizations"
14149 rtx op0 = gen_reg_rtx (XFmode);
14151 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14152 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14156 (define_expand "atanxf2"
14157 [(parallel [(set (match_operand:XF 0 "register_operand")
14158 (unspec:XF [(match_dup 2)
14159 (match_operand:XF 1 "register_operand")]
14161 (clobber (match_scratch:XF 3))])]
14162 "TARGET_USE_FANCY_MATH_387
14163 && flag_unsafe_math_optimizations"
14165 operands[2] = gen_reg_rtx (XFmode);
14166 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14169 (define_expand "atan<mode>2"
14170 [(use (match_operand:MODEF 0 "register_operand"))
14171 (use (match_operand:MODEF 1 "register_operand"))]
14172 "TARGET_USE_FANCY_MATH_387
14173 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14174 || TARGET_MIX_SSE_I387)
14175 && flag_unsafe_math_optimizations"
14177 rtx op0 = gen_reg_rtx (XFmode);
14179 rtx op2 = gen_reg_rtx (<MODE>mode);
14180 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14182 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14183 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14187 (define_expand "asinxf2"
14188 [(set (match_dup 2)
14189 (mult:XF (match_operand:XF 1 "register_operand")
14191 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14192 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14193 (parallel [(set (match_operand:XF 0 "register_operand")
14194 (unspec:XF [(match_dup 5) (match_dup 1)]
14196 (clobber (match_scratch:XF 6))])]
14197 "TARGET_USE_FANCY_MATH_387
14198 && flag_unsafe_math_optimizations"
14202 if (optimize_insn_for_size_p ())
14205 for (i = 2; i < 6; i++)
14206 operands[i] = gen_reg_rtx (XFmode);
14208 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14211 (define_expand "asin<mode>2"
14212 [(use (match_operand:MODEF 0 "register_operand"))
14213 (use (match_operand:MODEF 1 "general_operand"))]
14214 "TARGET_USE_FANCY_MATH_387
14215 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14216 || TARGET_MIX_SSE_I387)
14217 && flag_unsafe_math_optimizations"
14219 rtx op0 = gen_reg_rtx (XFmode);
14220 rtx op1 = gen_reg_rtx (XFmode);
14222 if (optimize_insn_for_size_p ())
14225 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14226 emit_insn (gen_asinxf2 (op0, op1));
14227 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14231 (define_expand "acosxf2"
14232 [(set (match_dup 2)
14233 (mult:XF (match_operand:XF 1 "register_operand")
14235 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14236 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14237 (parallel [(set (match_operand:XF 0 "register_operand")
14238 (unspec:XF [(match_dup 1) (match_dup 5)]
14240 (clobber (match_scratch:XF 6))])]
14241 "TARGET_USE_FANCY_MATH_387
14242 && flag_unsafe_math_optimizations"
14246 if (optimize_insn_for_size_p ())
14249 for (i = 2; i < 6; i++)
14250 operands[i] = gen_reg_rtx (XFmode);
14252 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14255 (define_expand "acos<mode>2"
14256 [(use (match_operand:MODEF 0 "register_operand"))
14257 (use (match_operand:MODEF 1 "general_operand"))]
14258 "TARGET_USE_FANCY_MATH_387
14259 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14260 || TARGET_MIX_SSE_I387)
14261 && flag_unsafe_math_optimizations"
14263 rtx op0 = gen_reg_rtx (XFmode);
14264 rtx op1 = gen_reg_rtx (XFmode);
14266 if (optimize_insn_for_size_p ())
14269 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14270 emit_insn (gen_acosxf2 (op0, op1));
14271 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14275 (define_insn "fyl2xxf3_i387"
14276 [(set (match_operand:XF 0 "register_operand" "=f")
14277 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14278 (match_operand:XF 2 "register_operand" "u")]
14280 (clobber (match_scratch:XF 3 "=2"))]
14281 "TARGET_USE_FANCY_MATH_387
14282 && flag_unsafe_math_optimizations"
14284 [(set_attr "type" "fpspc")
14285 (set_attr "mode" "XF")])
14287 (define_insn "fyl2x_extend<mode>xf3_i387"
14288 [(set (match_operand:XF 0 "register_operand" "=f")
14289 (unspec:XF [(float_extend:XF
14290 (match_operand:MODEF 1 "register_operand" "0"))
14291 (match_operand:XF 2 "register_operand" "u")]
14293 (clobber (match_scratch:XF 3 "=2"))]
14294 "TARGET_USE_FANCY_MATH_387
14295 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14296 || TARGET_MIX_SSE_I387)
14297 && flag_unsafe_math_optimizations"
14299 [(set_attr "type" "fpspc")
14300 (set_attr "mode" "XF")])
14302 (define_expand "logxf2"
14303 [(parallel [(set (match_operand:XF 0 "register_operand")
14304 (unspec:XF [(match_operand:XF 1 "register_operand")
14305 (match_dup 2)] UNSPEC_FYL2X))
14306 (clobber (match_scratch:XF 3))])]
14307 "TARGET_USE_FANCY_MATH_387
14308 && flag_unsafe_math_optimizations"
14310 operands[2] = gen_reg_rtx (XFmode);
14311 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14314 (define_expand "log<mode>2"
14315 [(use (match_operand:MODEF 0 "register_operand"))
14316 (use (match_operand:MODEF 1 "register_operand"))]
14317 "TARGET_USE_FANCY_MATH_387
14318 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14319 || TARGET_MIX_SSE_I387)
14320 && flag_unsafe_math_optimizations"
14322 rtx op0 = gen_reg_rtx (XFmode);
14324 rtx op2 = gen_reg_rtx (XFmode);
14325 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14327 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14328 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14332 (define_expand "log10xf2"
14333 [(parallel [(set (match_operand:XF 0 "register_operand")
14334 (unspec:XF [(match_operand:XF 1 "register_operand")
14335 (match_dup 2)] UNSPEC_FYL2X))
14336 (clobber (match_scratch:XF 3))])]
14337 "TARGET_USE_FANCY_MATH_387
14338 && flag_unsafe_math_optimizations"
14340 operands[2] = gen_reg_rtx (XFmode);
14341 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14344 (define_expand "log10<mode>2"
14345 [(use (match_operand:MODEF 0 "register_operand"))
14346 (use (match_operand:MODEF 1 "register_operand"))]
14347 "TARGET_USE_FANCY_MATH_387
14348 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14349 || TARGET_MIX_SSE_I387)
14350 && flag_unsafe_math_optimizations"
14352 rtx op0 = gen_reg_rtx (XFmode);
14354 rtx op2 = gen_reg_rtx (XFmode);
14355 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14357 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14358 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14362 (define_expand "log2xf2"
14363 [(parallel [(set (match_operand:XF 0 "register_operand")
14364 (unspec:XF [(match_operand:XF 1 "register_operand")
14365 (match_dup 2)] UNSPEC_FYL2X))
14366 (clobber (match_scratch:XF 3))])]
14367 "TARGET_USE_FANCY_MATH_387
14368 && flag_unsafe_math_optimizations"
14370 operands[2] = gen_reg_rtx (XFmode);
14371 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14374 (define_expand "log2<mode>2"
14375 [(use (match_operand:MODEF 0 "register_operand"))
14376 (use (match_operand:MODEF 1 "register_operand"))]
14377 "TARGET_USE_FANCY_MATH_387
14378 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14379 || TARGET_MIX_SSE_I387)
14380 && flag_unsafe_math_optimizations"
14382 rtx op0 = gen_reg_rtx (XFmode);
14384 rtx op2 = gen_reg_rtx (XFmode);
14385 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14387 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14388 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14392 (define_insn "fyl2xp1xf3_i387"
14393 [(set (match_operand:XF 0 "register_operand" "=f")
14394 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14395 (match_operand:XF 2 "register_operand" "u")]
14397 (clobber (match_scratch:XF 3 "=2"))]
14398 "TARGET_USE_FANCY_MATH_387
14399 && flag_unsafe_math_optimizations"
14401 [(set_attr "type" "fpspc")
14402 (set_attr "mode" "XF")])
14404 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14405 [(set (match_operand:XF 0 "register_operand" "=f")
14406 (unspec:XF [(float_extend:XF
14407 (match_operand:MODEF 1 "register_operand" "0"))
14408 (match_operand:XF 2 "register_operand" "u")]
14410 (clobber (match_scratch:XF 3 "=2"))]
14411 "TARGET_USE_FANCY_MATH_387
14412 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14413 || TARGET_MIX_SSE_I387)
14414 && flag_unsafe_math_optimizations"
14416 [(set_attr "type" "fpspc")
14417 (set_attr "mode" "XF")])
14419 (define_expand "log1pxf2"
14420 [(use (match_operand:XF 0 "register_operand"))
14421 (use (match_operand:XF 1 "register_operand"))]
14422 "TARGET_USE_FANCY_MATH_387
14423 && flag_unsafe_math_optimizations"
14425 if (optimize_insn_for_size_p ())
14428 ix86_emit_i387_log1p (operands[0], operands[1]);
14432 (define_expand "log1p<mode>2"
14433 [(use (match_operand:MODEF 0 "register_operand"))
14434 (use (match_operand:MODEF 1 "register_operand"))]
14435 "TARGET_USE_FANCY_MATH_387
14436 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14437 || TARGET_MIX_SSE_I387)
14438 && flag_unsafe_math_optimizations"
14442 if (optimize_insn_for_size_p ())
14445 op0 = gen_reg_rtx (XFmode);
14447 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14449 ix86_emit_i387_log1p (op0, operands[1]);
14450 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14454 (define_insn "fxtractxf3_i387"
14455 [(set (match_operand:XF 0 "register_operand" "=f")
14456 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14457 UNSPEC_XTRACT_FRACT))
14458 (set (match_operand:XF 1 "register_operand" "=u")
14459 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14460 "TARGET_USE_FANCY_MATH_387
14461 && flag_unsafe_math_optimizations"
14463 [(set_attr "type" "fpspc")
14464 (set_attr "mode" "XF")])
14466 (define_insn "fxtract_extend<mode>xf3_i387"
14467 [(set (match_operand:XF 0 "register_operand" "=f")
14468 (unspec:XF [(float_extend:XF
14469 (match_operand:MODEF 2 "register_operand" "0"))]
14470 UNSPEC_XTRACT_FRACT))
14471 (set (match_operand:XF 1 "register_operand" "=u")
14472 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14473 "TARGET_USE_FANCY_MATH_387
14474 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14475 || TARGET_MIX_SSE_I387)
14476 && flag_unsafe_math_optimizations"
14478 [(set_attr "type" "fpspc")
14479 (set_attr "mode" "XF")])
14481 (define_expand "logbxf2"
14482 [(parallel [(set (match_dup 2)
14483 (unspec:XF [(match_operand:XF 1 "register_operand")]
14484 UNSPEC_XTRACT_FRACT))
14485 (set (match_operand:XF 0 "register_operand")
14486 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14487 "TARGET_USE_FANCY_MATH_387
14488 && flag_unsafe_math_optimizations"
14489 "operands[2] = gen_reg_rtx (XFmode);")
14491 (define_expand "logb<mode>2"
14492 [(use (match_operand:MODEF 0 "register_operand"))
14493 (use (match_operand:MODEF 1 "register_operand"))]
14494 "TARGET_USE_FANCY_MATH_387
14495 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14496 || TARGET_MIX_SSE_I387)
14497 && flag_unsafe_math_optimizations"
14499 rtx op0 = gen_reg_rtx (XFmode);
14500 rtx op1 = gen_reg_rtx (XFmode);
14502 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14503 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14507 (define_expand "ilogbxf2"
14508 [(use (match_operand:SI 0 "register_operand"))
14509 (use (match_operand:XF 1 "register_operand"))]
14510 "TARGET_USE_FANCY_MATH_387
14511 && flag_unsafe_math_optimizations"
14515 if (optimize_insn_for_size_p ())
14518 op0 = gen_reg_rtx (XFmode);
14519 op1 = gen_reg_rtx (XFmode);
14521 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14522 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14526 (define_expand "ilogb<mode>2"
14527 [(use (match_operand:SI 0 "register_operand"))
14528 (use (match_operand:MODEF 1 "register_operand"))]
14529 "TARGET_USE_FANCY_MATH_387
14530 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14531 || TARGET_MIX_SSE_I387)
14532 && flag_unsafe_math_optimizations"
14536 if (optimize_insn_for_size_p ())
14539 op0 = gen_reg_rtx (XFmode);
14540 op1 = gen_reg_rtx (XFmode);
14542 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14543 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14547 (define_insn "*f2xm1xf2_i387"
14548 [(set (match_operand:XF 0 "register_operand" "=f")
14549 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14551 "TARGET_USE_FANCY_MATH_387
14552 && flag_unsafe_math_optimizations"
14554 [(set_attr "type" "fpspc")
14555 (set_attr "mode" "XF")])
14557 (define_insn "*fscalexf4_i387"
14558 [(set (match_operand:XF 0 "register_operand" "=f")
14559 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14560 (match_operand:XF 3 "register_operand" "1")]
14561 UNSPEC_FSCALE_FRACT))
14562 (set (match_operand:XF 1 "register_operand" "=u")
14563 (unspec:XF [(match_dup 2) (match_dup 3)]
14564 UNSPEC_FSCALE_EXP))]
14565 "TARGET_USE_FANCY_MATH_387
14566 && flag_unsafe_math_optimizations"
14568 [(set_attr "type" "fpspc")
14569 (set_attr "mode" "XF")])
14571 (define_expand "expNcorexf3"
14572 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14573 (match_operand:XF 2 "register_operand")))
14574 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14575 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14576 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14577 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14578 (parallel [(set (match_operand:XF 0 "register_operand")
14579 (unspec:XF [(match_dup 8) (match_dup 4)]
14580 UNSPEC_FSCALE_FRACT))
14582 (unspec:XF [(match_dup 8) (match_dup 4)]
14583 UNSPEC_FSCALE_EXP))])]
14584 "TARGET_USE_FANCY_MATH_387
14585 && flag_unsafe_math_optimizations"
14589 if (optimize_insn_for_size_p ())
14592 for (i = 3; i < 10; i++)
14593 operands[i] = gen_reg_rtx (XFmode);
14595 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14598 (define_expand "expxf2"
14599 [(use (match_operand:XF 0 "register_operand"))
14600 (use (match_operand:XF 1 "register_operand"))]
14601 "TARGET_USE_FANCY_MATH_387
14602 && flag_unsafe_math_optimizations"
14606 if (optimize_insn_for_size_p ())
14609 op2 = gen_reg_rtx (XFmode);
14610 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14612 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14616 (define_expand "exp<mode>2"
14617 [(use (match_operand:MODEF 0 "register_operand"))
14618 (use (match_operand:MODEF 1 "general_operand"))]
14619 "TARGET_USE_FANCY_MATH_387
14620 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14621 || TARGET_MIX_SSE_I387)
14622 && flag_unsafe_math_optimizations"
14626 if (optimize_insn_for_size_p ())
14629 op0 = gen_reg_rtx (XFmode);
14630 op1 = gen_reg_rtx (XFmode);
14632 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14633 emit_insn (gen_expxf2 (op0, op1));
14634 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14638 (define_expand "exp10xf2"
14639 [(use (match_operand:XF 0 "register_operand"))
14640 (use (match_operand:XF 1 "register_operand"))]
14641 "TARGET_USE_FANCY_MATH_387
14642 && flag_unsafe_math_optimizations"
14646 if (optimize_insn_for_size_p ())
14649 op2 = gen_reg_rtx (XFmode);
14650 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14652 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14656 (define_expand "exp10<mode>2"
14657 [(use (match_operand:MODEF 0 "register_operand"))
14658 (use (match_operand:MODEF 1 "general_operand"))]
14659 "TARGET_USE_FANCY_MATH_387
14660 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14661 || TARGET_MIX_SSE_I387)
14662 && flag_unsafe_math_optimizations"
14666 if (optimize_insn_for_size_p ())
14669 op0 = gen_reg_rtx (XFmode);
14670 op1 = gen_reg_rtx (XFmode);
14672 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14673 emit_insn (gen_exp10xf2 (op0, op1));
14674 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14678 (define_expand "exp2xf2"
14679 [(use (match_operand:XF 0 "register_operand"))
14680 (use (match_operand:XF 1 "register_operand"))]
14681 "TARGET_USE_FANCY_MATH_387
14682 && flag_unsafe_math_optimizations"
14686 if (optimize_insn_for_size_p ())
14689 op2 = gen_reg_rtx (XFmode);
14690 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14692 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14696 (define_expand "exp2<mode>2"
14697 [(use (match_operand:MODEF 0 "register_operand"))
14698 (use (match_operand:MODEF 1 "general_operand"))]
14699 "TARGET_USE_FANCY_MATH_387
14700 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14701 || TARGET_MIX_SSE_I387)
14702 && flag_unsafe_math_optimizations"
14706 if (optimize_insn_for_size_p ())
14709 op0 = gen_reg_rtx (XFmode);
14710 op1 = gen_reg_rtx (XFmode);
14712 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14713 emit_insn (gen_exp2xf2 (op0, op1));
14714 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14718 (define_expand "expm1xf2"
14719 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14721 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14722 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14723 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14724 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14725 (parallel [(set (match_dup 7)
14726 (unspec:XF [(match_dup 6) (match_dup 4)]
14727 UNSPEC_FSCALE_FRACT))
14729 (unspec:XF [(match_dup 6) (match_dup 4)]
14730 UNSPEC_FSCALE_EXP))])
14731 (parallel [(set (match_dup 10)
14732 (unspec:XF [(match_dup 9) (match_dup 8)]
14733 UNSPEC_FSCALE_FRACT))
14734 (set (match_dup 11)
14735 (unspec:XF [(match_dup 9) (match_dup 8)]
14736 UNSPEC_FSCALE_EXP))])
14737 (set (match_dup 12) (minus:XF (match_dup 10)
14738 (float_extend:XF (match_dup 13))))
14739 (set (match_operand:XF 0 "register_operand")
14740 (plus:XF (match_dup 12) (match_dup 7)))]
14741 "TARGET_USE_FANCY_MATH_387
14742 && flag_unsafe_math_optimizations"
14746 if (optimize_insn_for_size_p ())
14749 for (i = 2; i < 13; i++)
14750 operands[i] = gen_reg_rtx (XFmode);
14753 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14755 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14758 (define_expand "expm1<mode>2"
14759 [(use (match_operand:MODEF 0 "register_operand"))
14760 (use (match_operand:MODEF 1 "general_operand"))]
14761 "TARGET_USE_FANCY_MATH_387
14762 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14763 || TARGET_MIX_SSE_I387)
14764 && flag_unsafe_math_optimizations"
14768 if (optimize_insn_for_size_p ())
14771 op0 = gen_reg_rtx (XFmode);
14772 op1 = gen_reg_rtx (XFmode);
14774 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14775 emit_insn (gen_expm1xf2 (op0, op1));
14776 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14780 (define_expand "ldexpxf3"
14781 [(set (match_dup 3)
14782 (float:XF (match_operand:SI 2 "register_operand")))
14783 (parallel [(set (match_operand:XF 0 " register_operand")
14784 (unspec:XF [(match_operand:XF 1 "register_operand")
14786 UNSPEC_FSCALE_FRACT))
14788 (unspec:XF [(match_dup 1) (match_dup 3)]
14789 UNSPEC_FSCALE_EXP))])]
14790 "TARGET_USE_FANCY_MATH_387
14791 && flag_unsafe_math_optimizations"
14793 if (optimize_insn_for_size_p ())
14796 operands[3] = gen_reg_rtx (XFmode);
14797 operands[4] = gen_reg_rtx (XFmode);
14800 (define_expand "ldexp<mode>3"
14801 [(use (match_operand:MODEF 0 "register_operand"))
14802 (use (match_operand:MODEF 1 "general_operand"))
14803 (use (match_operand:SI 2 "register_operand"))]
14804 "TARGET_USE_FANCY_MATH_387
14805 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14806 || TARGET_MIX_SSE_I387)
14807 && flag_unsafe_math_optimizations"
14811 if (optimize_insn_for_size_p ())
14814 op0 = gen_reg_rtx (XFmode);
14815 op1 = gen_reg_rtx (XFmode);
14817 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14818 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14819 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14823 (define_expand "scalbxf3"
14824 [(parallel [(set (match_operand:XF 0 " register_operand")
14825 (unspec:XF [(match_operand:XF 1 "register_operand")
14826 (match_operand:XF 2 "register_operand")]
14827 UNSPEC_FSCALE_FRACT))
14829 (unspec:XF [(match_dup 1) (match_dup 2)]
14830 UNSPEC_FSCALE_EXP))])]
14831 "TARGET_USE_FANCY_MATH_387
14832 && flag_unsafe_math_optimizations"
14834 if (optimize_insn_for_size_p ())
14837 operands[3] = gen_reg_rtx (XFmode);
14840 (define_expand "scalb<mode>3"
14841 [(use (match_operand:MODEF 0 "register_operand"))
14842 (use (match_operand:MODEF 1 "general_operand"))
14843 (use (match_operand:MODEF 2 "general_operand"))]
14844 "TARGET_USE_FANCY_MATH_387
14845 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14846 || TARGET_MIX_SSE_I387)
14847 && flag_unsafe_math_optimizations"
14851 if (optimize_insn_for_size_p ())
14854 op0 = gen_reg_rtx (XFmode);
14855 op1 = gen_reg_rtx (XFmode);
14856 op2 = gen_reg_rtx (XFmode);
14858 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14859 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14860 emit_insn (gen_scalbxf3 (op0, op1, op2));
14861 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14865 (define_expand "significandxf2"
14866 [(parallel [(set (match_operand:XF 0 "register_operand")
14867 (unspec:XF [(match_operand:XF 1 "register_operand")]
14868 UNSPEC_XTRACT_FRACT))
14870 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14871 "TARGET_USE_FANCY_MATH_387
14872 && flag_unsafe_math_optimizations"
14873 "operands[2] = gen_reg_rtx (XFmode);")
14875 (define_expand "significand<mode>2"
14876 [(use (match_operand:MODEF 0 "register_operand"))
14877 (use (match_operand:MODEF 1 "register_operand"))]
14878 "TARGET_USE_FANCY_MATH_387
14879 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14880 || TARGET_MIX_SSE_I387)
14881 && flag_unsafe_math_optimizations"
14883 rtx op0 = gen_reg_rtx (XFmode);
14884 rtx op1 = gen_reg_rtx (XFmode);
14886 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14887 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14892 (define_insn "sse4_1_round<mode>2"
14893 [(set (match_operand:MODEF 0 "register_operand" "=x")
14894 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14895 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14898 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14899 [(set_attr "type" "ssecvt")
14900 (set_attr "prefix_extra" "1")
14901 (set_attr "prefix" "maybe_vex")
14902 (set_attr "mode" "<MODE>")])
14904 (define_insn "rintxf2"
14905 [(set (match_operand:XF 0 "register_operand" "=f")
14906 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14908 "TARGET_USE_FANCY_MATH_387
14909 && flag_unsafe_math_optimizations"
14911 [(set_attr "type" "fpspc")
14912 (set_attr "mode" "XF")])
14914 (define_expand "rint<mode>2"
14915 [(use (match_operand:MODEF 0 "register_operand"))
14916 (use (match_operand:MODEF 1 "register_operand"))]
14917 "(TARGET_USE_FANCY_MATH_387
14918 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14919 || TARGET_MIX_SSE_I387)
14920 && flag_unsafe_math_optimizations)
14921 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14922 && !flag_trapping_math)"
14924 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14925 && !flag_trapping_math)
14928 emit_insn (gen_sse4_1_round<mode>2
14929 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14930 else if (optimize_insn_for_size_p ())
14933 ix86_expand_rint (operands[0], operands[1]);
14937 rtx op0 = gen_reg_rtx (XFmode);
14938 rtx op1 = gen_reg_rtx (XFmode);
14940 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14941 emit_insn (gen_rintxf2 (op0, op1));
14943 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14948 (define_expand "round<mode>2"
14949 [(match_operand:X87MODEF 0 "register_operand")
14950 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14951 "(TARGET_USE_FANCY_MATH_387
14952 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14953 || TARGET_MIX_SSE_I387)
14954 && flag_unsafe_math_optimizations)
14955 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14956 && !flag_trapping_math && !flag_rounding_math)"
14958 if (optimize_insn_for_size_p ())
14961 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14962 && !flag_trapping_math && !flag_rounding_math)
14966 operands[1] = force_reg (<MODE>mode, operands[1]);
14967 ix86_expand_round_sse4 (operands[0], operands[1]);
14969 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14970 ix86_expand_round (operands[0], operands[1]);
14972 ix86_expand_rounddf_32 (operands[0], operands[1]);
14976 operands[1] = force_reg (<MODE>mode, operands[1]);
14977 ix86_emit_i387_round (operands[0], operands[1]);
14982 (define_insn_and_split "*fistdi2_1"
14983 [(set (match_operand:DI 0 "nonimmediate_operand")
14984 (unspec:DI [(match_operand:XF 1 "register_operand")]
14986 "TARGET_USE_FANCY_MATH_387
14987 && can_create_pseudo_p ()"
14992 if (memory_operand (operands[0], VOIDmode))
14993 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14996 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14997 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15002 [(set_attr "type" "fpspc")
15003 (set_attr "mode" "DI")])
15005 (define_insn "fistdi2"
15006 [(set (match_operand:DI 0 "memory_operand" "=m")
15007 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15009 (clobber (match_scratch:XF 2 "=&1f"))]
15010 "TARGET_USE_FANCY_MATH_387"
15011 "* return output_fix_trunc (insn, operands, false);"
15012 [(set_attr "type" "fpspc")
15013 (set_attr "mode" "DI")])
15015 (define_insn "fistdi2_with_temp"
15016 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15017 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15019 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15020 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15021 "TARGET_USE_FANCY_MATH_387"
15023 [(set_attr "type" "fpspc")
15024 (set_attr "mode" "DI")])
15027 [(set (match_operand:DI 0 "register_operand")
15028 (unspec:DI [(match_operand:XF 1 "register_operand")]
15030 (clobber (match_operand:DI 2 "memory_operand"))
15031 (clobber (match_scratch 3))]
15033 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15034 (clobber (match_dup 3))])
15035 (set (match_dup 0) (match_dup 2))])
15038 [(set (match_operand:DI 0 "memory_operand")
15039 (unspec:DI [(match_operand:XF 1 "register_operand")]
15041 (clobber (match_operand:DI 2 "memory_operand"))
15042 (clobber (match_scratch 3))]
15044 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15045 (clobber (match_dup 3))])])
15047 (define_insn_and_split "*fist<mode>2_1"
15048 [(set (match_operand:SWI24 0 "register_operand")
15049 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15051 "TARGET_USE_FANCY_MATH_387
15052 && can_create_pseudo_p ()"
15057 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15058 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15062 [(set_attr "type" "fpspc")
15063 (set_attr "mode" "<MODE>")])
15065 (define_insn "fist<mode>2"
15066 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15067 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15069 "TARGET_USE_FANCY_MATH_387"
15070 "* return output_fix_trunc (insn, operands, false);"
15071 [(set_attr "type" "fpspc")
15072 (set_attr "mode" "<MODE>")])
15074 (define_insn "fist<mode>2_with_temp"
15075 [(set (match_operand:SWI24 0 "register_operand" "=r")
15076 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15078 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15079 "TARGET_USE_FANCY_MATH_387"
15081 [(set_attr "type" "fpspc")
15082 (set_attr "mode" "<MODE>")])
15085 [(set (match_operand:SWI24 0 "register_operand")
15086 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15088 (clobber (match_operand:SWI24 2 "memory_operand"))]
15090 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15091 (set (match_dup 0) (match_dup 2))])
15094 [(set (match_operand:SWI24 0 "memory_operand")
15095 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15097 (clobber (match_operand:SWI24 2 "memory_operand"))]
15099 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15101 (define_expand "lrintxf<mode>2"
15102 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15103 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15105 "TARGET_USE_FANCY_MATH_387")
15107 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
15108 [(set (match_operand:SWI48x 0 "nonimmediate_operand")
15109 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand")]
15110 UNSPEC_FIX_NOTRUNC))]
15111 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15112 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
15114 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15115 [(match_operand:SWI248x 0 "nonimmediate_operand")
15116 (match_operand:X87MODEF 1 "register_operand")]
15117 "(TARGET_USE_FANCY_MATH_387
15118 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15119 || TARGET_MIX_SSE_I387)
15120 && flag_unsafe_math_optimizations)
15121 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15122 && <SWI248x:MODE>mode != HImode
15123 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15124 && !flag_trapping_math && !flag_rounding_math)"
15126 if (optimize_insn_for_size_p ())
15129 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15130 && <SWI248x:MODE>mode != HImode
15131 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15132 && !flag_trapping_math && !flag_rounding_math)
15133 ix86_expand_lround (operands[0], operands[1]);
15135 ix86_emit_i387_round (operands[0], operands[1]);
15139 (define_int_iterator FRNDINT_ROUNDING
15140 [UNSPEC_FRNDINT_FLOOR
15141 UNSPEC_FRNDINT_CEIL
15142 UNSPEC_FRNDINT_TRUNC])
15144 (define_int_iterator FIST_ROUNDING
15148 ;; Base name for define_insn
15149 (define_int_attr rounding_insn
15150 [(UNSPEC_FRNDINT_FLOOR "floor")
15151 (UNSPEC_FRNDINT_CEIL "ceil")
15152 (UNSPEC_FRNDINT_TRUNC "btrunc")
15153 (UNSPEC_FIST_FLOOR "floor")
15154 (UNSPEC_FIST_CEIL "ceil")])
15156 (define_int_attr rounding
15157 [(UNSPEC_FRNDINT_FLOOR "floor")
15158 (UNSPEC_FRNDINT_CEIL "ceil")
15159 (UNSPEC_FRNDINT_TRUNC "trunc")
15160 (UNSPEC_FIST_FLOOR "floor")
15161 (UNSPEC_FIST_CEIL "ceil")])
15163 (define_int_attr ROUNDING
15164 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15165 (UNSPEC_FRNDINT_CEIL "CEIL")
15166 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15167 (UNSPEC_FIST_FLOOR "FLOOR")
15168 (UNSPEC_FIST_CEIL "CEIL")])
15170 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15171 (define_insn_and_split "frndintxf2_<rounding>"
15172 [(set (match_operand:XF 0 "register_operand")
15173 (unspec:XF [(match_operand:XF 1 "register_operand")]
15175 (clobber (reg:CC FLAGS_REG))]
15176 "TARGET_USE_FANCY_MATH_387
15177 && flag_unsafe_math_optimizations
15178 && can_create_pseudo_p ()"
15183 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15185 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15186 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15188 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15189 operands[2], operands[3]));
15192 [(set_attr "type" "frndint")
15193 (set_attr "i387_cw" "<rounding>")
15194 (set_attr "mode" "XF")])
15196 (define_insn "frndintxf2_<rounding>_i387"
15197 [(set (match_operand:XF 0 "register_operand" "=f")
15198 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15200 (use (match_operand:HI 2 "memory_operand" "m"))
15201 (use (match_operand:HI 3 "memory_operand" "m"))]
15202 "TARGET_USE_FANCY_MATH_387
15203 && flag_unsafe_math_optimizations"
15204 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15205 [(set_attr "type" "frndint")
15206 (set_attr "i387_cw" "<rounding>")
15207 (set_attr "mode" "XF")])
15209 (define_expand "<rounding_insn>xf2"
15210 [(parallel [(set (match_operand:XF 0 "register_operand")
15211 (unspec:XF [(match_operand:XF 1 "register_operand")]
15213 (clobber (reg:CC FLAGS_REG))])]
15214 "TARGET_USE_FANCY_MATH_387
15215 && flag_unsafe_math_optimizations
15216 && !optimize_insn_for_size_p ()")
15218 (define_expand "<rounding_insn><mode>2"
15219 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15220 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15222 (clobber (reg:CC FLAGS_REG))])]
15223 "(TARGET_USE_FANCY_MATH_387
15224 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15225 || TARGET_MIX_SSE_I387)
15226 && flag_unsafe_math_optimizations)
15227 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15228 && !flag_trapping_math)"
15230 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15231 && !flag_trapping_math)
15234 emit_insn (gen_sse4_1_round<mode>2
15235 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15236 else if (optimize_insn_for_size_p ())
15238 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15240 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15241 ix86_expand_floorceil (operands[0], operands[1], true);
15242 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15243 ix86_expand_floorceil (operands[0], operands[1], false);
15244 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15245 ix86_expand_trunc (operands[0], operands[1]);
15247 gcc_unreachable ();
15251 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15252 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15253 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15254 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15255 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15256 ix86_expand_truncdf_32 (operands[0], operands[1]);
15258 gcc_unreachable ();
15265 if (optimize_insn_for_size_p ())
15268 op0 = gen_reg_rtx (XFmode);
15269 op1 = gen_reg_rtx (XFmode);
15270 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15271 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15273 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15278 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15279 (define_insn_and_split "frndintxf2_mask_pm"
15280 [(set (match_operand:XF 0 "register_operand")
15281 (unspec:XF [(match_operand:XF 1 "register_operand")]
15282 UNSPEC_FRNDINT_MASK_PM))
15283 (clobber (reg:CC FLAGS_REG))]
15284 "TARGET_USE_FANCY_MATH_387
15285 && flag_unsafe_math_optimizations
15286 && can_create_pseudo_p ()"
15291 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15293 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15294 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15296 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15297 operands[2], operands[3]));
15300 [(set_attr "type" "frndint")
15301 (set_attr "i387_cw" "mask_pm")
15302 (set_attr "mode" "XF")])
15304 (define_insn "frndintxf2_mask_pm_i387"
15305 [(set (match_operand:XF 0 "register_operand" "=f")
15306 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15307 UNSPEC_FRNDINT_MASK_PM))
15308 (use (match_operand:HI 2 "memory_operand" "m"))
15309 (use (match_operand:HI 3 "memory_operand" "m"))]
15310 "TARGET_USE_FANCY_MATH_387
15311 && flag_unsafe_math_optimizations"
15312 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15313 [(set_attr "type" "frndint")
15314 (set_attr "i387_cw" "mask_pm")
15315 (set_attr "mode" "XF")])
15317 (define_expand "nearbyintxf2"
15318 [(parallel [(set (match_operand:XF 0 "register_operand")
15319 (unspec:XF [(match_operand:XF 1 "register_operand")]
15320 UNSPEC_FRNDINT_MASK_PM))
15321 (clobber (reg:CC FLAGS_REG))])]
15322 "TARGET_USE_FANCY_MATH_387
15323 && flag_unsafe_math_optimizations")
15325 (define_expand "nearbyint<mode>2"
15326 [(use (match_operand:MODEF 0 "register_operand"))
15327 (use (match_operand:MODEF 1 "register_operand"))]
15328 "TARGET_USE_FANCY_MATH_387
15329 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15330 || TARGET_MIX_SSE_I387)
15331 && flag_unsafe_math_optimizations"
15333 rtx op0 = gen_reg_rtx (XFmode);
15334 rtx op1 = gen_reg_rtx (XFmode);
15336 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15337 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15339 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15343 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15344 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15345 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15346 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15348 (clobber (reg:CC FLAGS_REG))]
15349 "TARGET_USE_FANCY_MATH_387
15350 && flag_unsafe_math_optimizations
15351 && can_create_pseudo_p ()"
15356 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15358 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15359 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15360 if (memory_operand (operands[0], VOIDmode))
15361 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15362 operands[2], operands[3]));
15365 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15366 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15367 (operands[0], operands[1], operands[2],
15368 operands[3], operands[4]));
15372 [(set_attr "type" "fistp")
15373 (set_attr "i387_cw" "<rounding>")
15374 (set_attr "mode" "<MODE>")])
15376 (define_insn "fistdi2_<rounding>"
15377 [(set (match_operand:DI 0 "memory_operand" "=m")
15378 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15380 (use (match_operand:HI 2 "memory_operand" "m"))
15381 (use (match_operand:HI 3 "memory_operand" "m"))
15382 (clobber (match_scratch:XF 4 "=&1f"))]
15383 "TARGET_USE_FANCY_MATH_387
15384 && flag_unsafe_math_optimizations"
15385 "* return output_fix_trunc (insn, operands, false);"
15386 [(set_attr "type" "fistp")
15387 (set_attr "i387_cw" "<rounding>")
15388 (set_attr "mode" "DI")])
15390 (define_insn "fistdi2_<rounding>_with_temp"
15391 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15392 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15394 (use (match_operand:HI 2 "memory_operand" "m,m"))
15395 (use (match_operand:HI 3 "memory_operand" "m,m"))
15396 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15397 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15398 "TARGET_USE_FANCY_MATH_387
15399 && flag_unsafe_math_optimizations"
15401 [(set_attr "type" "fistp")
15402 (set_attr "i387_cw" "<rounding>")
15403 (set_attr "mode" "DI")])
15406 [(set (match_operand:DI 0 "register_operand")
15407 (unspec:DI [(match_operand:XF 1 "register_operand")]
15409 (use (match_operand:HI 2 "memory_operand"))
15410 (use (match_operand:HI 3 "memory_operand"))
15411 (clobber (match_operand:DI 4 "memory_operand"))
15412 (clobber (match_scratch 5))]
15414 [(parallel [(set (match_dup 4)
15415 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15416 (use (match_dup 2))
15417 (use (match_dup 3))
15418 (clobber (match_dup 5))])
15419 (set (match_dup 0) (match_dup 4))])
15422 [(set (match_operand:DI 0 "memory_operand")
15423 (unspec:DI [(match_operand:XF 1 "register_operand")]
15425 (use (match_operand:HI 2 "memory_operand"))
15426 (use (match_operand:HI 3 "memory_operand"))
15427 (clobber (match_operand:DI 4 "memory_operand"))
15428 (clobber (match_scratch 5))]
15430 [(parallel [(set (match_dup 0)
15431 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15432 (use (match_dup 2))
15433 (use (match_dup 3))
15434 (clobber (match_dup 5))])])
15436 (define_insn "fist<mode>2_<rounding>"
15437 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15438 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15440 (use (match_operand:HI 2 "memory_operand" "m"))
15441 (use (match_operand:HI 3 "memory_operand" "m"))]
15442 "TARGET_USE_FANCY_MATH_387
15443 && flag_unsafe_math_optimizations"
15444 "* return output_fix_trunc (insn, operands, false);"
15445 [(set_attr "type" "fistp")
15446 (set_attr "i387_cw" "<rounding>")
15447 (set_attr "mode" "<MODE>")])
15449 (define_insn "fist<mode>2_<rounding>_with_temp"
15450 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15451 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15453 (use (match_operand:HI 2 "memory_operand" "m,m"))
15454 (use (match_operand:HI 3 "memory_operand" "m,m"))
15455 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15456 "TARGET_USE_FANCY_MATH_387
15457 && flag_unsafe_math_optimizations"
15459 [(set_attr "type" "fistp")
15460 (set_attr "i387_cw" "<rounding>")
15461 (set_attr "mode" "<MODE>")])
15464 [(set (match_operand:SWI24 0 "register_operand")
15465 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15467 (use (match_operand:HI 2 "memory_operand"))
15468 (use (match_operand:HI 3 "memory_operand"))
15469 (clobber (match_operand:SWI24 4 "memory_operand"))]
15471 [(parallel [(set (match_dup 4)
15472 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15473 (use (match_dup 2))
15474 (use (match_dup 3))])
15475 (set (match_dup 0) (match_dup 4))])
15478 [(set (match_operand:SWI24 0 "memory_operand")
15479 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15481 (use (match_operand:HI 2 "memory_operand"))
15482 (use (match_operand:HI 3 "memory_operand"))
15483 (clobber (match_operand:SWI24 4 "memory_operand"))]
15485 [(parallel [(set (match_dup 0)
15486 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15487 (use (match_dup 2))
15488 (use (match_dup 3))])])
15490 (define_expand "l<rounding_insn>xf<mode>2"
15491 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15492 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15494 (clobber (reg:CC FLAGS_REG))])]
15495 "TARGET_USE_FANCY_MATH_387
15496 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15497 && flag_unsafe_math_optimizations")
15499 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15500 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15501 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15503 (clobber (reg:CC FLAGS_REG))])]
15504 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15505 && !flag_trapping_math"
15507 if (TARGET_64BIT && optimize_insn_for_size_p ())
15510 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15511 ix86_expand_lfloorceil (operands[0], operands[1], true);
15512 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15513 ix86_expand_lfloorceil (operands[0], operands[1], false);
15515 gcc_unreachable ();
15520 (define_insn "fxam<mode>2_i387"
15521 [(set (match_operand:HI 0 "register_operand" "=a")
15523 [(match_operand:X87MODEF 1 "register_operand" "f")]
15525 "TARGET_USE_FANCY_MATH_387"
15526 "fxam\n\tfnstsw\t%0"
15527 [(set_attr "type" "multi")
15528 (set_attr "length" "4")
15529 (set_attr "unit" "i387")
15530 (set_attr "mode" "<MODE>")])
15532 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15533 [(set (match_operand:HI 0 "register_operand")
15535 [(match_operand:MODEF 1 "memory_operand")]
15537 "TARGET_USE_FANCY_MATH_387
15538 && can_create_pseudo_p ()"
15541 [(set (match_dup 2)(match_dup 1))
15543 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15545 operands[2] = gen_reg_rtx (<MODE>mode);
15547 MEM_VOLATILE_P (operands[1]) = 1;
15549 [(set_attr "type" "multi")
15550 (set_attr "unit" "i387")
15551 (set_attr "mode" "<MODE>")])
15553 (define_expand "isinfxf2"
15554 [(use (match_operand:SI 0 "register_operand"))
15555 (use (match_operand:XF 1 "register_operand"))]
15556 "TARGET_USE_FANCY_MATH_387
15557 && TARGET_C99_FUNCTIONS"
15559 rtx mask = GEN_INT (0x45);
15560 rtx val = GEN_INT (0x05);
15564 rtx scratch = gen_reg_rtx (HImode);
15565 rtx res = gen_reg_rtx (QImode);
15567 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15569 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15570 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15571 cond = gen_rtx_fmt_ee (EQ, QImode,
15572 gen_rtx_REG (CCmode, FLAGS_REG),
15574 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15575 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15579 (define_expand "isinf<mode>2"
15580 [(use (match_operand:SI 0 "register_operand"))
15581 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15582 "TARGET_USE_FANCY_MATH_387
15583 && TARGET_C99_FUNCTIONS
15584 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15586 rtx mask = GEN_INT (0x45);
15587 rtx val = GEN_INT (0x05);
15591 rtx scratch = gen_reg_rtx (HImode);
15592 rtx res = gen_reg_rtx (QImode);
15594 /* Remove excess precision by forcing value through memory. */
15595 if (memory_operand (operands[1], VOIDmode))
15596 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15599 enum ix86_stack_slot slot = (virtuals_instantiated
15602 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15604 emit_move_insn (temp, operands[1]);
15605 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15608 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15609 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15610 cond = gen_rtx_fmt_ee (EQ, QImode,
15611 gen_rtx_REG (CCmode, FLAGS_REG),
15613 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15614 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15618 (define_expand "signbitxf2"
15619 [(use (match_operand:SI 0 "register_operand"))
15620 (use (match_operand:XF 1 "register_operand"))]
15621 "TARGET_USE_FANCY_MATH_387"
15623 rtx scratch = gen_reg_rtx (HImode);
15625 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15626 emit_insn (gen_andsi3 (operands[0],
15627 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15631 (define_insn "movmsk_df"
15632 [(set (match_operand:SI 0 "register_operand" "=r")
15634 [(match_operand:DF 1 "register_operand" "x")]
15636 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15637 "%vmovmskpd\t{%1, %0|%0, %1}"
15638 [(set_attr "type" "ssemov")
15639 (set_attr "prefix" "maybe_vex")
15640 (set_attr "mode" "DF")])
15642 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15643 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15644 (define_expand "signbitdf2"
15645 [(use (match_operand:SI 0 "register_operand"))
15646 (use (match_operand:DF 1 "register_operand"))]
15647 "TARGET_USE_FANCY_MATH_387
15648 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15650 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15652 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15653 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15657 rtx scratch = gen_reg_rtx (HImode);
15659 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15660 emit_insn (gen_andsi3 (operands[0],
15661 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15666 (define_expand "signbitsf2"
15667 [(use (match_operand:SI 0 "register_operand"))
15668 (use (match_operand:SF 1 "register_operand"))]
15669 "TARGET_USE_FANCY_MATH_387
15670 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15672 rtx scratch = gen_reg_rtx (HImode);
15674 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15675 emit_insn (gen_andsi3 (operands[0],
15676 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15680 ;; Block operation instructions
15683 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15686 [(set_attr "length" "1")
15687 (set_attr "length_immediate" "0")
15688 (set_attr "modrm" "0")])
15690 (define_expand "movmem<mode>"
15691 [(use (match_operand:BLK 0 "memory_operand"))
15692 (use (match_operand:BLK 1 "memory_operand"))
15693 (use (match_operand:SWI48 2 "nonmemory_operand"))
15694 (use (match_operand:SWI48 3 "const_int_operand"))
15695 (use (match_operand:SI 4 "const_int_operand"))
15696 (use (match_operand:SI 5 "const_int_operand"))]
15699 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15700 operands[4], operands[5]))
15706 ;; Most CPUs don't like single string operations
15707 ;; Handle this case here to simplify previous expander.
15709 (define_expand "strmov"
15710 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15711 (set (match_operand 1 "memory_operand") (match_dup 4))
15712 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15713 (clobber (reg:CC FLAGS_REG))])
15714 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15715 (clobber (reg:CC FLAGS_REG))])]
15718 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15720 /* If .md ever supports :P for Pmode, these can be directly
15721 in the pattern above. */
15722 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15723 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15725 /* Can't use this if the user has appropriated esi or edi. */
15726 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15727 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15729 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15730 operands[2], operands[3],
15731 operands[5], operands[6]));
15735 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15738 (define_expand "strmov_singleop"
15739 [(parallel [(set (match_operand 1 "memory_operand")
15740 (match_operand 3 "memory_operand"))
15741 (set (match_operand 0 "register_operand")
15743 (set (match_operand 2 "register_operand")
15744 (match_operand 5))])]
15746 "ix86_current_function_needs_cld = 1;")
15748 (define_insn "*strmovdi_rex_1"
15749 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15750 (mem:DI (match_operand:P 3 "register_operand" "1")))
15751 (set (match_operand:P 0 "register_operand" "=D")
15752 (plus:P (match_dup 2)
15754 (set (match_operand:P 1 "register_operand" "=S")
15755 (plus:P (match_dup 3)
15758 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15760 [(set_attr "type" "str")
15761 (set_attr "memory" "both")
15762 (set_attr "mode" "DI")])
15764 (define_insn "*strmovsi_1"
15765 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15766 (mem:SI (match_operand:P 3 "register_operand" "1")))
15767 (set (match_operand:P 0 "register_operand" "=D")
15768 (plus:P (match_dup 2)
15770 (set (match_operand:P 1 "register_operand" "=S")
15771 (plus:P (match_dup 3)
15773 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15775 [(set_attr "type" "str")
15776 (set_attr "memory" "both")
15777 (set_attr "mode" "SI")])
15779 (define_insn "*strmovhi_1"
15780 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15781 (mem:HI (match_operand:P 3 "register_operand" "1")))
15782 (set (match_operand:P 0 "register_operand" "=D")
15783 (plus:P (match_dup 2)
15785 (set (match_operand:P 1 "register_operand" "=S")
15786 (plus:P (match_dup 3)
15788 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15790 [(set_attr "type" "str")
15791 (set_attr "memory" "both")
15792 (set_attr "mode" "HI")])
15794 (define_insn "*strmovqi_1"
15795 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15796 (mem:QI (match_operand:P 3 "register_operand" "1")))
15797 (set (match_operand:P 0 "register_operand" "=D")
15798 (plus:P (match_dup 2)
15800 (set (match_operand:P 1 "register_operand" "=S")
15801 (plus:P (match_dup 3)
15803 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15805 [(set_attr "type" "str")
15806 (set_attr "memory" "both")
15807 (set (attr "prefix_rex")
15809 (match_test "<P:MODE>mode == DImode")
15811 (const_string "*")))
15812 (set_attr "mode" "QI")])
15814 (define_expand "rep_mov"
15815 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15816 (set (match_operand 0 "register_operand")
15818 (set (match_operand 2 "register_operand")
15820 (set (match_operand 1 "memory_operand")
15821 (match_operand 3 "memory_operand"))
15822 (use (match_dup 4))])]
15824 "ix86_current_function_needs_cld = 1;")
15826 (define_insn "*rep_movdi_rex64"
15827 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15828 (set (match_operand:P 0 "register_operand" "=D")
15829 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15831 (match_operand:P 3 "register_operand" "0")))
15832 (set (match_operand:P 1 "register_operand" "=S")
15833 (plus:P (ashift:P (match_dup 5) (const_int 3))
15834 (match_operand:P 4 "register_operand" "1")))
15835 (set (mem:BLK (match_dup 3))
15836 (mem:BLK (match_dup 4)))
15837 (use (match_dup 5))]
15839 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15841 [(set_attr "type" "str")
15842 (set_attr "prefix_rep" "1")
15843 (set_attr "memory" "both")
15844 (set_attr "mode" "DI")])
15846 (define_insn "*rep_movsi"
15847 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15848 (set (match_operand:P 0 "register_operand" "=D")
15849 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15851 (match_operand:P 3 "register_operand" "0")))
15852 (set (match_operand:P 1 "register_operand" "=S")
15853 (plus:P (ashift:P (match_dup 5) (const_int 2))
15854 (match_operand:P 4 "register_operand" "1")))
15855 (set (mem:BLK (match_dup 3))
15856 (mem:BLK (match_dup 4)))
15857 (use (match_dup 5))]
15858 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15859 "%^rep{%;} movs{l|d}"
15860 [(set_attr "type" "str")
15861 (set_attr "prefix_rep" "1")
15862 (set_attr "memory" "both")
15863 (set_attr "mode" "SI")])
15865 (define_insn "*rep_movqi"
15866 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15867 (set (match_operand:P 0 "register_operand" "=D")
15868 (plus:P (match_operand:P 3 "register_operand" "0")
15869 (match_operand:P 5 "register_operand" "2")))
15870 (set (match_operand:P 1 "register_operand" "=S")
15871 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15872 (set (mem:BLK (match_dup 3))
15873 (mem:BLK (match_dup 4)))
15874 (use (match_dup 5))]
15875 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15877 [(set_attr "type" "str")
15878 (set_attr "prefix_rep" "1")
15879 (set_attr "memory" "both")
15880 (set_attr "mode" "QI")])
15882 (define_expand "setmem<mode>"
15883 [(use (match_operand:BLK 0 "memory_operand"))
15884 (use (match_operand:SWI48 1 "nonmemory_operand"))
15885 (use (match_operand:QI 2 "nonmemory_operand"))
15886 (use (match_operand 3 "const_int_operand"))
15887 (use (match_operand:SI 4 "const_int_operand"))
15888 (use (match_operand:SI 5 "const_int_operand"))]
15891 if (ix86_expand_setmem (operands[0], operands[1],
15892 operands[2], operands[3],
15893 operands[4], operands[5]))
15899 ;; Most CPUs don't like single string operations
15900 ;; Handle this case here to simplify previous expander.
15902 (define_expand "strset"
15903 [(set (match_operand 1 "memory_operand")
15904 (match_operand 2 "register_operand"))
15905 (parallel [(set (match_operand 0 "register_operand")
15907 (clobber (reg:CC FLAGS_REG))])]
15910 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15911 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15913 /* If .md ever supports :P for Pmode, this can be directly
15914 in the pattern above. */
15915 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15916 GEN_INT (GET_MODE_SIZE (GET_MODE
15918 /* Can't use this if the user has appropriated eax or edi. */
15919 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15920 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15922 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15928 (define_expand "strset_singleop"
15929 [(parallel [(set (match_operand 1 "memory_operand")
15930 (match_operand 2 "register_operand"))
15931 (set (match_operand 0 "register_operand")
15932 (match_operand 3))])]
15934 "ix86_current_function_needs_cld = 1;")
15936 (define_insn "*strsetdi_rex_1"
15937 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15938 (match_operand:DI 2 "register_operand" "a"))
15939 (set (match_operand:P 0 "register_operand" "=D")
15940 (plus:P (match_dup 1)
15943 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15945 [(set_attr "type" "str")
15946 (set_attr "memory" "store")
15947 (set_attr "mode" "DI")])
15949 (define_insn "*strsetsi_1"
15950 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15951 (match_operand:SI 2 "register_operand" "a"))
15952 (set (match_operand:P 0 "register_operand" "=D")
15953 (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" "SI")])
15961 (define_insn "*strsethi_1"
15962 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15963 (match_operand:HI 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" "HI")])
15973 (define_insn "*strsetqi_1"
15974 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15975 (match_operand:QI 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 "prefix_rex")
15985 (match_test "<P:MODE>mode == DImode")
15987 (const_string "*")))
15988 (set_attr "mode" "QI")])
15990 (define_expand "rep_stos"
15991 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15992 (set (match_operand 0 "register_operand")
15994 (set (match_operand 2 "memory_operand") (const_int 0))
15995 (use (match_operand 3 "register_operand"))
15996 (use (match_dup 1))])]
15998 "ix86_current_function_needs_cld = 1;")
16000 (define_insn "*rep_stosdi_rex64"
16001 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16002 (set (match_operand:P 0 "register_operand" "=D")
16003 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16005 (match_operand:P 3 "register_operand" "0")))
16006 (set (mem:BLK (match_dup 3))
16008 (use (match_operand:DI 2 "register_operand" "a"))
16009 (use (match_dup 4))]
16011 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16013 [(set_attr "type" "str")
16014 (set_attr "prefix_rep" "1")
16015 (set_attr "memory" "store")
16016 (set_attr "mode" "DI")])
16018 (define_insn "*rep_stossi"
16019 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16020 (set (match_operand:P 0 "register_operand" "=D")
16021 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16023 (match_operand:P 3 "register_operand" "0")))
16024 (set (mem:BLK (match_dup 3))
16026 (use (match_operand:SI 2 "register_operand" "a"))
16027 (use (match_dup 4))]
16028 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16029 "%^rep{%;} stos{l|d}"
16030 [(set_attr "type" "str")
16031 (set_attr "prefix_rep" "1")
16032 (set_attr "memory" "store")
16033 (set_attr "mode" "SI")])
16035 (define_insn "*rep_stosqi"
16036 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16037 (set (match_operand:P 0 "register_operand" "=D")
16038 (plus:P (match_operand:P 3 "register_operand" "0")
16039 (match_operand:P 4 "register_operand" "1")))
16040 (set (mem:BLK (match_dup 3))
16042 (use (match_operand:QI 2 "register_operand" "a"))
16043 (use (match_dup 4))]
16044 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16046 [(set_attr "type" "str")
16047 (set_attr "prefix_rep" "1")
16048 (set_attr "memory" "store")
16049 (set (attr "prefix_rex")
16051 (match_test "<P:MODE>mode == DImode")
16053 (const_string "*")))
16054 (set_attr "mode" "QI")])
16056 (define_expand "cmpstrnsi"
16057 [(set (match_operand:SI 0 "register_operand")
16058 (compare:SI (match_operand:BLK 1 "general_operand")
16059 (match_operand:BLK 2 "general_operand")))
16060 (use (match_operand 3 "general_operand"))
16061 (use (match_operand 4 "immediate_operand"))]
16064 rtx addr1, addr2, out, outlow, count, countreg, align;
16066 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16069 /* Can't use this if the user has appropriated ecx, esi or edi. */
16070 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16075 out = gen_reg_rtx (SImode);
16077 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16078 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16079 if (addr1 != XEXP (operands[1], 0))
16080 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16081 if (addr2 != XEXP (operands[2], 0))
16082 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16084 count = operands[3];
16085 countreg = ix86_zero_extend_to_Pmode (count);
16087 /* %%% Iff we are testing strict equality, we can use known alignment
16088 to good advantage. This may be possible with combine, particularly
16089 once cc0 is dead. */
16090 align = operands[4];
16092 if (CONST_INT_P (count))
16094 if (INTVAL (count) == 0)
16096 emit_move_insn (operands[0], const0_rtx);
16099 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16100 operands[1], operands[2]));
16104 rtx (*gen_cmp) (rtx, rtx);
16106 gen_cmp = (TARGET_64BIT
16107 ? gen_cmpdi_1 : gen_cmpsi_1);
16109 emit_insn (gen_cmp (countreg, countreg));
16110 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16111 operands[1], operands[2]));
16114 outlow = gen_lowpart (QImode, out);
16115 emit_insn (gen_cmpintqi (outlow));
16116 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16118 if (operands[0] != out)
16119 emit_move_insn (operands[0], out);
16124 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16126 (define_expand "cmpintqi"
16127 [(set (match_dup 1)
16128 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16130 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16131 (parallel [(set (match_operand:QI 0 "register_operand")
16132 (minus:QI (match_dup 1)
16134 (clobber (reg:CC FLAGS_REG))])]
16137 operands[1] = gen_reg_rtx (QImode);
16138 operands[2] = gen_reg_rtx (QImode);
16141 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16142 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16144 (define_expand "cmpstrnqi_nz_1"
16145 [(parallel [(set (reg:CC FLAGS_REG)
16146 (compare:CC (match_operand 4 "memory_operand")
16147 (match_operand 5 "memory_operand")))
16148 (use (match_operand 2 "register_operand"))
16149 (use (match_operand:SI 3 "immediate_operand"))
16150 (clobber (match_operand 0 "register_operand"))
16151 (clobber (match_operand 1 "register_operand"))
16152 (clobber (match_dup 2))])]
16154 "ix86_current_function_needs_cld = 1;")
16156 (define_insn "*cmpstrnqi_nz_1"
16157 [(set (reg:CC FLAGS_REG)
16158 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16159 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16160 (use (match_operand:P 6 "register_operand" "2"))
16161 (use (match_operand:SI 3 "immediate_operand" "i"))
16162 (clobber (match_operand:P 0 "register_operand" "=S"))
16163 (clobber (match_operand:P 1 "register_operand" "=D"))
16164 (clobber (match_operand:P 2 "register_operand" "=c"))]
16165 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16167 [(set_attr "type" "str")
16168 (set_attr "mode" "QI")
16169 (set (attr "prefix_rex")
16171 (match_test "<P:MODE>mode == DImode")
16173 (const_string "*")))
16174 (set_attr "prefix_rep" "1")])
16176 ;; The same, but the count is not known to not be zero.
16178 (define_expand "cmpstrnqi_1"
16179 [(parallel [(set (reg:CC FLAGS_REG)
16180 (if_then_else:CC (ne (match_operand 2 "register_operand")
16182 (compare:CC (match_operand 4 "memory_operand")
16183 (match_operand 5 "memory_operand"))
16185 (use (match_operand:SI 3 "immediate_operand"))
16186 (use (reg:CC FLAGS_REG))
16187 (clobber (match_operand 0 "register_operand"))
16188 (clobber (match_operand 1 "register_operand"))
16189 (clobber (match_dup 2))])]
16191 "ix86_current_function_needs_cld = 1;")
16193 (define_insn "*cmpstrnqi_1"
16194 [(set (reg:CC FLAGS_REG)
16195 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16197 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16198 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16200 (use (match_operand:SI 3 "immediate_operand" "i"))
16201 (use (reg:CC FLAGS_REG))
16202 (clobber (match_operand:P 0 "register_operand" "=S"))
16203 (clobber (match_operand:P 1 "register_operand" "=D"))
16204 (clobber (match_operand:P 2 "register_operand" "=c"))]
16205 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16207 [(set_attr "type" "str")
16208 (set_attr "mode" "QI")
16209 (set (attr "prefix_rex")
16211 (match_test "<P:MODE>mode == DImode")
16213 (const_string "*")))
16214 (set_attr "prefix_rep" "1")])
16216 (define_expand "strlen<mode>"
16217 [(set (match_operand:P 0 "register_operand")
16218 (unspec:P [(match_operand:BLK 1 "general_operand")
16219 (match_operand:QI 2 "immediate_operand")
16220 (match_operand 3 "immediate_operand")]
16224 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16230 (define_expand "strlenqi_1"
16231 [(parallel [(set (match_operand 0 "register_operand")
16233 (clobber (match_operand 1 "register_operand"))
16234 (clobber (reg:CC FLAGS_REG))])]
16236 "ix86_current_function_needs_cld = 1;")
16238 (define_insn "*strlenqi_1"
16239 [(set (match_operand:P 0 "register_operand" "=&c")
16240 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16241 (match_operand:QI 2 "register_operand" "a")
16242 (match_operand:P 3 "immediate_operand" "i")
16243 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16244 (clobber (match_operand:P 1 "register_operand" "=D"))
16245 (clobber (reg:CC FLAGS_REG))]
16246 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16247 "%^repnz{%;} scasb"
16248 [(set_attr "type" "str")
16249 (set_attr "mode" "QI")
16250 (set (attr "prefix_rex")
16252 (match_test "<P:MODE>mode == DImode")
16254 (const_string "*")))
16255 (set_attr "prefix_rep" "1")])
16257 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16258 ;; handled in combine, but it is not currently up to the task.
16259 ;; When used for their truth value, the cmpstrn* expanders generate
16268 ;; The intermediate three instructions are unnecessary.
16270 ;; This one handles cmpstrn*_nz_1...
16273 (set (reg:CC FLAGS_REG)
16274 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16275 (mem:BLK (match_operand 5 "register_operand"))))
16276 (use (match_operand 6 "register_operand"))
16277 (use (match_operand:SI 3 "immediate_operand"))
16278 (clobber (match_operand 0 "register_operand"))
16279 (clobber (match_operand 1 "register_operand"))
16280 (clobber (match_operand 2 "register_operand"))])
16281 (set (match_operand:QI 7 "register_operand")
16282 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16283 (set (match_operand:QI 8 "register_operand")
16284 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16285 (set (reg FLAGS_REG)
16286 (compare (match_dup 7) (match_dup 8)))
16288 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16290 (set (reg:CC FLAGS_REG)
16291 (compare:CC (mem:BLK (match_dup 4))
16292 (mem:BLK (match_dup 5))))
16293 (use (match_dup 6))
16294 (use (match_dup 3))
16295 (clobber (match_dup 0))
16296 (clobber (match_dup 1))
16297 (clobber (match_dup 2))])])
16299 ;; ...and this one handles cmpstrn*_1.
16302 (set (reg:CC FLAGS_REG)
16303 (if_then_else:CC (ne (match_operand 6 "register_operand")
16305 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16306 (mem:BLK (match_operand 5 "register_operand")))
16308 (use (match_operand:SI 3 "immediate_operand"))
16309 (use (reg:CC FLAGS_REG))
16310 (clobber (match_operand 0 "register_operand"))
16311 (clobber (match_operand 1 "register_operand"))
16312 (clobber (match_operand 2 "register_operand"))])
16313 (set (match_operand:QI 7 "register_operand")
16314 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16315 (set (match_operand:QI 8 "register_operand")
16316 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16317 (set (reg FLAGS_REG)
16318 (compare (match_dup 7) (match_dup 8)))
16320 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16322 (set (reg:CC FLAGS_REG)
16323 (if_then_else:CC (ne (match_dup 6)
16325 (compare:CC (mem:BLK (match_dup 4))
16326 (mem:BLK (match_dup 5)))
16328 (use (match_dup 3))
16329 (use (reg:CC FLAGS_REG))
16330 (clobber (match_dup 0))
16331 (clobber (match_dup 1))
16332 (clobber (match_dup 2))])])
16334 ;; Conditional move instructions.
16336 (define_expand "mov<mode>cc"
16337 [(set (match_operand:SWIM 0 "register_operand")
16338 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator")
16339 (match_operand:SWIM 2 "<general_operand>")
16340 (match_operand:SWIM 3 "<general_operand>")))]
16342 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16344 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16345 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16346 ;; So just document what we're doing explicitly.
16348 (define_expand "x86_mov<mode>cc_0_m1"
16350 [(set (match_operand:SWI48 0 "register_operand")
16351 (if_then_else:SWI48
16352 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16353 [(match_operand 1 "flags_reg_operand")
16357 (clobber (reg:CC FLAGS_REG))])])
16359 (define_insn "*x86_mov<mode>cc_0_m1"
16360 [(set (match_operand:SWI48 0 "register_operand" "=r")
16361 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16362 [(reg FLAGS_REG) (const_int 0)])
16365 (clobber (reg:CC FLAGS_REG))]
16367 "sbb{<imodesuffix>}\t%0, %0"
16368 ; Since we don't have the proper number of operands for an alu insn,
16369 ; fill in all the blanks.
16370 [(set_attr "type" "alu")
16371 (set_attr "use_carry" "1")
16372 (set_attr "pent_pair" "pu")
16373 (set_attr "memory" "none")
16374 (set_attr "imm_disp" "false")
16375 (set_attr "mode" "<MODE>")
16376 (set_attr "length_immediate" "0")])
16378 (define_insn "*x86_mov<mode>cc_0_m1_se"
16379 [(set (match_operand:SWI48 0 "register_operand" "=r")
16380 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16381 [(reg FLAGS_REG) (const_int 0)])
16384 (clobber (reg:CC FLAGS_REG))]
16386 "sbb{<imodesuffix>}\t%0, %0"
16387 [(set_attr "type" "alu")
16388 (set_attr "use_carry" "1")
16389 (set_attr "pent_pair" "pu")
16390 (set_attr "memory" "none")
16391 (set_attr "imm_disp" "false")
16392 (set_attr "mode" "<MODE>")
16393 (set_attr "length_immediate" "0")])
16395 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16396 [(set (match_operand:SWI48 0 "register_operand" "=r")
16397 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16398 [(reg FLAGS_REG) (const_int 0)])))
16399 (clobber (reg:CC FLAGS_REG))]
16401 "sbb{<imodesuffix>}\t%0, %0"
16402 [(set_attr "type" "alu")
16403 (set_attr "use_carry" "1")
16404 (set_attr "pent_pair" "pu")
16405 (set_attr "memory" "none")
16406 (set_attr "imm_disp" "false")
16407 (set_attr "mode" "<MODE>")
16408 (set_attr "length_immediate" "0")])
16410 (define_insn "*mov<mode>cc_noc"
16411 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16412 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16413 [(reg FLAGS_REG) (const_int 0)])
16414 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16415 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16416 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16418 cmov%O2%C1\t{%2, %0|%0, %2}
16419 cmov%O2%c1\t{%3, %0|%0, %3}"
16420 [(set_attr "type" "icmov")
16421 (set_attr "mode" "<MODE>")])
16423 (define_insn "*movqicc_noc"
16424 [(set (match_operand:QI 0 "register_operand" "=r,r")
16425 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16426 [(reg FLAGS_REG) (const_int 0)])
16427 (match_operand:QI 2 "register_operand" "r,0")
16428 (match_operand:QI 3 "register_operand" "0,r")))]
16429 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16431 [(set_attr "type" "icmov")
16432 (set_attr "mode" "QI")])
16435 [(set (match_operand 0 "register_operand")
16436 (if_then_else (match_operator 1 "ix86_comparison_operator"
16437 [(reg FLAGS_REG) (const_int 0)])
16438 (match_operand 2 "register_operand")
16439 (match_operand 3 "register_operand")))]
16440 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16441 && (GET_MODE (operands[0]) == QImode
16442 || GET_MODE (operands[0]) == HImode)
16443 && reload_completed"
16444 [(set (match_dup 0)
16445 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16447 operands[0] = gen_lowpart (SImode, operands[0]);
16448 operands[2] = gen_lowpart (SImode, operands[2]);
16449 operands[3] = gen_lowpart (SImode, operands[3]);
16452 (define_expand "mov<mode>cc"
16453 [(set (match_operand:X87MODEF 0 "register_operand")
16454 (if_then_else:X87MODEF
16455 (match_operand 1 "ix86_fp_comparison_operator")
16456 (match_operand:X87MODEF 2 "register_operand")
16457 (match_operand:X87MODEF 3 "register_operand")))]
16458 "(TARGET_80387 && TARGET_CMOVE)
16459 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16460 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16462 (define_insn "*movxfcc_1"
16463 [(set (match_operand:XF 0 "register_operand" "=f,f")
16464 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16465 [(reg FLAGS_REG) (const_int 0)])
16466 (match_operand:XF 2 "register_operand" "f,0")
16467 (match_operand:XF 3 "register_operand" "0,f")))]
16468 "TARGET_80387 && TARGET_CMOVE"
16470 fcmov%F1\t{%2, %0|%0, %2}
16471 fcmov%f1\t{%3, %0|%0, %3}"
16472 [(set_attr "type" "fcmov")
16473 (set_attr "mode" "XF")])
16475 (define_insn "*movdfcc_1_rex64"
16476 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16477 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16478 [(reg FLAGS_REG) (const_int 0)])
16479 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16480 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16481 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16482 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16484 fcmov%F1\t{%2, %0|%0, %2}
16485 fcmov%f1\t{%3, %0|%0, %3}
16486 cmov%O2%C1\t{%2, %0|%0, %2}
16487 cmov%O2%c1\t{%3, %0|%0, %3}"
16488 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16489 (set_attr "mode" "DF,DF,DI,DI")])
16491 (define_insn "*movdfcc_1"
16492 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16493 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16494 [(reg FLAGS_REG) (const_int 0)])
16495 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16496 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16497 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16498 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16500 fcmov%F1\t{%2, %0|%0, %2}
16501 fcmov%f1\t{%3, %0|%0, %3}
16504 [(set_attr "type" "fcmov,fcmov,multi,multi")
16505 (set_attr "mode" "DF,DF,DI,DI")])
16508 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16509 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16510 [(reg FLAGS_REG) (const_int 0)])
16511 (match_operand:DF 2 "nonimmediate_operand")
16512 (match_operand:DF 3 "nonimmediate_operand")))]
16513 "!TARGET_64BIT && reload_completed"
16514 [(set (match_dup 2)
16515 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16517 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16519 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16520 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16523 (define_insn "*movsfcc_1_387"
16524 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16525 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16526 [(reg FLAGS_REG) (const_int 0)])
16527 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16528 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16529 "TARGET_80387 && TARGET_CMOVE
16530 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16532 fcmov%F1\t{%2, %0|%0, %2}
16533 fcmov%f1\t{%3, %0|%0, %3}
16534 cmov%O2%C1\t{%2, %0|%0, %2}
16535 cmov%O2%c1\t{%3, %0|%0, %3}"
16536 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16537 (set_attr "mode" "SF,SF,SI,SI")])
16539 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16540 ;; the scalar versions to have only XMM registers as operands.
16542 ;; XOP conditional move
16543 (define_insn "*xop_pcmov_<mode>"
16544 [(set (match_operand:MODEF 0 "register_operand" "=x")
16545 (if_then_else:MODEF
16546 (match_operand:MODEF 1 "register_operand" "x")
16547 (match_operand:MODEF 2 "register_operand" "x")
16548 (match_operand:MODEF 3 "register_operand" "x")))]
16550 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16551 [(set_attr "type" "sse4arg")])
16553 ;; These versions of the min/max patterns are intentionally ignorant of
16554 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16555 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16556 ;; are undefined in this condition, we're certain this is correct.
16558 (define_insn "<code><mode>3"
16559 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16561 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16562 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16563 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16565 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16566 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16567 [(set_attr "isa" "noavx,avx")
16568 (set_attr "prefix" "orig,vex")
16569 (set_attr "type" "sseadd")
16570 (set_attr "mode" "<MODE>")])
16572 ;; These versions of the min/max patterns implement exactly the operations
16573 ;; min = (op1 < op2 ? op1 : op2)
16574 ;; max = (!(op1 < op2) ? op1 : op2)
16575 ;; Their operands are not commutative, and thus they may be used in the
16576 ;; presence of -0.0 and NaN.
16578 (define_int_iterator IEEE_MAXMIN
16582 (define_int_attr ieee_maxmin
16583 [(UNSPEC_IEEE_MAX "max")
16584 (UNSPEC_IEEE_MIN "min")])
16586 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16587 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16589 [(match_operand:MODEF 1 "register_operand" "0,x")
16590 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16592 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16594 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16595 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16596 [(set_attr "isa" "noavx,avx")
16597 (set_attr "prefix" "orig,vex")
16598 (set_attr "type" "sseadd")
16599 (set_attr "mode" "<MODE>")])
16601 ;; Make two stack loads independent:
16603 ;; fld %st(0) -> fld bb
16604 ;; fmul bb fmul %st(1), %st
16606 ;; Actually we only match the last two instructions for simplicity.
16608 [(set (match_operand 0 "fp_register_operand")
16609 (match_operand 1 "fp_register_operand"))
16611 (match_operator 2 "binary_fp_operator"
16613 (match_operand 3 "memory_operand")]))]
16614 "REGNO (operands[0]) != REGNO (operands[1])"
16615 [(set (match_dup 0) (match_dup 3))
16616 (set (match_dup 0) (match_dup 4))]
16618 ;; The % modifier is not operational anymore in peephole2's, so we have to
16619 ;; swap the operands manually in the case of addition and multiplication.
16623 if (COMMUTATIVE_ARITH_P (operands[2]))
16624 op0 = operands[0], op1 = operands[1];
16626 op0 = operands[1], op1 = operands[0];
16628 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16629 GET_MODE (operands[2]),
16633 ;; Conditional addition patterns
16634 (define_expand "add<mode>cc"
16635 [(match_operand:SWI 0 "register_operand")
16636 (match_operand 1 "ordered_comparison_operator")
16637 (match_operand:SWI 2 "register_operand")
16638 (match_operand:SWI 3 "const_int_operand")]
16640 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16642 ;; Misc patterns (?)
16644 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16645 ;; Otherwise there will be nothing to keep
16647 ;; [(set (reg ebp) (reg esp))]
16648 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16649 ;; (clobber (eflags)]
16650 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16652 ;; in proper program order.
16654 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16655 [(set (match_operand:P 0 "register_operand" "=r,r")
16656 (plus:P (match_operand:P 1 "register_operand" "0,r")
16657 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16658 (clobber (reg:CC FLAGS_REG))
16659 (clobber (mem:BLK (scratch)))]
16662 switch (get_attr_type (insn))
16665 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16668 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16669 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16670 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16672 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16675 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16676 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16679 [(set (attr "type")
16680 (cond [(and (eq_attr "alternative" "0")
16681 (not (match_test "TARGET_OPT_AGU")))
16682 (const_string "alu")
16683 (match_operand:<MODE> 2 "const0_operand")
16684 (const_string "imov")
16686 (const_string "lea")))
16687 (set (attr "length_immediate")
16688 (cond [(eq_attr "type" "imov")
16690 (and (eq_attr "type" "alu")
16691 (match_operand 2 "const128_operand"))
16694 (const_string "*")))
16695 (set_attr "mode" "<MODE>")])
16697 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16698 [(set (match_operand:P 0 "register_operand" "=r")
16699 (minus:P (match_operand:P 1 "register_operand" "0")
16700 (match_operand:P 2 "register_operand" "r")))
16701 (clobber (reg:CC FLAGS_REG))
16702 (clobber (mem:BLK (scratch)))]
16704 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16705 [(set_attr "type" "alu")
16706 (set_attr "mode" "<MODE>")])
16708 (define_insn "allocate_stack_worker_probe_<mode>"
16709 [(set (match_operand:P 0 "register_operand" "=a")
16710 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16711 UNSPECV_STACK_PROBE))
16712 (clobber (reg:CC FLAGS_REG))]
16713 "ix86_target_stack_probe ()"
16714 "call\t___chkstk_ms"
16715 [(set_attr "type" "multi")
16716 (set_attr "length" "5")])
16718 (define_expand "allocate_stack"
16719 [(match_operand 0 "register_operand")
16720 (match_operand 1 "general_operand")]
16721 "ix86_target_stack_probe ()"
16725 #ifndef CHECK_STACK_LIMIT
16726 #define CHECK_STACK_LIMIT 0
16729 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16730 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16734 rtx (*insn) (rtx, rtx);
16736 x = copy_to_mode_reg (Pmode, operands[1]);
16738 insn = (TARGET_64BIT
16739 ? gen_allocate_stack_worker_probe_di
16740 : gen_allocate_stack_worker_probe_si);
16742 emit_insn (insn (x, x));
16745 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16746 stack_pointer_rtx, 0, OPTAB_DIRECT);
16748 if (x != stack_pointer_rtx)
16749 emit_move_insn (stack_pointer_rtx, x);
16751 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16755 ;; Use IOR for stack probes, this is shorter.
16756 (define_expand "probe_stack"
16757 [(match_operand 0 "memory_operand")]
16760 rtx (*gen_ior3) (rtx, rtx, rtx);
16762 gen_ior3 = (GET_MODE (operands[0]) == DImode
16763 ? gen_iordi3 : gen_iorsi3);
16765 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16769 (define_insn "adjust_stack_and_probe<mode>"
16770 [(set (match_operand:P 0 "register_operand" "=r")
16771 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16772 UNSPECV_PROBE_STACK_RANGE))
16773 (set (reg:P SP_REG)
16774 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16775 (clobber (reg:CC FLAGS_REG))
16776 (clobber (mem:BLK (scratch)))]
16778 "* return output_adjust_stack_and_probe (operands[0]);"
16779 [(set_attr "type" "multi")])
16781 (define_insn "probe_stack_range<mode>"
16782 [(set (match_operand:P 0 "register_operand" "=r")
16783 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16784 (match_operand:P 2 "const_int_operand" "n")]
16785 UNSPECV_PROBE_STACK_RANGE))
16786 (clobber (reg:CC FLAGS_REG))]
16788 "* return output_probe_stack_range (operands[0], operands[2]);"
16789 [(set_attr "type" "multi")])
16791 (define_expand "builtin_setjmp_receiver"
16792 [(label_ref (match_operand 0))]
16793 "!TARGET_64BIT && flag_pic"
16799 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16800 rtx label_rtx = gen_label_rtx ();
16801 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16802 xops[0] = xops[1] = picreg;
16803 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16804 ix86_expand_binary_operator (MINUS, SImode, xops);
16808 emit_insn (gen_set_got (pic_offset_table_rtx));
16812 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16815 [(set (match_operand 0 "register_operand")
16816 (match_operator 3 "promotable_binary_operator"
16817 [(match_operand 1 "register_operand")
16818 (match_operand 2 "aligned_operand")]))
16819 (clobber (reg:CC FLAGS_REG))]
16820 "! TARGET_PARTIAL_REG_STALL && reload_completed
16821 && ((GET_MODE (operands[0]) == HImode
16822 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16823 /* ??? next two lines just !satisfies_constraint_K (...) */
16824 || !CONST_INT_P (operands[2])
16825 || satisfies_constraint_K (operands[2])))
16826 || (GET_MODE (operands[0]) == QImode
16827 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16828 [(parallel [(set (match_dup 0)
16829 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16830 (clobber (reg:CC FLAGS_REG))])]
16832 operands[0] = gen_lowpart (SImode, operands[0]);
16833 operands[1] = gen_lowpart (SImode, operands[1]);
16834 if (GET_CODE (operands[3]) != ASHIFT)
16835 operands[2] = gen_lowpart (SImode, operands[2]);
16836 PUT_MODE (operands[3], SImode);
16839 ; Promote the QImode tests, as i386 has encoding of the AND
16840 ; instruction with 32-bit sign-extended immediate and thus the
16841 ; instruction size is unchanged, except in the %eax case for
16842 ; which it is increased by one byte, hence the ! optimize_size.
16844 [(set (match_operand 0 "flags_reg_operand")
16845 (match_operator 2 "compare_operator"
16846 [(and (match_operand 3 "aligned_operand")
16847 (match_operand 4 "const_int_operand"))
16849 (set (match_operand 1 "register_operand")
16850 (and (match_dup 3) (match_dup 4)))]
16851 "! TARGET_PARTIAL_REG_STALL && reload_completed
16852 && optimize_insn_for_speed_p ()
16853 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16854 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16855 /* Ensure that the operand will remain sign-extended immediate. */
16856 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16857 [(parallel [(set (match_dup 0)
16858 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16861 (and:SI (match_dup 3) (match_dup 4)))])]
16864 = gen_int_mode (INTVAL (operands[4])
16865 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16866 operands[1] = gen_lowpart (SImode, operands[1]);
16867 operands[3] = gen_lowpart (SImode, operands[3]);
16870 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16871 ; the TEST instruction with 32-bit sign-extended immediate and thus
16872 ; the instruction size would at least double, which is not what we
16873 ; want even with ! optimize_size.
16875 [(set (match_operand 0 "flags_reg_operand")
16876 (match_operator 1 "compare_operator"
16877 [(and (match_operand:HI 2 "aligned_operand")
16878 (match_operand:HI 3 "const_int_operand"))
16880 "! TARGET_PARTIAL_REG_STALL && reload_completed
16881 && ! TARGET_FAST_PREFIX
16882 && optimize_insn_for_speed_p ()
16883 /* Ensure that the operand will remain sign-extended immediate. */
16884 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16885 [(set (match_dup 0)
16886 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16890 = gen_int_mode (INTVAL (operands[3])
16891 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16892 operands[2] = gen_lowpart (SImode, operands[2]);
16896 [(set (match_operand 0 "register_operand")
16897 (neg (match_operand 1 "register_operand")))
16898 (clobber (reg:CC FLAGS_REG))]
16899 "! TARGET_PARTIAL_REG_STALL && reload_completed
16900 && (GET_MODE (operands[0]) == HImode
16901 || (GET_MODE (operands[0]) == QImode
16902 && (TARGET_PROMOTE_QImode
16903 || optimize_insn_for_size_p ())))"
16904 [(parallel [(set (match_dup 0)
16905 (neg:SI (match_dup 1)))
16906 (clobber (reg:CC FLAGS_REG))])]
16908 operands[0] = gen_lowpart (SImode, operands[0]);
16909 operands[1] = gen_lowpart (SImode, operands[1]);
16913 [(set (match_operand 0 "register_operand")
16914 (not (match_operand 1 "register_operand")))]
16915 "! TARGET_PARTIAL_REG_STALL && reload_completed
16916 && (GET_MODE (operands[0]) == HImode
16917 || (GET_MODE (operands[0]) == QImode
16918 && (TARGET_PROMOTE_QImode
16919 || optimize_insn_for_size_p ())))"
16920 [(set (match_dup 0)
16921 (not:SI (match_dup 1)))]
16923 operands[0] = gen_lowpart (SImode, operands[0]);
16924 operands[1] = gen_lowpart (SImode, operands[1]);
16927 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16928 ;; transform a complex memory operation into two memory to register operations.
16930 ;; Don't push memory operands
16932 [(set (match_operand:SWI 0 "push_operand")
16933 (match_operand:SWI 1 "memory_operand"))
16934 (match_scratch:SWI 2 "<r>")]
16935 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16936 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16937 [(set (match_dup 2) (match_dup 1))
16938 (set (match_dup 0) (match_dup 2))])
16940 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16943 [(set (match_operand:SF 0 "push_operand")
16944 (match_operand:SF 1 "memory_operand"))
16945 (match_scratch:SF 2 "r")]
16946 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16947 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16948 [(set (match_dup 2) (match_dup 1))
16949 (set (match_dup 0) (match_dup 2))])
16951 ;; Don't move an immediate directly to memory when the instruction
16952 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16954 [(match_scratch:SWI124 1 "<r>")
16955 (set (match_operand:SWI124 0 "memory_operand")
16957 "optimize_insn_for_speed_p ()
16958 && ((<MODE>mode == HImode
16959 && TARGET_LCP_STALL)
16960 || (!TARGET_USE_MOV0
16961 && TARGET_SPLIT_LONG_MOVES
16962 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16963 && peep2_regno_dead_p (0, FLAGS_REG)"
16964 [(parallel [(set (match_dup 2) (const_int 0))
16965 (clobber (reg:CC FLAGS_REG))])
16966 (set (match_dup 0) (match_dup 1))]
16967 "operands[2] = gen_lowpart (SImode, operands[1]);")
16970 [(match_scratch:SWI124 2 "<r>")
16971 (set (match_operand:SWI124 0 "memory_operand")
16972 (match_operand:SWI124 1 "immediate_operand"))]
16973 "optimize_insn_for_speed_p ()
16974 && ((<MODE>mode == HImode
16975 && TARGET_LCP_STALL)
16976 || (TARGET_SPLIT_LONG_MOVES
16977 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16978 [(set (match_dup 2) (match_dup 1))
16979 (set (match_dup 0) (match_dup 2))])
16981 ;; Don't compare memory with zero, load and use a test instead.
16983 [(set (match_operand 0 "flags_reg_operand")
16984 (match_operator 1 "compare_operator"
16985 [(match_operand:SI 2 "memory_operand")
16987 (match_scratch:SI 3 "r")]
16988 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16989 [(set (match_dup 3) (match_dup 2))
16990 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16992 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16993 ;; Don't split NOTs with a displacement operand, because resulting XOR
16994 ;; will not be pairable anyway.
16996 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16997 ;; represented using a modRM byte. The XOR replacement is long decoded,
16998 ;; so this split helps here as well.
17000 ;; Note: Can't do this as a regular split because we can't get proper
17001 ;; lifetime information then.
17004 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17005 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17006 "optimize_insn_for_speed_p ()
17007 && ((TARGET_NOT_UNPAIRABLE
17008 && (!MEM_P (operands[0])
17009 || !memory_displacement_operand (operands[0], <MODE>mode)))
17010 || (TARGET_NOT_VECTORMODE
17011 && long_memory_operand (operands[0], <MODE>mode)))
17012 && peep2_regno_dead_p (0, FLAGS_REG)"
17013 [(parallel [(set (match_dup 0)
17014 (xor:SWI124 (match_dup 1) (const_int -1)))
17015 (clobber (reg:CC FLAGS_REG))])])
17017 ;; Non pairable "test imm, reg" instructions can be translated to
17018 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17019 ;; byte opcode instead of two, have a short form for byte operands),
17020 ;; so do it for other CPUs as well. Given that the value was dead,
17021 ;; this should not create any new dependencies. Pass on the sub-word
17022 ;; versions if we're concerned about partial register stalls.
17025 [(set (match_operand 0 "flags_reg_operand")
17026 (match_operator 1 "compare_operator"
17027 [(and:SI (match_operand:SI 2 "register_operand")
17028 (match_operand:SI 3 "immediate_operand"))
17030 "ix86_match_ccmode (insn, CCNOmode)
17031 && (true_regnum (operands[2]) != AX_REG
17032 || satisfies_constraint_K (operands[3]))
17033 && peep2_reg_dead_p (1, operands[2])"
17035 [(set (match_dup 0)
17036 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17039 (and:SI (match_dup 2) (match_dup 3)))])])
17041 ;; We don't need to handle HImode case, because it will be promoted to SImode
17042 ;; on ! TARGET_PARTIAL_REG_STALL
17045 [(set (match_operand 0 "flags_reg_operand")
17046 (match_operator 1 "compare_operator"
17047 [(and:QI (match_operand:QI 2 "register_operand")
17048 (match_operand:QI 3 "immediate_operand"))
17050 "! TARGET_PARTIAL_REG_STALL
17051 && ix86_match_ccmode (insn, CCNOmode)
17052 && true_regnum (operands[2]) != AX_REG
17053 && peep2_reg_dead_p (1, operands[2])"
17055 [(set (match_dup 0)
17056 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17059 (and:QI (match_dup 2) (match_dup 3)))])])
17062 [(set (match_operand 0 "flags_reg_operand")
17063 (match_operator 1 "compare_operator"
17066 (match_operand 2 "ext_register_operand")
17069 (match_operand 3 "const_int_operand"))
17071 "! TARGET_PARTIAL_REG_STALL
17072 && ix86_match_ccmode (insn, CCNOmode)
17073 && true_regnum (operands[2]) != AX_REG
17074 && peep2_reg_dead_p (1, operands[2])"
17075 [(parallel [(set (match_dup 0)
17084 (set (zero_extract:SI (match_dup 2)
17092 (match_dup 3)))])])
17094 ;; Don't do logical operations with memory inputs.
17096 [(match_scratch:SI 2 "r")
17097 (parallel [(set (match_operand:SI 0 "register_operand")
17098 (match_operator:SI 3 "arith_or_logical_operator"
17100 (match_operand:SI 1 "memory_operand")]))
17101 (clobber (reg:CC FLAGS_REG))])]
17102 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17103 [(set (match_dup 2) (match_dup 1))
17104 (parallel [(set (match_dup 0)
17105 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17106 (clobber (reg:CC FLAGS_REG))])])
17109 [(match_scratch:SI 2 "r")
17110 (parallel [(set (match_operand:SI 0 "register_operand")
17111 (match_operator:SI 3 "arith_or_logical_operator"
17112 [(match_operand:SI 1 "memory_operand")
17114 (clobber (reg:CC FLAGS_REG))])]
17115 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17116 [(set (match_dup 2) (match_dup 1))
17117 (parallel [(set (match_dup 0)
17118 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17119 (clobber (reg:CC FLAGS_REG))])])
17121 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17122 ;; refers to the destination of the load!
17125 [(set (match_operand:SI 0 "register_operand")
17126 (match_operand:SI 1 "register_operand"))
17127 (parallel [(set (match_dup 0)
17128 (match_operator:SI 3 "commutative_operator"
17130 (match_operand:SI 2 "memory_operand")]))
17131 (clobber (reg:CC FLAGS_REG))])]
17132 "REGNO (operands[0]) != REGNO (operands[1])
17133 && GENERAL_REGNO_P (REGNO (operands[0]))
17134 && GENERAL_REGNO_P (REGNO (operands[1]))"
17135 [(set (match_dup 0) (match_dup 4))
17136 (parallel [(set (match_dup 0)
17137 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17138 (clobber (reg:CC FLAGS_REG))])]
17139 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17142 [(set (match_operand 0 "register_operand")
17143 (match_operand 1 "register_operand"))
17145 (match_operator 3 "commutative_operator"
17147 (match_operand 2 "memory_operand")]))]
17148 "REGNO (operands[0]) != REGNO (operands[1])
17149 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17150 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17151 [(set (match_dup 0) (match_dup 2))
17153 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17155 ; Don't do logical operations with memory outputs
17157 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17158 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17159 ; the same decoder scheduling characteristics as the original.
17162 [(match_scratch:SI 2 "r")
17163 (parallel [(set (match_operand:SI 0 "memory_operand")
17164 (match_operator:SI 3 "arith_or_logical_operator"
17166 (match_operand:SI 1 "nonmemory_operand")]))
17167 (clobber (reg:CC FLAGS_REG))])]
17168 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17169 /* Do not split stack checking probes. */
17170 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17171 [(set (match_dup 2) (match_dup 0))
17172 (parallel [(set (match_dup 2)
17173 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17174 (clobber (reg:CC FLAGS_REG))])
17175 (set (match_dup 0) (match_dup 2))])
17178 [(match_scratch:SI 2 "r")
17179 (parallel [(set (match_operand:SI 0 "memory_operand")
17180 (match_operator:SI 3 "arith_or_logical_operator"
17181 [(match_operand:SI 1 "nonmemory_operand")
17183 (clobber (reg:CC FLAGS_REG))])]
17184 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17185 /* Do not split stack checking probes. */
17186 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17187 [(set (match_dup 2) (match_dup 0))
17188 (parallel [(set (match_dup 2)
17189 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17190 (clobber (reg:CC FLAGS_REG))])
17191 (set (match_dup 0) (match_dup 2))])
17193 ;; Attempt to use arith or logical operations with memory outputs with
17194 ;; setting of flags.
17196 [(set (match_operand:SWI 0 "register_operand")
17197 (match_operand:SWI 1 "memory_operand"))
17198 (parallel [(set (match_dup 0)
17199 (match_operator:SWI 3 "plusminuslogic_operator"
17201 (match_operand:SWI 2 "<nonmemory_operand>")]))
17202 (clobber (reg:CC FLAGS_REG))])
17203 (set (match_dup 1) (match_dup 0))
17204 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17205 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17206 && peep2_reg_dead_p (4, operands[0])
17207 && !reg_overlap_mentioned_p (operands[0], operands[1])
17208 && (<MODE>mode != QImode
17209 || immediate_operand (operands[2], QImode)
17210 || q_regs_operand (operands[2], QImode))
17211 && ix86_match_ccmode (peep2_next_insn (3),
17212 (GET_CODE (operands[3]) == PLUS
17213 || GET_CODE (operands[3]) == MINUS)
17214 ? CCGOCmode : CCNOmode)"
17215 [(parallel [(set (match_dup 4) (match_dup 5))
17216 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17217 (match_dup 2)]))])]
17219 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17220 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17221 copy_rtx (operands[1]),
17222 copy_rtx (operands[2]));
17223 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17224 operands[5], const0_rtx);
17228 [(parallel [(set (match_operand:SWI 0 "register_operand")
17229 (match_operator:SWI 2 "plusminuslogic_operator"
17231 (match_operand:SWI 1 "memory_operand")]))
17232 (clobber (reg:CC FLAGS_REG))])
17233 (set (match_dup 1) (match_dup 0))
17234 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17235 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17236 && GET_CODE (operands[2]) != MINUS
17237 && peep2_reg_dead_p (3, operands[0])
17238 && !reg_overlap_mentioned_p (operands[0], operands[1])
17239 && ix86_match_ccmode (peep2_next_insn (2),
17240 GET_CODE (operands[2]) == PLUS
17241 ? CCGOCmode : CCNOmode)"
17242 [(parallel [(set (match_dup 3) (match_dup 4))
17243 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17244 (match_dup 0)]))])]
17246 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17247 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17248 copy_rtx (operands[1]),
17249 copy_rtx (operands[0]));
17250 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17251 operands[4], const0_rtx);
17255 [(set (match_operand:SWI12 0 "register_operand")
17256 (match_operand:SWI12 1 "memory_operand"))
17257 (parallel [(set (match_operand:SI 4 "register_operand")
17258 (match_operator:SI 3 "plusminuslogic_operator"
17260 (match_operand:SI 2 "nonmemory_operand")]))
17261 (clobber (reg:CC FLAGS_REG))])
17262 (set (match_dup 1) (match_dup 0))
17263 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17264 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17265 && REG_P (operands[0]) && REG_P (operands[4])
17266 && REGNO (operands[0]) == REGNO (operands[4])
17267 && peep2_reg_dead_p (4, operands[0])
17268 && (<MODE>mode != QImode
17269 || immediate_operand (operands[2], SImode)
17270 || q_regs_operand (operands[2], SImode))
17271 && !reg_overlap_mentioned_p (operands[0], operands[1])
17272 && ix86_match_ccmode (peep2_next_insn (3),
17273 (GET_CODE (operands[3]) == PLUS
17274 || GET_CODE (operands[3]) == MINUS)
17275 ? CCGOCmode : CCNOmode)"
17276 [(parallel [(set (match_dup 4) (match_dup 5))
17277 (set (match_dup 1) (match_dup 6))])]
17279 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17280 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17281 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17282 copy_rtx (operands[1]), operands[2]);
17283 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17284 operands[5], const0_rtx);
17285 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17286 copy_rtx (operands[1]),
17287 copy_rtx (operands[2]));
17290 ;; Attempt to always use XOR for zeroing registers.
17292 [(set (match_operand 0 "register_operand")
17293 (match_operand 1 "const0_operand"))]
17294 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17295 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17296 && GENERAL_REG_P (operands[0])
17297 && peep2_regno_dead_p (0, FLAGS_REG)"
17298 [(parallel [(set (match_dup 0) (const_int 0))
17299 (clobber (reg:CC FLAGS_REG))])]
17300 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17303 [(set (strict_low_part (match_operand 0 "register_operand"))
17305 "(GET_MODE (operands[0]) == QImode
17306 || GET_MODE (operands[0]) == HImode)
17307 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17308 && peep2_regno_dead_p (0, FLAGS_REG)"
17309 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17310 (clobber (reg:CC FLAGS_REG))])])
17312 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17314 [(set (match_operand:SWI248 0 "register_operand")
17316 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17317 && peep2_regno_dead_p (0, FLAGS_REG)"
17318 [(parallel [(set (match_dup 0) (const_int -1))
17319 (clobber (reg:CC FLAGS_REG))])]
17321 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17322 operands[0] = gen_lowpart (SImode, operands[0]);
17325 ;; Attempt to convert simple lea to add/shift.
17326 ;; These can be created by move expanders.
17327 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17328 ;; relevant lea instructions were already split.
17331 [(set (match_operand:SWI48 0 "register_operand")
17332 (plus:SWI48 (match_dup 0)
17333 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17335 && peep2_regno_dead_p (0, FLAGS_REG)"
17336 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17337 (clobber (reg:CC FLAGS_REG))])])
17340 [(set (match_operand:SWI48 0 "register_operand")
17341 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17344 && peep2_regno_dead_p (0, FLAGS_REG)"
17345 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17346 (clobber (reg:CC FLAGS_REG))])])
17349 [(set (match_operand:SI 0 "register_operand")
17350 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand")
17351 (match_operand:DI 2 "nonmemory_operand")) 0))]
17352 "TARGET_64BIT && !TARGET_OPT_AGU
17353 && REGNO (operands[0]) == REGNO (operands[1])
17354 && peep2_regno_dead_p (0, FLAGS_REG)"
17355 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17356 (clobber (reg:CC FLAGS_REG))])]
17357 "operands[2] = gen_lowpart (SImode, operands[2]);")
17360 [(set (match_operand:SI 0 "register_operand")
17361 (subreg:SI (plus:DI (match_operand:DI 1 "nonmemory_operand")
17362 (match_operand:DI 2 "register_operand")) 0))]
17363 "TARGET_64BIT && !TARGET_OPT_AGU
17364 && REGNO (operands[0]) == REGNO (operands[2])
17365 && peep2_regno_dead_p (0, FLAGS_REG)"
17366 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17367 (clobber (reg:CC FLAGS_REG))])]
17368 "operands[1] = gen_lowpart (SImode, operands[1]);")
17371 [(set (match_operand:DI 0 "register_operand")
17373 (plus:SI (match_operand:SI 1 "register_operand")
17374 (match_operand:SI 2 "nonmemory_operand"))))]
17375 "TARGET_64BIT && !TARGET_OPT_AGU
17376 && REGNO (operands[0]) == REGNO (operands[1])
17377 && peep2_regno_dead_p (0, FLAGS_REG)"
17378 [(parallel [(set (match_dup 0)
17379 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17380 (clobber (reg:CC FLAGS_REG))])])
17383 [(set (match_operand:DI 0 "register_operand")
17385 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17386 (match_operand:SI 2 "register_operand"))))]
17387 "TARGET_64BIT && !TARGET_OPT_AGU
17388 && REGNO (operands[0]) == REGNO (operands[2])
17389 && peep2_regno_dead_p (0, FLAGS_REG)"
17390 [(parallel [(set (match_dup 0)
17391 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17392 (clobber (reg:CC FLAGS_REG))])])
17395 [(set (match_operand:DI 0 "register_operand")
17397 (subreg:SI (plus:DI (match_dup 0)
17398 (match_operand:DI 1 "nonmemory_operand")) 0)))]
17399 "TARGET_64BIT && !TARGET_OPT_AGU
17400 && peep2_regno_dead_p (0, FLAGS_REG)"
17401 [(parallel [(set (match_dup 0)
17402 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17403 (clobber (reg:CC FLAGS_REG))])]
17405 operands[1] = gen_lowpart (SImode, operands[1]);
17406 operands[2] = gen_lowpart (SImode, operands[0]);
17410 [(set (match_operand:DI 0 "register_operand")
17412 (subreg:SI (plus:DI (match_operand:DI 1 "nonmemory_operand")
17413 (match_dup 0)) 0)))]
17414 "TARGET_64BIT && !TARGET_OPT_AGU
17415 && peep2_regno_dead_p (0, FLAGS_REG)"
17416 [(parallel [(set (match_dup 0)
17417 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17418 (clobber (reg:CC FLAGS_REG))])]
17420 operands[1] = gen_lowpart (SImode, operands[1]);
17421 operands[2] = gen_lowpart (SImode, operands[0]);
17425 [(set (match_operand:SWI48 0 "register_operand")
17426 (mult:SWI48 (match_dup 0)
17427 (match_operand:SWI48 1 "const_int_operand")))]
17428 "exact_log2 (INTVAL (operands[1])) >= 0
17429 && peep2_regno_dead_p (0, FLAGS_REG)"
17430 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17431 (clobber (reg:CC FLAGS_REG))])]
17432 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17435 [(set (match_operand:SI 0 "register_operand")
17436 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand")
17437 (match_operand:DI 2 "const_int_operand")) 0))]
17439 && exact_log2 (INTVAL (operands[2])) >= 0
17440 && REGNO (operands[0]) == REGNO (operands[1])
17441 && peep2_regno_dead_p (0, FLAGS_REG)"
17442 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17443 (clobber (reg:CC FLAGS_REG))])]
17444 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17447 [(set (match_operand:DI 0 "register_operand")
17449 (mult:SI (match_operand:SI 1 "register_operand")
17450 (match_operand:SI 2 "const_int_operand"))))]
17452 && exact_log2 (INTVAL (operands[2])) >= 0
17453 && REGNO (operands[0]) == REGNO (operands[1])
17454 && peep2_regno_dead_p (0, FLAGS_REG)"
17455 [(parallel [(set (match_dup 0)
17456 (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
17457 (clobber (reg:CC FLAGS_REG))])]
17458 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17461 [(set (match_operand:DI 0 "register_operand")
17463 (subreg:SI (mult:DI (match_dup 0)
17464 (match_operand:DI 1 "const_int_operand")) 0)))]
17466 && exact_log2 (INTVAL (operands[2])) >= 0
17467 && peep2_regno_dead_p (0, FLAGS_REG)"
17468 [(parallel [(set (match_dup 0)
17469 (zero_extend:DI (ashift:SI (match_dup 2) (match_dup 1))))
17470 (clobber (reg:CC FLAGS_REG))])]
17472 operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
17473 operands[2] = gen_lowpart (SImode, operands[0]);
17476 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17477 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17478 ;; On many CPUs it is also faster, since special hardware to avoid esp
17479 ;; dependencies is present.
17481 ;; While some of these conversions may be done using splitters, we use
17482 ;; peepholes in order to allow combine_stack_adjustments pass to see
17483 ;; nonobfuscated RTL.
17485 ;; Convert prologue esp subtractions to push.
17486 ;; We need register to push. In order to keep verify_flow_info happy we have
17488 ;; - use scratch and clobber it in order to avoid dependencies
17489 ;; - use already live register
17490 ;; We can't use the second way right now, since there is no reliable way how to
17491 ;; verify that given register is live. First choice will also most likely in
17492 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17493 ;; call clobbered registers are dead. We may want to use base pointer as an
17494 ;; alternative when no register is available later.
17497 [(match_scratch:W 1 "r")
17498 (parallel [(set (reg:P SP_REG)
17499 (plus:P (reg:P SP_REG)
17500 (match_operand:P 0 "const_int_operand")))
17501 (clobber (reg:CC FLAGS_REG))
17502 (clobber (mem:BLK (scratch)))])]
17503 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17504 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17505 [(clobber (match_dup 1))
17506 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17507 (clobber (mem:BLK (scratch)))])])
17510 [(match_scratch:W 1 "r")
17511 (parallel [(set (reg:P SP_REG)
17512 (plus:P (reg:P SP_REG)
17513 (match_operand:P 0 "const_int_operand")))
17514 (clobber (reg:CC FLAGS_REG))
17515 (clobber (mem:BLK (scratch)))])]
17516 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17517 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17518 [(clobber (match_dup 1))
17519 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17520 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17521 (clobber (mem:BLK (scratch)))])])
17523 ;; Convert esp subtractions to push.
17525 [(match_scratch:W 1 "r")
17526 (parallel [(set (reg:P SP_REG)
17527 (plus:P (reg:P SP_REG)
17528 (match_operand:P 0 "const_int_operand")))
17529 (clobber (reg:CC FLAGS_REG))])]
17530 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17531 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17532 [(clobber (match_dup 1))
17533 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17536 [(match_scratch:W 1 "r")
17537 (parallel [(set (reg:P SP_REG)
17538 (plus:P (reg:P SP_REG)
17539 (match_operand:P 0 "const_int_operand")))
17540 (clobber (reg:CC FLAGS_REG))])]
17541 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17542 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17543 [(clobber (match_dup 1))
17544 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17545 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17547 ;; Convert epilogue deallocator to pop.
17549 [(match_scratch:W 1 "r")
17550 (parallel [(set (reg:P SP_REG)
17551 (plus:P (reg:P SP_REG)
17552 (match_operand:P 0 "const_int_operand")))
17553 (clobber (reg:CC FLAGS_REG))
17554 (clobber (mem:BLK (scratch)))])]
17555 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17556 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17557 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17558 (clobber (mem:BLK (scratch)))])])
17560 ;; Two pops case is tricky, since pop causes dependency
17561 ;; on destination register. We use two registers if available.
17563 [(match_scratch:W 1 "r")
17564 (match_scratch:W 2 "r")
17565 (parallel [(set (reg:P SP_REG)
17566 (plus:P (reg:P SP_REG)
17567 (match_operand:P 0 "const_int_operand")))
17568 (clobber (reg:CC FLAGS_REG))
17569 (clobber (mem:BLK (scratch)))])]
17570 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17571 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17572 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17573 (clobber (mem:BLK (scratch)))])
17574 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17577 [(match_scratch:W 1 "r")
17578 (parallel [(set (reg:P SP_REG)
17579 (plus:P (reg:P SP_REG)
17580 (match_operand:P 0 "const_int_operand")))
17581 (clobber (reg:CC FLAGS_REG))
17582 (clobber (mem:BLK (scratch)))])]
17583 "optimize_insn_for_size_p ()
17584 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17585 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17586 (clobber (mem:BLK (scratch)))])
17587 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17589 ;; Convert esp additions to pop.
17591 [(match_scratch:W 1 "r")
17592 (parallel [(set (reg:P SP_REG)
17593 (plus:P (reg:P SP_REG)
17594 (match_operand:P 0 "const_int_operand")))
17595 (clobber (reg:CC FLAGS_REG))])]
17596 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17597 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17599 ;; Two pops case is tricky, since pop causes dependency
17600 ;; on destination register. We use two registers if available.
17602 [(match_scratch:W 1 "r")
17603 (match_scratch:W 2 "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]) == 2*GET_MODE_SIZE (word_mode)"
17609 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17610 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17613 [(match_scratch:W 1 "r")
17614 (parallel [(set (reg:P SP_REG)
17615 (plus:P (reg:P SP_REG)
17616 (match_operand:P 0 "const_int_operand")))
17617 (clobber (reg:CC FLAGS_REG))])]
17618 "optimize_insn_for_size_p ()
17619 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17620 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17621 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17623 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17624 ;; required and register dies. Similarly for 128 to -128.
17626 [(set (match_operand 0 "flags_reg_operand")
17627 (match_operator 1 "compare_operator"
17628 [(match_operand 2 "register_operand")
17629 (match_operand 3 "const_int_operand")]))]
17630 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17631 && incdec_operand (operands[3], GET_MODE (operands[3])))
17632 || (!TARGET_FUSE_CMP_AND_BRANCH
17633 && INTVAL (operands[3]) == 128))
17634 && ix86_match_ccmode (insn, CCGCmode)
17635 && peep2_reg_dead_p (1, operands[2])"
17636 [(parallel [(set (match_dup 0)
17637 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17638 (clobber (match_dup 2))])])
17640 ;; Convert imul by three, five and nine into lea
17643 [(set (match_operand:SWI48 0 "register_operand")
17644 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17645 (match_operand:SWI48 2 "const359_operand")))
17646 (clobber (reg:CC FLAGS_REG))])]
17647 "!TARGET_PARTIAL_REG_STALL
17648 || <MODE>mode == SImode
17649 || optimize_function_for_size_p (cfun)"
17650 [(set (match_dup 0)
17651 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17653 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17657 [(set (match_operand:SWI48 0 "register_operand")
17658 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17659 (match_operand:SWI48 2 "const359_operand")))
17660 (clobber (reg:CC FLAGS_REG))])]
17661 "optimize_insn_for_speed_p ()
17662 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17663 [(set (match_dup 0) (match_dup 1))
17665 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17667 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17669 ;; imul $32bit_imm, mem, reg is vector decoded, while
17670 ;; imul $32bit_imm, reg, reg is direct decoded.
17672 [(match_scratch:SWI48 3 "r")
17673 (parallel [(set (match_operand:SWI48 0 "register_operand")
17674 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17675 (match_operand:SWI48 2 "immediate_operand")))
17676 (clobber (reg:CC FLAGS_REG))])]
17677 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17678 && !satisfies_constraint_K (operands[2])"
17679 [(set (match_dup 3) (match_dup 1))
17680 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17681 (clobber (reg:CC FLAGS_REG))])])
17684 [(match_scratch:SI 3 "r")
17685 (parallel [(set (match_operand:DI 0 "register_operand")
17687 (mult:SI (match_operand:SI 1 "memory_operand")
17688 (match_operand:SI 2 "immediate_operand"))))
17689 (clobber (reg:CC FLAGS_REG))])]
17691 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17692 && !satisfies_constraint_K (operands[2])"
17693 [(set (match_dup 3) (match_dup 1))
17694 (parallel [(set (match_dup 0)
17695 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17696 (clobber (reg:CC FLAGS_REG))])])
17698 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17699 ;; Convert it into imul reg, reg
17700 ;; It would be better to force assembler to encode instruction using long
17701 ;; immediate, but there is apparently no way to do so.
17703 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17705 (match_operand:SWI248 1 "nonimmediate_operand")
17706 (match_operand:SWI248 2 "const_int_operand")))
17707 (clobber (reg:CC FLAGS_REG))])
17708 (match_scratch:SWI248 3 "r")]
17709 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17710 && satisfies_constraint_K (operands[2])"
17711 [(set (match_dup 3) (match_dup 2))
17712 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17713 (clobber (reg:CC FLAGS_REG))])]
17715 if (!rtx_equal_p (operands[0], operands[1]))
17716 emit_move_insn (operands[0], operands[1]);
17719 ;; After splitting up read-modify operations, array accesses with memory
17720 ;; operands might end up in form:
17722 ;; movl 4(%esp), %edx
17724 ;; instead of pre-splitting:
17726 ;; addl 4(%esp), %eax
17728 ;; movl 4(%esp), %edx
17729 ;; leal (%edx,%eax,4), %eax
17732 [(match_scratch:W 5 "r")
17733 (parallel [(set (match_operand 0 "register_operand")
17734 (ashift (match_operand 1 "register_operand")
17735 (match_operand 2 "const_int_operand")))
17736 (clobber (reg:CC FLAGS_REG))])
17737 (parallel [(set (match_operand 3 "register_operand")
17738 (plus (match_dup 0)
17739 (match_operand 4 "x86_64_general_operand")))
17740 (clobber (reg:CC FLAGS_REG))])]
17741 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17742 /* Validate MODE for lea. */
17743 && ((!TARGET_PARTIAL_REG_STALL
17744 && (GET_MODE (operands[0]) == QImode
17745 || GET_MODE (operands[0]) == HImode))
17746 || GET_MODE (operands[0]) == SImode
17747 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17748 && (rtx_equal_p (operands[0], operands[3])
17749 || peep2_reg_dead_p (2, operands[0]))
17750 /* We reorder load and the shift. */
17751 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17752 [(set (match_dup 5) (match_dup 4))
17753 (set (match_dup 0) (match_dup 1))]
17755 enum machine_mode op1mode = GET_MODE (operands[1]);
17756 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17757 int scale = 1 << INTVAL (operands[2]);
17758 rtx index = gen_lowpart (word_mode, operands[1]);
17759 rtx base = gen_lowpart (word_mode, operands[5]);
17760 rtx dest = gen_lowpart (mode, operands[3]);
17762 operands[1] = gen_rtx_PLUS (word_mode, base,
17763 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17764 operands[5] = base;
17765 if (mode != word_mode)
17766 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17767 if (op1mode != word_mode)
17768 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17769 operands[0] = dest;
17772 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17773 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17774 ;; caught for use by garbage collectors and the like. Using an insn that
17775 ;; maps to SIGILL makes it more likely the program will rightfully die.
17776 ;; Keeping with tradition, "6" is in honor of #UD.
17777 (define_insn "trap"
17778 [(trap_if (const_int 1) (const_int 6))]
17780 { return ASM_SHORT "0x0b0f"; }
17781 [(set_attr "length" "2")])
17783 (define_expand "prefetch"
17784 [(prefetch (match_operand 0 "address_operand")
17785 (match_operand:SI 1 "const_int_operand")
17786 (match_operand:SI 2 "const_int_operand"))]
17787 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17789 int rw = INTVAL (operands[1]);
17790 int locality = INTVAL (operands[2]);
17792 gcc_assert (rw == 0 || rw == 1);
17793 gcc_assert (locality >= 0 && locality <= 3);
17794 gcc_assert (GET_MODE (operands[0]) == Pmode
17795 || GET_MODE (operands[0]) == VOIDmode);
17796 if (TARGET_PRFCHW && rw)
17797 operands[2] = GEN_INT (3);
17799 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17800 supported by SSE counterpart or the SSE prefetch is not available
17801 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17803 else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17804 operands[2] = GEN_INT (3);
17806 operands[1] = const0_rtx;
17809 (define_insn "*prefetch_sse_<mode>"
17810 [(prefetch (match_operand:P 0 "address_operand" "p")
17812 (match_operand:SI 1 "const_int_operand"))]
17813 "TARGET_PREFETCH_SSE"
17815 static const char * const patterns[4] = {
17816 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17819 int locality = INTVAL (operands[1]);
17820 gcc_assert (locality >= 0 && locality <= 3);
17822 return patterns[locality];
17824 [(set_attr "type" "sse")
17825 (set_attr "atom_sse_attr" "prefetch")
17826 (set (attr "length_address")
17827 (symbol_ref "memory_address_length (operands[0])"))
17828 (set_attr "memory" "none")])
17830 (define_insn "*prefetch_3dnow_<mode>"
17831 [(prefetch (match_operand:P 0 "address_operand" "p")
17832 (match_operand:SI 1 "const_int_operand" "n")
17834 "TARGET_3DNOW || TARGET_PRFCHW"
17836 if (INTVAL (operands[1]) == 0)
17837 return "prefetch\t%a0";
17839 return "prefetchw\t%a0";
17841 [(set_attr "type" "mmx")
17842 (set (attr "length_address")
17843 (symbol_ref "memory_address_length (operands[0])"))
17844 (set_attr "memory" "none")])
17846 (define_expand "stack_protect_set"
17847 [(match_operand 0 "memory_operand")
17848 (match_operand 1 "memory_operand")]
17849 "!TARGET_HAS_BIONIC"
17851 rtx (*insn)(rtx, rtx);
17853 #ifdef TARGET_THREAD_SSP_OFFSET
17854 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17855 insn = (TARGET_LP64
17856 ? gen_stack_tls_protect_set_di
17857 : gen_stack_tls_protect_set_si);
17859 insn = (TARGET_LP64
17860 ? gen_stack_protect_set_di
17861 : gen_stack_protect_set_si);
17864 emit_insn (insn (operands[0], operands[1]));
17868 (define_insn "stack_protect_set_<mode>"
17869 [(set (match_operand:PTR 0 "memory_operand" "=m")
17870 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17872 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17873 (clobber (reg:CC FLAGS_REG))]
17874 "!TARGET_HAS_BIONIC"
17875 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17876 [(set_attr "type" "multi")])
17878 (define_insn "stack_tls_protect_set_<mode>"
17879 [(set (match_operand:PTR 0 "memory_operand" "=m")
17880 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17881 UNSPEC_SP_TLS_SET))
17882 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17883 (clobber (reg:CC FLAGS_REG))]
17885 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17886 [(set_attr "type" "multi")])
17888 (define_expand "stack_protect_test"
17889 [(match_operand 0 "memory_operand")
17890 (match_operand 1 "memory_operand")
17892 "!TARGET_HAS_BIONIC"
17894 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17896 rtx (*insn)(rtx, rtx, rtx);
17898 #ifdef TARGET_THREAD_SSP_OFFSET
17899 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17900 insn = (TARGET_LP64
17901 ? gen_stack_tls_protect_test_di
17902 : gen_stack_tls_protect_test_si);
17904 insn = (TARGET_LP64
17905 ? gen_stack_protect_test_di
17906 : gen_stack_protect_test_si);
17909 emit_insn (insn (flags, operands[0], operands[1]));
17911 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17912 flags, const0_rtx, operands[2]));
17916 (define_insn "stack_protect_test_<mode>"
17917 [(set (match_operand:CCZ 0 "flags_reg_operand")
17918 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17919 (match_operand:PTR 2 "memory_operand" "m")]
17921 (clobber (match_scratch:PTR 3 "=&r"))]
17922 "!TARGET_HAS_BIONIC"
17923 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17924 [(set_attr "type" "multi")])
17926 (define_insn "stack_tls_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 "const_int_operand" "i")]
17930 UNSPEC_SP_TLS_TEST))
17931 (clobber (match_scratch:PTR 3 "=r"))]
17933 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17934 [(set_attr "type" "multi")])
17936 (define_insn "sse4_2_crc32<mode>"
17937 [(set (match_operand:SI 0 "register_operand" "=r")
17939 [(match_operand:SI 1 "register_operand" "0")
17940 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17942 "TARGET_SSE4_2 || TARGET_CRC32"
17943 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17944 [(set_attr "type" "sselog1")
17945 (set_attr "prefix_rep" "1")
17946 (set_attr "prefix_extra" "1")
17947 (set (attr "prefix_data16")
17948 (if_then_else (match_operand:HI 2)
17950 (const_string "*")))
17951 (set (attr "prefix_rex")
17952 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17954 (const_string "*")))
17955 (set_attr "mode" "SI")])
17957 (define_insn "sse4_2_crc32di"
17958 [(set (match_operand:DI 0 "register_operand" "=r")
17960 [(match_operand:DI 1 "register_operand" "0")
17961 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17963 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17964 "crc32{q}\t{%2, %0|%0, %2}"
17965 [(set_attr "type" "sselog1")
17966 (set_attr "prefix_rep" "1")
17967 (set_attr "prefix_extra" "1")
17968 (set_attr "mode" "DI")])
17970 (define_expand "rdpmc"
17971 [(match_operand:DI 0 "register_operand")
17972 (match_operand:SI 1 "register_operand")]
17975 rtx reg = gen_reg_rtx (DImode);
17978 /* Force operand 1 into ECX. */
17979 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17980 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17981 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17986 rtvec vec = rtvec_alloc (2);
17987 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17988 rtx upper = gen_reg_rtx (DImode);
17989 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17990 gen_rtvec (1, const0_rtx),
17992 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17993 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17995 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17996 NULL, 1, OPTAB_DIRECT);
17997 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18001 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18002 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18006 (define_insn "*rdpmc"
18007 [(set (match_operand:DI 0 "register_operand" "=A")
18008 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18012 [(set_attr "type" "other")
18013 (set_attr "length" "2")])
18015 (define_insn "*rdpmc_rex64"
18016 [(set (match_operand:DI 0 "register_operand" "=a")
18017 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18019 (set (match_operand:DI 1 "register_operand" "=d")
18020 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18023 [(set_attr "type" "other")
18024 (set_attr "length" "2")])
18026 (define_expand "rdtsc"
18027 [(set (match_operand:DI 0 "register_operand")
18028 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18033 rtvec vec = rtvec_alloc (2);
18034 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18035 rtx upper = gen_reg_rtx (DImode);
18036 rtx lower = gen_reg_rtx (DImode);
18037 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18038 gen_rtvec (1, const0_rtx),
18040 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18041 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18043 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18044 NULL, 1, OPTAB_DIRECT);
18045 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18047 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18052 (define_insn "*rdtsc"
18053 [(set (match_operand:DI 0 "register_operand" "=A")
18054 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18057 [(set_attr "type" "other")
18058 (set_attr "length" "2")])
18060 (define_insn "*rdtsc_rex64"
18061 [(set (match_operand:DI 0 "register_operand" "=a")
18062 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18063 (set (match_operand:DI 1 "register_operand" "=d")
18064 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18067 [(set_attr "type" "other")
18068 (set_attr "length" "2")])
18070 (define_expand "rdtscp"
18071 [(match_operand:DI 0 "register_operand")
18072 (match_operand:SI 1 "memory_operand")]
18075 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18076 gen_rtvec (1, const0_rtx),
18078 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18079 gen_rtvec (1, const0_rtx),
18081 rtx reg = gen_reg_rtx (DImode);
18082 rtx tmp = gen_reg_rtx (SImode);
18086 rtvec vec = rtvec_alloc (3);
18087 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18088 rtx upper = gen_reg_rtx (DImode);
18089 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18090 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18091 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18093 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18094 NULL, 1, OPTAB_DIRECT);
18095 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18100 rtvec vec = rtvec_alloc (2);
18101 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18102 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18103 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18106 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18107 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18111 (define_insn "*rdtscp"
18112 [(set (match_operand:DI 0 "register_operand" "=A")
18113 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18114 (set (match_operand:SI 1 "register_operand" "=c")
18115 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18118 [(set_attr "type" "other")
18119 (set_attr "length" "3")])
18121 (define_insn "*rdtscp_rex64"
18122 [(set (match_operand:DI 0 "register_operand" "=a")
18123 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18124 (set (match_operand:DI 1 "register_operand" "=d")
18125 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18126 (set (match_operand:SI 2 "register_operand" "=c")
18127 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18130 [(set_attr "type" "other")
18131 (set_attr "length" "3")])
18133 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18135 ;; LWP instructions
18137 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18139 (define_expand "lwp_llwpcb"
18140 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18141 UNSPECV_LLWP_INTRINSIC)]
18144 (define_insn "*lwp_llwpcb<mode>1"
18145 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18146 UNSPECV_LLWP_INTRINSIC)]
18149 [(set_attr "type" "lwp")
18150 (set_attr "mode" "<MODE>")
18151 (set_attr "length" "5")])
18153 (define_expand "lwp_slwpcb"
18154 [(set (match_operand 0 "register_operand" "=r")
18155 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18160 insn = (Pmode == DImode
18162 : gen_lwp_slwpcbsi);
18164 emit_insn (insn (operands[0]));
18168 (define_insn "lwp_slwpcb<mode>"
18169 [(set (match_operand:P 0 "register_operand" "=r")
18170 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18173 [(set_attr "type" "lwp")
18174 (set_attr "mode" "<MODE>")
18175 (set_attr "length" "5")])
18177 (define_expand "lwp_lwpval<mode>3"
18178 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18179 (match_operand:SI 2 "nonimmediate_operand" "rm")
18180 (match_operand:SI 3 "const_int_operand" "i")]
18181 UNSPECV_LWPVAL_INTRINSIC)]
18183 ;; Avoid unused variable warning.
18184 "(void) operands[0];")
18186 (define_insn "*lwp_lwpval<mode>3_1"
18187 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18188 (match_operand:SI 1 "nonimmediate_operand" "rm")
18189 (match_operand:SI 2 "const_int_operand" "i")]
18190 UNSPECV_LWPVAL_INTRINSIC)]
18192 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18193 [(set_attr "type" "lwp")
18194 (set_attr "mode" "<MODE>")
18195 (set (attr "length")
18196 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18198 (define_expand "lwp_lwpins<mode>3"
18199 [(set (reg:CCC FLAGS_REG)
18200 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18201 (match_operand:SI 2 "nonimmediate_operand" "rm")
18202 (match_operand:SI 3 "const_int_operand" "i")]
18203 UNSPECV_LWPINS_INTRINSIC))
18204 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18205 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18208 (define_insn "*lwp_lwpins<mode>3_1"
18209 [(set (reg:CCC FLAGS_REG)
18210 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18211 (match_operand:SI 1 "nonimmediate_operand" "rm")
18212 (match_operand:SI 2 "const_int_operand" "i")]
18213 UNSPECV_LWPINS_INTRINSIC))]
18215 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18216 [(set_attr "type" "lwp")
18217 (set_attr "mode" "<MODE>")
18218 (set (attr "length")
18219 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18221 (define_int_iterator RDFSGSBASE
18225 (define_int_iterator WRFSGSBASE
18229 (define_int_attr fsgs
18230 [(UNSPECV_RDFSBASE "fs")
18231 (UNSPECV_RDGSBASE "gs")
18232 (UNSPECV_WRFSBASE "fs")
18233 (UNSPECV_WRGSBASE "gs")])
18235 (define_insn "rd<fsgs>base<mode>"
18236 [(set (match_operand:SWI48 0 "register_operand" "=r")
18237 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18238 "TARGET_64BIT && TARGET_FSGSBASE"
18240 [(set_attr "type" "other")
18241 (set_attr "prefix_extra" "2")])
18243 (define_insn "wr<fsgs>base<mode>"
18244 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18246 "TARGET_64BIT && TARGET_FSGSBASE"
18248 [(set_attr "type" "other")
18249 (set_attr "prefix_extra" "2")])
18251 (define_insn "rdrand<mode>_1"
18252 [(set (match_operand:SWI248 0 "register_operand" "=r")
18253 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18254 (set (reg:CCC FLAGS_REG)
18255 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18258 [(set_attr "type" "other")
18259 (set_attr "prefix_extra" "1")])
18261 (define_insn "rdseed<mode>_1"
18262 [(set (match_operand:SWI248 0 "register_operand" "=r")
18263 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18264 (set (reg:CCC FLAGS_REG)
18265 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18268 [(set_attr "type" "other")
18269 (set_attr "prefix_extra" "1")])
18271 (define_expand "pause"
18272 [(set (match_dup 0)
18273 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18276 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18277 MEM_VOLATILE_P (operands[0]) = 1;
18280 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18281 ;; They have the same encoding.
18282 (define_insn "*pause"
18283 [(set (match_operand:BLK 0)
18284 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18287 [(set_attr "length" "2")
18288 (set_attr "memory" "unknown")])
18290 (define_expand "xbegin"
18291 [(set (match_operand:SI 0 "register_operand")
18292 (unspec_volatile:SI [(match_dup 1)] UNSPECV_XBEGIN))]
18295 rtx label = gen_label_rtx ();
18297 operands[1] = force_reg (SImode, constm1_rtx);
18299 emit_jump_insn (gen_xbegin_1 (operands[1], label));
18301 emit_label (label);
18302 LABEL_NUSES (label) = 1;
18304 emit_move_insn (operands[0], operands[1]);
18309 (define_insn "xbegin_1"
18311 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18313 (label_ref (match_operand 1))
18315 (set (match_operand:SI 0 "register_operand" "+a")
18316 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18319 [(set_attr "type" "other")
18320 (set_attr "length" "6")])
18322 (define_insn "xend"
18323 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18326 [(set_attr "type" "other")
18327 (set_attr "length" "3")])
18329 (define_insn "xabort"
18330 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18334 [(set_attr "type" "other")
18335 (set_attr "length" "3")])
18337 (define_expand "xtest"
18338 [(set (match_operand:QI 0 "register_operand")
18339 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18342 emit_insn (gen_xtest_1 ());
18344 ix86_expand_setcc (operands[0], NE,
18345 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18349 (define_insn "xtest_1"
18350 [(set (reg:CCZ FLAGS_REG)
18351 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18354 [(set_attr "type" "other")
18355 (set_attr "length" "3")])
18359 (include "sync.md")