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
216 ;; Constants to represent rounding modes in the ROUND instruction
225 ;; Constants to represent pcomtrue/pcomfalse variants
235 ;; Constants used in the XOP pperm instruction
237 [(PPERM_SRC 0x00) /* copy source */
238 (PPERM_INVERT 0x20) /* invert source */
239 (PPERM_REVERSE 0x40) /* bit reverse source */
240 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
241 (PPERM_ZERO 0x80) /* all 0's */
242 (PPERM_ONES 0xa0) /* all 1's */
243 (PPERM_SIGN 0xc0) /* propagate sign bit */
244 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
245 (PPERM_SRC1 0x00) /* use first source byte */
246 (PPERM_SRC2 0x10) /* use second source byte */
249 ;; Registers by name.
302 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
305 ;; In C guard expressions, put expressions which may be compile-time
306 ;; constants first. This allows for better optimization. For
307 ;; example, write "TARGET_64BIT && reload_completed", not
308 ;; "reload_completed && TARGET_64BIT".
312 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
313 atom,generic64,amdfam10,bdver1,bdver2,btver1"
314 (const (symbol_ref "ix86_schedule")))
316 ;; A basic instruction type. Refinements due to arguments to be
317 ;; provided in other attributes.
320 alu,alu1,negnot,imov,imovx,lea,
321 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
322 icmp,test,ibr,setcc,icmov,
323 push,pop,call,callv,leave,
325 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
326 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
327 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
328 ssemuladd,sse4arg,lwp,
329 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
330 (const_string "other"))
332 ;; Main data type used by the insn
334 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
335 (const_string "unknown"))
337 ;; The CPU unit operations uses.
338 (define_attr "unit" "integer,i387,sse,mmx,unknown"
339 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
340 (const_string "i387")
341 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
342 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
343 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
345 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
347 (eq_attr "type" "other")
348 (const_string "unknown")]
349 (const_string "integer")))
351 ;; The (bounding maximum) length of an instruction immediate.
352 (define_attr "length_immediate" ""
353 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
356 (eq_attr "unit" "i387,sse,mmx")
358 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
359 rotate,rotatex,rotate1,imul,icmp,push,pop")
360 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
361 (eq_attr "type" "imov,test")
362 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
363 (eq_attr "type" "call")
364 (if_then_else (match_operand 0 "constant_call_address_operand")
367 (eq_attr "type" "callv")
368 (if_then_else (match_operand 1 "constant_call_address_operand")
371 ;; We don't know the size before shorten_branches. Expect
372 ;; the instruction to fit for better scheduling.
373 (eq_attr "type" "ibr")
376 (symbol_ref "/* Update immediate_length and other attributes! */
377 gcc_unreachable (),1")))
379 ;; The (bounding maximum) length of an instruction address.
380 (define_attr "length_address" ""
381 (cond [(eq_attr "type" "str,other,multi,fxch")
383 (and (eq_attr "type" "call")
384 (match_operand 0 "constant_call_address_operand"))
386 (and (eq_attr "type" "callv")
387 (match_operand 1 "constant_call_address_operand"))
390 (symbol_ref "ix86_attr_length_address_default (insn)")))
392 ;; Set when length prefix is used.
393 (define_attr "prefix_data16" ""
394 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
396 (eq_attr "mode" "HI")
398 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
403 ;; Set when string REP prefix is used.
404 (define_attr "prefix_rep" ""
405 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
407 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
412 ;; Set when 0f opcode prefix is used.
413 (define_attr "prefix_0f" ""
415 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
416 (eq_attr "unit" "sse,mmx"))
420 ;; Set when REX opcode prefix is used.
421 (define_attr "prefix_rex" ""
422 (cond [(not (match_test "TARGET_64BIT"))
424 (and (eq_attr "mode" "DI")
425 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
426 (eq_attr "unit" "!mmx")))
428 (and (eq_attr "mode" "QI")
429 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
431 (match_test "x86_extended_reg_mentioned_p (insn)")
433 (and (eq_attr "type" "imovx")
434 (match_operand:QI 1 "ext_QIreg_operand"))
439 ;; There are also additional prefixes in 3DNOW, SSSE3.
440 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
441 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
442 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
443 (define_attr "prefix_extra" ""
444 (cond [(eq_attr "type" "ssemuladd,sse4arg")
446 (eq_attr "type" "sseiadd1,ssecvt1")
451 ;; Prefix used: original, VEX or maybe VEX.
452 (define_attr "prefix" "orig,vex,maybe_vex"
453 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
455 (const_string "orig")))
457 ;; VEX W bit is used.
458 (define_attr "prefix_vex_w" "" (const_int 0))
460 ;; The length of VEX prefix
461 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
462 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
463 ;; still prefix_0f 1, with prefix_extra 1.
464 (define_attr "length_vex" ""
465 (if_then_else (and (eq_attr "prefix_0f" "1")
466 (eq_attr "prefix_extra" "0"))
467 (if_then_else (eq_attr "prefix_vex_w" "1")
468 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
469 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
470 (if_then_else (eq_attr "prefix_vex_w" "1")
471 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
472 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
474 ;; Set when modrm byte is used.
475 (define_attr "modrm" ""
476 (cond [(eq_attr "type" "str,leave")
478 (eq_attr "unit" "i387")
480 (and (eq_attr "type" "incdec")
481 (and (not (match_test "TARGET_64BIT"))
482 (ior (match_operand:SI 1 "register_operand")
483 (match_operand:HI 1 "register_operand"))))
485 (and (eq_attr "type" "push")
486 (not (match_operand 1 "memory_operand")))
488 (and (eq_attr "type" "pop")
489 (not (match_operand 0 "memory_operand")))
491 (and (eq_attr "type" "imov")
492 (and (not (eq_attr "mode" "DI"))
493 (ior (and (match_operand 0 "register_operand")
494 (match_operand 1 "immediate_operand"))
495 (ior (and (match_operand 0 "ax_reg_operand")
496 (match_operand 1 "memory_displacement_only_operand"))
497 (and (match_operand 0 "memory_displacement_only_operand")
498 (match_operand 1 "ax_reg_operand"))))))
500 (and (eq_attr "type" "call")
501 (match_operand 0 "constant_call_address_operand"))
503 (and (eq_attr "type" "callv")
504 (match_operand 1 "constant_call_address_operand"))
506 (and (eq_attr "type" "alu,alu1,icmp,test")
507 (match_operand 0 "ax_reg_operand"))
508 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
512 ;; The (bounding maximum) length of an instruction in bytes.
513 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
514 ;; Later we may want to split them and compute proper length as for
516 (define_attr "length" ""
517 (cond [(eq_attr "type" "other,multi,fistp,frndint")
519 (eq_attr "type" "fcmp")
521 (eq_attr "unit" "i387")
523 (plus (attr "prefix_data16")
524 (attr "length_address")))
525 (ior (eq_attr "prefix" "vex")
526 (and (eq_attr "prefix" "maybe_vex")
527 (match_test "TARGET_AVX")))
528 (plus (attr "length_vex")
529 (plus (attr "length_immediate")
531 (attr "length_address"))))]
532 (plus (plus (attr "modrm")
533 (plus (attr "prefix_0f")
534 (plus (attr "prefix_rex")
535 (plus (attr "prefix_extra")
537 (plus (attr "prefix_rep")
538 (plus (attr "prefix_data16")
539 (plus (attr "length_immediate")
540 (attr "length_address")))))))
542 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
543 ;; `store' if there is a simple memory reference therein, or `unknown'
544 ;; if the instruction is complex.
546 (define_attr "memory" "none,load,store,both,unknown"
547 (cond [(eq_attr "type" "other,multi,str,lwp")
548 (const_string "unknown")
549 (eq_attr "type" "lea,fcmov,fpspc")
550 (const_string "none")
551 (eq_attr "type" "fistp,leave")
552 (const_string "both")
553 (eq_attr "type" "frndint")
554 (const_string "load")
555 (eq_attr "type" "push")
556 (if_then_else (match_operand 1 "memory_operand")
557 (const_string "both")
558 (const_string "store"))
559 (eq_attr "type" "pop")
560 (if_then_else (match_operand 0 "memory_operand")
561 (const_string "both")
562 (const_string "load"))
563 (eq_attr "type" "setcc")
564 (if_then_else (match_operand 0 "memory_operand")
565 (const_string "store")
566 (const_string "none"))
567 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
568 (if_then_else (ior (match_operand 0 "memory_operand")
569 (match_operand 1 "memory_operand"))
570 (const_string "load")
571 (const_string "none"))
572 (eq_attr "type" "ibr")
573 (if_then_else (match_operand 0 "memory_operand")
574 (const_string "load")
575 (const_string "none"))
576 (eq_attr "type" "call")
577 (if_then_else (match_operand 0 "constant_call_address_operand")
578 (const_string "none")
579 (const_string "load"))
580 (eq_attr "type" "callv")
581 (if_then_else (match_operand 1 "constant_call_address_operand")
582 (const_string "none")
583 (const_string "load"))
584 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
585 (match_operand 1 "memory_operand"))
586 (const_string "both")
587 (and (match_operand 0 "memory_operand")
588 (match_operand 1 "memory_operand"))
589 (const_string "both")
590 (match_operand 0 "memory_operand")
591 (const_string "store")
592 (match_operand 1 "memory_operand")
593 (const_string "load")
595 "!alu1,negnot,ishift1,
596 imov,imovx,icmp,test,bitmanip,
598 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
599 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
600 (match_operand 2 "memory_operand"))
601 (const_string "load")
602 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
603 (match_operand 3 "memory_operand"))
604 (const_string "load")
606 (const_string "none")))
608 ;; Indicates if an instruction has both an immediate and a displacement.
610 (define_attr "imm_disp" "false,true,unknown"
611 (cond [(eq_attr "type" "other,multi")
612 (const_string "unknown")
613 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
614 (and (match_operand 0 "memory_displacement_operand")
615 (match_operand 1 "immediate_operand")))
616 (const_string "true")
617 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
618 (and (match_operand 0 "memory_displacement_operand")
619 (match_operand 2 "immediate_operand")))
620 (const_string "true")
622 (const_string "false")))
624 ;; Indicates if an FP operation has an integer source.
626 (define_attr "fp_int_src" "false,true"
627 (const_string "false"))
629 ;; Defines rounding mode of an FP operation.
631 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
632 (const_string "any"))
634 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
635 (define_attr "use_carry" "0,1" (const_string "0"))
637 ;; Define attribute to indicate unaligned ssemov insns
638 (define_attr "movu" "0,1" (const_string "0"))
640 ;; Used to control the "enabled" attribute on a per-instruction basis.
641 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,avx2,noavx2,bmi2"
642 (const_string "base"))
644 (define_attr "enabled" ""
645 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
646 (eq_attr "isa" "sse2_noavx")
647 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
648 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
649 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
650 (eq_attr "isa" "sse4_noavx")
651 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
652 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
653 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
654 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
655 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
656 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
660 ;; Describe a user's asm statement.
661 (define_asm_attributes
662 [(set_attr "length" "128")
663 (set_attr "type" "multi")])
665 (define_code_iterator plusminus [plus minus])
667 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
669 ;; Base name for define_insn
670 (define_code_attr plusminus_insn
671 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
672 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
674 ;; Base name for insn mnemonic.
675 (define_code_attr plusminus_mnemonic
676 [(plus "add") (ss_plus "adds") (us_plus "addus")
677 (minus "sub") (ss_minus "subs") (us_minus "subus")])
678 (define_code_attr plusminus_carry_mnemonic
679 [(plus "adc") (minus "sbb")])
681 ;; Mark commutative operators as such in constraints.
682 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
683 (minus "") (ss_minus "") (us_minus "")])
685 ;; Mapping of max and min
686 (define_code_iterator maxmin [smax smin umax umin])
688 ;; Mapping of signed max and min
689 (define_code_iterator smaxmin [smax smin])
691 ;; Mapping of unsigned max and min
692 (define_code_iterator umaxmin [umax umin])
694 ;; Base name for integer and FP insn mnemonic
695 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
696 (umax "maxu") (umin "minu")])
697 (define_code_attr maxmin_float [(smax "max") (smin "min")])
699 ;; Mapping of logic operators
700 (define_code_iterator any_logic [and ior xor])
701 (define_code_iterator any_or [ior xor])
703 ;; Base name for insn mnemonic.
704 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
706 ;; Mapping of logic-shift operators
707 (define_code_iterator any_lshift [ashift lshiftrt])
709 ;; Mapping of shift-right operators
710 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
712 ;; Mapping of all shift operators
713 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
715 ;; Base name for define_insn
716 (define_code_attr shift_insn
717 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
719 ;; Base name for insn mnemonic.
720 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
721 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
723 ;; Mapping of rotate operators
724 (define_code_iterator any_rotate [rotate rotatert])
726 ;; Base name for define_insn
727 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
729 ;; Base name for insn mnemonic.
730 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
732 ;; Mapping of abs neg operators
733 (define_code_iterator absneg [abs neg])
735 ;; Base name for x87 insn mnemonic.
736 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
738 ;; Used in signed and unsigned widening multiplications.
739 (define_code_iterator any_extend [sign_extend zero_extend])
741 ;; Prefix for insn menmonic.
742 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
744 ;; Prefix for define_insn
745 (define_code_attr u [(sign_extend "") (zero_extend "u")])
746 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
748 ;; All integer modes.
749 (define_mode_iterator SWI1248x [QI HI SI DI])
751 ;; All integer modes without QImode.
752 (define_mode_iterator SWI248x [HI SI DI])
754 ;; All integer modes without QImode and HImode.
755 (define_mode_iterator SWI48x [SI DI])
757 ;; All integer modes without SImode and DImode.
758 (define_mode_iterator SWI12 [QI HI])
760 ;; All integer modes without DImode.
761 (define_mode_iterator SWI124 [QI HI SI])
763 ;; All integer modes without QImode and DImode.
764 (define_mode_iterator SWI24 [HI SI])
766 ;; Single word integer modes.
767 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
769 ;; Single word integer modes without QImode.
770 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
772 ;; Single word integer modes without QImode and HImode.
773 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
775 ;; All math-dependant single and double word integer modes.
776 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
777 (HI "TARGET_HIMODE_MATH")
778 SI DI (TI "TARGET_64BIT")])
780 ;; Math-dependant single word integer modes.
781 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
782 (HI "TARGET_HIMODE_MATH")
783 SI (DI "TARGET_64BIT")])
785 ;; Math-dependant integer modes without DImode.
786 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
787 (HI "TARGET_HIMODE_MATH")
790 ;; Math-dependant single word integer modes without QImode.
791 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
792 SI (DI "TARGET_64BIT")])
794 ;; Double word integer modes.
795 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
796 (TI "TARGET_64BIT")])
798 ;; Double word integer modes as mode attribute.
799 (define_mode_attr DWI [(SI "DI") (DI "TI")])
800 (define_mode_attr dwi [(SI "di") (DI "ti")])
802 ;; Half mode for double word integer modes.
803 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
804 (DI "TARGET_64BIT")])
806 ;; Instruction suffix for integer modes.
807 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
809 ;; Pointer size prefix for integer modes (Intel asm dialect)
810 (define_mode_attr iptrsize [(QI "BYTE")
815 ;; Register class for integer modes.
816 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
818 ;; Immediate operand constraint for integer modes.
819 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
821 ;; General operand constraint for word modes.
822 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
824 ;; Immediate operand constraint for double integer modes.
825 (define_mode_attr di [(SI "nF") (DI "e")])
827 ;; Immediate operand constraint for shifts.
828 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
830 ;; General operand predicate for integer modes.
831 (define_mode_attr general_operand
832 [(QI "general_operand")
833 (HI "general_operand")
834 (SI "x86_64_general_operand")
835 (DI "x86_64_general_operand")
836 (TI "x86_64_general_operand")])
838 ;; General sign/zero extend operand predicate for integer modes.
839 (define_mode_attr general_szext_operand
840 [(QI "general_operand")
841 (HI "general_operand")
842 (SI "x86_64_szext_general_operand")
843 (DI "x86_64_szext_general_operand")])
845 ;; Immediate operand predicate for integer modes.
846 (define_mode_attr immediate_operand
847 [(QI "immediate_operand")
848 (HI "immediate_operand")
849 (SI "x86_64_immediate_operand")
850 (DI "x86_64_immediate_operand")])
852 ;; Nonmemory operand predicate for integer modes.
853 (define_mode_attr nonmemory_operand
854 [(QI "nonmemory_operand")
855 (HI "nonmemory_operand")
856 (SI "x86_64_nonmemory_operand")
857 (DI "x86_64_nonmemory_operand")])
859 ;; Operand predicate for shifts.
860 (define_mode_attr shift_operand
861 [(QI "nonimmediate_operand")
862 (HI "nonimmediate_operand")
863 (SI "nonimmediate_operand")
864 (DI "shiftdi_operand")
865 (TI "register_operand")])
867 ;; Operand predicate for shift argument.
868 (define_mode_attr shift_immediate_operand
869 [(QI "const_1_to_31_operand")
870 (HI "const_1_to_31_operand")
871 (SI "const_1_to_31_operand")
872 (DI "const_1_to_63_operand")])
874 ;; Input operand predicate for arithmetic left shifts.
875 (define_mode_attr ashl_input_operand
876 [(QI "nonimmediate_operand")
877 (HI "nonimmediate_operand")
878 (SI "nonimmediate_operand")
879 (DI "ashldi_input_operand")
880 (TI "reg_or_pm1_operand")])
882 ;; SSE and x87 SFmode and DFmode floating point modes
883 (define_mode_iterator MODEF [SF DF])
885 ;; All x87 floating point modes
886 (define_mode_iterator X87MODEF [SF DF XF])
888 ;; SSE instruction suffix for various modes
889 (define_mode_attr ssemodesuffix
891 (V8SF "ps") (V4DF "pd")
892 (V4SF "ps") (V2DF "pd")
893 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
894 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
896 ;; SSE vector suffix for floating point modes
897 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
899 ;; SSE vector mode corresponding to a scalar mode
900 (define_mode_attr ssevecmode
901 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
903 ;; Instruction suffix for REX 64bit operators.
904 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
906 ;; This mode iterator allows :P to be used for patterns that operate on
907 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
908 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
910 ;; This mode iterator allows :W to be used for patterns that operate on
911 ;; word_mode sized quantities.
912 (define_mode_iterator W
913 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
915 ;; This mode iterator allows :PTR to be used for patterns that operate on
916 ;; ptr_mode sized quantities.
917 (define_mode_iterator PTR
918 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
920 ;; Scheduling descriptions
922 (include "pentium.md")
925 (include "athlon.md")
926 (include "bdver1.md")
932 ;; Operand and operator predicates and constraints
934 (include "predicates.md")
935 (include "constraints.md")
938 ;; Compare and branch/compare and store instructions.
940 (define_expand "cbranch<mode>4"
941 [(set (reg:CC FLAGS_REG)
942 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
943 (match_operand:SDWIM 2 "<general_operand>")))
944 (set (pc) (if_then_else
945 (match_operator 0 "ordered_comparison_operator"
946 [(reg:CC FLAGS_REG) (const_int 0)])
947 (label_ref (match_operand 3))
951 if (MEM_P (operands[1]) && MEM_P (operands[2]))
952 operands[1] = force_reg (<MODE>mode, operands[1]);
953 ix86_expand_branch (GET_CODE (operands[0]),
954 operands[1], operands[2], operands[3]);
958 (define_expand "cstore<mode>4"
959 [(set (reg:CC FLAGS_REG)
960 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
961 (match_operand:SWIM 3 "<general_operand>")))
962 (set (match_operand:QI 0 "register_operand")
963 (match_operator 1 "ordered_comparison_operator"
964 [(reg:CC FLAGS_REG) (const_int 0)]))]
967 if (MEM_P (operands[2]) && MEM_P (operands[3]))
968 operands[2] = force_reg (<MODE>mode, operands[2]);
969 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
970 operands[2], operands[3]);
974 (define_expand "cmp<mode>_1"
975 [(set (reg:CC FLAGS_REG)
976 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
977 (match_operand:SWI48 1 "<general_operand>")))])
979 (define_insn "*cmp<mode>_ccno_1"
980 [(set (reg FLAGS_REG)
981 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
982 (match_operand:SWI 1 "const0_operand")))]
983 "ix86_match_ccmode (insn, CCNOmode)"
985 test{<imodesuffix>}\t%0, %0
986 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
987 [(set_attr "type" "test,icmp")
988 (set_attr "length_immediate" "0,1")
989 (set_attr "mode" "<MODE>")])
991 (define_insn "*cmp<mode>_1"
992 [(set (reg FLAGS_REG)
993 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
994 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
995 "ix86_match_ccmode (insn, CCmode)"
996 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
997 [(set_attr "type" "icmp")
998 (set_attr "mode" "<MODE>")])
1000 (define_insn "*cmp<mode>_minus_1"
1001 [(set (reg FLAGS_REG)
1003 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1004 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1006 "ix86_match_ccmode (insn, CCGOCmode)"
1007 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1008 [(set_attr "type" "icmp")
1009 (set_attr "mode" "<MODE>")])
1011 (define_insn "*cmpqi_ext_1"
1012 [(set (reg FLAGS_REG)
1014 (match_operand:QI 0 "general_operand" "Qm")
1017 (match_operand 1 "ext_register_operand" "Q")
1019 (const_int 8)) 0)))]
1020 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1021 "cmp{b}\t{%h1, %0|%0, %h1}"
1022 [(set_attr "type" "icmp")
1023 (set_attr "mode" "QI")])
1025 (define_insn "*cmpqi_ext_1_rex64"
1026 [(set (reg FLAGS_REG)
1028 (match_operand:QI 0 "register_operand" "Q")
1031 (match_operand 1 "ext_register_operand" "Q")
1033 (const_int 8)) 0)))]
1034 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1035 "cmp{b}\t{%h1, %0|%0, %h1}"
1036 [(set_attr "type" "icmp")
1037 (set_attr "mode" "QI")])
1039 (define_insn "*cmpqi_ext_2"
1040 [(set (reg FLAGS_REG)
1044 (match_operand 0 "ext_register_operand" "Q")
1047 (match_operand:QI 1 "const0_operand")))]
1048 "ix86_match_ccmode (insn, CCNOmode)"
1050 [(set_attr "type" "test")
1051 (set_attr "length_immediate" "0")
1052 (set_attr "mode" "QI")])
1054 (define_expand "cmpqi_ext_3"
1055 [(set (reg:CC FLAGS_REG)
1059 (match_operand 0 "ext_register_operand")
1062 (match_operand:QI 1 "immediate_operand")))])
1064 (define_insn "*cmpqi_ext_3_insn"
1065 [(set (reg FLAGS_REG)
1069 (match_operand 0 "ext_register_operand" "Q")
1072 (match_operand:QI 1 "general_operand" "Qmn")))]
1073 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1074 "cmp{b}\t{%1, %h0|%h0, %1}"
1075 [(set_attr "type" "icmp")
1076 (set_attr "modrm" "1")
1077 (set_attr "mode" "QI")])
1079 (define_insn "*cmpqi_ext_3_insn_rex64"
1080 [(set (reg FLAGS_REG)
1084 (match_operand 0 "ext_register_operand" "Q")
1087 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1088 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1089 "cmp{b}\t{%1, %h0|%h0, %1}"
1090 [(set_attr "type" "icmp")
1091 (set_attr "modrm" "1")
1092 (set_attr "mode" "QI")])
1094 (define_insn "*cmpqi_ext_4"
1095 [(set (reg FLAGS_REG)
1099 (match_operand 0 "ext_register_operand" "Q")
1104 (match_operand 1 "ext_register_operand" "Q")
1106 (const_int 8)) 0)))]
1107 "ix86_match_ccmode (insn, CCmode)"
1108 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1109 [(set_attr "type" "icmp")
1110 (set_attr "mode" "QI")])
1112 ;; These implement float point compares.
1113 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1114 ;; which would allow mix and match FP modes on the compares. Which is what
1115 ;; the old patterns did, but with many more of them.
1117 (define_expand "cbranchxf4"
1118 [(set (reg:CC FLAGS_REG)
1119 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1120 (match_operand:XF 2 "nonmemory_operand")))
1121 (set (pc) (if_then_else
1122 (match_operator 0 "ix86_fp_comparison_operator"
1125 (label_ref (match_operand 3))
1129 ix86_expand_branch (GET_CODE (operands[0]),
1130 operands[1], operands[2], operands[3]);
1134 (define_expand "cstorexf4"
1135 [(set (reg:CC FLAGS_REG)
1136 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1137 (match_operand:XF 3 "nonmemory_operand")))
1138 (set (match_operand:QI 0 "register_operand")
1139 (match_operator 1 "ix86_fp_comparison_operator"
1144 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1145 operands[2], operands[3]);
1149 (define_expand "cbranch<mode>4"
1150 [(set (reg:CC FLAGS_REG)
1151 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1152 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1153 (set (pc) (if_then_else
1154 (match_operator 0 "ix86_fp_comparison_operator"
1157 (label_ref (match_operand 3))
1159 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1161 ix86_expand_branch (GET_CODE (operands[0]),
1162 operands[1], operands[2], operands[3]);
1166 (define_expand "cstore<mode>4"
1167 [(set (reg:CC FLAGS_REG)
1168 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1169 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1170 (set (match_operand:QI 0 "register_operand")
1171 (match_operator 1 "ix86_fp_comparison_operator"
1174 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1176 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1177 operands[2], operands[3]);
1181 (define_expand "cbranchcc4"
1182 [(set (pc) (if_then_else
1183 (match_operator 0 "comparison_operator"
1184 [(match_operand 1 "flags_reg_operand")
1185 (match_operand 2 "const0_operand")])
1186 (label_ref (match_operand 3))
1190 ix86_expand_branch (GET_CODE (operands[0]),
1191 operands[1], operands[2], operands[3]);
1195 (define_expand "cstorecc4"
1196 [(set (match_operand:QI 0 "register_operand")
1197 (match_operator 1 "comparison_operator"
1198 [(match_operand 2 "flags_reg_operand")
1199 (match_operand 3 "const0_operand")]))]
1202 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1203 operands[2], operands[3]);
1208 ;; FP compares, step 1:
1209 ;; Set the FP condition codes.
1211 ;; CCFPmode compare with exceptions
1212 ;; CCFPUmode compare with no exceptions
1214 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1215 ;; used to manage the reg stack popping would not be preserved.
1217 (define_insn "*cmpfp_0"
1218 [(set (match_operand:HI 0 "register_operand" "=a")
1221 (match_operand 1 "register_operand" "f")
1222 (match_operand 2 "const0_operand"))]
1224 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1225 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1226 "* return output_fp_compare (insn, operands, false, false);"
1227 [(set_attr "type" "multi")
1228 (set_attr "unit" "i387")
1230 (cond [(match_operand:SF 1)
1232 (match_operand:DF 1)
1235 (const_string "XF")))])
1237 (define_insn_and_split "*cmpfp_0_cc"
1238 [(set (reg:CCFP FLAGS_REG)
1240 (match_operand 1 "register_operand" "f")
1241 (match_operand 2 "const0_operand")))
1242 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1243 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1244 && TARGET_SAHF && !TARGET_CMOVE
1245 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1247 "&& reload_completed"
1250 [(compare:CCFP (match_dup 1)(match_dup 2))]
1252 (set (reg:CC FLAGS_REG)
1253 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1255 [(set_attr "type" "multi")
1256 (set_attr "unit" "i387")
1258 (cond [(match_operand:SF 1)
1260 (match_operand:DF 1)
1263 (const_string "XF")))])
1265 (define_insn "*cmpfp_xf"
1266 [(set (match_operand:HI 0 "register_operand" "=a")
1269 (match_operand:XF 1 "register_operand" "f")
1270 (match_operand:XF 2 "register_operand" "f"))]
1273 "* return output_fp_compare (insn, operands, false, false);"
1274 [(set_attr "type" "multi")
1275 (set_attr "unit" "i387")
1276 (set_attr "mode" "XF")])
1278 (define_insn_and_split "*cmpfp_xf_cc"
1279 [(set (reg:CCFP FLAGS_REG)
1281 (match_operand:XF 1 "register_operand" "f")
1282 (match_operand:XF 2 "register_operand" "f")))
1283 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1285 && TARGET_SAHF && !TARGET_CMOVE"
1287 "&& reload_completed"
1290 [(compare:CCFP (match_dup 1)(match_dup 2))]
1292 (set (reg:CC FLAGS_REG)
1293 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1295 [(set_attr "type" "multi")
1296 (set_attr "unit" "i387")
1297 (set_attr "mode" "XF")])
1299 (define_insn "*cmpfp_<mode>"
1300 [(set (match_operand:HI 0 "register_operand" "=a")
1303 (match_operand:MODEF 1 "register_operand" "f")
1304 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1307 "* return output_fp_compare (insn, operands, false, false);"
1308 [(set_attr "type" "multi")
1309 (set_attr "unit" "i387")
1310 (set_attr "mode" "<MODE>")])
1312 (define_insn_and_split "*cmpfp_<mode>_cc"
1313 [(set (reg:CCFP FLAGS_REG)
1315 (match_operand:MODEF 1 "register_operand" "f")
1316 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1317 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1319 && TARGET_SAHF && !TARGET_CMOVE"
1321 "&& reload_completed"
1324 [(compare:CCFP (match_dup 1)(match_dup 2))]
1326 (set (reg:CC FLAGS_REG)
1327 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1329 [(set_attr "type" "multi")
1330 (set_attr "unit" "i387")
1331 (set_attr "mode" "<MODE>")])
1333 (define_insn "*cmpfp_u"
1334 [(set (match_operand:HI 0 "register_operand" "=a")
1337 (match_operand 1 "register_operand" "f")
1338 (match_operand 2 "register_operand" "f"))]
1340 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1341 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1342 "* return output_fp_compare (insn, operands, false, true);"
1343 [(set_attr "type" "multi")
1344 (set_attr "unit" "i387")
1346 (cond [(match_operand:SF 1)
1348 (match_operand:DF 1)
1351 (const_string "XF")))])
1353 (define_insn_and_split "*cmpfp_u_cc"
1354 [(set (reg:CCFPU FLAGS_REG)
1356 (match_operand 1 "register_operand" "f")
1357 (match_operand 2 "register_operand" "f")))
1358 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1359 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1360 && TARGET_SAHF && !TARGET_CMOVE
1361 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1363 "&& reload_completed"
1366 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1368 (set (reg:CC FLAGS_REG)
1369 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1371 [(set_attr "type" "multi")
1372 (set_attr "unit" "i387")
1374 (cond [(match_operand:SF 1)
1376 (match_operand:DF 1)
1379 (const_string "XF")))])
1381 (define_insn "*cmpfp_<mode>"
1382 [(set (match_operand:HI 0 "register_operand" "=a")
1385 (match_operand 1 "register_operand" "f")
1386 (match_operator 3 "float_operator"
1387 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1389 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1390 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1391 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1392 "* return output_fp_compare (insn, operands, false, false);"
1393 [(set_attr "type" "multi")
1394 (set_attr "unit" "i387")
1395 (set_attr "fp_int_src" "true")
1396 (set_attr "mode" "<MODE>")])
1398 (define_insn_and_split "*cmpfp_<mode>_cc"
1399 [(set (reg:CCFP FLAGS_REG)
1401 (match_operand 1 "register_operand" "f")
1402 (match_operator 3 "float_operator"
1403 [(match_operand:SWI24 2 "memory_operand" "m")])))
1404 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1405 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1406 && TARGET_SAHF && !TARGET_CMOVE
1407 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1408 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1410 "&& reload_completed"
1415 (match_op_dup 3 [(match_dup 2)]))]
1417 (set (reg:CC FLAGS_REG)
1418 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1420 [(set_attr "type" "multi")
1421 (set_attr "unit" "i387")
1422 (set_attr "fp_int_src" "true")
1423 (set_attr "mode" "<MODE>")])
1425 ;; FP compares, step 2
1426 ;; Move the fpsw to ax.
1428 (define_insn "x86_fnstsw_1"
1429 [(set (match_operand:HI 0 "register_operand" "=a")
1430 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1433 [(set (attr "length")
1434 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1435 (set_attr "mode" "SI")
1436 (set_attr "unit" "i387")])
1438 ;; FP compares, step 3
1439 ;; Get ax into flags, general case.
1441 (define_insn "x86_sahf_1"
1442 [(set (reg:CC FLAGS_REG)
1443 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1447 #ifndef HAVE_AS_IX86_SAHF
1449 return ASM_BYTE "0x9e";
1454 [(set_attr "length" "1")
1455 (set_attr "athlon_decode" "vector")
1456 (set_attr "amdfam10_decode" "direct")
1457 (set_attr "bdver1_decode" "direct")
1458 (set_attr "mode" "SI")])
1460 ;; Pentium Pro can do steps 1 through 3 in one go.
1461 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1462 ;; (these i387 instructions set flags directly)
1463 (define_insn "*cmpfp_i_mixed"
1464 [(set (reg:CCFP FLAGS_REG)
1465 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1466 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1467 "TARGET_MIX_SSE_I387
1468 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1469 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1470 "* return output_fp_compare (insn, operands, true, false);"
1471 [(set_attr "type" "fcmp,ssecomi")
1472 (set_attr "prefix" "orig,maybe_vex")
1474 (if_then_else (match_operand:SF 1)
1476 (const_string "DF")))
1477 (set (attr "prefix_rep")
1478 (if_then_else (eq_attr "type" "ssecomi")
1480 (const_string "*")))
1481 (set (attr "prefix_data16")
1482 (cond [(eq_attr "type" "fcmp")
1484 (eq_attr "mode" "DF")
1487 (const_string "0")))
1488 (set_attr "athlon_decode" "vector")
1489 (set_attr "amdfam10_decode" "direct")
1490 (set_attr "bdver1_decode" "double")])
1492 (define_insn "*cmpfp_i_sse"
1493 [(set (reg:CCFP FLAGS_REG)
1494 (compare:CCFP (match_operand 0 "register_operand" "x")
1495 (match_operand 1 "nonimmediate_operand" "xm")))]
1497 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1498 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1499 "* return output_fp_compare (insn, operands, true, false);"
1500 [(set_attr "type" "ssecomi")
1501 (set_attr "prefix" "maybe_vex")
1503 (if_then_else (match_operand:SF 1)
1505 (const_string "DF")))
1506 (set_attr "prefix_rep" "0")
1507 (set (attr "prefix_data16")
1508 (if_then_else (eq_attr "mode" "DF")
1510 (const_string "0")))
1511 (set_attr "athlon_decode" "vector")
1512 (set_attr "amdfam10_decode" "direct")
1513 (set_attr "bdver1_decode" "double")])
1515 (define_insn "*cmpfp_i_i387"
1516 [(set (reg:CCFP FLAGS_REG)
1517 (compare:CCFP (match_operand 0 "register_operand" "f")
1518 (match_operand 1 "register_operand" "f")))]
1519 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1521 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1522 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1523 "* return output_fp_compare (insn, operands, true, false);"
1524 [(set_attr "type" "fcmp")
1526 (cond [(match_operand:SF 1)
1528 (match_operand:DF 1)
1531 (const_string "XF")))
1532 (set_attr "athlon_decode" "vector")
1533 (set_attr "amdfam10_decode" "direct")
1534 (set_attr "bdver1_decode" "double")])
1536 (define_insn "*cmpfp_iu_mixed"
1537 [(set (reg:CCFPU FLAGS_REG)
1538 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1539 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1540 "TARGET_MIX_SSE_I387
1541 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1542 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1543 "* return output_fp_compare (insn, operands, true, true);"
1544 [(set_attr "type" "fcmp,ssecomi")
1545 (set_attr "prefix" "orig,maybe_vex")
1547 (if_then_else (match_operand:SF 1)
1549 (const_string "DF")))
1550 (set (attr "prefix_rep")
1551 (if_then_else (eq_attr "type" "ssecomi")
1553 (const_string "*")))
1554 (set (attr "prefix_data16")
1555 (cond [(eq_attr "type" "fcmp")
1557 (eq_attr "mode" "DF")
1560 (const_string "0")))
1561 (set_attr "athlon_decode" "vector")
1562 (set_attr "amdfam10_decode" "direct")
1563 (set_attr "bdver1_decode" "double")])
1565 (define_insn "*cmpfp_iu_sse"
1566 [(set (reg:CCFPU FLAGS_REG)
1567 (compare:CCFPU (match_operand 0 "register_operand" "x")
1568 (match_operand 1 "nonimmediate_operand" "xm")))]
1570 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1571 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1572 "* return output_fp_compare (insn, operands, true, true);"
1573 [(set_attr "type" "ssecomi")
1574 (set_attr "prefix" "maybe_vex")
1576 (if_then_else (match_operand:SF 1)
1578 (const_string "DF")))
1579 (set_attr "prefix_rep" "0")
1580 (set (attr "prefix_data16")
1581 (if_then_else (eq_attr "mode" "DF")
1583 (const_string "0")))
1584 (set_attr "athlon_decode" "vector")
1585 (set_attr "amdfam10_decode" "direct")
1586 (set_attr "bdver1_decode" "double")])
1588 (define_insn "*cmpfp_iu_387"
1589 [(set (reg:CCFPU FLAGS_REG)
1590 (compare:CCFPU (match_operand 0 "register_operand" "f")
1591 (match_operand 1 "register_operand" "f")))]
1592 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1594 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1595 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1596 "* return output_fp_compare (insn, operands, true, true);"
1597 [(set_attr "type" "fcmp")
1599 (cond [(match_operand:SF 1)
1601 (match_operand:DF 1)
1604 (const_string "XF")))
1605 (set_attr "athlon_decode" "vector")
1606 (set_attr "amdfam10_decode" "direct")
1607 (set_attr "bdver1_decode" "direct")])
1609 ;; Push/pop instructions.
1611 (define_insn "*push<mode>2"
1612 [(set (match_operand:DWI 0 "push_operand" "=<")
1613 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1616 [(set_attr "type" "multi")
1617 (set_attr "mode" "<MODE>")])
1620 [(set (match_operand:TI 0 "push_operand")
1621 (match_operand:TI 1 "general_operand"))]
1622 "TARGET_64BIT && reload_completed
1623 && !SSE_REG_P (operands[1])"
1625 "ix86_split_long_move (operands); DONE;")
1627 (define_insn "*pushdi2_rex64"
1628 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1629 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1634 [(set_attr "type" "push,multi")
1635 (set_attr "mode" "DI")])
1637 ;; Convert impossible pushes of immediate to existing instructions.
1638 ;; First try to get scratch register and go through it. In case this
1639 ;; fails, push sign extended lower part first and then overwrite
1640 ;; upper part by 32bit move.
1642 [(match_scratch:DI 2 "r")
1643 (set (match_operand:DI 0 "push_operand")
1644 (match_operand:DI 1 "immediate_operand"))]
1645 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1646 && !x86_64_immediate_operand (operands[1], DImode)"
1647 [(set (match_dup 2) (match_dup 1))
1648 (set (match_dup 0) (match_dup 2))])
1650 ;; We need to define this as both peepholer and splitter for case
1651 ;; peephole2 pass is not run.
1652 ;; "&& 1" is needed to keep it from matching the previous pattern.
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) && 1"
1658 [(set (match_dup 0) (match_dup 1))
1659 (set (match_dup 2) (match_dup 3))]
1661 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1663 operands[1] = gen_lowpart (DImode, operands[2]);
1664 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1669 [(set (match_operand:DI 0 "push_operand")
1670 (match_operand:DI 1 "immediate_operand"))]
1671 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1672 ? epilogue_completed : reload_completed)
1673 && !symbolic_operand (operands[1], DImode)
1674 && !x86_64_immediate_operand (operands[1], DImode)"
1675 [(set (match_dup 0) (match_dup 1))
1676 (set (match_dup 2) (match_dup 3))]
1678 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1680 operands[1] = gen_lowpart (DImode, operands[2]);
1681 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1686 [(set (match_operand:DI 0 "push_operand")
1687 (match_operand:DI 1 "general_operand"))]
1688 "!TARGET_64BIT && reload_completed
1689 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1691 "ix86_split_long_move (operands); DONE;")
1693 (define_insn "*pushsi2"
1694 [(set (match_operand:SI 0 "push_operand" "=<")
1695 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1698 [(set_attr "type" "push")
1699 (set_attr "mode" "SI")])
1701 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1702 ;; "push a byte/word". But actually we use pushl, which has the effect
1703 ;; of rounding the amount pushed up to a word.
1705 ;; For TARGET_64BIT we always round up to 8 bytes.
1706 (define_insn "*push<mode>2_rex64"
1707 [(set (match_operand:SWI124 0 "push_operand" "=X")
1708 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1711 [(set_attr "type" "push")
1712 (set_attr "mode" "DI")])
1714 (define_insn "*push<mode>2"
1715 [(set (match_operand:SWI12 0 "push_operand" "=X")
1716 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1719 [(set_attr "type" "push")
1720 (set_attr "mode" "SI")])
1722 (define_insn "*push<mode>2_prologue"
1723 [(set (match_operand:W 0 "push_operand" "=<")
1724 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1725 (clobber (mem:BLK (scratch)))]
1727 "push{<imodesuffix>}\t%1"
1728 [(set_attr "type" "push")
1729 (set_attr "mode" "<MODE>")])
1731 (define_insn "*pop<mode>1"
1732 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1733 (match_operand:W 1 "pop_operand" ">"))]
1735 "pop{<imodesuffix>}\t%0"
1736 [(set_attr "type" "pop")
1737 (set_attr "mode" "<MODE>")])
1739 (define_insn "*pop<mode>1_epilogue"
1740 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1741 (match_operand:W 1 "pop_operand" ">"))
1742 (clobber (mem:BLK (scratch)))]
1744 "pop{<imodesuffix>}\t%0"
1745 [(set_attr "type" "pop")
1746 (set_attr "mode" "<MODE>")])
1748 ;; Move instructions.
1750 (define_expand "movoi"
1751 [(set (match_operand:OI 0 "nonimmediate_operand")
1752 (match_operand:OI 1 "general_operand"))]
1754 "ix86_expand_move (OImode, operands); DONE;")
1756 (define_expand "movti"
1757 [(set (match_operand:TI 0 "nonimmediate_operand")
1758 (match_operand:TI 1 "nonimmediate_operand"))]
1759 "TARGET_64BIT || TARGET_SSE"
1762 ix86_expand_move (TImode, operands);
1763 else if (push_operand (operands[0], TImode))
1764 ix86_expand_push (TImode, operands[1]);
1766 ix86_expand_vector_move (TImode, operands);
1770 ;; This expands to what emit_move_complex would generate if we didn't
1771 ;; have a movti pattern. Having this avoids problems with reload on
1772 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1773 ;; to have around all the time.
1774 (define_expand "movcdi"
1775 [(set (match_operand:CDI 0 "nonimmediate_operand")
1776 (match_operand:CDI 1 "general_operand"))]
1779 if (push_operand (operands[0], CDImode))
1780 emit_move_complex_push (CDImode, operands[0], operands[1]);
1782 emit_move_complex_parts (operands[0], operands[1]);
1786 (define_expand "mov<mode>"
1787 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1788 (match_operand:SWI1248x 1 "general_operand"))]
1790 "ix86_expand_move (<MODE>mode, operands); DONE;")
1792 (define_insn "*mov<mode>_xor"
1793 [(set (match_operand:SWI48 0 "register_operand" "=r")
1794 (match_operand:SWI48 1 "const0_operand"))
1795 (clobber (reg:CC FLAGS_REG))]
1798 [(set_attr "type" "alu1")
1799 (set_attr "mode" "SI")
1800 (set_attr "length_immediate" "0")])
1802 (define_insn "*mov<mode>_or"
1803 [(set (match_operand:SWI48 0 "register_operand" "=r")
1804 (match_operand:SWI48 1 "const_int_operand"))
1805 (clobber (reg:CC FLAGS_REG))]
1807 && operands[1] == constm1_rtx"
1808 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1809 [(set_attr "type" "alu1")
1810 (set_attr "mode" "<MODE>")
1811 (set_attr "length_immediate" "1")])
1813 (define_insn "*movoi_internal_avx"
1814 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1815 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1816 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1818 switch (which_alternative)
1821 return standard_sse_constant_opcode (insn, operands[1]);
1824 if (misaligned_operand (operands[0], OImode)
1825 || misaligned_operand (operands[1], OImode))
1827 if (get_attr_mode (insn) == MODE_V8SF)
1828 return "vmovups\t{%1, %0|%0, %1}";
1830 return "vmovdqu\t{%1, %0|%0, %1}";
1834 if (get_attr_mode (insn) == MODE_V8SF)
1835 return "vmovaps\t{%1, %0|%0, %1}";
1837 return "vmovdqa\t{%1, %0|%0, %1}";
1843 [(set_attr "type" "sselog1,ssemov,ssemov")
1844 (set_attr "prefix" "vex")
1846 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1847 (const_string "V8SF")
1848 (and (eq_attr "alternative" "2")
1849 (match_test "TARGET_SSE_TYPELESS_STORES"))
1850 (const_string "V8SF")
1852 (const_string "OI")))])
1854 (define_insn "*movti_internal_rex64"
1855 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1856 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1857 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1859 switch (which_alternative)
1865 return standard_sse_constant_opcode (insn, operands[1]);
1868 /* TDmode values are passed as TImode on the stack. Moving them
1869 to stack may result in unaligned memory access. */
1870 if (misaligned_operand (operands[0], TImode)
1871 || misaligned_operand (operands[1], TImode))
1873 if (get_attr_mode (insn) == MODE_V4SF)
1874 return "%vmovups\t{%1, %0|%0, %1}";
1876 return "%vmovdqu\t{%1, %0|%0, %1}";
1880 if (get_attr_mode (insn) == MODE_V4SF)
1881 return "%vmovaps\t{%1, %0|%0, %1}";
1883 return "%vmovdqa\t{%1, %0|%0, %1}";
1889 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1890 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1892 (cond [(eq_attr "alternative" "0,1")
1894 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1895 (const_string "V4SF")
1896 (and (eq_attr "alternative" "4")
1897 (match_test "TARGET_SSE_TYPELESS_STORES"))
1898 (const_string "V4SF")
1899 (match_test "TARGET_AVX")
1901 (match_test "optimize_function_for_size_p (cfun)")
1902 (const_string "V4SF")
1904 (const_string "TI")))])
1907 [(set (match_operand:TI 0 "nonimmediate_operand")
1908 (match_operand:TI 1 "general_operand"))]
1910 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1912 "ix86_split_long_move (operands); DONE;")
1914 (define_insn "*movti_internal_sse"
1915 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x ,m")
1916 (match_operand:TI 1 "vector_move_operand" "C ,xm,x"))]
1917 "TARGET_SSE && !TARGET_64BIT
1918 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1920 switch (which_alternative)
1923 return standard_sse_constant_opcode (insn, operands[1]);
1926 /* TDmode values are passed as TImode on the stack. Moving them
1927 to stack may result in unaligned memory access. */
1928 if (misaligned_operand (operands[0], TImode)
1929 || misaligned_operand (operands[1], TImode))
1931 if (get_attr_mode (insn) == MODE_V4SF)
1932 return "%vmovups\t{%1, %0|%0, %1}";
1934 return "%vmovdqu\t{%1, %0|%0, %1}";
1938 if (get_attr_mode (insn) == MODE_V4SF)
1939 return "%vmovaps\t{%1, %0|%0, %1}";
1941 return "%vmovdqa\t{%1, %0|%0, %1}";
1947 [(set_attr "type" "sselog1,ssemov,ssemov")
1948 (set_attr "prefix" "maybe_vex")
1950 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1951 (const_string "V4SF")
1952 (and (eq_attr "alternative" "2")
1953 (match_test "TARGET_SSE_TYPELESS_STORES"))
1954 (const_string "V4SF")
1955 (match_test "TARGET_AVX")
1957 (ior (not (match_test "TARGET_SSE2"))
1958 (match_test "optimize_function_for_size_p (cfun)"))
1959 (const_string "V4SF")
1961 (const_string "TI")))])
1963 (define_insn "*movdi_internal_rex64"
1964 [(set (match_operand:DI 0 "nonimmediate_operand"
1965 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1966 (match_operand:DI 1 "general_operand"
1967 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1968 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1970 switch (get_attr_type (insn))
1973 if (SSE_REG_P (operands[0]))
1974 return "movq2dq\t{%1, %0|%0, %1}";
1976 return "movdq2q\t{%1, %0|%0, %1}";
1979 if (get_attr_mode (insn) == MODE_V4SF)
1980 return "%vmovaps\t{%1, %0|%0, %1}";
1981 else if (get_attr_mode (insn) == MODE_TI)
1982 return "%vmovdqa\t{%1, %0|%0, %1}";
1984 /* Handle broken assemblers that require movd instead of movq. */
1985 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1986 return "%vmovd\t{%1, %0|%0, %1}";
1988 return "%vmovq\t{%1, %0|%0, %1}";
1991 /* Handle broken assemblers that require movd instead of movq. */
1992 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1993 return "movd\t{%1, %0|%0, %1}";
1995 return "movq\t{%1, %0|%0, %1}";
1998 return standard_sse_constant_opcode (insn, operands[1]);
2001 return "pxor\t%0, %0";
2007 return "lea{q}\t{%E1, %0|%0, %E1}";
2010 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2011 if (get_attr_mode (insn) == MODE_SI)
2012 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2013 else if (which_alternative == 2)
2014 return "movabs{q}\t{%1, %0|%0, %1}";
2015 else if (ix86_use_lea_for_mov (insn, operands))
2016 return "lea{q}\t{%E1, %0|%0, %E1}";
2018 return "mov{q}\t{%1, %0|%0, %1}";
2022 (cond [(eq_attr "alternative" "4")
2023 (const_string "multi")
2024 (eq_attr "alternative" "5")
2025 (const_string "mmx")
2026 (eq_attr "alternative" "6,7,8,9")
2027 (const_string "mmxmov")
2028 (eq_attr "alternative" "10")
2029 (const_string "sselog1")
2030 (eq_attr "alternative" "11,12,13,14,15")
2031 (const_string "ssemov")
2032 (eq_attr "alternative" "16,17")
2033 (const_string "ssecvt")
2034 (match_operand 1 "pic_32bit_operand")
2035 (const_string "lea")
2037 (const_string "imov")))
2040 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2042 (const_string "*")))
2043 (set (attr "length_immediate")
2045 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2047 (const_string "*")))
2048 (set (attr "prefix_rex")
2049 (if_then_else (eq_attr "alternative" "8,9")
2051 (const_string "*")))
2052 (set (attr "prefix_data16")
2053 (if_then_else (eq_attr "alternative" "11")
2055 (const_string "*")))
2056 (set (attr "prefix")
2057 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2058 (const_string "maybe_vex")
2059 (const_string "orig")))
2061 (cond [(eq_attr "alternative" "0,4")
2063 (eq_attr "alternative" "10,12")
2064 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2065 (const_string "V4SF")
2066 (match_test "TARGET_AVX")
2068 (match_test "optimize_function_for_size_p (cfun)")
2069 (const_string "V4SF")
2071 (const_string "TI"))
2073 (const_string "DI")))])
2075 ;; Reload patterns to support multi-word load/store
2076 ;; with non-offsetable address.
2077 (define_expand "reload_noff_store"
2078 [(parallel [(match_operand 0 "memory_operand" "=m")
2079 (match_operand 1 "register_operand" "r")
2080 (match_operand:DI 2 "register_operand" "=&r")])]
2083 rtx mem = operands[0];
2084 rtx addr = XEXP (mem, 0);
2086 emit_move_insn (operands[2], addr);
2087 mem = replace_equiv_address_nv (mem, operands[2]);
2089 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2093 (define_expand "reload_noff_load"
2094 [(parallel [(match_operand 0 "register_operand" "=r")
2095 (match_operand 1 "memory_operand" "m")
2096 (match_operand:DI 2 "register_operand" "=r")])]
2099 rtx mem = operands[1];
2100 rtx addr = XEXP (mem, 0);
2102 emit_move_insn (operands[2], addr);
2103 mem = replace_equiv_address_nv (mem, operands[2]);
2105 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2109 ;; Convert impossible stores of immediate to existing instructions.
2110 ;; First try to get scratch register and go through it. In case this
2111 ;; fails, move by 32bit parts.
2113 [(match_scratch:DI 2 "r")
2114 (set (match_operand:DI 0 "memory_operand")
2115 (match_operand:DI 1 "immediate_operand"))]
2116 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2117 && !x86_64_immediate_operand (operands[1], DImode)"
2118 [(set (match_dup 2) (match_dup 1))
2119 (set (match_dup 0) (match_dup 2))])
2121 ;; We need to define this as both peepholer and splitter for case
2122 ;; peephole2 pass is not run.
2123 ;; "&& 1" is needed to keep it from matching the previous pattern.
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) && 1"
2129 [(set (match_dup 2) (match_dup 3))
2130 (set (match_dup 4) (match_dup 5))]
2131 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2134 [(set (match_operand:DI 0 "memory_operand")
2135 (match_operand:DI 1 "immediate_operand"))]
2136 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2137 ? epilogue_completed : reload_completed)
2138 && !symbolic_operand (operands[1], DImode)
2139 && !x86_64_immediate_operand (operands[1], DImode)"
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]);")
2144 (define_insn "*movdi_internal"
2145 [(set (match_operand:DI 0 "nonimmediate_operand"
2146 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2147 (match_operand:DI 1 "general_operand"
2148 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2149 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2151 switch (get_attr_type (insn))
2154 if (SSE_REG_P (operands[0]))
2155 return "movq2dq\t{%1, %0|%0, %1}";
2157 return "movdq2q\t{%1, %0|%0, %1}";
2160 switch (get_attr_mode (insn))
2163 return "%vmovdqa\t{%1, %0|%0, %1}";
2165 return "%vmovq\t{%1, %0|%0, %1}";
2167 return "%vmovaps\t{%1, %0|%0, %1}";
2169 return "movlps\t{%1, %0|%0, %1}";
2175 return "movq\t{%1, %0|%0, %1}";
2178 return standard_sse_constant_opcode (insn, operands[1]);
2181 return "pxor\t%0, %0";
2191 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2192 (const_string "sse2")
2193 (eq_attr "alternative" "9,10,11,12")
2194 (const_string "noavx")
2196 (const_string "*")))
2198 (cond [(eq_attr "alternative" "0,1")
2199 (const_string "multi")
2200 (eq_attr "alternative" "2")
2201 (const_string "mmx")
2202 (eq_attr "alternative" "3,4")
2203 (const_string "mmxmov")
2204 (eq_attr "alternative" "5,9")
2205 (const_string "sselog1")
2206 (eq_attr "alternative" "13,14")
2207 (const_string "ssecvt")
2209 (const_string "ssemov")))
2210 (set (attr "prefix")
2211 (if_then_else (eq_attr "alternative" "5,6,7,8")
2212 (const_string "maybe_vex")
2213 (const_string "orig")))
2215 (cond [(eq_attr "alternative" "9,11")
2216 (const_string "V4SF")
2217 (eq_attr "alternative" "10,12")
2218 (const_string "V2SF")
2219 (eq_attr "alternative" "5,7")
2220 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2221 (const_string "V4SF")
2222 (match_test "TARGET_AVX")
2224 (match_test "optimize_function_for_size_p (cfun)")
2225 (const_string "V4SF")
2227 (const_string "TI"))
2229 (const_string "DI")))])
2232 [(set (match_operand:DI 0 "nonimmediate_operand")
2233 (match_operand:DI 1 "general_operand"))]
2234 "!TARGET_64BIT && reload_completed
2235 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2236 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2238 "ix86_split_long_move (operands); DONE;")
2240 (define_insn "*movsi_internal"
2241 [(set (match_operand:SI 0 "nonimmediate_operand"
2242 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2243 (match_operand:SI 1 "general_operand"
2244 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2245 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2247 switch (get_attr_type (insn))
2250 return standard_sse_constant_opcode (insn, operands[1]);
2253 switch (get_attr_mode (insn))
2256 return "%vmovdqa\t{%1, %0|%0, %1}";
2258 return "%vmovaps\t{%1, %0|%0, %1}";
2260 return "%vmovd\t{%1, %0|%0, %1}";
2262 return "%vmovss\t{%1, %0|%0, %1}";
2268 return "pxor\t%0, %0";
2271 if (get_attr_mode (insn) == MODE_DI)
2272 return "movq\t{%1, %0|%0, %1}";
2273 return "movd\t{%1, %0|%0, %1}";
2276 return "lea{l}\t{%E1, %0|%0, %E1}";
2279 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2280 if (ix86_use_lea_for_mov (insn, operands))
2281 return "lea{l}\t{%E1, %0|%0, %E1}";
2283 return "mov{l}\t{%1, %0|%0, %1}";
2287 (cond [(eq_attr "alternative" "2")
2288 (const_string "mmx")
2289 (eq_attr "alternative" "3,4,5")
2290 (const_string "mmxmov")
2291 (eq_attr "alternative" "6")
2292 (const_string "sselog1")
2293 (eq_attr "alternative" "7,8,9,10,11")
2294 (const_string "ssemov")
2295 (match_operand 1 "pic_32bit_operand")
2296 (const_string "lea")
2298 (const_string "imov")))
2299 (set (attr "prefix")
2300 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2301 (const_string "orig")
2302 (const_string "maybe_vex")))
2303 (set (attr "prefix_data16")
2304 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2306 (const_string "*")))
2308 (cond [(eq_attr "alternative" "2,3")
2310 (eq_attr "alternative" "6,7")
2311 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2312 (const_string "V4SF")
2313 (match_test "TARGET_AVX")
2315 (ior (not (match_test "TARGET_SSE2"))
2316 (match_test "optimize_function_for_size_p (cfun)"))
2317 (const_string "V4SF")
2319 (const_string "TI"))
2320 (and (eq_attr "alternative" "8,9,10,11")
2321 (not (match_test "TARGET_SSE2")))
2324 (const_string "SI")))])
2326 (define_insn "*movhi_internal"
2327 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2328 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2329 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2331 switch (get_attr_type (insn))
2334 /* movzwl is faster than movw on p2 due to partial word stalls,
2335 though not as fast as an aligned movl. */
2336 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2338 if (get_attr_mode (insn) == MODE_SI)
2339 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2341 return "mov{w}\t{%1, %0|%0, %1}";
2345 (cond [(match_test "optimize_function_for_size_p (cfun)")
2346 (const_string "imov")
2347 (and (eq_attr "alternative" "0")
2348 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2349 (not (match_test "TARGET_HIMODE_MATH"))))
2350 (const_string "imov")
2351 (and (eq_attr "alternative" "1,2")
2352 (match_operand:HI 1 "aligned_operand"))
2353 (const_string "imov")
2354 (and (match_test "TARGET_MOVX")
2355 (eq_attr "alternative" "0,2"))
2356 (const_string "imovx")
2358 (const_string "imov")))
2360 (cond [(eq_attr "type" "imovx")
2362 (and (eq_attr "alternative" "1,2")
2363 (match_operand:HI 1 "aligned_operand"))
2365 (and (eq_attr "alternative" "0")
2366 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2367 (not (match_test "TARGET_HIMODE_MATH"))))
2370 (const_string "HI")))])
2372 ;; Situation is quite tricky about when to choose full sized (SImode) move
2373 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2374 ;; partial register dependency machines (such as AMD Athlon), where QImode
2375 ;; moves issue extra dependency and for partial register stalls machines
2376 ;; that don't use QImode patterns (and QImode move cause stall on the next
2379 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2380 ;; register stall machines with, where we use QImode instructions, since
2381 ;; partial register stall can be caused there. Then we use movzx.
2382 (define_insn "*movqi_internal"
2383 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2384 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2385 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2387 switch (get_attr_type (insn))
2390 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2391 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2393 if (get_attr_mode (insn) == MODE_SI)
2394 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2396 return "mov{b}\t{%1, %0|%0, %1}";
2400 (cond [(and (eq_attr "alternative" "5")
2401 (not (match_operand:QI 1 "aligned_operand")))
2402 (const_string "imovx")
2403 (match_test "optimize_function_for_size_p (cfun)")
2404 (const_string "imov")
2405 (and (eq_attr "alternative" "3")
2406 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2407 (not (match_test "TARGET_QIMODE_MATH"))))
2408 (const_string "imov")
2409 (eq_attr "alternative" "3,5")
2410 (const_string "imovx")
2411 (and (match_test "TARGET_MOVX")
2412 (eq_attr "alternative" "2"))
2413 (const_string "imovx")
2415 (const_string "imov")))
2417 (cond [(eq_attr "alternative" "3,4,5")
2419 (eq_attr "alternative" "6")
2421 (eq_attr "type" "imovx")
2423 (and (eq_attr "type" "imov")
2424 (and (eq_attr "alternative" "0,1")
2425 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2426 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2427 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2429 ;; Avoid partial register stalls when not using QImode arithmetic
2430 (and (eq_attr "type" "imov")
2431 (and (eq_attr "alternative" "0,1")
2432 (and (match_test "TARGET_PARTIAL_REG_STALL")
2433 (not (match_test "TARGET_QIMODE_MATH")))))
2436 (const_string "QI")))])
2438 ;; Stores and loads of ax to arbitrary constant address.
2439 ;; We fake an second form of instruction to force reload to load address
2440 ;; into register when rax is not available
2441 (define_insn "*movabs<mode>_1"
2442 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2443 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2444 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2446 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2447 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2448 [(set_attr "type" "imov")
2449 (set_attr "modrm" "0,*")
2450 (set_attr "length_address" "8,0")
2451 (set_attr "length_immediate" "0,*")
2452 (set_attr "memory" "store")
2453 (set_attr "mode" "<MODE>")])
2455 (define_insn "*movabs<mode>_2"
2456 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2457 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2458 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2460 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2461 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2462 [(set_attr "type" "imov")
2463 (set_attr "modrm" "0,*")
2464 (set_attr "length_address" "8,0")
2465 (set_attr "length_immediate" "0")
2466 (set_attr "memory" "load")
2467 (set_attr "mode" "<MODE>")])
2469 (define_insn "swap<mode>"
2470 [(set (match_operand:SWI48 0 "register_operand" "+r")
2471 (match_operand:SWI48 1 "register_operand" "+r"))
2475 "xchg{<imodesuffix>}\t%1, %0"
2476 [(set_attr "type" "imov")
2477 (set_attr "mode" "<MODE>")
2478 (set_attr "pent_pair" "np")
2479 (set_attr "athlon_decode" "vector")
2480 (set_attr "amdfam10_decode" "double")
2481 (set_attr "bdver1_decode" "double")])
2483 (define_insn "*swap<mode>_1"
2484 [(set (match_operand:SWI12 0 "register_operand" "+r")
2485 (match_operand:SWI12 1 "register_operand" "+r"))
2488 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2490 [(set_attr "type" "imov")
2491 (set_attr "mode" "SI")
2492 (set_attr "pent_pair" "np")
2493 (set_attr "athlon_decode" "vector")
2494 (set_attr "amdfam10_decode" "double")
2495 (set_attr "bdver1_decode" "double")])
2497 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2498 ;; is disabled for AMDFAM10
2499 (define_insn "*swap<mode>_2"
2500 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2501 (match_operand:SWI12 1 "register_operand" "+<r>"))
2504 "TARGET_PARTIAL_REG_STALL"
2505 "xchg{<imodesuffix>}\t%1, %0"
2506 [(set_attr "type" "imov")
2507 (set_attr "mode" "<MODE>")
2508 (set_attr "pent_pair" "np")
2509 (set_attr "athlon_decode" "vector")])
2511 (define_expand "movstrict<mode>"
2512 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2513 (match_operand:SWI12 1 "general_operand"))]
2516 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2518 if (GET_CODE (operands[0]) == SUBREG
2519 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2521 /* Don't generate memory->memory moves, go through a register */
2522 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2523 operands[1] = force_reg (<MODE>mode, operands[1]);
2526 (define_insn "*movstrict<mode>_1"
2527 [(set (strict_low_part
2528 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2529 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2530 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2531 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2532 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2533 [(set_attr "type" "imov")
2534 (set_attr "mode" "<MODE>")])
2536 (define_insn "*movstrict<mode>_xor"
2537 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2538 (match_operand:SWI12 1 "const0_operand"))
2539 (clobber (reg:CC FLAGS_REG))]
2541 "xor{<imodesuffix>}\t%0, %0"
2542 [(set_attr "type" "alu1")
2543 (set_attr "mode" "<MODE>")
2544 (set_attr "length_immediate" "0")])
2546 (define_insn "*mov<mode>_extv_1"
2547 [(set (match_operand:SWI24 0 "register_operand" "=R")
2548 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2552 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2553 [(set_attr "type" "imovx")
2554 (set_attr "mode" "SI")])
2556 (define_insn "*movqi_extv_1_rex64"
2557 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2558 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2563 switch (get_attr_type (insn))
2566 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2568 return "mov{b}\t{%h1, %0|%0, %h1}";
2572 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2573 (match_test "TARGET_MOVX"))
2574 (const_string "imovx")
2575 (const_string "imov")))
2577 (if_then_else (eq_attr "type" "imovx")
2579 (const_string "QI")))])
2581 (define_insn "*movqi_extv_1"
2582 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2583 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2588 switch (get_attr_type (insn))
2591 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2593 return "mov{b}\t{%h1, %0|%0, %h1}";
2597 (if_then_else (and (match_operand:QI 0 "register_operand")
2598 (ior (not (match_operand:QI 0 "QIreg_operand"))
2599 (match_test "TARGET_MOVX")))
2600 (const_string "imovx")
2601 (const_string "imov")))
2603 (if_then_else (eq_attr "type" "imovx")
2605 (const_string "QI")))])
2607 (define_insn "*mov<mode>_extzv_1"
2608 [(set (match_operand:SWI48 0 "register_operand" "=R")
2609 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2613 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2614 [(set_attr "type" "imovx")
2615 (set_attr "mode" "SI")])
2617 (define_insn "*movqi_extzv_2_rex64"
2618 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2620 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2625 switch (get_attr_type (insn))
2628 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2630 return "mov{b}\t{%h1, %0|%0, %h1}";
2634 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2635 (match_test "TARGET_MOVX"))
2636 (const_string "imovx")
2637 (const_string "imov")))
2639 (if_then_else (eq_attr "type" "imovx")
2641 (const_string "QI")))])
2643 (define_insn "*movqi_extzv_2"
2644 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2646 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2651 switch (get_attr_type (insn))
2654 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2656 return "mov{b}\t{%h1, %0|%0, %h1}";
2660 (if_then_else (and (match_operand:QI 0 "register_operand")
2661 (ior (not (match_operand:QI 0 "QIreg_operand"))
2662 (match_test "TARGET_MOVX")))
2663 (const_string "imovx")
2664 (const_string "imov")))
2666 (if_then_else (eq_attr "type" "imovx")
2668 (const_string "QI")))])
2670 (define_expand "mov<mode>_insv_1"
2671 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2674 (match_operand:SWI48 1 "nonmemory_operand"))])
2676 (define_insn "*mov<mode>_insv_1_rex64"
2677 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2680 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2682 "mov{b}\t{%b1, %h0|%h0, %b1}"
2683 [(set_attr "type" "imov")
2684 (set_attr "mode" "QI")])
2686 (define_insn "*movsi_insv_1"
2687 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2690 (match_operand:SI 1 "general_operand" "Qmn"))]
2692 "mov{b}\t{%b1, %h0|%h0, %b1}"
2693 [(set_attr "type" "imov")
2694 (set_attr "mode" "QI")])
2696 (define_insn "*movqi_insv_2"
2697 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2700 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2703 "mov{b}\t{%h1, %h0|%h0, %h1}"
2704 [(set_attr "type" "imov")
2705 (set_attr "mode" "QI")])
2707 ;; Floating point push instructions.
2709 (define_insn "*pushtf"
2710 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2711 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2714 /* This insn should be already split before reg-stack. */
2717 [(set_attr "type" "multi")
2718 (set_attr "unit" "sse,*,*")
2719 (set_attr "mode" "TF,SI,SI")])
2721 ;; %%% Kill this when call knows how to work this out.
2723 [(set (match_operand:TF 0 "push_operand")
2724 (match_operand:TF 1 "sse_reg_operand"))]
2725 "TARGET_SSE && reload_completed"
2726 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2727 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2729 (define_insn "*pushxf"
2730 [(set (match_operand:XF 0 "push_operand" "=<,<")
2731 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2732 "optimize_function_for_speed_p (cfun)"
2734 /* This insn should be already split before reg-stack. */
2737 [(set_attr "type" "multi")
2738 (set_attr "unit" "i387,*")
2739 (set_attr "mode" "XF,SI")])
2741 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2742 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2743 ;; Pushing using integer instructions is longer except for constants
2744 ;; and direct memory references (assuming that any given constant is pushed
2745 ;; only once, but this ought to be handled elsewhere).
2747 (define_insn "*pushxf_nointeger"
2748 [(set (match_operand:XF 0 "push_operand" "=<,<")
2749 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2750 "optimize_function_for_size_p (cfun)"
2752 /* This insn should be already split before reg-stack. */
2755 [(set_attr "type" "multi")
2756 (set_attr "unit" "i387,*")
2757 (set_attr "mode" "XF,SI")])
2759 ;; %%% Kill this when call knows how to work this out.
2761 [(set (match_operand:XF 0 "push_operand")
2762 (match_operand:XF 1 "fp_register_operand"))]
2764 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2765 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2766 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2768 (define_insn "*pushdf_rex64"
2769 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2770 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2773 /* This insn should be already split before reg-stack. */
2776 [(set_attr "type" "multi")
2777 (set_attr "unit" "i387,*,*")
2778 (set_attr "mode" "DF,DI,DF")])
2780 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2781 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2782 ;; On the average, pushdf using integers can be still shorter.
2784 (define_insn "*pushdf"
2785 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2786 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2789 /* This insn should be already split before reg-stack. */
2792 [(set_attr "isa" "*,*,sse2")
2793 (set_attr "type" "multi")
2794 (set_attr "unit" "i387,*,*")
2795 (set_attr "mode" "DF,DI,DF")])
2797 ;; %%% Kill this when call knows how to work this out.
2799 [(set (match_operand:DF 0 "push_operand")
2800 (match_operand:DF 1 "any_fp_register_operand"))]
2802 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2803 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2805 (define_insn "*pushsf_rex64"
2806 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2807 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2810 /* Anything else should be already split before reg-stack. */
2811 gcc_assert (which_alternative == 1);
2812 return "push{q}\t%q1";
2814 [(set_attr "type" "multi,push,multi")
2815 (set_attr "unit" "i387,*,*")
2816 (set_attr "mode" "SF,DI,SF")])
2818 (define_insn "*pushsf"
2819 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2820 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2823 /* Anything else should be already split before reg-stack. */
2824 gcc_assert (which_alternative == 1);
2825 return "push{l}\t%1";
2827 [(set_attr "type" "multi,push,multi")
2828 (set_attr "unit" "i387,*,*")
2829 (set_attr "mode" "SF,SI,SF")])
2831 ;; %%% Kill this when call knows how to work this out.
2833 [(set (match_operand:SF 0 "push_operand")
2834 (match_operand:SF 1 "any_fp_register_operand"))]
2836 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2837 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2838 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2841 [(set (match_operand:SF 0 "push_operand")
2842 (match_operand:SF 1 "memory_operand"))]
2844 && (operands[2] = find_constant_src (insn))"
2845 [(set (match_dup 0) (match_dup 2))])
2848 [(set (match_operand 0 "push_operand")
2849 (match_operand 1 "general_operand"))]
2851 && (GET_MODE (operands[0]) == TFmode
2852 || GET_MODE (operands[0]) == XFmode
2853 || GET_MODE (operands[0]) == DFmode)
2854 && !ANY_FP_REG_P (operands[1])"
2856 "ix86_split_long_move (operands); DONE;")
2858 ;; Floating point move instructions.
2860 (define_expand "movtf"
2861 [(set (match_operand:TF 0 "nonimmediate_operand")
2862 (match_operand:TF 1 "nonimmediate_operand"))]
2865 ix86_expand_move (TFmode, operands);
2869 (define_expand "mov<mode>"
2870 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2871 (match_operand:X87MODEF 1 "general_operand"))]
2873 "ix86_expand_move (<MODE>mode, operands); DONE;")
2875 (define_insn "*movtf_internal"
2876 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2877 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,F*r"))]
2879 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2880 && (!can_create_pseudo_p ()
2881 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2882 || GET_CODE (operands[1]) != CONST_DOUBLE
2883 || (optimize_function_for_size_p (cfun)
2884 && standard_sse_constant_p (operands[1])
2885 && !memory_operand (operands[0], TFmode))
2886 || (!TARGET_MEMORY_MISMATCH_STALL
2887 && memory_operand (operands[0], TFmode)))"
2889 switch (which_alternative)
2892 return standard_sse_constant_opcode (insn, operands[1]);
2895 /* Handle misaligned load/store since we
2896 don't have movmisaligntf pattern. */
2897 if (misaligned_operand (operands[0], TFmode)
2898 || misaligned_operand (operands[1], TFmode))
2900 if (get_attr_mode (insn) == MODE_V4SF)
2901 return "%vmovups\t{%1, %0|%0, %1}";
2903 return "%vmovdqu\t{%1, %0|%0, %1}";
2907 if (get_attr_mode (insn) == MODE_V4SF)
2908 return "%vmovaps\t{%1, %0|%0, %1}";
2910 return "%vmovdqa\t{%1, %0|%0, %1}";
2921 [(set_attr "type" "sselog1,ssemov,ssemov,*,*")
2922 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2924 (cond [(eq_attr "alternative" "3,4")
2926 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2927 (const_string "V4SF")
2928 (and (eq_attr "alternative" "2")
2929 (match_test "TARGET_SSE_TYPELESS_STORES"))
2930 (const_string "V4SF")
2931 (match_test "TARGET_AVX")
2933 (ior (not (match_test "TARGET_SSE2"))
2934 (match_test "optimize_function_for_size_p (cfun)"))
2935 (const_string "V4SF")
2937 (const_string "TI")))])
2939 ;; Possible store forwarding (partial memory) stall in alternative 4.
2940 (define_insn "*movxf_internal"
2941 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2942 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2943 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2944 && (!can_create_pseudo_p ()
2945 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2946 || GET_CODE (operands[1]) != CONST_DOUBLE
2947 || (optimize_function_for_size_p (cfun)
2948 && standard_80387_constant_p (operands[1]) > 0
2949 && !memory_operand (operands[0], XFmode))
2950 || (!TARGET_MEMORY_MISMATCH_STALL
2951 && memory_operand (operands[0], XFmode)))"
2953 switch (which_alternative)
2957 return output_387_reg_move (insn, operands);
2960 return standard_80387_constant_opcode (operands[1]);
2970 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2971 (set_attr "mode" "XF,XF,XF,SI,SI")])
2973 (define_insn "*movdf_internal_rex64"
2974 [(set (match_operand:DF 0 "nonimmediate_operand"
2975 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2976 (match_operand:DF 1 "general_operand"
2977 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2978 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2979 && (!can_create_pseudo_p ()
2980 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2981 || GET_CODE (operands[1]) != CONST_DOUBLE
2982 || (optimize_function_for_size_p (cfun)
2983 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2984 && standard_80387_constant_p (operands[1]) > 0)
2985 || (TARGET_SSE2 && TARGET_SSE_MATH
2986 && standard_sse_constant_p (operands[1]))))
2987 || memory_operand (operands[0], DFmode))"
2989 switch (which_alternative)
2993 return output_387_reg_move (insn, operands);
2996 return standard_80387_constant_opcode (operands[1]);
3000 return "mov{q}\t{%1, %0|%0, %1}";
3003 return "movabs{q}\t{%1, %0|%0, %1}";
3009 return standard_sse_constant_opcode (insn, operands[1]);
3014 switch (get_attr_mode (insn))
3017 return "%vmovapd\t{%1, %0|%0, %1}";
3019 return "%vmovaps\t{%1, %0|%0, %1}";
3022 return "%vmovq\t{%1, %0|%0, %1}";
3024 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3025 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3026 return "%vmovsd\t{%1, %0|%0, %1}";
3028 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3030 return "%vmovlps\t{%1, %d0|%d0, %1}";
3037 /* Handle broken assemblers that require movd instead of movq. */
3038 return "%vmovd\t{%1, %0|%0, %1}";
3045 (cond [(eq_attr "alternative" "0,1,2")
3046 (const_string "fmov")
3047 (eq_attr "alternative" "3,4,5")
3048 (const_string "imov")
3049 (eq_attr "alternative" "6")
3050 (const_string "multi")
3051 (eq_attr "alternative" "7")
3052 (const_string "sselog1")
3054 (const_string "ssemov")))
3057 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3059 (const_string "*")))
3060 (set (attr "length_immediate")
3062 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3064 (const_string "*")))
3065 (set (attr "prefix")
3066 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3067 (const_string "orig")
3068 (const_string "maybe_vex")))
3069 (set (attr "prefix_data16")
3070 (if_then_else (eq_attr "mode" "V1DF")
3072 (const_string "*")))
3074 (cond [(eq_attr "alternative" "0,1,2")
3076 (eq_attr "alternative" "3,4,5,6,11,12")
3079 /* xorps is one byte shorter for !TARGET_AVX. */
3080 (eq_attr "alternative" "7")
3081 (cond [(match_test "TARGET_AVX")
3082 (const_string "V2DF")
3083 (match_test "optimize_function_for_size_p (cfun)")
3084 (const_string "V4SF")
3085 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3088 (const_string "V2DF"))
3090 /* For architectures resolving dependencies on
3091 whole SSE registers use APD move to break dependency
3092 chains, otherwise use short move to avoid extra work.
3094 movaps encodes one byte shorter for !TARGET_AVX. */
3095 (eq_attr "alternative" "8")
3096 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3097 (const_string "V4SF")
3098 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3099 (const_string "V2DF")
3100 (match_test "TARGET_AVX")
3102 (match_test "optimize_function_for_size_p (cfun)")
3103 (const_string "V4SF")
3105 (const_string "DF"))
3106 /* For architectures resolving dependencies on register
3107 parts we may avoid extra work to zero out upper part
3109 (eq_attr "alternative" "9")
3111 (match_test "TARGET_SSE_SPLIT_REGS")
3112 (const_string "V1DF")
3113 (const_string "DF"))
3115 (const_string "DF")))])
3117 ;; Possible store forwarding (partial memory) stall in alternative 4.
3118 (define_insn "*movdf_internal"
3119 [(set (match_operand:DF 0 "nonimmediate_operand"
3120 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3121 (match_operand:DF 1 "general_operand"
3122 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3123 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3124 && (!can_create_pseudo_p ()
3125 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3126 || GET_CODE (operands[1]) != CONST_DOUBLE
3127 || (optimize_function_for_size_p (cfun)
3128 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3129 && standard_80387_constant_p (operands[1]) > 0)
3130 || (TARGET_SSE2 && TARGET_SSE_MATH
3131 && standard_sse_constant_p (operands[1])))
3132 && !memory_operand (operands[0], DFmode))
3133 || (!TARGET_MEMORY_MISMATCH_STALL
3134 && memory_operand (operands[0], DFmode)))"
3136 switch (which_alternative)
3140 return output_387_reg_move (insn, operands);
3143 return standard_80387_constant_opcode (operands[1]);
3151 return standard_sse_constant_opcode (insn, operands[1]);
3159 switch (get_attr_mode (insn))
3162 return "%vmovapd\t{%1, %0|%0, %1}";
3164 return "%vmovaps\t{%1, %0|%0, %1}";
3167 return "%vmovq\t{%1, %0|%0, %1}";
3169 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3170 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3171 return "%vmovsd\t{%1, %0|%0, %1}";
3173 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3175 return "%vmovlps\t{%1, %d0|%d0, %1}";
3185 (if_then_else (eq_attr "alternative" "5,6,7,8")
3186 (const_string "sse2")
3187 (const_string "*")))
3189 (cond [(eq_attr "alternative" "0,1,2")
3190 (const_string "fmov")
3191 (eq_attr "alternative" "3,4")
3192 (const_string "multi")
3193 (eq_attr "alternative" "5,9")
3194 (const_string "sselog1")
3196 (const_string "ssemov")))
3197 (set (attr "prefix")
3198 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3199 (const_string "orig")
3200 (const_string "maybe_vex")))
3201 (set (attr "prefix_data16")
3202 (if_then_else (eq_attr "mode" "V1DF")
3204 (const_string "*")))
3206 (cond [(eq_attr "alternative" "0,1,2")
3208 (eq_attr "alternative" "3,4")
3211 /* For SSE1, we have many fewer alternatives. */
3212 (not (match_test "TARGET_SSE2"))
3214 (eq_attr "alternative" "5,6,9,10")
3215 (const_string "V4SF")
3216 (const_string "V2SF"))
3218 /* xorps is one byte shorter for !TARGET_AVX. */
3219 (eq_attr "alternative" "5,9")
3220 (cond [(match_test "TARGET_AVX")
3221 (const_string "V2DF")
3222 (match_test "optimize_function_for_size_p (cfun)")
3223 (const_string "V4SF")
3224 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3227 (const_string "V2DF"))
3229 /* For architectures resolving dependencies on
3230 whole SSE registers use APD move to break dependency
3231 chains, otherwise use short move to avoid extra work.
3233 movaps encodes one byte shorter for !TARGET_AVX. */
3234 (eq_attr "alternative" "6,10")
3235 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3236 (const_string "V4SF")
3237 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3238 (const_string "V2DF")
3239 (match_test "TARGET_AVX")
3241 (match_test "optimize_function_for_size_p (cfun)")
3242 (const_string "V4SF")
3244 (const_string "DF"))
3246 /* For architectures resolving dependencies on register
3247 parts we may avoid extra work to zero out upper part
3249 (eq_attr "alternative" "7,11")
3251 (match_test "TARGET_SSE_SPLIT_REGS")
3252 (const_string "V1DF")
3253 (const_string "DF"))
3255 (const_string "DF")))])
3257 (define_insn "*movsf_internal"
3258 [(set (match_operand:SF 0 "nonimmediate_operand"
3259 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3260 (match_operand:SF 1 "general_operand"
3261 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3262 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3263 && (!can_create_pseudo_p ()
3264 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3265 || GET_CODE (operands[1]) != CONST_DOUBLE
3266 || (optimize_function_for_size_p (cfun)
3267 && ((!TARGET_SSE_MATH
3268 && standard_80387_constant_p (operands[1]) > 0)
3270 && standard_sse_constant_p (operands[1]))))
3271 || memory_operand (operands[0], SFmode))"
3273 switch (which_alternative)
3277 return output_387_reg_move (insn, operands);
3280 return standard_80387_constant_opcode (operands[1]);
3284 return "mov{l}\t{%1, %0|%0, %1}";
3287 return standard_sse_constant_opcode (insn, operands[1]);
3290 if (get_attr_mode (insn) == MODE_V4SF)
3291 return "%vmovaps\t{%1, %0|%0, %1}";
3293 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3297 return "%vmovss\t{%1, %0|%0, %1}";
3303 return "movd\t{%1, %0|%0, %1}";
3306 return "movq\t{%1, %0|%0, %1}";
3310 return "%vmovd\t{%1, %0|%0, %1}";
3317 (cond [(eq_attr "alternative" "0,1,2")
3318 (const_string "fmov")
3319 (eq_attr "alternative" "3,4")
3320 (const_string "multi")
3321 (eq_attr "alternative" "5")
3322 (const_string "sselog1")
3323 (eq_attr "alternative" "9,10,11,14,15")
3324 (const_string "mmxmov")
3326 (const_string "ssemov")))
3327 (set (attr "prefix")
3328 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3329 (const_string "maybe_vex")
3330 (const_string "orig")))
3332 (cond [(eq_attr "alternative" "3,4,9,10")
3334 (eq_attr "alternative" "5")
3335 (cond [(match_test "TARGET_AVX")
3336 (const_string "V4SF")
3337 (ior (not (match_test "TARGET_SSE2"))
3338 (match_test "optimize_function_for_size_p (cfun)"))
3339 (const_string "V4SF")
3340 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3343 (const_string "V4SF"))
3345 /* For architectures resolving dependencies on
3346 whole SSE registers use APS move to break dependency
3347 chains, otherwise use short move to avoid extra work.
3349 Do the same for architectures resolving dependencies on
3350 the parts. While in DF mode it is better to always handle
3351 just register parts, the SF mode is different due to lack
3352 of instructions to load just part of the register. It is
3353 better to maintain the whole registers in single format
3354 to avoid problems on using packed logical operations. */
3355 (eq_attr "alternative" "6")
3357 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3358 (match_test "TARGET_SSE_SPLIT_REGS"))
3359 (const_string "V4SF")
3360 (const_string "SF"))
3361 (eq_attr "alternative" "11")
3362 (const_string "DI")]
3363 (const_string "SF")))])
3366 [(set (match_operand 0 "any_fp_register_operand")
3367 (match_operand 1 "memory_operand"))]
3369 && (GET_MODE (operands[0]) == TFmode
3370 || GET_MODE (operands[0]) == XFmode
3371 || GET_MODE (operands[0]) == DFmode
3372 || GET_MODE (operands[0]) == SFmode)
3373 && (operands[2] = find_constant_src (insn))"
3374 [(set (match_dup 0) (match_dup 2))]
3376 rtx c = operands[2];
3377 int r = REGNO (operands[0]);
3379 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3380 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3385 [(set (match_operand 0 "any_fp_register_operand")
3386 (float_extend (match_operand 1 "memory_operand")))]
3388 && (GET_MODE (operands[0]) == TFmode
3389 || GET_MODE (operands[0]) == XFmode
3390 || GET_MODE (operands[0]) == DFmode)
3391 && (operands[2] = find_constant_src (insn))"
3392 [(set (match_dup 0) (match_dup 2))]
3394 rtx c = operands[2];
3395 int r = REGNO (operands[0]);
3397 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3398 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3402 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3404 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3405 (match_operand:X87MODEF 1 "immediate_operand"))]
3407 && (standard_80387_constant_p (operands[1]) == 8
3408 || standard_80387_constant_p (operands[1]) == 9)"
3409 [(set (match_dup 0)(match_dup 1))
3411 (neg:X87MODEF (match_dup 0)))]
3415 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3416 if (real_isnegzero (&r))
3417 operands[1] = CONST0_RTX (<MODE>mode);
3419 operands[1] = CONST1_RTX (<MODE>mode);
3423 [(set (match_operand 0 "nonimmediate_operand")
3424 (match_operand 1 "general_operand"))]
3426 && (GET_MODE (operands[0]) == TFmode
3427 || GET_MODE (operands[0]) == XFmode
3428 || GET_MODE (operands[0]) == DFmode)
3429 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3431 "ix86_split_long_move (operands); DONE;")
3433 (define_insn "swapxf"
3434 [(set (match_operand:XF 0 "register_operand" "+f")
3435 (match_operand:XF 1 "register_operand" "+f"))
3440 if (STACK_TOP_P (operands[0]))
3445 [(set_attr "type" "fxch")
3446 (set_attr "mode" "XF")])
3448 (define_insn "*swap<mode>"
3449 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3450 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3453 "TARGET_80387 || reload_completed"
3455 if (STACK_TOP_P (operands[0]))
3460 [(set_attr "type" "fxch")
3461 (set_attr "mode" "<MODE>")])
3463 ;; Zero extension instructions
3465 (define_expand "zero_extendsidi2"
3466 [(set (match_operand:DI 0 "nonimmediate_operand")
3467 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3469 (define_insn "*zero_extendsidi2_rex64"
3470 [(set (match_operand:DI 0 "nonimmediate_operand"
3471 "=r ,o,?*Ym,?*y,?*Yi,?*x")
3473 (match_operand:SI 1 "x86_64_zext_general_operand"
3474 "rmWz,0,r ,m ,r ,m")))]
3477 mov{l}\t{%1, %k0|%k0, %1}
3479 movd\t{%1, %0|%0, %1}
3480 movd\t{%1, %0|%0, %1}
3481 %vmovd\t{%1, %0|%0, %1}
3482 %vmovd\t{%1, %0|%0, %1}"
3483 [(set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3484 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3485 (set_attr "prefix_0f" "0,*,*,*,*,*")
3486 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3488 (define_insn "*zero_extendsidi2"
3489 [(set (match_operand:DI 0 "nonimmediate_operand"
3490 "=ro,?r,?o,?*Ym,?*y,?*Yi,?*x")
3491 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3492 "0 ,rm,r ,r ,m ,r ,m")))]
3498 movd\t{%1, %0|%0, %1}
3499 movd\t{%1, %0|%0, %1}
3500 %vmovd\t{%1, %0|%0, %1}
3501 %vmovd\t{%1, %0|%0, %1}"
3502 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3503 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3504 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3505 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3508 [(set (match_operand:DI 0 "memory_operand")
3509 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3511 [(set (match_dup 4) (const_int 0))]
3512 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3515 [(set (match_operand:DI 0 "register_operand")
3516 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3517 "!TARGET_64BIT && reload_completed
3518 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3519 && true_regnum (operands[0]) == true_regnum (operands[1])"
3520 [(set (match_dup 4) (const_int 0))]
3521 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3524 [(set (match_operand:DI 0 "nonimmediate_operand")
3525 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3526 "!TARGET_64BIT && reload_completed
3527 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3528 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3529 [(set (match_dup 3) (match_dup 1))
3530 (set (match_dup 4) (const_int 0))]
3531 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3533 (define_insn "zero_extend<mode>di2"
3534 [(set (match_operand:DI 0 "register_operand" "=r")
3536 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3538 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3539 [(set_attr "type" "imovx")
3540 (set_attr "mode" "SI")])
3542 (define_expand "zero_extend<mode>si2"
3543 [(set (match_operand:SI 0 "register_operand")
3544 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3547 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3549 operands[1] = force_reg (<MODE>mode, operands[1]);
3550 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3555 (define_insn_and_split "zero_extend<mode>si2_and"
3556 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3558 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3559 (clobber (reg:CC FLAGS_REG))]
3560 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3562 "&& reload_completed"
3563 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3564 (clobber (reg:CC FLAGS_REG))])]
3566 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3568 ix86_expand_clear (operands[0]);
3570 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3571 emit_insn (gen_movstrict<mode>
3572 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3576 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3578 [(set_attr "type" "alu1")
3579 (set_attr "mode" "SI")])
3581 (define_insn "*zero_extend<mode>si2"
3582 [(set (match_operand:SI 0 "register_operand" "=r")
3584 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3585 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3586 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3587 [(set_attr "type" "imovx")
3588 (set_attr "mode" "SI")])
3590 (define_expand "zero_extendqihi2"
3591 [(set (match_operand:HI 0 "register_operand")
3592 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3595 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3597 operands[1] = force_reg (QImode, operands[1]);
3598 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3603 (define_insn_and_split "zero_extendqihi2_and"
3604 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3605 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3606 (clobber (reg:CC FLAGS_REG))]
3607 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3609 "&& reload_completed"
3610 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3611 (clobber (reg:CC FLAGS_REG))])]
3613 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3615 ix86_expand_clear (operands[0]);
3617 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3618 emit_insn (gen_movstrictqi
3619 (gen_lowpart (QImode, operands[0]), operands[1]));
3623 operands[0] = gen_lowpart (SImode, operands[0]);
3625 [(set_attr "type" "alu1")
3626 (set_attr "mode" "SI")])
3628 ; zero extend to SImode to avoid partial register stalls
3629 (define_insn "*zero_extendqihi2"
3630 [(set (match_operand:HI 0 "register_operand" "=r")
3631 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3632 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3633 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3634 [(set_attr "type" "imovx")
3635 (set_attr "mode" "SI")])
3637 ;; Sign extension instructions
3639 (define_expand "extendsidi2"
3640 [(set (match_operand:DI 0 "register_operand")
3641 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3646 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3651 (define_insn "*extendsidi2_rex64"
3652 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3653 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3657 movs{lq|x}\t{%1, %0|%0, %1}"
3658 [(set_attr "type" "imovx")
3659 (set_attr "mode" "DI")
3660 (set_attr "prefix_0f" "0")
3661 (set_attr "modrm" "0,1")])
3663 (define_insn "extendsidi2_1"
3664 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3665 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3666 (clobber (reg:CC FLAGS_REG))
3667 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3671 ;; Extend to memory case when source register does die.
3673 [(set (match_operand:DI 0 "memory_operand")
3674 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3675 (clobber (reg:CC FLAGS_REG))
3676 (clobber (match_operand:SI 2 "register_operand"))]
3678 && dead_or_set_p (insn, operands[1])
3679 && !reg_mentioned_p (operands[1], operands[0]))"
3680 [(set (match_dup 3) (match_dup 1))
3681 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3682 (clobber (reg:CC FLAGS_REG))])
3683 (set (match_dup 4) (match_dup 1))]
3684 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3686 ;; Extend to memory case when source register does not die.
3688 [(set (match_operand:DI 0 "memory_operand")
3689 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3690 (clobber (reg:CC FLAGS_REG))
3691 (clobber (match_operand:SI 2 "register_operand"))]
3695 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3697 emit_move_insn (operands[3], operands[1]);
3699 /* Generate a cltd if possible and doing so it profitable. */
3700 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3701 && true_regnum (operands[1]) == AX_REG
3702 && true_regnum (operands[2]) == DX_REG)
3704 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3708 emit_move_insn (operands[2], operands[1]);
3709 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3711 emit_move_insn (operands[4], operands[2]);
3715 ;; Extend to register case. Optimize case where source and destination
3716 ;; registers match and cases where we can use cltd.
3718 [(set (match_operand:DI 0 "register_operand")
3719 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3720 (clobber (reg:CC FLAGS_REG))
3721 (clobber (match_scratch:SI 2))]
3725 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3727 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3728 emit_move_insn (operands[3], operands[1]);
3730 /* Generate a cltd if possible and doing so it profitable. */
3731 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3732 && true_regnum (operands[3]) == AX_REG
3733 && true_regnum (operands[4]) == DX_REG)
3735 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3739 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3740 emit_move_insn (operands[4], operands[1]);
3742 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3746 (define_insn "extend<mode>di2"
3747 [(set (match_operand:DI 0 "register_operand" "=r")
3749 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3751 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3752 [(set_attr "type" "imovx")
3753 (set_attr "mode" "DI")])
3755 (define_insn "extendhisi2"
3756 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3757 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3760 switch (get_attr_prefix_0f (insn))
3763 return "{cwtl|cwde}";
3765 return "movs{wl|x}\t{%1, %0|%0, %1}";
3768 [(set_attr "type" "imovx")
3769 (set_attr "mode" "SI")
3770 (set (attr "prefix_0f")
3771 ;; movsx is short decodable while cwtl is vector decoded.
3772 (if_then_else (and (eq_attr "cpu" "!k6")
3773 (eq_attr "alternative" "0"))
3775 (const_string "1")))
3777 (if_then_else (eq_attr "prefix_0f" "0")
3779 (const_string "1")))])
3781 (define_insn "*extendhisi2_zext"
3782 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3785 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3788 switch (get_attr_prefix_0f (insn))
3791 return "{cwtl|cwde}";
3793 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3796 [(set_attr "type" "imovx")
3797 (set_attr "mode" "SI")
3798 (set (attr "prefix_0f")
3799 ;; movsx is short decodable while cwtl is vector decoded.
3800 (if_then_else (and (eq_attr "cpu" "!k6")
3801 (eq_attr "alternative" "0"))
3803 (const_string "1")))
3805 (if_then_else (eq_attr "prefix_0f" "0")
3807 (const_string "1")))])
3809 (define_insn "extendqisi2"
3810 [(set (match_operand:SI 0 "register_operand" "=r")
3811 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3813 "movs{bl|x}\t{%1, %0|%0, %1}"
3814 [(set_attr "type" "imovx")
3815 (set_attr "mode" "SI")])
3817 (define_insn "*extendqisi2_zext"
3818 [(set (match_operand:DI 0 "register_operand" "=r")
3820 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3822 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3823 [(set_attr "type" "imovx")
3824 (set_attr "mode" "SI")])
3826 (define_insn "extendqihi2"
3827 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3828 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3831 switch (get_attr_prefix_0f (insn))
3834 return "{cbtw|cbw}";
3836 return "movs{bw|x}\t{%1, %0|%0, %1}";
3839 [(set_attr "type" "imovx")
3840 (set_attr "mode" "HI")
3841 (set (attr "prefix_0f")
3842 ;; movsx is short decodable while cwtl is vector decoded.
3843 (if_then_else (and (eq_attr "cpu" "!k6")
3844 (eq_attr "alternative" "0"))
3846 (const_string "1")))
3848 (if_then_else (eq_attr "prefix_0f" "0")
3850 (const_string "1")))])
3852 ;; Conversions between float and double.
3854 ;; These are all no-ops in the model used for the 80387.
3855 ;; So just emit moves.
3857 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3859 [(set (match_operand:DF 0 "push_operand")
3860 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3862 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3863 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3866 [(set (match_operand:XF 0 "push_operand")
3867 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3869 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3870 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3871 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3873 (define_expand "extendsfdf2"
3874 [(set (match_operand:DF 0 "nonimmediate_operand")
3875 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3876 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3878 /* ??? Needed for compress_float_constant since all fp constants
3879 are TARGET_LEGITIMATE_CONSTANT_P. */
3880 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3882 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3883 && standard_80387_constant_p (operands[1]) > 0)
3885 operands[1] = simplify_const_unary_operation
3886 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3887 emit_move_insn_1 (operands[0], operands[1]);
3890 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3894 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3896 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3898 We do the conversion post reload to avoid producing of 128bit spills
3899 that might lead to ICE on 32bit target. The sequence unlikely combine
3902 [(set (match_operand:DF 0 "register_operand")
3904 (match_operand:SF 1 "nonimmediate_operand")))]
3905 "TARGET_USE_VECTOR_FP_CONVERTS
3906 && optimize_insn_for_speed_p ()
3907 && reload_completed && SSE_REG_P (operands[0])"
3912 (parallel [(const_int 0) (const_int 1)]))))]
3914 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3915 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3916 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3917 Try to avoid move when unpacking can be done in source. */
3918 if (REG_P (operands[1]))
3920 /* If it is unsafe to overwrite upper half of source, we need
3921 to move to destination and unpack there. */
3922 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3923 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3924 && true_regnum (operands[0]) != true_regnum (operands[1]))
3926 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3927 emit_move_insn (tmp, operands[1]);
3930 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3931 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3935 emit_insn (gen_vec_setv4sf_0 (operands[3],
3936 CONST0_RTX (V4SFmode), operands[1]));
3939 (define_insn "*extendsfdf2_mixed"
3940 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3942 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3943 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3945 switch (which_alternative)
3949 return output_387_reg_move (insn, operands);
3952 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3958 [(set_attr "type" "fmov,fmov,ssecvt")
3959 (set_attr "prefix" "orig,orig,maybe_vex")
3960 (set_attr "mode" "SF,XF,DF")])
3962 (define_insn "*extendsfdf2_sse"
3963 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3964 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3965 "TARGET_SSE2 && TARGET_SSE_MATH"
3966 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3967 [(set_attr "type" "ssecvt")
3968 (set_attr "prefix" "maybe_vex")
3969 (set_attr "mode" "DF")])
3971 (define_insn "*extendsfdf2_i387"
3972 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3973 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3975 "* return output_387_reg_move (insn, operands);"
3976 [(set_attr "type" "fmov")
3977 (set_attr "mode" "SF,XF")])
3979 (define_expand "extend<mode>xf2"
3980 [(set (match_operand:XF 0 "nonimmediate_operand")
3981 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3984 /* ??? Needed for compress_float_constant since all fp constants
3985 are TARGET_LEGITIMATE_CONSTANT_P. */
3986 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3988 if (standard_80387_constant_p (operands[1]) > 0)
3990 operands[1] = simplify_const_unary_operation
3991 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3992 emit_move_insn_1 (operands[0], operands[1]);
3995 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3999 (define_insn "*extend<mode>xf2_i387"
4000 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4002 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4004 "* return output_387_reg_move (insn, operands);"
4005 [(set_attr "type" "fmov")
4006 (set_attr "mode" "<MODE>,XF")])
4008 ;; %%% This seems bad bad news.
4009 ;; This cannot output into an f-reg because there is no way to be sure
4010 ;; of truncating in that case. Otherwise this is just like a simple move
4011 ;; insn. So we pretend we can output to a reg in order to get better
4012 ;; register preferencing, but we really use a stack slot.
4014 ;; Conversion from DFmode to SFmode.
4016 (define_expand "truncdfsf2"
4017 [(set (match_operand:SF 0 "nonimmediate_operand")
4019 (match_operand:DF 1 "nonimmediate_operand")))]
4020 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4022 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4024 else if (flag_unsafe_math_optimizations)
4028 enum ix86_stack_slot slot = (virtuals_instantiated
4031 rtx temp = assign_386_stack_local (SFmode, slot);
4032 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4037 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4039 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4041 We do the conversion post reload to avoid producing of 128bit spills
4042 that might lead to ICE on 32bit target. The sequence unlikely combine
4045 [(set (match_operand:SF 0 "register_operand")
4047 (match_operand:DF 1 "nonimmediate_operand")))]
4048 "TARGET_USE_VECTOR_FP_CONVERTS
4049 && optimize_insn_for_speed_p ()
4050 && reload_completed && SSE_REG_P (operands[0])"
4053 (float_truncate:V2SF
4057 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4058 operands[3] = CONST0_RTX (V2SFmode);
4059 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4060 /* Use movsd for loading from memory, unpcklpd for registers.
4061 Try to avoid move when unpacking can be done in source, or SSE3
4062 movddup is available. */
4063 if (REG_P (operands[1]))
4066 && true_regnum (operands[0]) != true_regnum (operands[1])
4067 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4068 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4070 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4071 emit_move_insn (tmp, operands[1]);
4074 else if (!TARGET_SSE3)
4075 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4076 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4079 emit_insn (gen_sse2_loadlpd (operands[4],
4080 CONST0_RTX (V2DFmode), operands[1]));
4083 (define_expand "truncdfsf2_with_temp"
4084 [(parallel [(set (match_operand:SF 0)
4085 (float_truncate:SF (match_operand:DF 1)))
4086 (clobber (match_operand:SF 2))])])
4088 (define_insn "*truncdfsf_fast_mixed"
4089 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4091 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4092 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4094 switch (which_alternative)
4097 return output_387_reg_move (insn, operands);
4099 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4104 [(set_attr "type" "fmov,ssecvt")
4105 (set_attr "prefix" "orig,maybe_vex")
4106 (set_attr "mode" "SF")])
4108 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4109 ;; because nothing we do here is unsafe.
4110 (define_insn "*truncdfsf_fast_sse"
4111 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4113 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4114 "TARGET_SSE2 && TARGET_SSE_MATH"
4115 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4116 [(set_attr "type" "ssecvt")
4117 (set_attr "prefix" "maybe_vex")
4118 (set_attr "mode" "SF")])
4120 (define_insn "*truncdfsf_fast_i387"
4121 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4123 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4124 "TARGET_80387 && flag_unsafe_math_optimizations"
4125 "* return output_387_reg_move (insn, operands);"
4126 [(set_attr "type" "fmov")
4127 (set_attr "mode" "SF")])
4129 (define_insn "*truncdfsf_mixed"
4130 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4132 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4133 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4134 "TARGET_MIX_SSE_I387"
4136 switch (which_alternative)
4139 return output_387_reg_move (insn, operands);
4141 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4147 [(set_attr "isa" "*,sse2,*,*,*")
4148 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4149 (set_attr "unit" "*,*,i387,i387,i387")
4150 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4151 (set_attr "mode" "SF")])
4153 (define_insn "*truncdfsf_i387"
4154 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4156 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4157 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4160 switch (which_alternative)
4163 return output_387_reg_move (insn, operands);
4169 [(set_attr "type" "fmov,multi,multi,multi")
4170 (set_attr "unit" "*,i387,i387,i387")
4171 (set_attr "mode" "SF")])
4173 (define_insn "*truncdfsf2_i387_1"
4174 [(set (match_operand:SF 0 "memory_operand" "=m")
4176 (match_operand:DF 1 "register_operand" "f")))]
4178 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4179 && !TARGET_MIX_SSE_I387"
4180 "* return output_387_reg_move (insn, operands);"
4181 [(set_attr "type" "fmov")
4182 (set_attr "mode" "SF")])
4185 [(set (match_operand:SF 0 "register_operand")
4187 (match_operand:DF 1 "fp_register_operand")))
4188 (clobber (match_operand 2))]
4190 [(set (match_dup 2) (match_dup 1))
4191 (set (match_dup 0) (match_dup 2))]
4192 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4194 ;; Conversion from XFmode to {SF,DF}mode
4196 (define_expand "truncxf<mode>2"
4197 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4198 (float_truncate:MODEF
4199 (match_operand:XF 1 "register_operand")))
4200 (clobber (match_dup 2))])]
4203 if (flag_unsafe_math_optimizations)
4205 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4206 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4207 if (reg != operands[0])
4208 emit_move_insn (operands[0], reg);
4213 enum ix86_stack_slot slot = (virtuals_instantiated
4216 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4220 (define_insn "*truncxfsf2_mixed"
4221 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4223 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4224 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4227 gcc_assert (!which_alternative);
4228 return output_387_reg_move (insn, operands);
4230 [(set_attr "type" "fmov,multi,multi,multi")
4231 (set_attr "unit" "*,i387,i387,i387")
4232 (set_attr "mode" "SF")])
4234 (define_insn "*truncxfdf2_mixed"
4235 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4237 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4238 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4241 gcc_assert (!which_alternative);
4242 return output_387_reg_move (insn, operands);
4244 [(set_attr "isa" "*,*,sse2,*")
4245 (set_attr "type" "fmov,multi,multi,multi")
4246 (set_attr "unit" "*,i387,i387,i387")
4247 (set_attr "mode" "DF")])
4249 (define_insn "truncxf<mode>2_i387_noop"
4250 [(set (match_operand:MODEF 0 "register_operand" "=f")
4251 (float_truncate:MODEF
4252 (match_operand:XF 1 "register_operand" "f")))]
4253 "TARGET_80387 && flag_unsafe_math_optimizations"
4254 "* return output_387_reg_move (insn, operands);"
4255 [(set_attr "type" "fmov")
4256 (set_attr "mode" "<MODE>")])
4258 (define_insn "*truncxf<mode>2_i387"
4259 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4260 (float_truncate:MODEF
4261 (match_operand:XF 1 "register_operand" "f")))]
4263 "* return output_387_reg_move (insn, operands);"
4264 [(set_attr "type" "fmov")
4265 (set_attr "mode" "<MODE>")])
4268 [(set (match_operand:MODEF 0 "register_operand")
4269 (float_truncate:MODEF
4270 (match_operand:XF 1 "register_operand")))
4271 (clobber (match_operand:MODEF 2 "memory_operand"))]
4272 "TARGET_80387 && reload_completed"
4273 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4274 (set (match_dup 0) (match_dup 2))])
4277 [(set (match_operand:MODEF 0 "memory_operand")
4278 (float_truncate:MODEF
4279 (match_operand:XF 1 "register_operand")))
4280 (clobber (match_operand:MODEF 2 "memory_operand"))]
4282 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4284 ;; Signed conversion to DImode.
4286 (define_expand "fix_truncxfdi2"
4287 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4288 (fix:DI (match_operand:XF 1 "register_operand")))
4289 (clobber (reg:CC FLAGS_REG))])]
4294 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4299 (define_expand "fix_trunc<mode>di2"
4300 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4301 (fix:DI (match_operand:MODEF 1 "register_operand")))
4302 (clobber (reg:CC FLAGS_REG))])]
4303 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4306 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4308 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4311 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4313 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4314 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4315 if (out != operands[0])
4316 emit_move_insn (operands[0], out);
4321 ;; Signed conversion to SImode.
4323 (define_expand "fix_truncxfsi2"
4324 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4325 (fix:SI (match_operand:XF 1 "register_operand")))
4326 (clobber (reg:CC FLAGS_REG))])]
4331 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4336 (define_expand "fix_trunc<mode>si2"
4337 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4338 (fix:SI (match_operand:MODEF 1 "register_operand")))
4339 (clobber (reg:CC FLAGS_REG))])]
4340 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4343 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4345 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4348 if (SSE_FLOAT_MODE_P (<MODE>mode))
4350 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4351 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4352 if (out != operands[0])
4353 emit_move_insn (operands[0], out);
4358 ;; Signed conversion to HImode.
4360 (define_expand "fix_trunc<mode>hi2"
4361 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4362 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4363 (clobber (reg:CC FLAGS_REG))])]
4365 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4369 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4374 ;; Unsigned conversion to SImode.
4376 (define_expand "fixuns_trunc<mode>si2"
4378 [(set (match_operand:SI 0 "register_operand")
4380 (match_operand:MODEF 1 "nonimmediate_operand")))
4382 (clobber (match_scratch:<ssevecmode> 3))
4383 (clobber (match_scratch:<ssevecmode> 4))])]
4384 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4386 enum machine_mode mode = <MODE>mode;
4387 enum machine_mode vecmode = <ssevecmode>mode;
4388 REAL_VALUE_TYPE TWO31r;
4391 if (optimize_insn_for_size_p ())
4394 real_ldexp (&TWO31r, &dconst1, 31);
4395 two31 = const_double_from_real_value (TWO31r, mode);
4396 two31 = ix86_build_const_vector (vecmode, true, two31);
4397 operands[2] = force_reg (vecmode, two31);
4400 (define_insn_and_split "*fixuns_trunc<mode>_1"
4401 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4403 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4404 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4405 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4406 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4407 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4408 && optimize_function_for_speed_p (cfun)"
4410 "&& reload_completed"
4413 ix86_split_convert_uns_si_sse (operands);
4417 ;; Unsigned conversion to HImode.
4418 ;; Without these patterns, we'll try the unsigned SI conversion which
4419 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4421 (define_expand "fixuns_trunc<mode>hi2"
4423 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4424 (set (match_operand:HI 0 "nonimmediate_operand")
4425 (subreg:HI (match_dup 2) 0))]
4426 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4427 "operands[2] = gen_reg_rtx (SImode);")
4429 ;; When SSE is available, it is always faster to use it!
4430 (define_insn "fix_trunc<mode>di_sse"
4431 [(set (match_operand:DI 0 "register_operand" "=r,r")
4432 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4433 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4434 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4435 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4436 [(set_attr "type" "sseicvt")
4437 (set_attr "prefix" "maybe_vex")
4438 (set_attr "prefix_rex" "1")
4439 (set_attr "mode" "<MODE>")
4440 (set_attr "athlon_decode" "double,vector")
4441 (set_attr "amdfam10_decode" "double,double")
4442 (set_attr "bdver1_decode" "double,double")])
4444 (define_insn "fix_trunc<mode>si_sse"
4445 [(set (match_operand:SI 0 "register_operand" "=r,r")
4446 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4447 "SSE_FLOAT_MODE_P (<MODE>mode)
4448 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4449 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4450 [(set_attr "type" "sseicvt")
4451 (set_attr "prefix" "maybe_vex")
4452 (set_attr "mode" "<MODE>")
4453 (set_attr "athlon_decode" "double,vector")
4454 (set_attr "amdfam10_decode" "double,double")
4455 (set_attr "bdver1_decode" "double,double")])
4457 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4459 [(set (match_operand:MODEF 0 "register_operand")
4460 (match_operand:MODEF 1 "memory_operand"))
4461 (set (match_operand:SWI48x 2 "register_operand")
4462 (fix:SWI48x (match_dup 0)))]
4463 "TARGET_SHORTEN_X87_SSE
4464 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4465 && peep2_reg_dead_p (2, operands[0])"
4466 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4468 ;; Avoid vector decoded forms of the instruction.
4470 [(match_scratch:DF 2 "x")
4471 (set (match_operand:SWI48x 0 "register_operand")
4472 (fix:SWI48x (match_operand:DF 1 "memory_operand")))]
4473 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4474 [(set (match_dup 2) (match_dup 1))
4475 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4478 [(match_scratch:SF 2 "x")
4479 (set (match_operand:SWI48x 0 "register_operand")
4480 (fix:SWI48x (match_operand:SF 1 "memory_operand")))]
4481 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4482 [(set (match_dup 2) (match_dup 1))
4483 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4485 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4486 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4487 (fix:SWI248x (match_operand 1 "register_operand")))]
4488 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4490 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4491 && (TARGET_64BIT || <MODE>mode != DImode))
4493 && can_create_pseudo_p ()"
4498 if (memory_operand (operands[0], VOIDmode))
4499 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4502 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4503 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4509 [(set_attr "type" "fisttp")
4510 (set_attr "mode" "<MODE>")])
4512 (define_insn "fix_trunc<mode>_i387_fisttp"
4513 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4514 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4515 (clobber (match_scratch:XF 2 "=&1f"))]
4516 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4518 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4519 && (TARGET_64BIT || <MODE>mode != DImode))
4520 && TARGET_SSE_MATH)"
4521 "* return output_fix_trunc (insn, operands, true);"
4522 [(set_attr "type" "fisttp")
4523 (set_attr "mode" "<MODE>")])
4525 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4526 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4527 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4528 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4529 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4530 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4532 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4533 && (TARGET_64BIT || <MODE>mode != DImode))
4534 && TARGET_SSE_MATH)"
4536 [(set_attr "type" "fisttp")
4537 (set_attr "mode" "<MODE>")])
4540 [(set (match_operand:SWI248x 0 "register_operand")
4541 (fix:SWI248x (match_operand 1 "register_operand")))
4542 (clobber (match_operand:SWI248x 2 "memory_operand"))
4543 (clobber (match_scratch 3))]
4545 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4546 (clobber (match_dup 3))])
4547 (set (match_dup 0) (match_dup 2))])
4550 [(set (match_operand:SWI248x 0 "memory_operand")
4551 (fix:SWI248x (match_operand 1 "register_operand")))
4552 (clobber (match_operand:SWI248x 2 "memory_operand"))
4553 (clobber (match_scratch 3))]
4555 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4556 (clobber (match_dup 3))])])
4558 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4559 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4560 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4561 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4562 ;; function in i386.c.
4563 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4564 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4565 (fix:SWI248x (match_operand 1 "register_operand")))
4566 (clobber (reg:CC FLAGS_REG))]
4567 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4569 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4570 && (TARGET_64BIT || <MODE>mode != DImode))
4571 && can_create_pseudo_p ()"
4576 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4578 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4579 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4580 if (memory_operand (operands[0], VOIDmode))
4581 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4582 operands[2], operands[3]));
4585 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4586 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4587 operands[2], operands[3],
4592 [(set_attr "type" "fistp")
4593 (set_attr "i387_cw" "trunc")
4594 (set_attr "mode" "<MODE>")])
4596 (define_insn "fix_truncdi_i387"
4597 [(set (match_operand:DI 0 "memory_operand" "=m")
4598 (fix:DI (match_operand 1 "register_operand" "f")))
4599 (use (match_operand:HI 2 "memory_operand" "m"))
4600 (use (match_operand:HI 3 "memory_operand" "m"))
4601 (clobber (match_scratch:XF 4 "=&1f"))]
4602 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4604 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4605 "* return output_fix_trunc (insn, operands, false);"
4606 [(set_attr "type" "fistp")
4607 (set_attr "i387_cw" "trunc")
4608 (set_attr "mode" "DI")])
4610 (define_insn "fix_truncdi_i387_with_temp"
4611 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4612 (fix:DI (match_operand 1 "register_operand" "f,f")))
4613 (use (match_operand:HI 2 "memory_operand" "m,m"))
4614 (use (match_operand:HI 3 "memory_operand" "m,m"))
4615 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4616 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4617 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4619 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4621 [(set_attr "type" "fistp")
4622 (set_attr "i387_cw" "trunc")
4623 (set_attr "mode" "DI")])
4626 [(set (match_operand:DI 0 "register_operand")
4627 (fix:DI (match_operand 1 "register_operand")))
4628 (use (match_operand:HI 2 "memory_operand"))
4629 (use (match_operand:HI 3 "memory_operand"))
4630 (clobber (match_operand:DI 4 "memory_operand"))
4631 (clobber (match_scratch 5))]
4633 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4636 (clobber (match_dup 5))])
4637 (set (match_dup 0) (match_dup 4))])
4640 [(set (match_operand:DI 0 "memory_operand")
4641 (fix:DI (match_operand 1 "register_operand")))
4642 (use (match_operand:HI 2 "memory_operand"))
4643 (use (match_operand:HI 3 "memory_operand"))
4644 (clobber (match_operand:DI 4 "memory_operand"))
4645 (clobber (match_scratch 5))]
4647 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4650 (clobber (match_dup 5))])])
4652 (define_insn "fix_trunc<mode>_i387"
4653 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4654 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4655 (use (match_operand:HI 2 "memory_operand" "m"))
4656 (use (match_operand:HI 3 "memory_operand" "m"))]
4657 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4659 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4660 "* return output_fix_trunc (insn, operands, false);"
4661 [(set_attr "type" "fistp")
4662 (set_attr "i387_cw" "trunc")
4663 (set_attr "mode" "<MODE>")])
4665 (define_insn "fix_trunc<mode>_i387_with_temp"
4666 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4667 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4668 (use (match_operand:HI 2 "memory_operand" "m,m"))
4669 (use (match_operand:HI 3 "memory_operand" "m,m"))
4670 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4671 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4673 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4675 [(set_attr "type" "fistp")
4676 (set_attr "i387_cw" "trunc")
4677 (set_attr "mode" "<MODE>")])
4680 [(set (match_operand:SWI24 0 "register_operand")
4681 (fix:SWI24 (match_operand 1 "register_operand")))
4682 (use (match_operand:HI 2 "memory_operand"))
4683 (use (match_operand:HI 3 "memory_operand"))
4684 (clobber (match_operand:SWI24 4 "memory_operand"))]
4686 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4688 (use (match_dup 3))])
4689 (set (match_dup 0) (match_dup 4))])
4692 [(set (match_operand:SWI24 0 "memory_operand")
4693 (fix:SWI24 (match_operand 1 "register_operand")))
4694 (use (match_operand:HI 2 "memory_operand"))
4695 (use (match_operand:HI 3 "memory_operand"))
4696 (clobber (match_operand:SWI24 4 "memory_operand"))]
4698 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4700 (use (match_dup 3))])])
4702 (define_insn "x86_fnstcw_1"
4703 [(set (match_operand:HI 0 "memory_operand" "=m")
4704 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4707 [(set (attr "length")
4708 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4709 (set_attr "mode" "HI")
4710 (set_attr "unit" "i387")
4711 (set_attr "bdver1_decode" "vector")])
4713 (define_insn "x86_fldcw_1"
4714 [(set (reg:HI FPCR_REG)
4715 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4718 [(set (attr "length")
4719 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4720 (set_attr "mode" "HI")
4721 (set_attr "unit" "i387")
4722 (set_attr "athlon_decode" "vector")
4723 (set_attr "amdfam10_decode" "vector")
4724 (set_attr "bdver1_decode" "vector")])
4726 ;; Conversion between fixed point and floating point.
4728 ;; Even though we only accept memory inputs, the backend _really_
4729 ;; wants to be able to do this between registers.
4731 (define_expand "floathi<mode>2"
4732 [(set (match_operand:X87MODEF 0 "register_operand")
4733 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4735 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4736 || TARGET_MIX_SSE_I387)")
4738 ;; Pre-reload splitter to add memory clobber to the pattern.
4739 (define_insn_and_split "*floathi<mode>2_1"
4740 [(set (match_operand:X87MODEF 0 "register_operand")
4741 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4743 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4744 || TARGET_MIX_SSE_I387)
4745 && can_create_pseudo_p ()"
4748 [(parallel [(set (match_dup 0)
4749 (float:X87MODEF (match_dup 1)))
4750 (clobber (match_dup 2))])]
4751 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4753 (define_insn "*floathi<mode>2_i387_with_temp"
4754 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4755 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4756 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4758 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4759 || TARGET_MIX_SSE_I387)"
4761 [(set_attr "type" "fmov,multi")
4762 (set_attr "mode" "<MODE>")
4763 (set_attr "unit" "*,i387")
4764 (set_attr "fp_int_src" "true")])
4766 (define_insn "*floathi<mode>2_i387"
4767 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4768 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4770 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4771 || TARGET_MIX_SSE_I387)"
4773 [(set_attr "type" "fmov")
4774 (set_attr "mode" "<MODE>")
4775 (set_attr "fp_int_src" "true")])
4778 [(set (match_operand:X87MODEF 0 "register_operand")
4779 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4780 (clobber (match_operand:HI 2 "memory_operand"))]
4782 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4783 || TARGET_MIX_SSE_I387)
4784 && reload_completed"
4785 [(set (match_dup 2) (match_dup 1))
4786 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4789 [(set (match_operand:X87MODEF 0 "register_operand")
4790 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4791 (clobber (match_operand:HI 2 "memory_operand"))]
4793 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4794 || TARGET_MIX_SSE_I387)
4795 && reload_completed"
4796 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4798 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4799 [(set (match_operand:X87MODEF 0 "register_operand")
4801 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4803 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4804 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4806 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4807 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4808 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4810 rtx reg = gen_reg_rtx (XFmode);
4811 rtx (*insn)(rtx, rtx);
4813 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4815 if (<X87MODEF:MODE>mode == SFmode)
4816 insn = gen_truncxfsf2;
4817 else if (<X87MODEF:MODE>mode == DFmode)
4818 insn = gen_truncxfdf2;
4822 emit_insn (insn (operands[0], reg));
4827 ;; Pre-reload splitter to add memory clobber to the pattern.
4828 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4829 [(set (match_operand:X87MODEF 0 "register_operand")
4830 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4832 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4833 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4834 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4835 || TARGET_MIX_SSE_I387))
4836 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4837 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4838 && ((<SWI48x:MODE>mode == SImode
4839 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4840 && optimize_function_for_speed_p (cfun)
4841 && flag_trapping_math)
4842 || !(TARGET_INTER_UNIT_CONVERSIONS
4843 || optimize_function_for_size_p (cfun)))))
4844 && can_create_pseudo_p ()"
4847 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4848 (clobber (match_dup 2))])]
4850 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4852 /* Avoid store forwarding (partial memory) stall penalty
4853 by passing DImode value through XMM registers. */
4854 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4855 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4856 && optimize_function_for_speed_p (cfun))
4858 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4865 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4866 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4868 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4869 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4870 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4871 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4873 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4874 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4875 (set_attr "unit" "*,i387,*,*,*")
4876 (set_attr "athlon_decode" "*,*,double,direct,double")
4877 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4878 (set_attr "bdver1_decode" "*,*,double,direct,double")
4879 (set_attr "fp_int_src" "true")])
4881 (define_insn "*floatsi<mode>2_vector_mixed"
4882 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4883 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4884 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4885 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4889 [(set_attr "type" "fmov,sseicvt")
4890 (set_attr "mode" "<MODE>,<ssevecmode>")
4891 (set_attr "unit" "i387,*")
4892 (set_attr "athlon_decode" "*,direct")
4893 (set_attr "amdfam10_decode" "*,double")
4894 (set_attr "bdver1_decode" "*,direct")
4895 (set_attr "fp_int_src" "true")])
4897 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4898 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4900 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4901 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4902 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4903 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4905 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4906 (set_attr "mode" "<MODEF:MODE>")
4907 (set_attr "unit" "*,i387,*,*")
4908 (set_attr "athlon_decode" "*,*,double,direct")
4909 (set_attr "amdfam10_decode" "*,*,vector,double")
4910 (set_attr "bdver1_decode" "*,*,double,direct")
4911 (set_attr "fp_int_src" "true")])
4914 [(set (match_operand:MODEF 0 "register_operand")
4915 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4916 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4917 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4918 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4919 && TARGET_INTER_UNIT_CONVERSIONS
4921 && (SSE_REG_P (operands[0])
4922 || (GET_CODE (operands[0]) == SUBREG
4923 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4924 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4927 [(set (match_operand:MODEF 0 "register_operand")
4928 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4929 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4930 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4931 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4932 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4934 && (SSE_REG_P (operands[0])
4935 || (GET_CODE (operands[0]) == SUBREG
4936 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4937 [(set (match_dup 2) (match_dup 1))
4938 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4940 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4941 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4943 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4944 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4945 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4946 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4949 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4950 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4951 [(set_attr "type" "fmov,sseicvt,sseicvt")
4952 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4953 (set_attr "mode" "<MODEF:MODE>")
4954 (set (attr "prefix_rex")
4956 (and (eq_attr "prefix" "maybe_vex")
4957 (match_test "<SWI48x:MODE>mode == DImode"))
4959 (const_string "*")))
4960 (set_attr "unit" "i387,*,*")
4961 (set_attr "athlon_decode" "*,double,direct")
4962 (set_attr "amdfam10_decode" "*,vector,double")
4963 (set_attr "bdver1_decode" "*,double,direct")
4964 (set_attr "fp_int_src" "true")])
4966 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4967 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4969 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4970 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4971 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4972 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4975 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4976 [(set_attr "type" "fmov,sseicvt")
4977 (set_attr "prefix" "orig,maybe_vex")
4978 (set_attr "mode" "<MODEF:MODE>")
4979 (set (attr "prefix_rex")
4981 (and (eq_attr "prefix" "maybe_vex")
4982 (match_test "<SWI48x:MODE>mode == DImode"))
4984 (const_string "*")))
4985 (set_attr "athlon_decode" "*,direct")
4986 (set_attr "amdfam10_decode" "*,double")
4987 (set_attr "bdver1_decode" "*,direct")
4988 (set_attr "fp_int_src" "true")])
4990 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4991 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4993 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4994 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4995 "TARGET_SSE2 && TARGET_SSE_MATH
4996 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4998 [(set_attr "type" "sseicvt")
4999 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5000 (set_attr "athlon_decode" "double,direct,double")
5001 (set_attr "amdfam10_decode" "vector,double,double")
5002 (set_attr "bdver1_decode" "double,direct,double")
5003 (set_attr "fp_int_src" "true")])
5005 (define_insn "*floatsi<mode>2_vector_sse"
5006 [(set (match_operand:MODEF 0 "register_operand" "=x")
5007 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5008 "TARGET_SSE2 && TARGET_SSE_MATH
5009 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5011 [(set_attr "type" "sseicvt")
5012 (set_attr "mode" "<MODE>")
5013 (set_attr "athlon_decode" "direct")
5014 (set_attr "amdfam10_decode" "double")
5015 (set_attr "bdver1_decode" "direct")
5016 (set_attr "fp_int_src" "true")])
5019 [(set (match_operand:MODEF 0 "register_operand")
5020 (float:MODEF (match_operand:SI 1 "register_operand")))
5021 (clobber (match_operand:SI 2 "memory_operand"))]
5022 "TARGET_SSE2 && TARGET_SSE_MATH
5023 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5025 && (SSE_REG_P (operands[0])
5026 || (GET_CODE (operands[0]) == SUBREG
5027 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5030 rtx op1 = operands[1];
5032 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5034 if (GET_CODE (op1) == SUBREG)
5035 op1 = SUBREG_REG (op1);
5037 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5039 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5040 emit_insn (gen_sse2_loadld (operands[4],
5041 CONST0_RTX (V4SImode), operands[1]));
5043 /* We can ignore possible trapping value in the
5044 high part of SSE register for non-trapping math. */
5045 else if (SSE_REG_P (op1) && !flag_trapping_math)
5046 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5049 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5050 emit_move_insn (operands[2], operands[1]);
5051 emit_insn (gen_sse2_loadld (operands[4],
5052 CONST0_RTX (V4SImode), operands[2]));
5054 if (<ssevecmode>mode == V4SFmode)
5055 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5057 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5062 [(set (match_operand:MODEF 0 "register_operand")
5063 (float:MODEF (match_operand:SI 1 "memory_operand")))
5064 (clobber (match_operand:SI 2 "memory_operand"))]
5065 "TARGET_SSE2 && TARGET_SSE_MATH
5066 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5068 && (SSE_REG_P (operands[0])
5069 || (GET_CODE (operands[0]) == SUBREG
5070 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5073 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5075 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5077 emit_insn (gen_sse2_loadld (operands[4],
5078 CONST0_RTX (V4SImode), operands[1]));
5079 if (<ssevecmode>mode == V4SFmode)
5080 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5082 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5087 [(set (match_operand:MODEF 0 "register_operand")
5088 (float:MODEF (match_operand:SI 1 "register_operand")))]
5089 "TARGET_SSE2 && TARGET_SSE_MATH
5090 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5092 && (SSE_REG_P (operands[0])
5093 || (GET_CODE (operands[0]) == SUBREG
5094 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5097 rtx op1 = operands[1];
5099 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5101 if (GET_CODE (op1) == SUBREG)
5102 op1 = SUBREG_REG (op1);
5104 if (GENERAL_REG_P (op1))
5106 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5107 if (TARGET_INTER_UNIT_MOVES)
5108 emit_insn (gen_sse2_loadld (operands[4],
5109 CONST0_RTX (V4SImode), operands[1]));
5112 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5114 emit_insn (gen_sse2_loadld (operands[4],
5115 CONST0_RTX (V4SImode), operands[5]));
5116 ix86_free_from_memory (GET_MODE (operands[1]));
5119 /* We can ignore possible trapping value in the
5120 high part of SSE register for non-trapping math. */
5121 else if (SSE_REG_P (op1) && !flag_trapping_math)
5122 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5125 if (<ssevecmode>mode == V4SFmode)
5126 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5128 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5133 [(set (match_operand:MODEF 0 "register_operand")
5134 (float:MODEF (match_operand:SI 1 "memory_operand")))]
5135 "TARGET_SSE2 && TARGET_SSE_MATH
5136 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5138 && (SSE_REG_P (operands[0])
5139 || (GET_CODE (operands[0]) == SUBREG
5140 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5143 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5145 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5147 emit_insn (gen_sse2_loadld (operands[4],
5148 CONST0_RTX (V4SImode), operands[1]));
5149 if (<ssevecmode>mode == V4SFmode)
5150 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5152 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5156 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5157 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5159 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5160 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5161 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5162 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5164 [(set_attr "type" "sseicvt")
5165 (set_attr "mode" "<MODEF:MODE>")
5166 (set_attr "athlon_decode" "double,direct")
5167 (set_attr "amdfam10_decode" "vector,double")
5168 (set_attr "bdver1_decode" "double,direct")
5169 (set_attr "fp_int_src" "true")])
5171 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5172 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5174 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5175 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5176 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5177 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5178 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5179 [(set_attr "type" "sseicvt")
5180 (set_attr "prefix" "maybe_vex")
5181 (set_attr "mode" "<MODEF:MODE>")
5182 (set (attr "prefix_rex")
5184 (and (eq_attr "prefix" "maybe_vex")
5185 (match_test "<SWI48x:MODE>mode == DImode"))
5187 (const_string "*")))
5188 (set_attr "athlon_decode" "double,direct")
5189 (set_attr "amdfam10_decode" "vector,double")
5190 (set_attr "bdver1_decode" "double,direct")
5191 (set_attr "fp_int_src" "true")])
5194 [(set (match_operand:MODEF 0 "register_operand")
5195 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))
5196 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5197 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5198 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5199 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5201 && (SSE_REG_P (operands[0])
5202 || (GET_CODE (operands[0]) == SUBREG
5203 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5204 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5206 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5207 [(set (match_operand:MODEF 0 "register_operand" "=x")
5209 (match_operand:SWI48x 1 "memory_operand" "m")))]
5210 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5211 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5212 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5213 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5214 [(set_attr "type" "sseicvt")
5215 (set_attr "prefix" "maybe_vex")
5216 (set_attr "mode" "<MODEF:MODE>")
5217 (set (attr "prefix_rex")
5219 (and (eq_attr "prefix" "maybe_vex")
5220 (match_test "<SWI48x:MODE>mode == DImode"))
5222 (const_string "*")))
5223 (set_attr "athlon_decode" "direct")
5224 (set_attr "amdfam10_decode" "double")
5225 (set_attr "bdver1_decode" "direct")
5226 (set_attr "fp_int_src" "true")])
5229 [(set (match_operand:MODEF 0 "register_operand")
5230 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
5231 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5232 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5233 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5234 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5236 && (SSE_REG_P (operands[0])
5237 || (GET_CODE (operands[0]) == SUBREG
5238 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5239 [(set (match_dup 2) (match_dup 1))
5240 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5243 [(set (match_operand:MODEF 0 "register_operand")
5244 (float:MODEF (match_operand:SWI48x 1 "memory_operand")))
5245 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5246 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5247 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5249 && (SSE_REG_P (operands[0])
5250 || (GET_CODE (operands[0]) == SUBREG
5251 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5252 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5254 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5255 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5257 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5258 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5260 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5264 [(set_attr "type" "fmov,multi")
5265 (set_attr "mode" "<X87MODEF:MODE>")
5266 (set_attr "unit" "*,i387")
5267 (set_attr "fp_int_src" "true")])
5269 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5270 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5272 (match_operand:SWI48x 1 "memory_operand" "m")))]
5274 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5276 [(set_attr "type" "fmov")
5277 (set_attr "mode" "<X87MODEF:MODE>")
5278 (set_attr "fp_int_src" "true")])
5281 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5282 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5283 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5285 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5286 && reload_completed"
5287 [(set (match_dup 2) (match_dup 1))
5288 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5291 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5292 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5293 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5295 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5296 && reload_completed"
5297 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5299 ;; Avoid store forwarding (partial memory) stall penalty
5300 ;; by passing DImode value through XMM registers. */
5302 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5303 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5305 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5306 (clobber (match_scratch:V4SI 3 "=X,x"))
5307 (clobber (match_scratch:V4SI 4 "=X,x"))
5308 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5309 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5310 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5311 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5313 [(set_attr "type" "multi")
5314 (set_attr "mode" "<X87MODEF:MODE>")
5315 (set_attr "unit" "i387")
5316 (set_attr "fp_int_src" "true")])
5319 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5320 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5321 (clobber (match_scratch:V4SI 3))
5322 (clobber (match_scratch:V4SI 4))
5323 (clobber (match_operand:DI 2 "memory_operand"))]
5324 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5325 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5326 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5327 && reload_completed"
5328 [(set (match_dup 2) (match_dup 3))
5329 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5331 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5332 Assemble the 64-bit DImode value in an xmm register. */
5333 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5334 gen_rtx_SUBREG (SImode, operands[1], 0)));
5335 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5336 gen_rtx_SUBREG (SImode, operands[1], 4)));
5337 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5340 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5344 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5345 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5346 (clobber (match_scratch:V4SI 3))
5347 (clobber (match_scratch:V4SI 4))
5348 (clobber (match_operand:DI 2 "memory_operand"))]
5349 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5350 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5351 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5352 && reload_completed"
5353 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5355 ;; Avoid store forwarding (partial memory) stall penalty by extending
5356 ;; SImode value to DImode through XMM register instead of pushing two
5357 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5358 ;; targets benefit from this optimization. Also note that fild
5359 ;; loads from memory only.
5361 (define_insn "*floatunssi<mode>2_1"
5362 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5363 (unsigned_float:X87MODEF
5364 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5365 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5366 (clobber (match_scratch:SI 3 "=X,x"))]
5368 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5371 [(set_attr "type" "multi")
5372 (set_attr "mode" "<MODE>")])
5375 [(set (match_operand:X87MODEF 0 "register_operand")
5376 (unsigned_float:X87MODEF
5377 (match_operand:SI 1 "register_operand")))
5378 (clobber (match_operand:DI 2 "memory_operand"))
5379 (clobber (match_scratch:SI 3))]
5381 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5383 && reload_completed"
5384 [(set (match_dup 2) (match_dup 1))
5386 (float:X87MODEF (match_dup 2)))]
5387 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5390 [(set (match_operand:X87MODEF 0 "register_operand")
5391 (unsigned_float:X87MODEF
5392 (match_operand:SI 1 "memory_operand")))
5393 (clobber (match_operand:DI 2 "memory_operand"))
5394 (clobber (match_scratch:SI 3))]
5396 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5398 && reload_completed"
5399 [(set (match_dup 2) (match_dup 3))
5401 (float:X87MODEF (match_dup 2)))]
5403 emit_move_insn (operands[3], operands[1]);
5404 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5407 (define_expand "floatunssi<mode>2"
5409 [(set (match_operand:X87MODEF 0 "register_operand")
5410 (unsigned_float:X87MODEF
5411 (match_operand:SI 1 "nonimmediate_operand")))
5412 (clobber (match_dup 2))
5413 (clobber (match_scratch:SI 3))])]
5415 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5417 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5419 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5421 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5426 enum ix86_stack_slot slot = (virtuals_instantiated
5429 operands[2] = assign_386_stack_local (DImode, slot);
5433 (define_expand "floatunsdisf2"
5434 [(use (match_operand:SF 0 "register_operand"))
5435 (use (match_operand:DI 1 "nonimmediate_operand"))]
5436 "TARGET_64BIT && TARGET_SSE_MATH"
5437 "x86_emit_floatuns (operands); DONE;")
5439 (define_expand "floatunsdidf2"
5440 [(use (match_operand:DF 0 "register_operand"))
5441 (use (match_operand:DI 1 "nonimmediate_operand"))]
5442 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5443 && TARGET_SSE2 && TARGET_SSE_MATH"
5446 x86_emit_floatuns (operands);
5448 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5454 (define_expand "add<mode>3"
5455 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5456 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5457 (match_operand:SDWIM 2 "<general_operand>")))]
5459 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5461 (define_insn_and_split "*add<dwi>3_doubleword"
5462 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5464 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5465 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5466 (clobber (reg:CC FLAGS_REG))]
5467 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5470 [(parallel [(set (reg:CC FLAGS_REG)
5471 (unspec:CC [(match_dup 1) (match_dup 2)]
5474 (plus:DWIH (match_dup 1) (match_dup 2)))])
5475 (parallel [(set (match_dup 3)
5479 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5481 (clobber (reg:CC FLAGS_REG))])]
5482 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5484 (define_insn "*add<mode>3_cc"
5485 [(set (reg:CC FLAGS_REG)
5487 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5488 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5490 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5491 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5492 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5493 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5494 [(set_attr "type" "alu")
5495 (set_attr "mode" "<MODE>")])
5497 (define_insn "addqi3_cc"
5498 [(set (reg:CC FLAGS_REG)
5500 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5501 (match_operand:QI 2 "general_operand" "qn,qm")]
5503 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5504 (plus:QI (match_dup 1) (match_dup 2)))]
5505 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5506 "add{b}\t{%2, %0|%0, %2}"
5507 [(set_attr "type" "alu")
5508 (set_attr "mode" "QI")])
5510 (define_insn_and_split "*lea_1"
5511 [(set (match_operand:SI 0 "register_operand" "=r")
5512 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5514 "lea{l}\t{%E1, %0|%0, %E1}"
5515 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5518 ix86_split_lea_for_addr (operands, SImode);
5521 [(set_attr "type" "lea")
5522 (set_attr "mode" "SI")])
5524 (define_insn_and_split "*lea<mode>_2"
5525 [(set (match_operand:SWI48 0 "register_operand" "=r")
5526 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5528 "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"
5529 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5532 ix86_split_lea_for_addr (operands, <MODE>mode);
5535 [(set_attr "type" "lea")
5536 (set_attr "mode" "<MODE>")])
5538 (define_insn "*lea_3_zext"
5539 [(set (match_operand:DI 0 "register_operand" "=r")
5541 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5543 "lea{l}\t{%E1, %k0|%k0, %E1}"
5544 [(set_attr "type" "lea")
5545 (set_attr "mode" "SI")])
5547 (define_insn "*lea_4_zext"
5548 [(set (match_operand:DI 0 "register_operand" "=r")
5550 (match_operand:SI 1 "lea_address_operand" "j")))]
5552 "lea{l}\t{%E1, %k0|%k0, %E1}"
5553 [(set_attr "type" "lea")
5554 (set_attr "mode" "SI")])
5556 (define_insn "*lea_5_zext"
5557 [(set (match_operand:DI 0 "register_operand" "=r")
5559 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5560 (match_operand:DI 2 "const_32bit_mask" "n")))]
5562 "lea{l}\t{%E1, %k0|%k0, %E1}"
5563 [(set_attr "type" "lea")
5564 (set_attr "mode" "SI")])
5566 (define_insn "*lea_6_zext"
5567 [(set (match_operand:DI 0 "register_operand" "=r")
5569 (match_operand:DI 1 "lea_address_operand" "p")
5570 (match_operand:DI 2 "const_32bit_mask" "n")))]
5572 "lea{l}\t{%E1, %k0|%k0, %E1}"
5573 [(set_attr "type" "lea")
5574 (set_attr "mode" "SI")])
5576 (define_insn "*add<mode>_1"
5577 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5579 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5580 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5581 (clobber (reg:CC FLAGS_REG))]
5582 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5584 switch (get_attr_type (insn))
5590 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5591 if (operands[2] == const1_rtx)
5592 return "inc{<imodesuffix>}\t%0";
5595 gcc_assert (operands[2] == constm1_rtx);
5596 return "dec{<imodesuffix>}\t%0";
5600 /* For most processors, ADD is faster than LEA. This alternative
5601 was added to use ADD as much as possible. */
5602 if (which_alternative == 2)
5605 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5608 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5609 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5610 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5612 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5616 (cond [(eq_attr "alternative" "3")
5617 (const_string "lea")
5618 (match_operand:SWI48 2 "incdec_operand")
5619 (const_string "incdec")
5621 (const_string "alu")))
5622 (set (attr "length_immediate")
5624 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5626 (const_string "*")))
5627 (set_attr "mode" "<MODE>")])
5629 ;; It may seem that nonimmediate operand is proper one for operand 1.
5630 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5631 ;; we take care in ix86_binary_operator_ok to not allow two memory
5632 ;; operands so proper swapping will be done in reload. This allow
5633 ;; patterns constructed from addsi_1 to match.
5635 (define_insn "addsi_1_zext"
5636 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5638 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5639 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5640 (clobber (reg:CC FLAGS_REG))]
5641 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5643 switch (get_attr_type (insn))
5649 if (operands[2] == const1_rtx)
5650 return "inc{l}\t%k0";
5653 gcc_assert (operands[2] == constm1_rtx);
5654 return "dec{l}\t%k0";
5658 /* For most processors, ADD is faster than LEA. This alternative
5659 was added to use ADD as much as possible. */
5660 if (which_alternative == 1)
5663 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5666 if (x86_maybe_negate_const_int (&operands[2], SImode))
5667 return "sub{l}\t{%2, %k0|%k0, %2}";
5669 return "add{l}\t{%2, %k0|%k0, %2}";
5673 (cond [(eq_attr "alternative" "2")
5674 (const_string "lea")
5675 (match_operand:SI 2 "incdec_operand")
5676 (const_string "incdec")
5678 (const_string "alu")))
5679 (set (attr "length_immediate")
5681 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5683 (const_string "*")))
5684 (set_attr "mode" "SI")])
5686 (define_insn "*addhi_1"
5687 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5688 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5689 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5690 (clobber (reg:CC FLAGS_REG))]
5691 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5693 switch (get_attr_type (insn))
5699 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5700 if (operands[2] == const1_rtx)
5701 return "inc{w}\t%0";
5704 gcc_assert (operands[2] == constm1_rtx);
5705 return "dec{w}\t%0";
5709 /* For most processors, ADD is faster than LEA. This alternative
5710 was added to use ADD as much as possible. */
5711 if (which_alternative == 2)
5714 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5717 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5718 if (x86_maybe_negate_const_int (&operands[2], HImode))
5719 return "sub{w}\t{%2, %0|%0, %2}";
5721 return "add{w}\t{%2, %0|%0, %2}";
5725 (cond [(eq_attr "alternative" "3")
5726 (const_string "lea")
5727 (match_operand:HI 2 "incdec_operand")
5728 (const_string "incdec")
5730 (const_string "alu")))
5731 (set (attr "length_immediate")
5733 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5735 (const_string "*")))
5736 (set_attr "mode" "HI,HI,HI,SI")])
5738 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5739 (define_insn "*addqi_1"
5740 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5741 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5742 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5743 (clobber (reg:CC FLAGS_REG))]
5744 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5746 bool widen = (which_alternative == 3 || which_alternative == 4);
5748 switch (get_attr_type (insn))
5754 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5755 if (operands[2] == const1_rtx)
5756 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5759 gcc_assert (operands[2] == constm1_rtx);
5760 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5764 /* For most processors, ADD is faster than LEA. These alternatives
5765 were added to use ADD as much as possible. */
5766 if (which_alternative == 2 || which_alternative == 4)
5769 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5772 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5773 if (x86_maybe_negate_const_int (&operands[2], QImode))
5776 return "sub{l}\t{%2, %k0|%k0, %2}";
5778 return "sub{b}\t{%2, %0|%0, %2}";
5781 return "add{l}\t{%k2, %k0|%k0, %k2}";
5783 return "add{b}\t{%2, %0|%0, %2}";
5787 (cond [(eq_attr "alternative" "5")
5788 (const_string "lea")
5789 (match_operand:QI 2 "incdec_operand")
5790 (const_string "incdec")
5792 (const_string "alu")))
5793 (set (attr "length_immediate")
5795 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5797 (const_string "*")))
5798 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5800 (define_insn "*addqi_1_slp"
5801 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5802 (plus:QI (match_dup 0)
5803 (match_operand:QI 1 "general_operand" "qn,qm")))
5804 (clobber (reg:CC FLAGS_REG))]
5805 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5806 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5808 switch (get_attr_type (insn))
5811 if (operands[1] == const1_rtx)
5812 return "inc{b}\t%0";
5815 gcc_assert (operands[1] == constm1_rtx);
5816 return "dec{b}\t%0";
5820 if (x86_maybe_negate_const_int (&operands[1], QImode))
5821 return "sub{b}\t{%1, %0|%0, %1}";
5823 return "add{b}\t{%1, %0|%0, %1}";
5827 (if_then_else (match_operand:QI 1 "incdec_operand")
5828 (const_string "incdec")
5829 (const_string "alu1")))
5830 (set (attr "memory")
5831 (if_then_else (match_operand 1 "memory_operand")
5832 (const_string "load")
5833 (const_string "none")))
5834 (set_attr "mode" "QI")])
5836 ;; Split non destructive adds if we cannot use lea.
5838 [(set (match_operand:SWI48 0 "register_operand")
5839 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5840 (match_operand:SWI48 2 "nonmemory_operand")))
5841 (clobber (reg:CC FLAGS_REG))]
5842 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5843 [(set (match_dup 0) (match_dup 1))
5844 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5845 (clobber (reg:CC FLAGS_REG))])])
5847 ;; Convert add to the lea pattern to avoid flags dependency.
5849 [(set (match_operand:SWI 0 "register_operand")
5850 (plus:SWI (match_operand:SWI 1 "register_operand")
5851 (match_operand:SWI 2 "<nonmemory_operand>")))
5852 (clobber (reg:CC FLAGS_REG))]
5853 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5856 enum machine_mode mode = <MODE>mode;
5859 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5862 operands[0] = gen_lowpart (mode, operands[0]);
5863 operands[1] = gen_lowpart (mode, operands[1]);
5864 operands[2] = gen_lowpart (mode, operands[2]);
5867 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5869 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5873 ;; Convert add to the lea pattern to avoid flags dependency.
5875 [(set (match_operand:DI 0 "register_operand")
5877 (plus:SI (match_operand:SI 1 "register_operand")
5878 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5879 (clobber (reg:CC FLAGS_REG))]
5880 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5882 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5884 (define_insn "*add<mode>_2"
5885 [(set (reg FLAGS_REG)
5888 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5889 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5891 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5892 (plus:SWI (match_dup 1) (match_dup 2)))]
5893 "ix86_match_ccmode (insn, CCGOCmode)
5894 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5896 switch (get_attr_type (insn))
5899 if (operands[2] == const1_rtx)
5900 return "inc{<imodesuffix>}\t%0";
5903 gcc_assert (operands[2] == constm1_rtx);
5904 return "dec{<imodesuffix>}\t%0";
5908 if (which_alternative == 2)
5911 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5914 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5915 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5916 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5918 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5922 (if_then_else (match_operand:SWI 2 "incdec_operand")
5923 (const_string "incdec")
5924 (const_string "alu")))
5925 (set (attr "length_immediate")
5927 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5929 (const_string "*")))
5930 (set_attr "mode" "<MODE>")])
5932 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5933 (define_insn "*addsi_2_zext"
5934 [(set (reg FLAGS_REG)
5936 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5937 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5939 (set (match_operand:DI 0 "register_operand" "=r,r")
5940 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5941 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5942 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5944 switch (get_attr_type (insn))
5947 if (operands[2] == const1_rtx)
5948 return "inc{l}\t%k0";
5951 gcc_assert (operands[2] == constm1_rtx);
5952 return "dec{l}\t%k0";
5956 if (which_alternative == 1)
5959 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5962 if (x86_maybe_negate_const_int (&operands[2], SImode))
5963 return "sub{l}\t{%2, %k0|%k0, %2}";
5965 return "add{l}\t{%2, %k0|%k0, %2}";
5969 (if_then_else (match_operand:SI 2 "incdec_operand")
5970 (const_string "incdec")
5971 (const_string "alu")))
5972 (set (attr "length_immediate")
5974 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5976 (const_string "*")))
5977 (set_attr "mode" "SI")])
5979 (define_insn "*add<mode>_3"
5980 [(set (reg FLAGS_REG)
5982 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5983 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5984 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5985 "ix86_match_ccmode (insn, CCZmode)
5986 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5988 switch (get_attr_type (insn))
5991 if (operands[2] == const1_rtx)
5992 return "inc{<imodesuffix>}\t%0";
5995 gcc_assert (operands[2] == constm1_rtx);
5996 return "dec{<imodesuffix>}\t%0";
6000 if (which_alternative == 1)
6003 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6006 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6007 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6008 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6010 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6014 (if_then_else (match_operand:SWI 2 "incdec_operand")
6015 (const_string "incdec")
6016 (const_string "alu")))
6017 (set (attr "length_immediate")
6019 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6021 (const_string "*")))
6022 (set_attr "mode" "<MODE>")])
6024 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6025 (define_insn "*addsi_3_zext"
6026 [(set (reg FLAGS_REG)
6028 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6029 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6030 (set (match_operand:DI 0 "register_operand" "=r,r")
6031 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6032 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6033 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6035 switch (get_attr_type (insn))
6038 if (operands[2] == const1_rtx)
6039 return "inc{l}\t%k0";
6042 gcc_assert (operands[2] == constm1_rtx);
6043 return "dec{l}\t%k0";
6047 if (which_alternative == 1)
6050 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6053 if (x86_maybe_negate_const_int (&operands[2], SImode))
6054 return "sub{l}\t{%2, %k0|%k0, %2}";
6056 return "add{l}\t{%2, %k0|%k0, %2}";
6060 (if_then_else (match_operand:SI 2 "incdec_operand")
6061 (const_string "incdec")
6062 (const_string "alu")))
6063 (set (attr "length_immediate")
6065 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6067 (const_string "*")))
6068 (set_attr "mode" "SI")])
6070 ; For comparisons against 1, -1 and 128, we may generate better code
6071 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6072 ; is matched then. We can't accept general immediate, because for
6073 ; case of overflows, the result is messed up.
6074 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6075 ; only for comparisons not depending on it.
6077 (define_insn "*adddi_4"
6078 [(set (reg FLAGS_REG)
6080 (match_operand:DI 1 "nonimmediate_operand" "0")
6081 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6082 (clobber (match_scratch:DI 0 "=rm"))]
6084 && ix86_match_ccmode (insn, CCGCmode)"
6086 switch (get_attr_type (insn))
6089 if (operands[2] == constm1_rtx)
6090 return "inc{q}\t%0";
6093 gcc_assert (operands[2] == const1_rtx);
6094 return "dec{q}\t%0";
6098 if (x86_maybe_negate_const_int (&operands[2], DImode))
6099 return "add{q}\t{%2, %0|%0, %2}";
6101 return "sub{q}\t{%2, %0|%0, %2}";
6105 (if_then_else (match_operand:DI 2 "incdec_operand")
6106 (const_string "incdec")
6107 (const_string "alu")))
6108 (set (attr "length_immediate")
6110 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6112 (const_string "*")))
6113 (set_attr "mode" "DI")])
6115 ; For comparisons against 1, -1 and 128, we may generate better code
6116 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6117 ; is matched then. We can't accept general immediate, because for
6118 ; case of overflows, the result is messed up.
6119 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6120 ; only for comparisons not depending on it.
6122 (define_insn "*add<mode>_4"
6123 [(set (reg FLAGS_REG)
6125 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6126 (match_operand:SWI124 2 "const_int_operand" "n")))
6127 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6128 "ix86_match_ccmode (insn, CCGCmode)"
6130 switch (get_attr_type (insn))
6133 if (operands[2] == constm1_rtx)
6134 return "inc{<imodesuffix>}\t%0";
6137 gcc_assert (operands[2] == const1_rtx);
6138 return "dec{<imodesuffix>}\t%0";
6142 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6143 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6145 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6149 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6150 (const_string "incdec")
6151 (const_string "alu")))
6152 (set (attr "length_immediate")
6154 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6156 (const_string "*")))
6157 (set_attr "mode" "<MODE>")])
6159 (define_insn "*add<mode>_5"
6160 [(set (reg FLAGS_REG)
6163 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6164 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6166 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6167 "ix86_match_ccmode (insn, CCGOCmode)
6168 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6170 switch (get_attr_type (insn))
6173 if (operands[2] == const1_rtx)
6174 return "inc{<imodesuffix>}\t%0";
6177 gcc_assert (operands[2] == constm1_rtx);
6178 return "dec{<imodesuffix>}\t%0";
6182 if (which_alternative == 1)
6185 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6188 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6189 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6190 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6192 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6196 (if_then_else (match_operand:SWI 2 "incdec_operand")
6197 (const_string "incdec")
6198 (const_string "alu")))
6199 (set (attr "length_immediate")
6201 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6203 (const_string "*")))
6204 (set_attr "mode" "<MODE>")])
6206 (define_insn "*addqi_ext_1_rex64"
6207 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6212 (match_operand 1 "ext_register_operand" "0")
6215 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6216 (clobber (reg:CC FLAGS_REG))]
6219 switch (get_attr_type (insn))
6222 if (operands[2] == const1_rtx)
6223 return "inc{b}\t%h0";
6226 gcc_assert (operands[2] == constm1_rtx);
6227 return "dec{b}\t%h0";
6231 return "add{b}\t{%2, %h0|%h0, %2}";
6235 (if_then_else (match_operand:QI 2 "incdec_operand")
6236 (const_string "incdec")
6237 (const_string "alu")))
6238 (set_attr "modrm" "1")
6239 (set_attr "mode" "QI")])
6241 (define_insn "addqi_ext_1"
6242 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6247 (match_operand 1 "ext_register_operand" "0")
6250 (match_operand:QI 2 "general_operand" "Qmn")))
6251 (clobber (reg:CC FLAGS_REG))]
6254 switch (get_attr_type (insn))
6257 if (operands[2] == const1_rtx)
6258 return "inc{b}\t%h0";
6261 gcc_assert (operands[2] == constm1_rtx);
6262 return "dec{b}\t%h0";
6266 return "add{b}\t{%2, %h0|%h0, %2}";
6270 (if_then_else (match_operand:QI 2 "incdec_operand")
6271 (const_string "incdec")
6272 (const_string "alu")))
6273 (set_attr "modrm" "1")
6274 (set_attr "mode" "QI")])
6276 (define_insn "*addqi_ext_2"
6277 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6282 (match_operand 1 "ext_register_operand" "%0")
6286 (match_operand 2 "ext_register_operand" "Q")
6289 (clobber (reg:CC FLAGS_REG))]
6291 "add{b}\t{%h2, %h0|%h0, %h2}"
6292 [(set_attr "type" "alu")
6293 (set_attr "mode" "QI")])
6295 ;; The lea patterns for modes less than 32 bits need to be matched by
6296 ;; several insns converted to real lea by splitters.
6298 (define_insn_and_split "*lea_general_1"
6299 [(set (match_operand 0 "register_operand" "=r")
6300 (plus (plus (match_operand 1 "index_register_operand" "l")
6301 (match_operand 2 "register_operand" "r"))
6302 (match_operand 3 "immediate_operand" "i")))]
6303 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6304 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6305 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6306 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6307 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6308 || GET_MODE (operands[3]) == VOIDmode)"
6310 "&& reload_completed"
6313 enum machine_mode mode = SImode;
6316 operands[0] = gen_lowpart (mode, operands[0]);
6317 operands[1] = gen_lowpart (mode, operands[1]);
6318 operands[2] = gen_lowpart (mode, operands[2]);
6319 operands[3] = gen_lowpart (mode, operands[3]);
6321 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6324 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6327 [(set_attr "type" "lea")
6328 (set_attr "mode" "SI")])
6330 (define_insn_and_split "*lea_general_2"
6331 [(set (match_operand 0 "register_operand" "=r")
6332 (plus (mult (match_operand 1 "index_register_operand" "l")
6333 (match_operand 2 "const248_operand" "n"))
6334 (match_operand 3 "nonmemory_operand" "ri")))]
6335 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6336 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6337 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6338 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6339 || GET_MODE (operands[3]) == VOIDmode)"
6341 "&& reload_completed"
6344 enum machine_mode mode = SImode;
6347 operands[0] = gen_lowpart (mode, operands[0]);
6348 operands[1] = gen_lowpart (mode, operands[1]);
6349 operands[3] = gen_lowpart (mode, operands[3]);
6351 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6354 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6357 [(set_attr "type" "lea")
6358 (set_attr "mode" "SI")])
6360 (define_insn_and_split "*lea_general_3"
6361 [(set (match_operand 0 "register_operand" "=r")
6362 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6363 (match_operand 2 "const248_operand" "n"))
6364 (match_operand 3 "register_operand" "r"))
6365 (match_operand 4 "immediate_operand" "i")))]
6366 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6367 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6368 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6369 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6371 "&& reload_completed"
6374 enum machine_mode mode = SImode;
6377 operands[0] = gen_lowpart (mode, operands[0]);
6378 operands[1] = gen_lowpart (mode, operands[1]);
6379 operands[3] = gen_lowpart (mode, operands[3]);
6380 operands[4] = gen_lowpart (mode, operands[4]);
6382 pat = gen_rtx_PLUS (mode,
6384 gen_rtx_MULT (mode, operands[1],
6389 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6392 [(set_attr "type" "lea")
6393 (set_attr "mode" "SI")])
6395 (define_insn_and_split "*lea_general_4"
6396 [(set (match_operand 0 "register_operand" "=r")
6398 (match_operand 1 "index_register_operand" "l")
6399 (match_operand 2 "const_int_operand" "n"))
6400 (match_operand 3 "const_int_operand" "n")))]
6401 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6402 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6403 || GET_MODE (operands[0]) == SImode
6404 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6405 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6406 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6407 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6408 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6410 "&& reload_completed"
6413 enum machine_mode mode = GET_MODE (operands[0]);
6416 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6419 operands[0] = gen_lowpart (mode, operands[0]);
6420 operands[1] = gen_lowpart (mode, operands[1]);
6423 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6425 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6426 INTVAL (operands[3]));
6428 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6431 [(set_attr "type" "lea")
6433 (if_then_else (match_operand:DI 0)
6435 (const_string "SI")))])
6437 ;; Subtract instructions
6439 (define_expand "sub<mode>3"
6440 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6441 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6442 (match_operand:SDWIM 2 "<general_operand>")))]
6444 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6446 (define_insn_and_split "*sub<dwi>3_doubleword"
6447 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6449 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6450 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6451 (clobber (reg:CC FLAGS_REG))]
6452 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6455 [(parallel [(set (reg:CC FLAGS_REG)
6456 (compare:CC (match_dup 1) (match_dup 2)))
6458 (minus:DWIH (match_dup 1) (match_dup 2)))])
6459 (parallel [(set (match_dup 3)
6463 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6465 (clobber (reg:CC FLAGS_REG))])]
6466 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6468 (define_insn "*sub<mode>_1"
6469 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6471 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6472 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6473 (clobber (reg:CC FLAGS_REG))]
6474 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6475 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6476 [(set_attr "type" "alu")
6477 (set_attr "mode" "<MODE>")])
6479 (define_insn "*subsi_1_zext"
6480 [(set (match_operand:DI 0 "register_operand" "=r")
6482 (minus:SI (match_operand:SI 1 "register_operand" "0")
6483 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6484 (clobber (reg:CC FLAGS_REG))]
6485 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6486 "sub{l}\t{%2, %k0|%k0, %2}"
6487 [(set_attr "type" "alu")
6488 (set_attr "mode" "SI")])
6490 (define_insn "*subqi_1_slp"
6491 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6492 (minus:QI (match_dup 0)
6493 (match_operand:QI 1 "general_operand" "qn,qm")))
6494 (clobber (reg:CC FLAGS_REG))]
6495 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6496 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6497 "sub{b}\t{%1, %0|%0, %1}"
6498 [(set_attr "type" "alu1")
6499 (set_attr "mode" "QI")])
6501 (define_insn "*sub<mode>_2"
6502 [(set (reg FLAGS_REG)
6505 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6506 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6508 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6509 (minus:SWI (match_dup 1) (match_dup 2)))]
6510 "ix86_match_ccmode (insn, CCGOCmode)
6511 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6512 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6513 [(set_attr "type" "alu")
6514 (set_attr "mode" "<MODE>")])
6516 (define_insn "*subsi_2_zext"
6517 [(set (reg FLAGS_REG)
6519 (minus:SI (match_operand:SI 1 "register_operand" "0")
6520 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6522 (set (match_operand:DI 0 "register_operand" "=r")
6524 (minus:SI (match_dup 1)
6526 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6527 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6528 "sub{l}\t{%2, %k0|%k0, %2}"
6529 [(set_attr "type" "alu")
6530 (set_attr "mode" "SI")])
6532 (define_insn "*sub<mode>_3"
6533 [(set (reg FLAGS_REG)
6534 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6535 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6536 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6537 (minus:SWI (match_dup 1) (match_dup 2)))]
6538 "ix86_match_ccmode (insn, CCmode)
6539 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6540 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6541 [(set_attr "type" "alu")
6542 (set_attr "mode" "<MODE>")])
6544 (define_insn "*subsi_3_zext"
6545 [(set (reg FLAGS_REG)
6546 (compare (match_operand:SI 1 "register_operand" "0")
6547 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6548 (set (match_operand:DI 0 "register_operand" "=r")
6550 (minus:SI (match_dup 1)
6552 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6553 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6554 "sub{l}\t{%2, %1|%1, %2}"
6555 [(set_attr "type" "alu")
6556 (set_attr "mode" "SI")])
6558 ;; Add with carry and subtract with borrow
6560 (define_expand "<plusminus_insn><mode>3_carry"
6562 [(set (match_operand:SWI 0 "nonimmediate_operand")
6564 (match_operand:SWI 1 "nonimmediate_operand")
6565 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6566 [(match_operand 3 "flags_reg_operand")
6568 (match_operand:SWI 2 "<general_operand>"))))
6569 (clobber (reg:CC FLAGS_REG))])]
6570 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6572 (define_insn "*<plusminus_insn><mode>3_carry"
6573 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6575 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6577 (match_operator 3 "ix86_carry_flag_operator"
6578 [(reg FLAGS_REG) (const_int 0)])
6579 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6580 (clobber (reg:CC FLAGS_REG))]
6581 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6582 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6583 [(set_attr "type" "alu")
6584 (set_attr "use_carry" "1")
6585 (set_attr "pent_pair" "pu")
6586 (set_attr "mode" "<MODE>")])
6588 (define_insn "*addsi3_carry_zext"
6589 [(set (match_operand:DI 0 "register_operand" "=r")
6591 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6592 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6593 [(reg FLAGS_REG) (const_int 0)])
6594 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6595 (clobber (reg:CC FLAGS_REG))]
6596 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6597 "adc{l}\t{%2, %k0|%k0, %2}"
6598 [(set_attr "type" "alu")
6599 (set_attr "use_carry" "1")
6600 (set_attr "pent_pair" "pu")
6601 (set_attr "mode" "SI")])
6603 (define_insn "*subsi3_carry_zext"
6604 [(set (match_operand:DI 0 "register_operand" "=r")
6606 (minus:SI (match_operand:SI 1 "register_operand" "0")
6607 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6608 [(reg FLAGS_REG) (const_int 0)])
6609 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6610 (clobber (reg:CC FLAGS_REG))]
6611 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6612 "sbb{l}\t{%2, %k0|%k0, %2}"
6613 [(set_attr "type" "alu")
6614 (set_attr "pent_pair" "pu")
6615 (set_attr "mode" "SI")])
6617 ;; Overflow setting add and subtract instructions
6619 (define_insn "*add<mode>3_cconly_overflow"
6620 [(set (reg:CCC FLAGS_REG)
6623 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6624 (match_operand:SWI 2 "<general_operand>" "<g>"))
6626 (clobber (match_scratch:SWI 0 "=<r>"))]
6627 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6628 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6629 [(set_attr "type" "alu")
6630 (set_attr "mode" "<MODE>")])
6632 (define_insn "*sub<mode>3_cconly_overflow"
6633 [(set (reg:CCC FLAGS_REG)
6636 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6637 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6640 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6641 [(set_attr "type" "icmp")
6642 (set_attr "mode" "<MODE>")])
6644 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6645 [(set (reg:CCC FLAGS_REG)
6648 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6649 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6651 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6652 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6653 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6654 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6655 [(set_attr "type" "alu")
6656 (set_attr "mode" "<MODE>")])
6658 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6659 [(set (reg:CCC FLAGS_REG)
6662 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6663 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6665 (set (match_operand:DI 0 "register_operand" "=r")
6666 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6667 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6668 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6669 [(set_attr "type" "alu")
6670 (set_attr "mode" "SI")])
6672 ;; The patterns that match these are at the end of this file.
6674 (define_expand "<plusminus_insn>xf3"
6675 [(set (match_operand:XF 0 "register_operand")
6677 (match_operand:XF 1 "register_operand")
6678 (match_operand:XF 2 "register_operand")))]
6681 (define_expand "<plusminus_insn><mode>3"
6682 [(set (match_operand:MODEF 0 "register_operand")
6684 (match_operand:MODEF 1 "register_operand")
6685 (match_operand:MODEF 2 "nonimmediate_operand")))]
6686 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6687 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6689 ;; Multiply instructions
6691 (define_expand "mul<mode>3"
6692 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6694 (match_operand:SWIM248 1 "register_operand")
6695 (match_operand:SWIM248 2 "<general_operand>")))
6696 (clobber (reg:CC FLAGS_REG))])])
6698 (define_expand "mulqi3"
6699 [(parallel [(set (match_operand:QI 0 "register_operand")
6701 (match_operand:QI 1 "register_operand")
6702 (match_operand:QI 2 "nonimmediate_operand")))
6703 (clobber (reg:CC FLAGS_REG))])]
6704 "TARGET_QIMODE_MATH")
6707 ;; IMUL reg32/64, reg32/64, imm8 Direct
6708 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6709 ;; IMUL reg32/64, reg32/64, imm32 Direct
6710 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6711 ;; IMUL reg32/64, reg32/64 Direct
6712 ;; IMUL reg32/64, mem32/64 Direct
6714 ;; On BDVER1, all above IMULs use DirectPath
6716 (define_insn "*mul<mode>3_1"
6717 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6719 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6720 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6721 (clobber (reg:CC FLAGS_REG))]
6722 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6724 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6725 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6726 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6727 [(set_attr "type" "imul")
6728 (set_attr "prefix_0f" "0,0,1")
6729 (set (attr "athlon_decode")
6730 (cond [(eq_attr "cpu" "athlon")
6731 (const_string "vector")
6732 (eq_attr "alternative" "1")
6733 (const_string "vector")
6734 (and (eq_attr "alternative" "2")
6735 (match_operand 1 "memory_operand"))
6736 (const_string "vector")]
6737 (const_string "direct")))
6738 (set (attr "amdfam10_decode")
6739 (cond [(and (eq_attr "alternative" "0,1")
6740 (match_operand 1 "memory_operand"))
6741 (const_string "vector")]
6742 (const_string "direct")))
6743 (set_attr "bdver1_decode" "direct")
6744 (set_attr "mode" "<MODE>")])
6746 (define_insn "*mulsi3_1_zext"
6747 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6749 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6750 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6751 (clobber (reg:CC FLAGS_REG))]
6753 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6755 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6756 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6757 imul{l}\t{%2, %k0|%k0, %2}"
6758 [(set_attr "type" "imul")
6759 (set_attr "prefix_0f" "0,0,1")
6760 (set (attr "athlon_decode")
6761 (cond [(eq_attr "cpu" "athlon")
6762 (const_string "vector")
6763 (eq_attr "alternative" "1")
6764 (const_string "vector")
6765 (and (eq_attr "alternative" "2")
6766 (match_operand 1 "memory_operand"))
6767 (const_string "vector")]
6768 (const_string "direct")))
6769 (set (attr "amdfam10_decode")
6770 (cond [(and (eq_attr "alternative" "0,1")
6771 (match_operand 1 "memory_operand"))
6772 (const_string "vector")]
6773 (const_string "direct")))
6774 (set_attr "bdver1_decode" "direct")
6775 (set_attr "mode" "SI")])
6778 ;; IMUL reg16, reg16, imm8 VectorPath
6779 ;; IMUL reg16, mem16, imm8 VectorPath
6780 ;; IMUL reg16, reg16, imm16 VectorPath
6781 ;; IMUL reg16, mem16, imm16 VectorPath
6782 ;; IMUL reg16, reg16 Direct
6783 ;; IMUL reg16, mem16 Direct
6785 ;; On BDVER1, all HI MULs use DoublePath
6787 (define_insn "*mulhi3_1"
6788 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6789 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6790 (match_operand:HI 2 "general_operand" "K,n,mr")))
6791 (clobber (reg:CC FLAGS_REG))]
6793 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6795 imul{w}\t{%2, %1, %0|%0, %1, %2}
6796 imul{w}\t{%2, %1, %0|%0, %1, %2}
6797 imul{w}\t{%2, %0|%0, %2}"
6798 [(set_attr "type" "imul")
6799 (set_attr "prefix_0f" "0,0,1")
6800 (set (attr "athlon_decode")
6801 (cond [(eq_attr "cpu" "athlon")
6802 (const_string "vector")
6803 (eq_attr "alternative" "1,2")
6804 (const_string "vector")]
6805 (const_string "direct")))
6806 (set (attr "amdfam10_decode")
6807 (cond [(eq_attr "alternative" "0,1")
6808 (const_string "vector")]
6809 (const_string "direct")))
6810 (set_attr "bdver1_decode" "double")
6811 (set_attr "mode" "HI")])
6813 ;;On AMDFAM10 and BDVER1
6817 (define_insn "*mulqi3_1"
6818 [(set (match_operand:QI 0 "register_operand" "=a")
6819 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6820 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6821 (clobber (reg:CC FLAGS_REG))]
6823 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6825 [(set_attr "type" "imul")
6826 (set_attr "length_immediate" "0")
6827 (set (attr "athlon_decode")
6828 (if_then_else (eq_attr "cpu" "athlon")
6829 (const_string "vector")
6830 (const_string "direct")))
6831 (set_attr "amdfam10_decode" "direct")
6832 (set_attr "bdver1_decode" "direct")
6833 (set_attr "mode" "QI")])
6835 (define_expand "<u>mul<mode><dwi>3"
6836 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6839 (match_operand:DWIH 1 "nonimmediate_operand"))
6841 (match_operand:DWIH 2 "register_operand"))))
6842 (clobber (reg:CC FLAGS_REG))])])
6844 (define_expand "<u>mulqihi3"
6845 [(parallel [(set (match_operand:HI 0 "register_operand")
6848 (match_operand:QI 1 "nonimmediate_operand"))
6850 (match_operand:QI 2 "register_operand"))))
6851 (clobber (reg:CC FLAGS_REG))])]
6852 "TARGET_QIMODE_MATH")
6854 (define_insn "*bmi2_umulditi3_1"
6855 [(set (match_operand:DI 0 "register_operand" "=r")
6857 (match_operand:DI 2 "nonimmediate_operand" "%d")
6858 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6859 (set (match_operand:DI 1 "register_operand" "=r")
6862 (mult:TI (zero_extend:TI (match_dup 2))
6863 (zero_extend:TI (match_dup 3)))
6865 "TARGET_64BIT && TARGET_BMI2
6866 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6867 "mulx\t{%3, %0, %1|%1, %0, %3}"
6868 [(set_attr "type" "imulx")
6869 (set_attr "prefix" "vex")
6870 (set_attr "mode" "DI")])
6872 (define_insn "*bmi2_umulsidi3_1"
6873 [(set (match_operand:SI 0 "register_operand" "=r")
6875 (match_operand:SI 2 "nonimmediate_operand" "%d")
6876 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6877 (set (match_operand:SI 1 "register_operand" "=r")
6880 (mult:DI (zero_extend:DI (match_dup 2))
6881 (zero_extend:DI (match_dup 3)))
6883 "!TARGET_64BIT && TARGET_BMI2
6884 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6885 "mulx\t{%3, %0, %1|%1, %0, %3}"
6886 [(set_attr "type" "imulx")
6887 (set_attr "prefix" "vex")
6888 (set_attr "mode" "SI")])
6890 (define_insn "*umul<mode><dwi>3_1"
6891 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6894 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6896 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6897 (clobber (reg:CC FLAGS_REG))]
6898 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6901 mul{<imodesuffix>}\t%2"
6902 [(set_attr "isa" "bmi2,*")
6903 (set_attr "type" "imulx,imul")
6904 (set_attr "length_immediate" "*,0")
6905 (set (attr "athlon_decode")
6906 (cond [(eq_attr "alternative" "1")
6907 (if_then_else (eq_attr "cpu" "athlon")
6908 (const_string "vector")
6909 (const_string "double"))]
6910 (const_string "*")))
6911 (set_attr "amdfam10_decode" "*,double")
6912 (set_attr "bdver1_decode" "*,direct")
6913 (set_attr "prefix" "vex,orig")
6914 (set_attr "mode" "<MODE>")])
6916 ;; Convert mul to the mulx pattern to avoid flags dependency.
6918 [(set (match_operand:<DWI> 0 "register_operand")
6921 (match_operand:DWIH 1 "register_operand"))
6923 (match_operand:DWIH 2 "nonimmediate_operand"))))
6924 (clobber (reg:CC FLAGS_REG))]
6925 "TARGET_BMI2 && reload_completed
6926 && true_regnum (operands[1]) == DX_REG"
6927 [(parallel [(set (match_dup 3)
6928 (mult:DWIH (match_dup 1) (match_dup 2)))
6932 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6933 (zero_extend:<DWI> (match_dup 2)))
6936 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6938 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6941 (define_insn "*mul<mode><dwi>3_1"
6942 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6945 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6947 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6948 (clobber (reg:CC FLAGS_REG))]
6949 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6950 "imul{<imodesuffix>}\t%2"
6951 [(set_attr "type" "imul")
6952 (set_attr "length_immediate" "0")
6953 (set (attr "athlon_decode")
6954 (if_then_else (eq_attr "cpu" "athlon")
6955 (const_string "vector")
6956 (const_string "double")))
6957 (set_attr "amdfam10_decode" "double")
6958 (set_attr "bdver1_decode" "direct")
6959 (set_attr "mode" "<MODE>")])
6961 (define_insn "*<u>mulqihi3_1"
6962 [(set (match_operand:HI 0 "register_operand" "=a")
6965 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6967 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6968 (clobber (reg:CC FLAGS_REG))]
6970 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6971 "<sgnprefix>mul{b}\t%2"
6972 [(set_attr "type" "imul")
6973 (set_attr "length_immediate" "0")
6974 (set (attr "athlon_decode")
6975 (if_then_else (eq_attr "cpu" "athlon")
6976 (const_string "vector")
6977 (const_string "direct")))
6978 (set_attr "amdfam10_decode" "direct")
6979 (set_attr "bdver1_decode" "direct")
6980 (set_attr "mode" "QI")])
6982 (define_expand "<s>mul<mode>3_highpart"
6983 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6988 (match_operand:SWI48 1 "nonimmediate_operand"))
6990 (match_operand:SWI48 2 "register_operand")))
6992 (clobber (match_scratch:SWI48 3))
6993 (clobber (reg:CC FLAGS_REG))])]
6995 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6997 (define_insn "*<s>muldi3_highpart_1"
6998 [(set (match_operand:DI 0 "register_operand" "=d")
7003 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7005 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7007 (clobber (match_scratch:DI 3 "=1"))
7008 (clobber (reg:CC FLAGS_REG))]
7010 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7011 "<sgnprefix>mul{q}\t%2"
7012 [(set_attr "type" "imul")
7013 (set_attr "length_immediate" "0")
7014 (set (attr "athlon_decode")
7015 (if_then_else (eq_attr "cpu" "athlon")
7016 (const_string "vector")
7017 (const_string "double")))
7018 (set_attr "amdfam10_decode" "double")
7019 (set_attr "bdver1_decode" "direct")
7020 (set_attr "mode" "DI")])
7022 (define_insn "*<s>mulsi3_highpart_1"
7023 [(set (match_operand:SI 0 "register_operand" "=d")
7028 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7030 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7032 (clobber (match_scratch:SI 3 "=1"))
7033 (clobber (reg:CC FLAGS_REG))]
7034 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7035 "<sgnprefix>mul{l}\t%2"
7036 [(set_attr "type" "imul")
7037 (set_attr "length_immediate" "0")
7038 (set (attr "athlon_decode")
7039 (if_then_else (eq_attr "cpu" "athlon")
7040 (const_string "vector")
7041 (const_string "double")))
7042 (set_attr "amdfam10_decode" "double")
7043 (set_attr "bdver1_decode" "direct")
7044 (set_attr "mode" "SI")])
7046 (define_insn "*<s>mulsi3_highpart_zext"
7047 [(set (match_operand:DI 0 "register_operand" "=d")
7048 (zero_extend:DI (truncate:SI
7050 (mult:DI (any_extend:DI
7051 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7053 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7055 (clobber (match_scratch:SI 3 "=1"))
7056 (clobber (reg:CC FLAGS_REG))]
7058 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7059 "<sgnprefix>mul{l}\t%2"
7060 [(set_attr "type" "imul")
7061 (set_attr "length_immediate" "0")
7062 (set (attr "athlon_decode")
7063 (if_then_else (eq_attr "cpu" "athlon")
7064 (const_string "vector")
7065 (const_string "double")))
7066 (set_attr "amdfam10_decode" "double")
7067 (set_attr "bdver1_decode" "direct")
7068 (set_attr "mode" "SI")])
7070 ;; The patterns that match these are at the end of this file.
7072 (define_expand "mulxf3"
7073 [(set (match_operand:XF 0 "register_operand")
7074 (mult:XF (match_operand:XF 1 "register_operand")
7075 (match_operand:XF 2 "register_operand")))]
7078 (define_expand "mul<mode>3"
7079 [(set (match_operand:MODEF 0 "register_operand")
7080 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7081 (match_operand:MODEF 2 "nonimmediate_operand")))]
7082 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7083 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7085 ;; Divide instructions
7087 ;; The patterns that match these are at the end of this file.
7089 (define_expand "divxf3"
7090 [(set (match_operand:XF 0 "register_operand")
7091 (div:XF (match_operand:XF 1 "register_operand")
7092 (match_operand:XF 2 "register_operand")))]
7095 (define_expand "divdf3"
7096 [(set (match_operand:DF 0 "register_operand")
7097 (div:DF (match_operand:DF 1 "register_operand")
7098 (match_operand:DF 2 "nonimmediate_operand")))]
7099 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7100 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7102 (define_expand "divsf3"
7103 [(set (match_operand:SF 0 "register_operand")
7104 (div:SF (match_operand:SF 1 "register_operand")
7105 (match_operand:SF 2 "nonimmediate_operand")))]
7106 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7111 && optimize_insn_for_speed_p ()
7112 && flag_finite_math_only && !flag_trapping_math
7113 && flag_unsafe_math_optimizations)
7115 ix86_emit_swdivsf (operands[0], operands[1],
7116 operands[2], SFmode);
7121 ;; Divmod instructions.
7123 (define_expand "divmod<mode>4"
7124 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7126 (match_operand:SWIM248 1 "register_operand")
7127 (match_operand:SWIM248 2 "nonimmediate_operand")))
7128 (set (match_operand:SWIM248 3 "register_operand")
7129 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7130 (clobber (reg:CC FLAGS_REG))])])
7132 ;; Split with 8bit unsigned divide:
7133 ;; if (dividend an divisor are in [0-255])
7134 ;; use 8bit unsigned integer divide
7136 ;; use original integer divide
7138 [(set (match_operand:SWI48 0 "register_operand")
7139 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7140 (match_operand:SWI48 3 "nonimmediate_operand")))
7141 (set (match_operand:SWI48 1 "register_operand")
7142 (mod:SWI48 (match_dup 2) (match_dup 3)))
7143 (clobber (reg:CC FLAGS_REG))]
7144 "TARGET_USE_8BIT_IDIV
7145 && TARGET_QIMODE_MATH
7146 && can_create_pseudo_p ()
7147 && !optimize_insn_for_size_p ()"
7149 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7151 (define_insn_and_split "divmod<mode>4_1"
7152 [(set (match_operand:SWI48 0 "register_operand" "=a")
7153 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7154 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7155 (set (match_operand:SWI48 1 "register_operand" "=&d")
7156 (mod:SWI48 (match_dup 2) (match_dup 3)))
7157 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7158 (clobber (reg:CC FLAGS_REG))]
7162 [(parallel [(set (match_dup 1)
7163 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7164 (clobber (reg:CC FLAGS_REG))])
7165 (parallel [(set (match_dup 0)
7166 (div:SWI48 (match_dup 2) (match_dup 3)))
7168 (mod:SWI48 (match_dup 2) (match_dup 3)))
7170 (clobber (reg:CC FLAGS_REG))])]
7172 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7174 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7175 operands[4] = operands[2];
7178 /* Avoid use of cltd in favor of a mov+shift. */
7179 emit_move_insn (operands[1], operands[2]);
7180 operands[4] = operands[1];
7183 [(set_attr "type" "multi")
7184 (set_attr "mode" "<MODE>")])
7186 (define_insn_and_split "*divmod<mode>4"
7187 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7188 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7189 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7190 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7191 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7192 (clobber (reg:CC FLAGS_REG))]
7196 [(parallel [(set (match_dup 1)
7197 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7198 (clobber (reg:CC FLAGS_REG))])
7199 (parallel [(set (match_dup 0)
7200 (div:SWIM248 (match_dup 2) (match_dup 3)))
7202 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7204 (clobber (reg:CC FLAGS_REG))])]
7206 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7208 if (<MODE>mode != HImode
7209 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7210 operands[4] = operands[2];
7213 /* Avoid use of cltd in favor of a mov+shift. */
7214 emit_move_insn (operands[1], operands[2]);
7215 operands[4] = operands[1];
7218 [(set_attr "type" "multi")
7219 (set_attr "mode" "<MODE>")])
7221 (define_insn "*divmod<mode>4_noext"
7222 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7223 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7224 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7225 (set (match_operand:SWIM248 1 "register_operand" "=d")
7226 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7227 (use (match_operand:SWIM248 4 "register_operand" "1"))
7228 (clobber (reg:CC FLAGS_REG))]
7230 "idiv{<imodesuffix>}\t%3"
7231 [(set_attr "type" "idiv")
7232 (set_attr "mode" "<MODE>")])
7234 (define_expand "divmodqi4"
7235 [(parallel [(set (match_operand:QI 0 "register_operand")
7237 (match_operand:QI 1 "register_operand")
7238 (match_operand:QI 2 "nonimmediate_operand")))
7239 (set (match_operand:QI 3 "register_operand")
7240 (mod:QI (match_dup 1) (match_dup 2)))
7241 (clobber (reg:CC FLAGS_REG))])]
7242 "TARGET_QIMODE_MATH"
7247 tmp0 = gen_reg_rtx (HImode);
7248 tmp1 = gen_reg_rtx (HImode);
7250 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7252 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7253 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7255 /* Extract remainder from AH. */
7256 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7257 insn = emit_move_insn (operands[3], tmp1);
7259 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7260 set_unique_reg_note (insn, REG_EQUAL, mod);
7262 /* Extract quotient from AL. */
7263 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7265 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7266 set_unique_reg_note (insn, REG_EQUAL, div);
7271 ;; Divide AX by r/m8, with result stored in
7274 ;; Change div/mod to HImode and extend the second argument to HImode
7275 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7276 ;; combine may fail.
7277 (define_insn "divmodhiqi3"
7278 [(set (match_operand:HI 0 "register_operand" "=a")
7283 (mod:HI (match_operand:HI 1 "register_operand" "0")
7285 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7289 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7290 (clobber (reg:CC FLAGS_REG))]
7291 "TARGET_QIMODE_MATH"
7293 [(set_attr "type" "idiv")
7294 (set_attr "mode" "QI")])
7296 (define_expand "udivmod<mode>4"
7297 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7299 (match_operand:SWIM248 1 "register_operand")
7300 (match_operand:SWIM248 2 "nonimmediate_operand")))
7301 (set (match_operand:SWIM248 3 "register_operand")
7302 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7303 (clobber (reg:CC FLAGS_REG))])])
7305 ;; Split with 8bit unsigned divide:
7306 ;; if (dividend an divisor are in [0-255])
7307 ;; use 8bit unsigned integer divide
7309 ;; use original integer divide
7311 [(set (match_operand:SWI48 0 "register_operand")
7312 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7313 (match_operand:SWI48 3 "nonimmediate_operand")))
7314 (set (match_operand:SWI48 1 "register_operand")
7315 (umod:SWI48 (match_dup 2) (match_dup 3)))
7316 (clobber (reg:CC FLAGS_REG))]
7317 "TARGET_USE_8BIT_IDIV
7318 && TARGET_QIMODE_MATH
7319 && can_create_pseudo_p ()
7320 && !optimize_insn_for_size_p ()"
7322 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7324 (define_insn_and_split "udivmod<mode>4_1"
7325 [(set (match_operand:SWI48 0 "register_operand" "=a")
7326 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7327 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7328 (set (match_operand:SWI48 1 "register_operand" "=&d")
7329 (umod:SWI48 (match_dup 2) (match_dup 3)))
7330 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7331 (clobber (reg:CC FLAGS_REG))]
7335 [(set (match_dup 1) (const_int 0))
7336 (parallel [(set (match_dup 0)
7337 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7339 (umod:SWI48 (match_dup 2) (match_dup 3)))
7341 (clobber (reg:CC FLAGS_REG))])]
7343 [(set_attr "type" "multi")
7344 (set_attr "mode" "<MODE>")])
7346 (define_insn_and_split "*udivmod<mode>4"
7347 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7348 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7349 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7350 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7351 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7352 (clobber (reg:CC FLAGS_REG))]
7356 [(set (match_dup 1) (const_int 0))
7357 (parallel [(set (match_dup 0)
7358 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7360 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7362 (clobber (reg:CC FLAGS_REG))])]
7364 [(set_attr "type" "multi")
7365 (set_attr "mode" "<MODE>")])
7367 (define_insn "*udivmod<mode>4_noext"
7368 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7369 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7370 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7371 (set (match_operand:SWIM248 1 "register_operand" "=d")
7372 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7373 (use (match_operand:SWIM248 4 "register_operand" "1"))
7374 (clobber (reg:CC FLAGS_REG))]
7376 "div{<imodesuffix>}\t%3"
7377 [(set_attr "type" "idiv")
7378 (set_attr "mode" "<MODE>")])
7380 (define_expand "udivmodqi4"
7381 [(parallel [(set (match_operand:QI 0 "register_operand")
7383 (match_operand:QI 1 "register_operand")
7384 (match_operand:QI 2 "nonimmediate_operand")))
7385 (set (match_operand:QI 3 "register_operand")
7386 (umod:QI (match_dup 1) (match_dup 2)))
7387 (clobber (reg:CC FLAGS_REG))])]
7388 "TARGET_QIMODE_MATH"
7393 tmp0 = gen_reg_rtx (HImode);
7394 tmp1 = gen_reg_rtx (HImode);
7396 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7398 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7399 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7401 /* Extract remainder from AH. */
7402 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7403 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7404 insn = emit_move_insn (operands[3], tmp1);
7406 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7407 set_unique_reg_note (insn, REG_EQUAL, mod);
7409 /* Extract quotient from AL. */
7410 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7412 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7413 set_unique_reg_note (insn, REG_EQUAL, div);
7418 (define_insn "udivmodhiqi3"
7419 [(set (match_operand:HI 0 "register_operand" "=a")
7424 (mod:HI (match_operand:HI 1 "register_operand" "0")
7426 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7430 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7431 (clobber (reg:CC FLAGS_REG))]
7432 "TARGET_QIMODE_MATH"
7434 [(set_attr "type" "idiv")
7435 (set_attr "mode" "QI")])
7437 ;; We cannot use div/idiv for double division, because it causes
7438 ;; "division by zero" on the overflow and that's not what we expect
7439 ;; from truncate. Because true (non truncating) double division is
7440 ;; never generated, we can't create this insn anyway.
7443 ; [(set (match_operand:SI 0 "register_operand" "=a")
7445 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7447 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7448 ; (set (match_operand:SI 3 "register_operand" "=d")
7450 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7451 ; (clobber (reg:CC FLAGS_REG))]
7453 ; "div{l}\t{%2, %0|%0, %2}"
7454 ; [(set_attr "type" "idiv")])
7456 ;;- Logical AND instructions
7458 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7459 ;; Note that this excludes ah.
7461 (define_expand "testsi_ccno_1"
7462 [(set (reg:CCNO FLAGS_REG)
7464 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7465 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7468 (define_expand "testqi_ccz_1"
7469 [(set (reg:CCZ FLAGS_REG)
7470 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7471 (match_operand:QI 1 "nonmemory_operand"))
7474 (define_expand "testdi_ccno_1"
7475 [(set (reg:CCNO FLAGS_REG)
7477 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7478 (match_operand:DI 1 "x86_64_szext_general_operand"))
7480 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7482 (define_insn "*testdi_1"
7483 [(set (reg FLAGS_REG)
7486 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7487 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7489 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7490 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7492 test{l}\t{%k1, %k0|%k0, %k1}
7493 test{l}\t{%k1, %k0|%k0, %k1}
7494 test{q}\t{%1, %0|%0, %1}
7495 test{q}\t{%1, %0|%0, %1}
7496 test{q}\t{%1, %0|%0, %1}"
7497 [(set_attr "type" "test")
7498 (set_attr "modrm" "0,1,0,1,1")
7499 (set_attr "mode" "SI,SI,DI,DI,DI")])
7501 (define_insn "*testqi_1_maybe_si"
7502 [(set (reg FLAGS_REG)
7505 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7506 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7508 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7509 && ix86_match_ccmode (insn,
7510 CONST_INT_P (operands[1])
7511 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7513 if (which_alternative == 3)
7515 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7516 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7517 return "test{l}\t{%1, %k0|%k0, %1}";
7519 return "test{b}\t{%1, %0|%0, %1}";
7521 [(set_attr "type" "test")
7522 (set_attr "modrm" "0,1,1,1")
7523 (set_attr "mode" "QI,QI,QI,SI")
7524 (set_attr "pent_pair" "uv,np,uv,np")])
7526 (define_insn "*test<mode>_1"
7527 [(set (reg FLAGS_REG)
7530 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7531 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7533 "ix86_match_ccmode (insn, CCNOmode)
7534 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7535 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7536 [(set_attr "type" "test")
7537 (set_attr "modrm" "0,1,1")
7538 (set_attr "mode" "<MODE>")
7539 (set_attr "pent_pair" "uv,np,uv")])
7541 (define_expand "testqi_ext_ccno_0"
7542 [(set (reg:CCNO FLAGS_REG)
7546 (match_operand 0 "ext_register_operand")
7549 (match_operand 1 "const_int_operand"))
7552 (define_insn "*testqi_ext_0"
7553 [(set (reg FLAGS_REG)
7557 (match_operand 0 "ext_register_operand" "Q")
7560 (match_operand 1 "const_int_operand" "n"))
7562 "ix86_match_ccmode (insn, CCNOmode)"
7563 "test{b}\t{%1, %h0|%h0, %1}"
7564 [(set_attr "type" "test")
7565 (set_attr "mode" "QI")
7566 (set_attr "length_immediate" "1")
7567 (set_attr "modrm" "1")
7568 (set_attr "pent_pair" "np")])
7570 (define_insn "*testqi_ext_1_rex64"
7571 [(set (reg FLAGS_REG)
7575 (match_operand 0 "ext_register_operand" "Q")
7579 (match_operand:QI 1 "register_operand" "Q")))
7581 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7582 "test{b}\t{%1, %h0|%h0, %1}"
7583 [(set_attr "type" "test")
7584 (set_attr "mode" "QI")])
7586 (define_insn "*testqi_ext_1"
7587 [(set (reg FLAGS_REG)
7591 (match_operand 0 "ext_register_operand" "Q")
7595 (match_operand:QI 1 "general_operand" "Qm")))
7597 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7598 "test{b}\t{%1, %h0|%h0, %1}"
7599 [(set_attr "type" "test")
7600 (set_attr "mode" "QI")])
7602 (define_insn "*testqi_ext_2"
7603 [(set (reg FLAGS_REG)
7607 (match_operand 0 "ext_register_operand" "Q")
7611 (match_operand 1 "ext_register_operand" "Q")
7615 "ix86_match_ccmode (insn, CCNOmode)"
7616 "test{b}\t{%h1, %h0|%h0, %h1}"
7617 [(set_attr "type" "test")
7618 (set_attr "mode" "QI")])
7620 (define_insn "*testqi_ext_3_rex64"
7621 [(set (reg FLAGS_REG)
7622 (compare (zero_extract:DI
7623 (match_operand 0 "nonimmediate_operand" "rm")
7624 (match_operand:DI 1 "const_int_operand")
7625 (match_operand:DI 2 "const_int_operand"))
7628 && ix86_match_ccmode (insn, CCNOmode)
7629 && INTVAL (operands[1]) > 0
7630 && INTVAL (operands[2]) >= 0
7631 /* Ensure that resulting mask is zero or sign extended operand. */
7632 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7633 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7634 && INTVAL (operands[1]) > 32))
7635 && (GET_MODE (operands[0]) == SImode
7636 || GET_MODE (operands[0]) == DImode
7637 || GET_MODE (operands[0]) == HImode
7638 || GET_MODE (operands[0]) == QImode)"
7641 ;; Combine likes to form bit extractions for some tests. Humor it.
7642 (define_insn "*testqi_ext_3"
7643 [(set (reg FLAGS_REG)
7644 (compare (zero_extract:SI
7645 (match_operand 0 "nonimmediate_operand" "rm")
7646 (match_operand:SI 1 "const_int_operand")
7647 (match_operand:SI 2 "const_int_operand"))
7649 "ix86_match_ccmode (insn, CCNOmode)
7650 && INTVAL (operands[1]) > 0
7651 && INTVAL (operands[2]) >= 0
7652 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7653 && (GET_MODE (operands[0]) == SImode
7654 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7655 || GET_MODE (operands[0]) == HImode
7656 || GET_MODE (operands[0]) == QImode)"
7660 [(set (match_operand 0 "flags_reg_operand")
7661 (match_operator 1 "compare_operator"
7663 (match_operand 2 "nonimmediate_operand")
7664 (match_operand 3 "const_int_operand")
7665 (match_operand 4 "const_int_operand"))
7667 "ix86_match_ccmode (insn, CCNOmode)"
7668 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7670 rtx val = operands[2];
7671 HOST_WIDE_INT len = INTVAL (operands[3]);
7672 HOST_WIDE_INT pos = INTVAL (operands[4]);
7674 enum machine_mode mode, submode;
7676 mode = GET_MODE (val);
7679 /* ??? Combine likes to put non-volatile mem extractions in QImode
7680 no matter the size of the test. So find a mode that works. */
7681 if (! MEM_VOLATILE_P (val))
7683 mode = smallest_mode_for_size (pos + len, MODE_INT);
7684 val = adjust_address (val, mode, 0);
7687 else if (GET_CODE (val) == SUBREG
7688 && (submode = GET_MODE (SUBREG_REG (val)),
7689 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7690 && pos + len <= GET_MODE_BITSIZE (submode)
7691 && GET_MODE_CLASS (submode) == MODE_INT)
7693 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7695 val = SUBREG_REG (val);
7697 else if (mode == HImode && pos + len <= 8)
7699 /* Small HImode tests can be converted to QImode. */
7701 val = gen_lowpart (QImode, val);
7704 if (len == HOST_BITS_PER_WIDE_INT)
7707 mask = ((HOST_WIDE_INT)1 << len) - 1;
7710 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7713 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7714 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7715 ;; this is relatively important trick.
7716 ;; Do the conversion only post-reload to avoid limiting of the register class
7719 [(set (match_operand 0 "flags_reg_operand")
7720 (match_operator 1 "compare_operator"
7721 [(and (match_operand 2 "register_operand")
7722 (match_operand 3 "const_int_operand"))
7725 && QI_REG_P (operands[2])
7726 && GET_MODE (operands[2]) != QImode
7727 && ((ix86_match_ccmode (insn, CCZmode)
7728 && !(INTVAL (operands[3]) & ~(255 << 8)))
7729 || (ix86_match_ccmode (insn, CCNOmode)
7730 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7733 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7737 operands[2] = gen_lowpart (SImode, operands[2]);
7738 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7742 [(set (match_operand 0 "flags_reg_operand")
7743 (match_operator 1 "compare_operator"
7744 [(and (match_operand 2 "nonimmediate_operand")
7745 (match_operand 3 "const_int_operand"))
7748 && GET_MODE (operands[2]) != QImode
7749 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7750 && ((ix86_match_ccmode (insn, CCZmode)
7751 && !(INTVAL (operands[3]) & ~255))
7752 || (ix86_match_ccmode (insn, CCNOmode)
7753 && !(INTVAL (operands[3]) & ~127)))"
7755 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7758 operands[2] = gen_lowpart (QImode, operands[2]);
7759 operands[3] = gen_lowpart (QImode, operands[3]);
7762 ;; %%% This used to optimize known byte-wide and operations to memory,
7763 ;; and sometimes to QImode registers. If this is considered useful,
7764 ;; it should be done with splitters.
7766 (define_expand "and<mode>3"
7767 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7768 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7769 (match_operand:SWIM 2 "<general_szext_operand>")))]
7772 enum machine_mode mode = <MODE>mode;
7773 rtx (*insn) (rtx, rtx);
7775 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7777 HOST_WIDE_INT ival = INTVAL (operands[2]);
7779 if (ival == (HOST_WIDE_INT) 0xffffffff)
7781 else if (ival == 0xffff)
7783 else if (ival == 0xff)
7787 if (mode == <MODE>mode)
7789 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7793 if (<MODE>mode == DImode)
7794 insn = (mode == SImode)
7795 ? gen_zero_extendsidi2
7797 ? gen_zero_extendhidi2
7798 : gen_zero_extendqidi2;
7799 else if (<MODE>mode == SImode)
7800 insn = (mode == HImode)
7801 ? gen_zero_extendhisi2
7802 : gen_zero_extendqisi2;
7803 else if (<MODE>mode == HImode)
7804 insn = gen_zero_extendqihi2;
7808 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7812 (define_insn "*anddi_1"
7813 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7815 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7816 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7817 (clobber (reg:CC FLAGS_REG))]
7818 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7820 switch (get_attr_type (insn))
7826 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7827 if (get_attr_mode (insn) == MODE_SI)
7828 return "and{l}\t{%k2, %k0|%k0, %k2}";
7830 return "and{q}\t{%2, %0|%0, %2}";
7833 [(set_attr "type" "alu,alu,alu,imovx")
7834 (set_attr "length_immediate" "*,*,*,0")
7835 (set (attr "prefix_rex")
7837 (and (eq_attr "type" "imovx")
7838 (and (match_test "INTVAL (operands[2]) == 0xff")
7839 (match_operand 1 "ext_QIreg_operand")))
7841 (const_string "*")))
7842 (set_attr "mode" "SI,DI,DI,SI")])
7844 (define_insn "*andsi_1"
7845 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7846 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7847 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7848 (clobber (reg:CC FLAGS_REG))]
7849 "ix86_binary_operator_ok (AND, SImode, operands)"
7851 switch (get_attr_type (insn))
7857 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7858 return "and{l}\t{%2, %0|%0, %2}";
7861 [(set_attr "type" "alu,alu,imovx")
7862 (set (attr "prefix_rex")
7864 (and (eq_attr "type" "imovx")
7865 (and (match_test "INTVAL (operands[2]) == 0xff")
7866 (match_operand 1 "ext_QIreg_operand")))
7868 (const_string "*")))
7869 (set_attr "length_immediate" "*,*,0")
7870 (set_attr "mode" "SI")])
7872 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7873 (define_insn "*andsi_1_zext"
7874 [(set (match_operand:DI 0 "register_operand" "=r")
7876 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7877 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7878 (clobber (reg:CC FLAGS_REG))]
7879 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7880 "and{l}\t{%2, %k0|%k0, %2}"
7881 [(set_attr "type" "alu")
7882 (set_attr "mode" "SI")])
7884 (define_insn "*andhi_1"
7885 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7886 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7887 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7888 (clobber (reg:CC FLAGS_REG))]
7889 "ix86_binary_operator_ok (AND, HImode, operands)"
7891 switch (get_attr_type (insn))
7897 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7898 return "and{w}\t{%2, %0|%0, %2}";
7901 [(set_attr "type" "alu,alu,imovx")
7902 (set_attr "length_immediate" "*,*,0")
7903 (set (attr "prefix_rex")
7905 (and (eq_attr "type" "imovx")
7906 (match_operand 1 "ext_QIreg_operand"))
7908 (const_string "*")))
7909 (set_attr "mode" "HI,HI,SI")])
7911 ;; %%% Potential partial reg stall on alternative 2. What to do?
7912 (define_insn "*andqi_1"
7913 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7914 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7915 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7916 (clobber (reg:CC FLAGS_REG))]
7917 "ix86_binary_operator_ok (AND, QImode, operands)"
7919 and{b}\t{%2, %0|%0, %2}
7920 and{b}\t{%2, %0|%0, %2}
7921 and{l}\t{%k2, %k0|%k0, %k2}"
7922 [(set_attr "type" "alu")
7923 (set_attr "mode" "QI,QI,SI")])
7925 (define_insn "*andqi_1_slp"
7926 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7927 (and:QI (match_dup 0)
7928 (match_operand:QI 1 "general_operand" "qn,qmn")))
7929 (clobber (reg:CC FLAGS_REG))]
7930 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7931 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7932 "and{b}\t{%1, %0|%0, %1}"
7933 [(set_attr "type" "alu1")
7934 (set_attr "mode" "QI")])
7936 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7938 [(set (match_operand:DI 0 "register_operand")
7939 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7940 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7941 (clobber (reg:CC FLAGS_REG))]
7943 [(parallel [(set (match_dup 0)
7944 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7945 (clobber (reg:CC FLAGS_REG))])]
7946 "operands[2] = gen_lowpart (SImode, operands[2]);")
7949 [(set (match_operand:SWI248 0 "register_operand")
7950 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7951 (match_operand:SWI248 2 "const_int_operand")))
7952 (clobber (reg:CC FLAGS_REG))]
7954 && true_regnum (operands[0]) != true_regnum (operands[1])"
7957 HOST_WIDE_INT ival = INTVAL (operands[2]);
7958 enum machine_mode mode;
7959 rtx (*insn) (rtx, rtx);
7961 if (ival == (HOST_WIDE_INT) 0xffffffff)
7963 else if (ival == 0xffff)
7967 gcc_assert (ival == 0xff);
7971 if (<MODE>mode == DImode)
7972 insn = (mode == SImode)
7973 ? gen_zero_extendsidi2
7975 ? gen_zero_extendhidi2
7976 : gen_zero_extendqidi2;
7979 if (<MODE>mode != SImode)
7980 /* Zero extend to SImode to avoid partial register stalls. */
7981 operands[0] = gen_lowpart (SImode, operands[0]);
7983 insn = (mode == HImode)
7984 ? gen_zero_extendhisi2
7985 : gen_zero_extendqisi2;
7987 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7992 [(set (match_operand 0 "register_operand")
7994 (const_int -65536)))
7995 (clobber (reg:CC FLAGS_REG))]
7996 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7997 || optimize_function_for_size_p (cfun)"
7998 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7999 "operands[1] = gen_lowpart (HImode, operands[0]);")
8002 [(set (match_operand 0 "ext_register_operand")
8005 (clobber (reg:CC FLAGS_REG))]
8006 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8007 && reload_completed"
8008 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8009 "operands[1] = gen_lowpart (QImode, operands[0]);")
8012 [(set (match_operand 0 "ext_register_operand")
8014 (const_int -65281)))
8015 (clobber (reg:CC FLAGS_REG))]
8016 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8017 && reload_completed"
8018 [(parallel [(set (zero_extract:SI (match_dup 0)
8022 (zero_extract:SI (match_dup 0)
8025 (zero_extract:SI (match_dup 0)
8028 (clobber (reg:CC FLAGS_REG))])]
8029 "operands[0] = gen_lowpart (SImode, operands[0]);")
8031 (define_insn "*anddi_2"
8032 [(set (reg FLAGS_REG)
8035 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8036 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8038 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8039 (and:DI (match_dup 1) (match_dup 2)))]
8040 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8041 && ix86_binary_operator_ok (AND, DImode, operands)"
8043 and{l}\t{%k2, %k0|%k0, %k2}
8044 and{q}\t{%2, %0|%0, %2}
8045 and{q}\t{%2, %0|%0, %2}"
8046 [(set_attr "type" "alu")
8047 (set_attr "mode" "SI,DI,DI")])
8049 (define_insn "*andqi_2_maybe_si"
8050 [(set (reg FLAGS_REG)
8052 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8053 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8055 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8056 (and:QI (match_dup 1) (match_dup 2)))]
8057 "ix86_binary_operator_ok (AND, QImode, operands)
8058 && ix86_match_ccmode (insn,
8059 CONST_INT_P (operands[2])
8060 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8062 if (which_alternative == 2)
8064 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8065 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8066 return "and{l}\t{%2, %k0|%k0, %2}";
8068 return "and{b}\t{%2, %0|%0, %2}";
8070 [(set_attr "type" "alu")
8071 (set_attr "mode" "QI,QI,SI")])
8073 (define_insn "*and<mode>_2"
8074 [(set (reg FLAGS_REG)
8075 (compare (and:SWI124
8076 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8077 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8079 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8080 (and:SWI124 (match_dup 1) (match_dup 2)))]
8081 "ix86_match_ccmode (insn, CCNOmode)
8082 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8083 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8084 [(set_attr "type" "alu")
8085 (set_attr "mode" "<MODE>")])
8087 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8088 (define_insn "*andsi_2_zext"
8089 [(set (reg FLAGS_REG)
8091 (match_operand:SI 1 "nonimmediate_operand" "%0")
8092 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8094 (set (match_operand:DI 0 "register_operand" "=r")
8095 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8096 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8097 && ix86_binary_operator_ok (AND, SImode, operands)"
8098 "and{l}\t{%2, %k0|%k0, %2}"
8099 [(set_attr "type" "alu")
8100 (set_attr "mode" "SI")])
8102 (define_insn "*andqi_2_slp"
8103 [(set (reg FLAGS_REG)
8105 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8106 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8108 (set (strict_low_part (match_dup 0))
8109 (and:QI (match_dup 0) (match_dup 1)))]
8110 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8111 && ix86_match_ccmode (insn, CCNOmode)
8112 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8113 "and{b}\t{%1, %0|%0, %1}"
8114 [(set_attr "type" "alu1")
8115 (set_attr "mode" "QI")])
8117 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8118 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8119 ;; for a QImode operand, which of course failed.
8120 (define_insn "andqi_ext_0"
8121 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8126 (match_operand 1 "ext_register_operand" "0")
8129 (match_operand 2 "const_int_operand" "n")))
8130 (clobber (reg:CC FLAGS_REG))]
8132 "and{b}\t{%2, %h0|%h0, %2}"
8133 [(set_attr "type" "alu")
8134 (set_attr "length_immediate" "1")
8135 (set_attr "modrm" "1")
8136 (set_attr "mode" "QI")])
8138 ;; Generated by peephole translating test to and. This shows up
8139 ;; often in fp comparisons.
8140 (define_insn "*andqi_ext_0_cc"
8141 [(set (reg FLAGS_REG)
8145 (match_operand 1 "ext_register_operand" "0")
8148 (match_operand 2 "const_int_operand" "n"))
8150 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8159 "ix86_match_ccmode (insn, CCNOmode)"
8160 "and{b}\t{%2, %h0|%h0, %2}"
8161 [(set_attr "type" "alu")
8162 (set_attr "length_immediate" "1")
8163 (set_attr "modrm" "1")
8164 (set_attr "mode" "QI")])
8166 (define_insn "*andqi_ext_1_rex64"
8167 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8172 (match_operand 1 "ext_register_operand" "0")
8176 (match_operand 2 "ext_register_operand" "Q"))))
8177 (clobber (reg:CC FLAGS_REG))]
8179 "and{b}\t{%2, %h0|%h0, %2}"
8180 [(set_attr "type" "alu")
8181 (set_attr "length_immediate" "0")
8182 (set_attr "mode" "QI")])
8184 (define_insn "*andqi_ext_1"
8185 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8190 (match_operand 1 "ext_register_operand" "0")
8194 (match_operand:QI 2 "general_operand" "Qm"))))
8195 (clobber (reg:CC FLAGS_REG))]
8197 "and{b}\t{%2, %h0|%h0, %2}"
8198 [(set_attr "type" "alu")
8199 (set_attr "length_immediate" "0")
8200 (set_attr "mode" "QI")])
8202 (define_insn "*andqi_ext_2"
8203 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8208 (match_operand 1 "ext_register_operand" "%0")
8212 (match_operand 2 "ext_register_operand" "Q")
8215 (clobber (reg:CC FLAGS_REG))]
8217 "and{b}\t{%h2, %h0|%h0, %h2}"
8218 [(set_attr "type" "alu")
8219 (set_attr "length_immediate" "0")
8220 (set_attr "mode" "QI")])
8222 ;; Convert wide AND instructions with immediate operand to shorter QImode
8223 ;; equivalents when possible.
8224 ;; Don't do the splitting with memory operands, since it introduces risk
8225 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8226 ;; for size, but that can (should?) be handled by generic code instead.
8228 [(set (match_operand 0 "register_operand")
8229 (and (match_operand 1 "register_operand")
8230 (match_operand 2 "const_int_operand")))
8231 (clobber (reg:CC FLAGS_REG))]
8233 && QI_REG_P (operands[0])
8234 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8235 && !(~INTVAL (operands[2]) & ~(255 << 8))
8236 && GET_MODE (operands[0]) != QImode"
8237 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8238 (and:SI (zero_extract:SI (match_dup 1)
8239 (const_int 8) (const_int 8))
8241 (clobber (reg:CC FLAGS_REG))])]
8243 operands[0] = gen_lowpart (SImode, operands[0]);
8244 operands[1] = gen_lowpart (SImode, operands[1]);
8245 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8248 ;; Since AND can be encoded with sign extended immediate, this is only
8249 ;; profitable when 7th bit is not set.
8251 [(set (match_operand 0 "register_operand")
8252 (and (match_operand 1 "general_operand")
8253 (match_operand 2 "const_int_operand")))
8254 (clobber (reg:CC FLAGS_REG))]
8256 && ANY_QI_REG_P (operands[0])
8257 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8258 && !(~INTVAL (operands[2]) & ~255)
8259 && !(INTVAL (operands[2]) & 128)
8260 && GET_MODE (operands[0]) != QImode"
8261 [(parallel [(set (strict_low_part (match_dup 0))
8262 (and:QI (match_dup 1)
8264 (clobber (reg:CC FLAGS_REG))])]
8266 operands[0] = gen_lowpart (QImode, operands[0]);
8267 operands[1] = gen_lowpart (QImode, operands[1]);
8268 operands[2] = gen_lowpart (QImode, operands[2]);
8271 ;; Logical inclusive and exclusive OR instructions
8273 ;; %%% This used to optimize known byte-wide and operations to memory.
8274 ;; If this is considered useful, it should be done with splitters.
8276 (define_expand "<code><mode>3"
8277 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8278 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8279 (match_operand:SWIM 2 "<general_operand>")))]
8281 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8283 (define_insn "*<code><mode>_1"
8284 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8286 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8287 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8288 (clobber (reg:CC FLAGS_REG))]
8289 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8290 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8291 [(set_attr "type" "alu")
8292 (set_attr "mode" "<MODE>")])
8294 ;; %%% Potential partial reg stall on alternative 2. What to do?
8295 (define_insn "*<code>qi_1"
8296 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8297 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8298 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8299 (clobber (reg:CC FLAGS_REG))]
8300 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8302 <logic>{b}\t{%2, %0|%0, %2}
8303 <logic>{b}\t{%2, %0|%0, %2}
8304 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8305 [(set_attr "type" "alu")
8306 (set_attr "mode" "QI,QI,SI")])
8308 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8309 (define_insn "*<code>si_1_zext"
8310 [(set (match_operand:DI 0 "register_operand" "=r")
8312 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8313 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8314 (clobber (reg:CC FLAGS_REG))]
8315 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8316 "<logic>{l}\t{%2, %k0|%k0, %2}"
8317 [(set_attr "type" "alu")
8318 (set_attr "mode" "SI")])
8320 (define_insn "*<code>si_1_zext_imm"
8321 [(set (match_operand:DI 0 "register_operand" "=r")
8323 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8324 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8325 (clobber (reg:CC FLAGS_REG))]
8326 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8327 "<logic>{l}\t{%2, %k0|%k0, %2}"
8328 [(set_attr "type" "alu")
8329 (set_attr "mode" "SI")])
8331 (define_insn "*<code>qi_1_slp"
8332 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8333 (any_or:QI (match_dup 0)
8334 (match_operand:QI 1 "general_operand" "qmn,qn")))
8335 (clobber (reg:CC FLAGS_REG))]
8336 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8337 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8338 "<logic>{b}\t{%1, %0|%0, %1}"
8339 [(set_attr "type" "alu1")
8340 (set_attr "mode" "QI")])
8342 (define_insn "*<code><mode>_2"
8343 [(set (reg FLAGS_REG)
8344 (compare (any_or:SWI
8345 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8346 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8348 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8349 (any_or:SWI (match_dup 1) (match_dup 2)))]
8350 "ix86_match_ccmode (insn, CCNOmode)
8351 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8352 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8353 [(set_attr "type" "alu")
8354 (set_attr "mode" "<MODE>")])
8356 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8357 ;; ??? Special case for immediate operand is missing - it is tricky.
8358 (define_insn "*<code>si_2_zext"
8359 [(set (reg FLAGS_REG)
8360 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8361 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8363 (set (match_operand:DI 0 "register_operand" "=r")
8364 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8365 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8366 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8367 "<logic>{l}\t{%2, %k0|%k0, %2}"
8368 [(set_attr "type" "alu")
8369 (set_attr "mode" "SI")])
8371 (define_insn "*<code>si_2_zext_imm"
8372 [(set (reg FLAGS_REG)
8374 (match_operand:SI 1 "nonimmediate_operand" "%0")
8375 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8377 (set (match_operand:DI 0 "register_operand" "=r")
8378 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8379 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8380 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8381 "<logic>{l}\t{%2, %k0|%k0, %2}"
8382 [(set_attr "type" "alu")
8383 (set_attr "mode" "SI")])
8385 (define_insn "*<code>qi_2_slp"
8386 [(set (reg FLAGS_REG)
8387 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8388 (match_operand:QI 1 "general_operand" "qmn,qn"))
8390 (set (strict_low_part (match_dup 0))
8391 (any_or:QI (match_dup 0) (match_dup 1)))]
8392 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8393 && ix86_match_ccmode (insn, CCNOmode)
8394 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8395 "<logic>{b}\t{%1, %0|%0, %1}"
8396 [(set_attr "type" "alu1")
8397 (set_attr "mode" "QI")])
8399 (define_insn "*<code><mode>_3"
8400 [(set (reg FLAGS_REG)
8401 (compare (any_or:SWI
8402 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8403 (match_operand:SWI 2 "<general_operand>" "<g>"))
8405 (clobber (match_scratch:SWI 0 "=<r>"))]
8406 "ix86_match_ccmode (insn, CCNOmode)
8407 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8408 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8409 [(set_attr "type" "alu")
8410 (set_attr "mode" "<MODE>")])
8412 (define_insn "*<code>qi_ext_0"
8413 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8418 (match_operand 1 "ext_register_operand" "0")
8421 (match_operand 2 "const_int_operand" "n")))
8422 (clobber (reg:CC FLAGS_REG))]
8423 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8424 "<logic>{b}\t{%2, %h0|%h0, %2}"
8425 [(set_attr "type" "alu")
8426 (set_attr "length_immediate" "1")
8427 (set_attr "modrm" "1")
8428 (set_attr "mode" "QI")])
8430 (define_insn "*<code>qi_ext_1_rex64"
8431 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8436 (match_operand 1 "ext_register_operand" "0")
8440 (match_operand 2 "ext_register_operand" "Q"))))
8441 (clobber (reg:CC FLAGS_REG))]
8443 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8444 "<logic>{b}\t{%2, %h0|%h0, %2}"
8445 [(set_attr "type" "alu")
8446 (set_attr "length_immediate" "0")
8447 (set_attr "mode" "QI")])
8449 (define_insn "*<code>qi_ext_1"
8450 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8455 (match_operand 1 "ext_register_operand" "0")
8459 (match_operand:QI 2 "general_operand" "Qm"))))
8460 (clobber (reg:CC FLAGS_REG))]
8462 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8463 "<logic>{b}\t{%2, %h0|%h0, %2}"
8464 [(set_attr "type" "alu")
8465 (set_attr "length_immediate" "0")
8466 (set_attr "mode" "QI")])
8468 (define_insn "*<code>qi_ext_2"
8469 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8473 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8476 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8479 (clobber (reg:CC FLAGS_REG))]
8480 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8481 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8482 [(set_attr "type" "alu")
8483 (set_attr "length_immediate" "0")
8484 (set_attr "mode" "QI")])
8487 [(set (match_operand 0 "register_operand")
8488 (any_or (match_operand 1 "register_operand")
8489 (match_operand 2 "const_int_operand")))
8490 (clobber (reg:CC FLAGS_REG))]
8492 && QI_REG_P (operands[0])
8493 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8494 && !(INTVAL (operands[2]) & ~(255 << 8))
8495 && GET_MODE (operands[0]) != QImode"
8496 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8497 (any_or:SI (zero_extract:SI (match_dup 1)
8498 (const_int 8) (const_int 8))
8500 (clobber (reg:CC FLAGS_REG))])]
8502 operands[0] = gen_lowpart (SImode, operands[0]);
8503 operands[1] = gen_lowpart (SImode, operands[1]);
8504 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8507 ;; Since OR can be encoded with sign extended immediate, this is only
8508 ;; profitable when 7th bit is set.
8510 [(set (match_operand 0 "register_operand")
8511 (any_or (match_operand 1 "general_operand")
8512 (match_operand 2 "const_int_operand")))
8513 (clobber (reg:CC FLAGS_REG))]
8515 && ANY_QI_REG_P (operands[0])
8516 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8517 && !(INTVAL (operands[2]) & ~255)
8518 && (INTVAL (operands[2]) & 128)
8519 && GET_MODE (operands[0]) != QImode"
8520 [(parallel [(set (strict_low_part (match_dup 0))
8521 (any_or:QI (match_dup 1)
8523 (clobber (reg:CC FLAGS_REG))])]
8525 operands[0] = gen_lowpart (QImode, operands[0]);
8526 operands[1] = gen_lowpart (QImode, operands[1]);
8527 operands[2] = gen_lowpart (QImode, operands[2]);
8530 (define_expand "xorqi_cc_ext_1"
8532 (set (reg:CCNO FLAGS_REG)
8536 (match_operand 1 "ext_register_operand")
8539 (match_operand:QI 2 "general_operand"))
8541 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8551 (define_insn "*xorqi_cc_ext_1_rex64"
8552 [(set (reg FLAGS_REG)
8556 (match_operand 1 "ext_register_operand" "0")
8559 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8561 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8570 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8571 "xor{b}\t{%2, %h0|%h0, %2}"
8572 [(set_attr "type" "alu")
8573 (set_attr "modrm" "1")
8574 (set_attr "mode" "QI")])
8576 (define_insn "*xorqi_cc_ext_1"
8577 [(set (reg FLAGS_REG)
8581 (match_operand 1 "ext_register_operand" "0")
8584 (match_operand:QI 2 "general_operand" "qmn"))
8586 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8595 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8596 "xor{b}\t{%2, %h0|%h0, %2}"
8597 [(set_attr "type" "alu")
8598 (set_attr "modrm" "1")
8599 (set_attr "mode" "QI")])
8601 ;; Negation instructions
8603 (define_expand "neg<mode>2"
8604 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8605 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8607 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8609 (define_insn_and_split "*neg<dwi>2_doubleword"
8610 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8611 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8612 (clobber (reg:CC FLAGS_REG))]
8613 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8617 [(set (reg:CCZ FLAGS_REG)
8618 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8619 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8622 (plus:DWIH (match_dup 3)
8623 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8625 (clobber (reg:CC FLAGS_REG))])
8628 (neg:DWIH (match_dup 2)))
8629 (clobber (reg:CC FLAGS_REG))])]
8630 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8632 (define_insn "*neg<mode>2_1"
8633 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8634 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8635 (clobber (reg:CC FLAGS_REG))]
8636 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8637 "neg{<imodesuffix>}\t%0"
8638 [(set_attr "type" "negnot")
8639 (set_attr "mode" "<MODE>")])
8641 ;; Combine is quite creative about this pattern.
8642 (define_insn "*negsi2_1_zext"
8643 [(set (match_operand:DI 0 "register_operand" "=r")
8645 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8648 (clobber (reg:CC FLAGS_REG))]
8649 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8651 [(set_attr "type" "negnot")
8652 (set_attr "mode" "SI")])
8654 ;; The problem with neg is that it does not perform (compare x 0),
8655 ;; it really performs (compare 0 x), which leaves us with the zero
8656 ;; flag being the only useful item.
8658 (define_insn "*neg<mode>2_cmpz"
8659 [(set (reg:CCZ FLAGS_REG)
8661 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8663 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8664 (neg:SWI (match_dup 1)))]
8665 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8666 "neg{<imodesuffix>}\t%0"
8667 [(set_attr "type" "negnot")
8668 (set_attr "mode" "<MODE>")])
8670 (define_insn "*negsi2_cmpz_zext"
8671 [(set (reg:CCZ FLAGS_REG)
8675 (match_operand:DI 1 "register_operand" "0")
8679 (set (match_operand:DI 0 "register_operand" "=r")
8680 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8683 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8685 [(set_attr "type" "negnot")
8686 (set_attr "mode" "SI")])
8688 ;; Changing of sign for FP values is doable using integer unit too.
8690 (define_expand "<code><mode>2"
8691 [(set (match_operand:X87MODEF 0 "register_operand")
8692 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8693 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8694 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8696 (define_insn "*absneg<mode>2_mixed"
8697 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8698 (match_operator:MODEF 3 "absneg_operator"
8699 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8700 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8701 (clobber (reg:CC FLAGS_REG))]
8702 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8705 (define_insn "*absneg<mode>2_sse"
8706 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8707 (match_operator:MODEF 3 "absneg_operator"
8708 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8709 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8710 (clobber (reg:CC FLAGS_REG))]
8711 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8714 (define_insn "*absneg<mode>2_i387"
8715 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8716 (match_operator:X87MODEF 3 "absneg_operator"
8717 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8718 (use (match_operand 2))
8719 (clobber (reg:CC FLAGS_REG))]
8720 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8723 (define_expand "<code>tf2"
8724 [(set (match_operand:TF 0 "register_operand")
8725 (absneg:TF (match_operand:TF 1 "register_operand")))]
8727 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8729 (define_insn "*absnegtf2_sse"
8730 [(set (match_operand:TF 0 "register_operand" "=x,x")
8731 (match_operator:TF 3 "absneg_operator"
8732 [(match_operand:TF 1 "register_operand" "0,x")]))
8733 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8734 (clobber (reg:CC FLAGS_REG))]
8738 ;; Splitters for fp abs and neg.
8741 [(set (match_operand 0 "fp_register_operand")
8742 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8743 (use (match_operand 2))
8744 (clobber (reg:CC FLAGS_REG))]
8746 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8749 [(set (match_operand 0 "register_operand")
8750 (match_operator 3 "absneg_operator"
8751 [(match_operand 1 "register_operand")]))
8752 (use (match_operand 2 "nonimmediate_operand"))
8753 (clobber (reg:CC FLAGS_REG))]
8754 "reload_completed && SSE_REG_P (operands[0])"
8755 [(set (match_dup 0) (match_dup 3))]
8757 enum machine_mode mode = GET_MODE (operands[0]);
8758 enum machine_mode vmode = GET_MODE (operands[2]);
8761 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8762 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8763 if (operands_match_p (operands[0], operands[2]))
8766 operands[1] = operands[2];
8769 if (GET_CODE (operands[3]) == ABS)
8770 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8772 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8777 [(set (match_operand:SF 0 "register_operand")
8778 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8779 (use (match_operand:V4SF 2))
8780 (clobber (reg:CC FLAGS_REG))]
8782 [(parallel [(set (match_dup 0) (match_dup 1))
8783 (clobber (reg:CC FLAGS_REG))])]
8786 operands[0] = gen_lowpart (SImode, operands[0]);
8787 if (GET_CODE (operands[1]) == ABS)
8789 tmp = gen_int_mode (0x7fffffff, SImode);
8790 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8794 tmp = gen_int_mode (0x80000000, SImode);
8795 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8801 [(set (match_operand:DF 0 "register_operand")
8802 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8803 (use (match_operand 2))
8804 (clobber (reg:CC FLAGS_REG))]
8806 [(parallel [(set (match_dup 0) (match_dup 1))
8807 (clobber (reg:CC FLAGS_REG))])]
8812 tmp = gen_lowpart (DImode, operands[0]);
8813 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8816 if (GET_CODE (operands[1]) == ABS)
8819 tmp = gen_rtx_NOT (DImode, tmp);
8823 operands[0] = gen_highpart (SImode, operands[0]);
8824 if (GET_CODE (operands[1]) == ABS)
8826 tmp = gen_int_mode (0x7fffffff, SImode);
8827 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8831 tmp = gen_int_mode (0x80000000, SImode);
8832 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8839 [(set (match_operand:XF 0 "register_operand")
8840 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8841 (use (match_operand 2))
8842 (clobber (reg:CC FLAGS_REG))]
8844 [(parallel [(set (match_dup 0) (match_dup 1))
8845 (clobber (reg:CC FLAGS_REG))])]
8848 operands[0] = gen_rtx_REG (SImode,
8849 true_regnum (operands[0])
8850 + (TARGET_64BIT ? 1 : 2));
8851 if (GET_CODE (operands[1]) == ABS)
8853 tmp = GEN_INT (0x7fff);
8854 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8858 tmp = GEN_INT (0x8000);
8859 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8864 ;; Conditionalize these after reload. If they match before reload, we
8865 ;; lose the clobber and ability to use integer instructions.
8867 (define_insn "*<code><mode>2_1"
8868 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8869 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8871 && (reload_completed
8872 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8873 "f<absneg_mnemonic>"
8874 [(set_attr "type" "fsgn")
8875 (set_attr "mode" "<MODE>")])
8877 (define_insn "*<code>extendsfdf2"
8878 [(set (match_operand:DF 0 "register_operand" "=f")
8879 (absneg:DF (float_extend:DF
8880 (match_operand:SF 1 "register_operand" "0"))))]
8881 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8882 "f<absneg_mnemonic>"
8883 [(set_attr "type" "fsgn")
8884 (set_attr "mode" "DF")])
8886 (define_insn "*<code>extendsfxf2"
8887 [(set (match_operand:XF 0 "register_operand" "=f")
8888 (absneg:XF (float_extend:XF
8889 (match_operand:SF 1 "register_operand" "0"))))]
8891 "f<absneg_mnemonic>"
8892 [(set_attr "type" "fsgn")
8893 (set_attr "mode" "XF")])
8895 (define_insn "*<code>extenddfxf2"
8896 [(set (match_operand:XF 0 "register_operand" "=f")
8897 (absneg:XF (float_extend:XF
8898 (match_operand:DF 1 "register_operand" "0"))))]
8900 "f<absneg_mnemonic>"
8901 [(set_attr "type" "fsgn")
8902 (set_attr "mode" "XF")])
8904 ;; Copysign instructions
8906 (define_mode_iterator CSGNMODE [SF DF TF])
8907 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8909 (define_expand "copysign<mode>3"
8910 [(match_operand:CSGNMODE 0 "register_operand")
8911 (match_operand:CSGNMODE 1 "nonmemory_operand")
8912 (match_operand:CSGNMODE 2 "register_operand")]
8913 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8914 || (TARGET_SSE && (<MODE>mode == TFmode))"
8915 "ix86_expand_copysign (operands); DONE;")
8917 (define_insn_and_split "copysign<mode>3_const"
8918 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8920 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8921 (match_operand:CSGNMODE 2 "register_operand" "0")
8922 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8924 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8925 || (TARGET_SSE && (<MODE>mode == TFmode))"
8927 "&& reload_completed"
8929 "ix86_split_copysign_const (operands); DONE;")
8931 (define_insn "copysign<mode>3_var"
8932 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8934 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8935 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8936 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8937 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8939 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8940 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8941 || (TARGET_SSE && (<MODE>mode == TFmode))"
8945 [(set (match_operand:CSGNMODE 0 "register_operand")
8947 [(match_operand:CSGNMODE 2 "register_operand")
8948 (match_operand:CSGNMODE 3 "register_operand")
8949 (match_operand:<CSGNVMODE> 4)
8950 (match_operand:<CSGNVMODE> 5)]
8952 (clobber (match_scratch:<CSGNVMODE> 1))]
8953 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8954 || (TARGET_SSE && (<MODE>mode == TFmode)))
8955 && reload_completed"
8957 "ix86_split_copysign_var (operands); DONE;")
8959 ;; One complement instructions
8961 (define_expand "one_cmpl<mode>2"
8962 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8963 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8965 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8967 (define_insn "*one_cmpl<mode>2_1"
8968 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8969 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8970 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8971 "not{<imodesuffix>}\t%0"
8972 [(set_attr "type" "negnot")
8973 (set_attr "mode" "<MODE>")])
8975 ;; %%% Potential partial reg stall on alternative 1. What to do?
8976 (define_insn "*one_cmplqi2_1"
8977 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8978 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8979 "ix86_unary_operator_ok (NOT, QImode, operands)"
8983 [(set_attr "type" "negnot")
8984 (set_attr "mode" "QI,SI")])
8986 ;; ??? Currently never generated - xor is used instead.
8987 (define_insn "*one_cmplsi2_1_zext"
8988 [(set (match_operand:DI 0 "register_operand" "=r")
8990 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8991 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8993 [(set_attr "type" "negnot")
8994 (set_attr "mode" "SI")])
8996 (define_insn "*one_cmpl<mode>2_2"
8997 [(set (reg FLAGS_REG)
8998 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9000 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9001 (not:SWI (match_dup 1)))]
9002 "ix86_match_ccmode (insn, CCNOmode)
9003 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9005 [(set_attr "type" "alu1")
9006 (set_attr "mode" "<MODE>")])
9009 [(set (match_operand 0 "flags_reg_operand")
9010 (match_operator 2 "compare_operator"
9011 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9013 (set (match_operand:SWI 1 "nonimmediate_operand")
9014 (not:SWI (match_dup 3)))]
9015 "ix86_match_ccmode (insn, CCNOmode)"
9016 [(parallel [(set (match_dup 0)
9017 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9020 (xor:SWI (match_dup 3) (const_int -1)))])])
9022 ;; ??? Currently never generated - xor is used instead.
9023 (define_insn "*one_cmplsi2_2_zext"
9024 [(set (reg FLAGS_REG)
9025 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9027 (set (match_operand:DI 0 "register_operand" "=r")
9028 (zero_extend:DI (not:SI (match_dup 1))))]
9029 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9030 && ix86_unary_operator_ok (NOT, SImode, operands)"
9032 [(set_attr "type" "alu1")
9033 (set_attr "mode" "SI")])
9036 [(set (match_operand 0 "flags_reg_operand")
9037 (match_operator 2 "compare_operator"
9038 [(not:SI (match_operand:SI 3 "register_operand"))
9040 (set (match_operand:DI 1 "register_operand")
9041 (zero_extend:DI (not:SI (match_dup 3))))]
9042 "ix86_match_ccmode (insn, CCNOmode)"
9043 [(parallel [(set (match_dup 0)
9044 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9047 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9049 ;; Shift instructions
9051 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9052 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9053 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9054 ;; from the assembler input.
9056 ;; This instruction shifts the target reg/mem as usual, but instead of
9057 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9058 ;; is a left shift double, bits are taken from the high order bits of
9059 ;; reg, else if the insn is a shift right double, bits are taken from the
9060 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9061 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9063 ;; Since sh[lr]d does not change the `reg' operand, that is done
9064 ;; separately, making all shifts emit pairs of shift double and normal
9065 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9066 ;; support a 63 bit shift, each shift where the count is in a reg expands
9067 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9069 ;; If the shift count is a constant, we need never emit more than one
9070 ;; shift pair, instead using moves and sign extension for counts greater
9073 (define_expand "ashl<mode>3"
9074 [(set (match_operand:SDWIM 0 "<shift_operand>")
9075 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9076 (match_operand:QI 2 "nonmemory_operand")))]
9078 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9080 (define_insn "*ashl<mode>3_doubleword"
9081 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9082 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9083 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9084 (clobber (reg:CC FLAGS_REG))]
9087 [(set_attr "type" "multi")])
9090 [(set (match_operand:DWI 0 "register_operand")
9091 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9092 (match_operand:QI 2 "nonmemory_operand")))
9093 (clobber (reg:CC FLAGS_REG))]
9094 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9096 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9098 ;; By default we don't ask for a scratch register, because when DWImode
9099 ;; values are manipulated, registers are already at a premium. But if
9100 ;; we have one handy, we won't turn it away.
9103 [(match_scratch:DWIH 3 "r")
9104 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9106 (match_operand:<DWI> 1 "nonmemory_operand")
9107 (match_operand:QI 2 "nonmemory_operand")))
9108 (clobber (reg:CC FLAGS_REG))])
9112 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9114 (define_insn "x86_64_shld"
9115 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9116 (ior:DI (ashift:DI (match_dup 0)
9117 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9118 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9119 (minus:QI (const_int 64) (match_dup 2)))))
9120 (clobber (reg:CC FLAGS_REG))]
9122 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9123 [(set_attr "type" "ishift")
9124 (set_attr "prefix_0f" "1")
9125 (set_attr "mode" "DI")
9126 (set_attr "athlon_decode" "vector")
9127 (set_attr "amdfam10_decode" "vector")
9128 (set_attr "bdver1_decode" "vector")])
9130 (define_insn "x86_shld"
9131 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9132 (ior:SI (ashift:SI (match_dup 0)
9133 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9134 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9135 (minus:QI (const_int 32) (match_dup 2)))))
9136 (clobber (reg:CC FLAGS_REG))]
9138 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9139 [(set_attr "type" "ishift")
9140 (set_attr "prefix_0f" "1")
9141 (set_attr "mode" "SI")
9142 (set_attr "pent_pair" "np")
9143 (set_attr "athlon_decode" "vector")
9144 (set_attr "amdfam10_decode" "vector")
9145 (set_attr "bdver1_decode" "vector")])
9147 (define_expand "x86_shift<mode>_adj_1"
9148 [(set (reg:CCZ FLAGS_REG)
9149 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9152 (set (match_operand:SWI48 0 "register_operand")
9153 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9154 (match_operand:SWI48 1 "register_operand")
9157 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9158 (match_operand:SWI48 3 "register_operand")
9161 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9163 (define_expand "x86_shift<mode>_adj_2"
9164 [(use (match_operand:SWI48 0 "register_operand"))
9165 (use (match_operand:SWI48 1 "register_operand"))
9166 (use (match_operand:QI 2 "register_operand"))]
9169 rtx label = gen_label_rtx ();
9172 emit_insn (gen_testqi_ccz_1 (operands[2],
9173 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9175 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9176 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9177 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9178 gen_rtx_LABEL_REF (VOIDmode, label),
9180 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9181 JUMP_LABEL (tmp) = label;
9183 emit_move_insn (operands[0], operands[1]);
9184 ix86_expand_clear (operands[1]);
9187 LABEL_NUSES (label) = 1;
9192 ;; Avoid useless masking of count operand.
9193 (define_insn_and_split "*ashl<mode>3_mask"
9194 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9196 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9199 (match_operand:SI 2 "nonimmediate_operand" "c")
9200 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9201 (clobber (reg:CC FLAGS_REG))]
9202 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9203 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9204 == GET_MODE_BITSIZE (<MODE>mode)-1"
9207 [(parallel [(set (match_dup 0)
9208 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9209 (clobber (reg:CC FLAGS_REG))])]
9211 if (can_create_pseudo_p ())
9212 operands [2] = force_reg (SImode, operands[2]);
9214 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9216 [(set_attr "type" "ishift")
9217 (set_attr "mode" "<MODE>")])
9219 (define_insn "*bmi2_ashl<mode>3_1"
9220 [(set (match_operand:SWI48 0 "register_operand" "=r")
9221 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9222 (match_operand:SWI48 2 "register_operand" "r")))]
9224 "shlx\t{%2, %1, %0|%0, %1, %2}"
9225 [(set_attr "type" "ishiftx")
9226 (set_attr "mode" "<MODE>")])
9228 (define_insn "*ashl<mode>3_1"
9229 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9230 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9231 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9232 (clobber (reg:CC FLAGS_REG))]
9233 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9235 switch (get_attr_type (insn))
9242 gcc_assert (operands[2] == const1_rtx);
9243 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9244 return "add{<imodesuffix>}\t%0, %0";
9247 if (operands[2] == const1_rtx
9248 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9249 return "sal{<imodesuffix>}\t%0";
9251 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9254 [(set_attr "isa" "*,*,bmi2")
9256 (cond [(eq_attr "alternative" "1")
9257 (const_string "lea")
9258 (eq_attr "alternative" "2")
9259 (const_string "ishiftx")
9260 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9261 (match_operand 0 "register_operand"))
9262 (match_operand 2 "const1_operand"))
9263 (const_string "alu")
9265 (const_string "ishift")))
9266 (set (attr "length_immediate")
9268 (ior (eq_attr "type" "alu")
9269 (and (eq_attr "type" "ishift")
9270 (and (match_operand 2 "const1_operand")
9271 (ior (match_test "TARGET_SHIFT1")
9272 (match_test "optimize_function_for_size_p (cfun)")))))
9274 (const_string "*")))
9275 (set_attr "mode" "<MODE>")])
9277 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9279 [(set (match_operand:SWI48 0 "register_operand")
9280 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9281 (match_operand:QI 2 "register_operand")))
9282 (clobber (reg:CC FLAGS_REG))]
9283 "TARGET_BMI2 && reload_completed"
9285 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9286 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9288 (define_insn "*bmi2_ashlsi3_1_zext"
9289 [(set (match_operand:DI 0 "register_operand" "=r")
9291 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9292 (match_operand:SI 2 "register_operand" "r"))))]
9293 "TARGET_64BIT && TARGET_BMI2"
9294 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9295 [(set_attr "type" "ishiftx")
9296 (set_attr "mode" "SI")])
9298 (define_insn "*ashlsi3_1_zext"
9299 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9301 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9302 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9303 (clobber (reg:CC FLAGS_REG))]
9304 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9306 switch (get_attr_type (insn))
9313 gcc_assert (operands[2] == const1_rtx);
9314 return "add{l}\t%k0, %k0";
9317 if (operands[2] == const1_rtx
9318 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9319 return "sal{l}\t%k0";
9321 return "sal{l}\t{%2, %k0|%k0, %2}";
9324 [(set_attr "isa" "*,*,bmi2")
9326 (cond [(eq_attr "alternative" "1")
9327 (const_string "lea")
9328 (eq_attr "alternative" "2")
9329 (const_string "ishiftx")
9330 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9331 (match_operand 2 "const1_operand"))
9332 (const_string "alu")
9334 (const_string "ishift")))
9335 (set (attr "length_immediate")
9337 (ior (eq_attr "type" "alu")
9338 (and (eq_attr "type" "ishift")
9339 (and (match_operand 2 "const1_operand")
9340 (ior (match_test "TARGET_SHIFT1")
9341 (match_test "optimize_function_for_size_p (cfun)")))))
9343 (const_string "*")))
9344 (set_attr "mode" "SI")])
9346 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9348 [(set (match_operand:DI 0 "register_operand")
9350 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9351 (match_operand:QI 2 "register_operand"))))
9352 (clobber (reg:CC FLAGS_REG))]
9353 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9355 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9356 "operands[2] = gen_lowpart (SImode, operands[2]);")
9358 (define_insn "*ashlhi3_1"
9359 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9360 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9361 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9362 (clobber (reg:CC FLAGS_REG))]
9363 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9365 switch (get_attr_type (insn))
9371 gcc_assert (operands[2] == const1_rtx);
9372 return "add{w}\t%0, %0";
9375 if (operands[2] == const1_rtx
9376 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9377 return "sal{w}\t%0";
9379 return "sal{w}\t{%2, %0|%0, %2}";
9383 (cond [(eq_attr "alternative" "1")
9384 (const_string "lea")
9385 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9386 (match_operand 0 "register_operand"))
9387 (match_operand 2 "const1_operand"))
9388 (const_string "alu")
9390 (const_string "ishift")))
9391 (set (attr "length_immediate")
9393 (ior (eq_attr "type" "alu")
9394 (and (eq_attr "type" "ishift")
9395 (and (match_operand 2 "const1_operand")
9396 (ior (match_test "TARGET_SHIFT1")
9397 (match_test "optimize_function_for_size_p (cfun)")))))
9399 (const_string "*")))
9400 (set_attr "mode" "HI,SI")])
9402 ;; %%% Potential partial reg stall on alternative 1. What to do?
9403 (define_insn "*ashlqi3_1"
9404 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9405 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9406 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9407 (clobber (reg:CC FLAGS_REG))]
9408 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9410 switch (get_attr_type (insn))
9416 gcc_assert (operands[2] == const1_rtx);
9417 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9418 return "add{l}\t%k0, %k0";
9420 return "add{b}\t%0, %0";
9423 if (operands[2] == const1_rtx
9424 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9426 if (get_attr_mode (insn) == MODE_SI)
9427 return "sal{l}\t%k0";
9429 return "sal{b}\t%0";
9433 if (get_attr_mode (insn) == MODE_SI)
9434 return "sal{l}\t{%2, %k0|%k0, %2}";
9436 return "sal{b}\t{%2, %0|%0, %2}";
9441 (cond [(eq_attr "alternative" "2")
9442 (const_string "lea")
9443 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9444 (match_operand 0 "register_operand"))
9445 (match_operand 2 "const1_operand"))
9446 (const_string "alu")
9448 (const_string "ishift")))
9449 (set (attr "length_immediate")
9451 (ior (eq_attr "type" "alu")
9452 (and (eq_attr "type" "ishift")
9453 (and (match_operand 2 "const1_operand")
9454 (ior (match_test "TARGET_SHIFT1")
9455 (match_test "optimize_function_for_size_p (cfun)")))))
9457 (const_string "*")))
9458 (set_attr "mode" "QI,SI,SI")])
9460 (define_insn "*ashlqi3_1_slp"
9461 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9462 (ashift:QI (match_dup 0)
9463 (match_operand:QI 1 "nonmemory_operand" "cI")))
9464 (clobber (reg:CC FLAGS_REG))]
9465 "(optimize_function_for_size_p (cfun)
9466 || !TARGET_PARTIAL_FLAG_REG_STALL
9467 || (operands[1] == const1_rtx
9469 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9471 switch (get_attr_type (insn))
9474 gcc_assert (operands[1] == const1_rtx);
9475 return "add{b}\t%0, %0";
9478 if (operands[1] == const1_rtx
9479 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9480 return "sal{b}\t%0";
9482 return "sal{b}\t{%1, %0|%0, %1}";
9486 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9487 (match_operand 0 "register_operand"))
9488 (match_operand 1 "const1_operand"))
9489 (const_string "alu")
9491 (const_string "ishift1")))
9492 (set (attr "length_immediate")
9494 (ior (eq_attr "type" "alu")
9495 (and (eq_attr "type" "ishift1")
9496 (and (match_operand 1 "const1_operand")
9497 (ior (match_test "TARGET_SHIFT1")
9498 (match_test "optimize_function_for_size_p (cfun)")))))
9500 (const_string "*")))
9501 (set_attr "mode" "QI")])
9503 ;; Convert ashift to the lea pattern to avoid flags dependency.
9505 [(set (match_operand 0 "register_operand")
9506 (ashift (match_operand 1 "index_register_operand")
9507 (match_operand:QI 2 "const_int_operand")))
9508 (clobber (reg:CC FLAGS_REG))]
9509 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9511 && true_regnum (operands[0]) != true_regnum (operands[1])"
9514 enum machine_mode mode = GET_MODE (operands[0]);
9517 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9520 operands[0] = gen_lowpart (mode, operands[0]);
9521 operands[1] = gen_lowpart (mode, operands[1]);
9524 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9526 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9528 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9532 ;; Convert ashift to the lea pattern to avoid flags dependency.
9534 [(set (match_operand:DI 0 "register_operand")
9536 (ashift:SI (match_operand:SI 1 "index_register_operand")
9537 (match_operand:QI 2 "const_int_operand"))))
9538 (clobber (reg:CC FLAGS_REG))]
9539 "TARGET_64BIT && reload_completed
9540 && true_regnum (operands[0]) != true_regnum (operands[1])"
9542 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9544 operands[1] = gen_lowpart (DImode, operands[1]);
9545 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9548 ;; This pattern can't accept a variable shift count, since shifts by
9549 ;; zero don't affect the flags. We assume that shifts by constant
9550 ;; zero are optimized away.
9551 (define_insn "*ashl<mode>3_cmp"
9552 [(set (reg FLAGS_REG)
9554 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9555 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9557 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9558 (ashift:SWI (match_dup 1) (match_dup 2)))]
9559 "(optimize_function_for_size_p (cfun)
9560 || !TARGET_PARTIAL_FLAG_REG_STALL
9561 || (operands[2] == const1_rtx
9563 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9564 && ix86_match_ccmode (insn, CCGOCmode)
9565 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9567 switch (get_attr_type (insn))
9570 gcc_assert (operands[2] == const1_rtx);
9571 return "add{<imodesuffix>}\t%0, %0";
9574 if (operands[2] == const1_rtx
9575 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9576 return "sal{<imodesuffix>}\t%0";
9578 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9582 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9583 (match_operand 0 "register_operand"))
9584 (match_operand 2 "const1_operand"))
9585 (const_string "alu")
9587 (const_string "ishift")))
9588 (set (attr "length_immediate")
9590 (ior (eq_attr "type" "alu")
9591 (and (eq_attr "type" "ishift")
9592 (and (match_operand 2 "const1_operand")
9593 (ior (match_test "TARGET_SHIFT1")
9594 (match_test "optimize_function_for_size_p (cfun)")))))
9596 (const_string "*")))
9597 (set_attr "mode" "<MODE>")])
9599 (define_insn "*ashlsi3_cmp_zext"
9600 [(set (reg FLAGS_REG)
9602 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9603 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9605 (set (match_operand:DI 0 "register_operand" "=r")
9606 (zero_extend:DI (ashift:SI (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)))
9613 && ix86_match_ccmode (insn, CCGOCmode)
9614 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9616 switch (get_attr_type (insn))
9619 gcc_assert (operands[2] == const1_rtx);
9620 return "add{l}\t%k0, %k0";
9623 if (operands[2] == const1_rtx
9624 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9625 return "sal{l}\t%k0";
9627 return "sal{l}\t{%2, %k0|%k0, %2}";
9631 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9632 (match_operand 2 "const1_operand"))
9633 (const_string "alu")
9635 (const_string "ishift")))
9636 (set (attr "length_immediate")
9638 (ior (eq_attr "type" "alu")
9639 (and (eq_attr "type" "ishift")
9640 (and (match_operand 2 "const1_operand")
9641 (ior (match_test "TARGET_SHIFT1")
9642 (match_test "optimize_function_for_size_p (cfun)")))))
9644 (const_string "*")))
9645 (set_attr "mode" "SI")])
9647 (define_insn "*ashl<mode>3_cconly"
9648 [(set (reg FLAGS_REG)
9650 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9651 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9653 (clobber (match_scratch:SWI 0 "=<r>"))]
9654 "(optimize_function_for_size_p (cfun)
9655 || !TARGET_PARTIAL_FLAG_REG_STALL
9656 || (operands[2] == const1_rtx
9658 || TARGET_DOUBLE_WITH_ADD)))
9659 && ix86_match_ccmode (insn, CCGOCmode)"
9661 switch (get_attr_type (insn))
9664 gcc_assert (operands[2] == const1_rtx);
9665 return "add{<imodesuffix>}\t%0, %0";
9668 if (operands[2] == const1_rtx
9669 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9670 return "sal{<imodesuffix>}\t%0";
9672 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9676 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9677 (match_operand 0 "register_operand"))
9678 (match_operand 2 "const1_operand"))
9679 (const_string "alu")
9681 (const_string "ishift")))
9682 (set (attr "length_immediate")
9684 (ior (eq_attr "type" "alu")
9685 (and (eq_attr "type" "ishift")
9686 (and (match_operand 2 "const1_operand")
9687 (ior (match_test "TARGET_SHIFT1")
9688 (match_test "optimize_function_for_size_p (cfun)")))))
9690 (const_string "*")))
9691 (set_attr "mode" "<MODE>")])
9693 ;; See comment above `ashl<mode>3' about how this works.
9695 (define_expand "<shift_insn><mode>3"
9696 [(set (match_operand:SDWIM 0 "<shift_operand>")
9697 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9698 (match_operand:QI 2 "nonmemory_operand")))]
9700 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9702 ;; Avoid useless masking of count operand.
9703 (define_insn_and_split "*<shift_insn><mode>3_mask"
9704 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9706 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9709 (match_operand:SI 2 "nonimmediate_operand" "c")
9710 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9711 (clobber (reg:CC FLAGS_REG))]
9712 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9713 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9714 == GET_MODE_BITSIZE (<MODE>mode)-1"
9717 [(parallel [(set (match_dup 0)
9718 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9719 (clobber (reg:CC FLAGS_REG))])]
9721 if (can_create_pseudo_p ())
9722 operands [2] = force_reg (SImode, operands[2]);
9724 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9726 [(set_attr "type" "ishift")
9727 (set_attr "mode" "<MODE>")])
9729 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9730 [(set (match_operand:DWI 0 "register_operand" "=r")
9731 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9732 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9733 (clobber (reg:CC FLAGS_REG))]
9736 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9738 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9739 [(set_attr "type" "multi")])
9741 ;; By default we don't ask for a scratch register, because when DWImode
9742 ;; values are manipulated, registers are already at a premium. But if
9743 ;; we have one handy, we won't turn it away.
9746 [(match_scratch:DWIH 3 "r")
9747 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9749 (match_operand:<DWI> 1 "register_operand")
9750 (match_operand:QI 2 "nonmemory_operand")))
9751 (clobber (reg:CC FLAGS_REG))])
9755 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9757 (define_insn "x86_64_shrd"
9758 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9759 (ior:DI (ashiftrt:DI (match_dup 0)
9760 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9761 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9762 (minus:QI (const_int 64) (match_dup 2)))))
9763 (clobber (reg:CC FLAGS_REG))]
9765 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9766 [(set_attr "type" "ishift")
9767 (set_attr "prefix_0f" "1")
9768 (set_attr "mode" "DI")
9769 (set_attr "athlon_decode" "vector")
9770 (set_attr "amdfam10_decode" "vector")
9771 (set_attr "bdver1_decode" "vector")])
9773 (define_insn "x86_shrd"
9774 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9775 (ior:SI (ashiftrt:SI (match_dup 0)
9776 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9777 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9778 (minus:QI (const_int 32) (match_dup 2)))))
9779 (clobber (reg:CC FLAGS_REG))]
9781 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9782 [(set_attr "type" "ishift")
9783 (set_attr "prefix_0f" "1")
9784 (set_attr "mode" "SI")
9785 (set_attr "pent_pair" "np")
9786 (set_attr "athlon_decode" "vector")
9787 (set_attr "amdfam10_decode" "vector")
9788 (set_attr "bdver1_decode" "vector")])
9790 (define_insn "ashrdi3_cvt"
9791 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9792 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9793 (match_operand:QI 2 "const_int_operand")))
9794 (clobber (reg:CC FLAGS_REG))]
9795 "TARGET_64BIT && INTVAL (operands[2]) == 63
9796 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9797 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9800 sar{q}\t{%2, %0|%0, %2}"
9801 [(set_attr "type" "imovx,ishift")
9802 (set_attr "prefix_0f" "0,*")
9803 (set_attr "length_immediate" "0,*")
9804 (set_attr "modrm" "0,1")
9805 (set_attr "mode" "DI")])
9807 (define_insn "ashrsi3_cvt"
9808 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9809 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9810 (match_operand:QI 2 "const_int_operand")))
9811 (clobber (reg:CC FLAGS_REG))]
9812 "INTVAL (operands[2]) == 31
9813 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9814 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9817 sar{l}\t{%2, %0|%0, %2}"
9818 [(set_attr "type" "imovx,ishift")
9819 (set_attr "prefix_0f" "0,*")
9820 (set_attr "length_immediate" "0,*")
9821 (set_attr "modrm" "0,1")
9822 (set_attr "mode" "SI")])
9824 (define_insn "*ashrsi3_cvt_zext"
9825 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9827 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9828 (match_operand:QI 2 "const_int_operand"))))
9829 (clobber (reg:CC FLAGS_REG))]
9830 "TARGET_64BIT && INTVAL (operands[2]) == 31
9831 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9832 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9835 sar{l}\t{%2, %k0|%k0, %2}"
9836 [(set_attr "type" "imovx,ishift")
9837 (set_attr "prefix_0f" "0,*")
9838 (set_attr "length_immediate" "0,*")
9839 (set_attr "modrm" "0,1")
9840 (set_attr "mode" "SI")])
9842 (define_expand "x86_shift<mode>_adj_3"
9843 [(use (match_operand:SWI48 0 "register_operand"))
9844 (use (match_operand:SWI48 1 "register_operand"))
9845 (use (match_operand:QI 2 "register_operand"))]
9848 rtx label = gen_label_rtx ();
9851 emit_insn (gen_testqi_ccz_1 (operands[2],
9852 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9854 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9855 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9856 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9857 gen_rtx_LABEL_REF (VOIDmode, label),
9859 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9860 JUMP_LABEL (tmp) = label;
9862 emit_move_insn (operands[0], operands[1]);
9863 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9864 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9866 LABEL_NUSES (label) = 1;
9871 (define_insn "*bmi2_<shift_insn><mode>3_1"
9872 [(set (match_operand:SWI48 0 "register_operand" "=r")
9873 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9874 (match_operand:SWI48 2 "register_operand" "r")))]
9876 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9877 [(set_attr "type" "ishiftx")
9878 (set_attr "mode" "<MODE>")])
9880 (define_insn "*<shift_insn><mode>3_1"
9881 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9883 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9884 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9885 (clobber (reg:CC FLAGS_REG))]
9886 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9888 switch (get_attr_type (insn))
9894 if (operands[2] == const1_rtx
9895 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9896 return "<shift>{<imodesuffix>}\t%0";
9898 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9901 [(set_attr "isa" "*,bmi2")
9902 (set_attr "type" "ishift,ishiftx")
9903 (set (attr "length_immediate")
9905 (and (match_operand 2 "const1_operand")
9906 (ior (match_test "TARGET_SHIFT1")
9907 (match_test "optimize_function_for_size_p (cfun)")))
9909 (const_string "*")))
9910 (set_attr "mode" "<MODE>")])
9912 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9914 [(set (match_operand:SWI48 0 "register_operand")
9915 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9916 (match_operand:QI 2 "register_operand")))
9917 (clobber (reg:CC FLAGS_REG))]
9918 "TARGET_BMI2 && reload_completed"
9920 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9921 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9923 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9924 [(set (match_operand:DI 0 "register_operand" "=r")
9926 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9927 (match_operand:SI 2 "register_operand" "r"))))]
9928 "TARGET_64BIT && TARGET_BMI2"
9929 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9930 [(set_attr "type" "ishiftx")
9931 (set_attr "mode" "SI")])
9933 (define_insn "*<shift_insn>si3_1_zext"
9934 [(set (match_operand:DI 0 "register_operand" "=r,r")
9936 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9937 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9938 (clobber (reg:CC FLAGS_REG))]
9939 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9941 switch (get_attr_type (insn))
9947 if (operands[2] == const1_rtx
9948 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9949 return "<shift>{l}\t%k0";
9951 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9954 [(set_attr "isa" "*,bmi2")
9955 (set_attr "type" "ishift,ishiftx")
9956 (set (attr "length_immediate")
9958 (and (match_operand 2 "const1_operand")
9959 (ior (match_test "TARGET_SHIFT1")
9960 (match_test "optimize_function_for_size_p (cfun)")))
9962 (const_string "*")))
9963 (set_attr "mode" "SI")])
9965 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9967 [(set (match_operand:DI 0 "register_operand")
9969 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9970 (match_operand:QI 2 "register_operand"))))
9971 (clobber (reg:CC FLAGS_REG))]
9972 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9974 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9975 "operands[2] = gen_lowpart (SImode, operands[2]);")
9977 (define_insn "*<shift_insn><mode>3_1"
9978 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9980 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9981 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9982 (clobber (reg:CC FLAGS_REG))]
9983 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9985 if (operands[2] == const1_rtx
9986 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9987 return "<shift>{<imodesuffix>}\t%0";
9989 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9991 [(set_attr "type" "ishift")
9992 (set (attr "length_immediate")
9994 (and (match_operand 2 "const1_operand")
9995 (ior (match_test "TARGET_SHIFT1")
9996 (match_test "optimize_function_for_size_p (cfun)")))
9998 (const_string "*")))
9999 (set_attr "mode" "<MODE>")])
10001 (define_insn "*<shift_insn>qi3_1_slp"
10002 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10003 (any_shiftrt:QI (match_dup 0)
10004 (match_operand:QI 1 "nonmemory_operand" "cI")))
10005 (clobber (reg:CC FLAGS_REG))]
10006 "(optimize_function_for_size_p (cfun)
10007 || !TARGET_PARTIAL_REG_STALL
10008 || (operands[1] == const1_rtx
10009 && TARGET_SHIFT1))"
10011 if (operands[1] == const1_rtx
10012 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10013 return "<shift>{b}\t%0";
10015 return "<shift>{b}\t{%1, %0|%0, %1}";
10017 [(set_attr "type" "ishift1")
10018 (set (attr "length_immediate")
10020 (and (match_operand 1 "const1_operand")
10021 (ior (match_test "TARGET_SHIFT1")
10022 (match_test "optimize_function_for_size_p (cfun)")))
10024 (const_string "*")))
10025 (set_attr "mode" "QI")])
10027 ;; This pattern can't accept a variable shift count, since shifts by
10028 ;; zero don't affect the flags. We assume that shifts by constant
10029 ;; zero are optimized away.
10030 (define_insn "*<shift_insn><mode>3_cmp"
10031 [(set (reg FLAGS_REG)
10034 (match_operand:SWI 1 "nonimmediate_operand" "0")
10035 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10037 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10038 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10039 "(optimize_function_for_size_p (cfun)
10040 || !TARGET_PARTIAL_FLAG_REG_STALL
10041 || (operands[2] == const1_rtx
10043 && ix86_match_ccmode (insn, CCGOCmode)
10044 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10046 if (operands[2] == const1_rtx
10047 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10048 return "<shift>{<imodesuffix>}\t%0";
10050 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10052 [(set_attr "type" "ishift")
10053 (set (attr "length_immediate")
10055 (and (match_operand 2 "const1_operand")
10056 (ior (match_test "TARGET_SHIFT1")
10057 (match_test "optimize_function_for_size_p (cfun)")))
10059 (const_string "*")))
10060 (set_attr "mode" "<MODE>")])
10062 (define_insn "*<shift_insn>si3_cmp_zext"
10063 [(set (reg FLAGS_REG)
10065 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10066 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10068 (set (match_operand:DI 0 "register_operand" "=r")
10069 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10071 && (optimize_function_for_size_p (cfun)
10072 || !TARGET_PARTIAL_FLAG_REG_STALL
10073 || (operands[2] == const1_rtx
10075 && ix86_match_ccmode (insn, CCGOCmode)
10076 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10078 if (operands[2] == const1_rtx
10079 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10080 return "<shift>{l}\t%k0";
10082 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10084 [(set_attr "type" "ishift")
10085 (set (attr "length_immediate")
10087 (and (match_operand 2 "const1_operand")
10088 (ior (match_test "TARGET_SHIFT1")
10089 (match_test "optimize_function_for_size_p (cfun)")))
10091 (const_string "*")))
10092 (set_attr "mode" "SI")])
10094 (define_insn "*<shift_insn><mode>3_cconly"
10095 [(set (reg FLAGS_REG)
10098 (match_operand:SWI 1 "register_operand" "0")
10099 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10101 (clobber (match_scratch:SWI 0 "=<r>"))]
10102 "(optimize_function_for_size_p (cfun)
10103 || !TARGET_PARTIAL_FLAG_REG_STALL
10104 || (operands[2] == const1_rtx
10106 && ix86_match_ccmode (insn, CCGOCmode)"
10108 if (operands[2] == const1_rtx
10109 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10110 return "<shift>{<imodesuffix>}\t%0";
10112 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10114 [(set_attr "type" "ishift")
10115 (set (attr "length_immediate")
10117 (and (match_operand 2 "const1_operand")
10118 (ior (match_test "TARGET_SHIFT1")
10119 (match_test "optimize_function_for_size_p (cfun)")))
10121 (const_string "*")))
10122 (set_attr "mode" "<MODE>")])
10124 ;; Rotate instructions
10126 (define_expand "<rotate_insn>ti3"
10127 [(set (match_operand:TI 0 "register_operand")
10128 (any_rotate:TI (match_operand:TI 1 "register_operand")
10129 (match_operand:QI 2 "nonmemory_operand")))]
10132 if (const_1_to_63_operand (operands[2], VOIDmode))
10133 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10134 (operands[0], operands[1], operands[2]));
10141 (define_expand "<rotate_insn>di3"
10142 [(set (match_operand:DI 0 "shiftdi_operand")
10143 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10144 (match_operand:QI 2 "nonmemory_operand")))]
10148 ix86_expand_binary_operator (<CODE>, DImode, operands);
10149 else if (const_1_to_31_operand (operands[2], VOIDmode))
10150 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10151 (operands[0], operands[1], operands[2]));
10158 (define_expand "<rotate_insn><mode>3"
10159 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10160 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10161 (match_operand:QI 2 "nonmemory_operand")))]
10163 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10165 ;; Avoid useless masking of count operand.
10166 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10167 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10169 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10172 (match_operand:SI 2 "nonimmediate_operand" "c")
10173 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10174 (clobber (reg:CC FLAGS_REG))]
10175 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10176 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10177 == GET_MODE_BITSIZE (<MODE>mode)-1"
10180 [(parallel [(set (match_dup 0)
10181 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10182 (clobber (reg:CC FLAGS_REG))])]
10184 if (can_create_pseudo_p ())
10185 operands [2] = force_reg (SImode, operands[2]);
10187 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10189 [(set_attr "type" "rotate")
10190 (set_attr "mode" "<MODE>")])
10192 ;; Implement rotation using two double-precision
10193 ;; shift instructions and a scratch register.
10195 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10196 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10197 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10198 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10199 (clobber (reg:CC FLAGS_REG))
10200 (clobber (match_scratch:DWIH 3 "=&r"))]
10204 [(set (match_dup 3) (match_dup 4))
10206 [(set (match_dup 4)
10207 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10208 (lshiftrt:DWIH (match_dup 5)
10209 (minus:QI (match_dup 6) (match_dup 2)))))
10210 (clobber (reg:CC FLAGS_REG))])
10212 [(set (match_dup 5)
10213 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10214 (lshiftrt:DWIH (match_dup 3)
10215 (minus:QI (match_dup 6) (match_dup 2)))))
10216 (clobber (reg:CC FLAGS_REG))])]
10218 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10220 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10223 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10224 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10225 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10226 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10227 (clobber (reg:CC FLAGS_REG))
10228 (clobber (match_scratch:DWIH 3 "=&r"))]
10232 [(set (match_dup 3) (match_dup 4))
10234 [(set (match_dup 4)
10235 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10236 (ashift:DWIH (match_dup 5)
10237 (minus:QI (match_dup 6) (match_dup 2)))))
10238 (clobber (reg:CC FLAGS_REG))])
10240 [(set (match_dup 5)
10241 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10242 (ashift:DWIH (match_dup 3)
10243 (minus:QI (match_dup 6) (match_dup 2)))))
10244 (clobber (reg:CC FLAGS_REG))])]
10246 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10248 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10251 (define_insn "*bmi2_rorx<mode>3_1"
10252 [(set (match_operand:SWI48 0 "register_operand" "=r")
10253 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10254 (match_operand:QI 2 "immediate_operand" "<S>")))]
10256 "rorx\t{%2, %1, %0|%0, %1, %2}"
10257 [(set_attr "type" "rotatex")
10258 (set_attr "mode" "<MODE>")])
10260 (define_insn "*<rotate_insn><mode>3_1"
10261 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10263 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10264 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10265 (clobber (reg:CC FLAGS_REG))]
10266 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10268 switch (get_attr_type (insn))
10274 if (operands[2] == const1_rtx
10275 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10276 return "<rotate>{<imodesuffix>}\t%0";
10278 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10281 [(set_attr "isa" "*,bmi2")
10282 (set_attr "type" "rotate,rotatex")
10283 (set (attr "length_immediate")
10285 (and (eq_attr "type" "rotate")
10286 (and (match_operand 2 "const1_operand")
10287 (ior (match_test "TARGET_SHIFT1")
10288 (match_test "optimize_function_for_size_p (cfun)"))))
10290 (const_string "*")))
10291 (set_attr "mode" "<MODE>")])
10293 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10295 [(set (match_operand:SWI48 0 "register_operand")
10296 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10297 (match_operand:QI 2 "immediate_operand")))
10298 (clobber (reg:CC FLAGS_REG))]
10299 "TARGET_BMI2 && reload_completed"
10300 [(set (match_dup 0)
10301 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10304 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10308 [(set (match_operand:SWI48 0 "register_operand")
10309 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10310 (match_operand:QI 2 "immediate_operand")))
10311 (clobber (reg:CC FLAGS_REG))]
10312 "TARGET_BMI2 && reload_completed"
10313 [(set (match_dup 0)
10314 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10316 (define_insn "*bmi2_rorxsi3_1_zext"
10317 [(set (match_operand:DI 0 "register_operand" "=r")
10319 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10320 (match_operand:QI 2 "immediate_operand" "I"))))]
10321 "TARGET_64BIT && TARGET_BMI2"
10322 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10323 [(set_attr "type" "rotatex")
10324 (set_attr "mode" "SI")])
10326 (define_insn "*<rotate_insn>si3_1_zext"
10327 [(set (match_operand:DI 0 "register_operand" "=r,r")
10329 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10330 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10331 (clobber (reg:CC FLAGS_REG))]
10332 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10334 switch (get_attr_type (insn))
10340 if (operands[2] == const1_rtx
10341 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10342 return "<rotate>{l}\t%k0";
10344 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10347 [(set_attr "isa" "*,bmi2")
10348 (set_attr "type" "rotate,rotatex")
10349 (set (attr "length_immediate")
10351 (and (eq_attr "type" "rotate")
10352 (and (match_operand 2 "const1_operand")
10353 (ior (match_test "TARGET_SHIFT1")
10354 (match_test "optimize_function_for_size_p (cfun)"))))
10356 (const_string "*")))
10357 (set_attr "mode" "SI")])
10359 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10361 [(set (match_operand:DI 0 "register_operand")
10363 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10364 (match_operand:QI 2 "immediate_operand"))))
10365 (clobber (reg:CC FLAGS_REG))]
10366 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10367 [(set (match_dup 0)
10368 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10371 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10375 [(set (match_operand:DI 0 "register_operand")
10377 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10378 (match_operand:QI 2 "immediate_operand"))))
10379 (clobber (reg:CC FLAGS_REG))]
10380 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10381 [(set (match_dup 0)
10382 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10384 (define_insn "*<rotate_insn><mode>3_1"
10385 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10386 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10387 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10388 (clobber (reg:CC FLAGS_REG))]
10389 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10391 if (operands[2] == const1_rtx
10392 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10393 return "<rotate>{<imodesuffix>}\t%0";
10395 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10397 [(set_attr "type" "rotate")
10398 (set (attr "length_immediate")
10400 (and (match_operand 2 "const1_operand")
10401 (ior (match_test "TARGET_SHIFT1")
10402 (match_test "optimize_function_for_size_p (cfun)")))
10404 (const_string "*")))
10405 (set_attr "mode" "<MODE>")])
10407 (define_insn "*<rotate_insn>qi3_1_slp"
10408 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10409 (any_rotate:QI (match_dup 0)
10410 (match_operand:QI 1 "nonmemory_operand" "cI")))
10411 (clobber (reg:CC FLAGS_REG))]
10412 "(optimize_function_for_size_p (cfun)
10413 || !TARGET_PARTIAL_REG_STALL
10414 || (operands[1] == const1_rtx
10415 && TARGET_SHIFT1))"
10417 if (operands[1] == const1_rtx
10418 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10419 return "<rotate>{b}\t%0";
10421 return "<rotate>{b}\t{%1, %0|%0, %1}";
10423 [(set_attr "type" "rotate1")
10424 (set (attr "length_immediate")
10426 (and (match_operand 1 "const1_operand")
10427 (ior (match_test "TARGET_SHIFT1")
10428 (match_test "optimize_function_for_size_p (cfun)")))
10430 (const_string "*")))
10431 (set_attr "mode" "QI")])
10434 [(set (match_operand:HI 0 "register_operand")
10435 (any_rotate:HI (match_dup 0) (const_int 8)))
10436 (clobber (reg:CC FLAGS_REG))]
10438 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10439 [(parallel [(set (strict_low_part (match_dup 0))
10440 (bswap:HI (match_dup 0)))
10441 (clobber (reg:CC FLAGS_REG))])])
10443 ;; Bit set / bit test instructions
10445 (define_expand "extv"
10446 [(set (match_operand:SI 0 "register_operand")
10447 (sign_extract:SI (match_operand:SI 1 "register_operand")
10448 (match_operand:SI 2 "const8_operand")
10449 (match_operand:SI 3 "const8_operand")))]
10452 /* Handle extractions from %ah et al. */
10453 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10456 /* From mips.md: extract_bit_field doesn't verify that our source
10457 matches the predicate, so check it again here. */
10458 if (! ext_register_operand (operands[1], VOIDmode))
10462 (define_expand "extzv"
10463 [(set (match_operand:SI 0 "register_operand")
10464 (zero_extract:SI (match_operand 1 "ext_register_operand")
10465 (match_operand:SI 2 "const8_operand")
10466 (match_operand:SI 3 "const8_operand")))]
10469 /* Handle extractions from %ah et al. */
10470 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10473 /* From mips.md: extract_bit_field doesn't verify that our source
10474 matches the predicate, so check it again here. */
10475 if (! ext_register_operand (operands[1], VOIDmode))
10479 (define_expand "insv"
10480 [(set (zero_extract (match_operand 0 "register_operand")
10481 (match_operand 1 "const_int_operand")
10482 (match_operand 2 "const_int_operand"))
10483 (match_operand 3 "register_operand"))]
10486 rtx (*gen_mov_insv_1) (rtx, rtx);
10488 if (ix86_expand_pinsr (operands))
10491 /* Handle insertions to %ah et al. */
10492 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10495 /* From mips.md: insert_bit_field doesn't verify that our source
10496 matches the predicate, so check it again here. */
10497 if (! ext_register_operand (operands[0], VOIDmode))
10500 gen_mov_insv_1 = (TARGET_64BIT
10501 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10503 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10507 ;; %%% bts, btr, btc, bt.
10508 ;; In general these instructions are *slow* when applied to memory,
10509 ;; since they enforce atomic operation. When applied to registers,
10510 ;; it depends on the cpu implementation. They're never faster than
10511 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10512 ;; no point. But in 64-bit, we can't hold the relevant immediates
10513 ;; within the instruction itself, so operating on bits in the high
10514 ;; 32-bits of a register becomes easier.
10516 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10517 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10518 ;; negdf respectively, so they can never be disabled entirely.
10520 (define_insn "*btsq"
10521 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10523 (match_operand:DI 1 "const_0_to_63_operand"))
10525 (clobber (reg:CC FLAGS_REG))]
10526 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10527 "bts{q}\t{%1, %0|%0, %1}"
10528 [(set_attr "type" "alu1")
10529 (set_attr "prefix_0f" "1")
10530 (set_attr "mode" "DI")])
10532 (define_insn "*btrq"
10533 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10535 (match_operand:DI 1 "const_0_to_63_operand"))
10537 (clobber (reg:CC FLAGS_REG))]
10538 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10539 "btr{q}\t{%1, %0|%0, %1}"
10540 [(set_attr "type" "alu1")
10541 (set_attr "prefix_0f" "1")
10542 (set_attr "mode" "DI")])
10544 (define_insn "*btcq"
10545 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10547 (match_operand:DI 1 "const_0_to_63_operand"))
10548 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10549 (clobber (reg:CC FLAGS_REG))]
10550 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10551 "btc{q}\t{%1, %0|%0, %1}"
10552 [(set_attr "type" "alu1")
10553 (set_attr "prefix_0f" "1")
10554 (set_attr "mode" "DI")])
10556 ;; Allow Nocona to avoid these instructions if a register is available.
10559 [(match_scratch:DI 2 "r")
10560 (parallel [(set (zero_extract:DI
10561 (match_operand:DI 0 "register_operand")
10563 (match_operand:DI 1 "const_0_to_63_operand"))
10565 (clobber (reg:CC FLAGS_REG))])]
10566 "TARGET_64BIT && !TARGET_USE_BT"
10569 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10572 if (HOST_BITS_PER_WIDE_INT >= 64)
10573 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10574 else if (i < HOST_BITS_PER_WIDE_INT)
10575 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10577 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10579 op1 = immed_double_const (lo, hi, DImode);
10582 emit_move_insn (operands[2], op1);
10586 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10591 [(match_scratch:DI 2 "r")
10592 (parallel [(set (zero_extract:DI
10593 (match_operand:DI 0 "register_operand")
10595 (match_operand:DI 1 "const_0_to_63_operand"))
10597 (clobber (reg:CC FLAGS_REG))])]
10598 "TARGET_64BIT && !TARGET_USE_BT"
10601 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10604 if (HOST_BITS_PER_WIDE_INT >= 64)
10605 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10606 else if (i < HOST_BITS_PER_WIDE_INT)
10607 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10609 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10611 op1 = immed_double_const (~lo, ~hi, DImode);
10614 emit_move_insn (operands[2], op1);
10618 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10623 [(match_scratch:DI 2 "r")
10624 (parallel [(set (zero_extract:DI
10625 (match_operand:DI 0 "register_operand")
10627 (match_operand:DI 1 "const_0_to_63_operand"))
10628 (not:DI (zero_extract:DI
10629 (match_dup 0) (const_int 1) (match_dup 1))))
10630 (clobber (reg:CC FLAGS_REG))])]
10631 "TARGET_64BIT && !TARGET_USE_BT"
10634 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10637 if (HOST_BITS_PER_WIDE_INT >= 64)
10638 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10639 else if (i < HOST_BITS_PER_WIDE_INT)
10640 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10642 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10644 op1 = immed_double_const (lo, hi, DImode);
10647 emit_move_insn (operands[2], op1);
10651 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10655 (define_insn "*bt<mode>"
10656 [(set (reg:CCC FLAGS_REG)
10658 (zero_extract:SWI48
10659 (match_operand:SWI48 0 "register_operand" "r")
10661 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10663 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10664 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10665 [(set_attr "type" "alu1")
10666 (set_attr "prefix_0f" "1")
10667 (set_attr "mode" "<MODE>")])
10669 ;; Store-flag instructions.
10671 ;; For all sCOND expanders, also expand the compare or test insn that
10672 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10674 (define_insn_and_split "*setcc_di_1"
10675 [(set (match_operand:DI 0 "register_operand" "=q")
10676 (match_operator:DI 1 "ix86_comparison_operator"
10677 [(reg FLAGS_REG) (const_int 0)]))]
10678 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10680 "&& reload_completed"
10681 [(set (match_dup 2) (match_dup 1))
10682 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10684 PUT_MODE (operands[1], QImode);
10685 operands[2] = gen_lowpart (QImode, operands[0]);
10688 (define_insn_and_split "*setcc_si_1_and"
10689 [(set (match_operand:SI 0 "register_operand" "=q")
10690 (match_operator:SI 1 "ix86_comparison_operator"
10691 [(reg FLAGS_REG) (const_int 0)]))
10692 (clobber (reg:CC FLAGS_REG))]
10693 "!TARGET_PARTIAL_REG_STALL
10694 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10696 "&& reload_completed"
10697 [(set (match_dup 2) (match_dup 1))
10698 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10699 (clobber (reg:CC FLAGS_REG))])]
10701 PUT_MODE (operands[1], QImode);
10702 operands[2] = gen_lowpart (QImode, operands[0]);
10705 (define_insn_and_split "*setcc_si_1_movzbl"
10706 [(set (match_operand:SI 0 "register_operand" "=q")
10707 (match_operator:SI 1 "ix86_comparison_operator"
10708 [(reg FLAGS_REG) (const_int 0)]))]
10709 "!TARGET_PARTIAL_REG_STALL
10710 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10712 "&& reload_completed"
10713 [(set (match_dup 2) (match_dup 1))
10714 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10716 PUT_MODE (operands[1], QImode);
10717 operands[2] = gen_lowpart (QImode, operands[0]);
10720 (define_insn "*setcc_qi"
10721 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10722 (match_operator:QI 1 "ix86_comparison_operator"
10723 [(reg FLAGS_REG) (const_int 0)]))]
10726 [(set_attr "type" "setcc")
10727 (set_attr "mode" "QI")])
10729 (define_insn "*setcc_qi_slp"
10730 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10731 (match_operator:QI 1 "ix86_comparison_operator"
10732 [(reg FLAGS_REG) (const_int 0)]))]
10735 [(set_attr "type" "setcc")
10736 (set_attr "mode" "QI")])
10738 ;; In general it is not safe to assume too much about CCmode registers,
10739 ;; so simplify-rtx stops when it sees a second one. Under certain
10740 ;; conditions this is safe on x86, so help combine not create
10747 [(set (match_operand:QI 0 "nonimmediate_operand")
10748 (ne:QI (match_operator 1 "ix86_comparison_operator"
10749 [(reg FLAGS_REG) (const_int 0)])
10752 [(set (match_dup 0) (match_dup 1))]
10753 "PUT_MODE (operands[1], QImode);")
10756 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10757 (ne:QI (match_operator 1 "ix86_comparison_operator"
10758 [(reg FLAGS_REG) (const_int 0)])
10761 [(set (match_dup 0) (match_dup 1))]
10762 "PUT_MODE (operands[1], QImode);")
10765 [(set (match_operand:QI 0 "nonimmediate_operand")
10766 (eq:QI (match_operator 1 "ix86_comparison_operator"
10767 [(reg FLAGS_REG) (const_int 0)])
10770 [(set (match_dup 0) (match_dup 1))]
10772 rtx new_op1 = copy_rtx (operands[1]);
10773 operands[1] = new_op1;
10774 PUT_MODE (new_op1, QImode);
10775 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10776 GET_MODE (XEXP (new_op1, 0))));
10778 /* Make sure that (a) the CCmode we have for the flags is strong
10779 enough for the reversed compare or (b) we have a valid FP compare. */
10780 if (! ix86_comparison_operator (new_op1, VOIDmode))
10785 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10786 (eq:QI (match_operator 1 "ix86_comparison_operator"
10787 [(reg FLAGS_REG) (const_int 0)])
10790 [(set (match_dup 0) (match_dup 1))]
10792 rtx new_op1 = copy_rtx (operands[1]);
10793 operands[1] = new_op1;
10794 PUT_MODE (new_op1, QImode);
10795 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10796 GET_MODE (XEXP (new_op1, 0))));
10798 /* Make sure that (a) the CCmode we have for the flags is strong
10799 enough for the reversed compare or (b) we have a valid FP compare. */
10800 if (! ix86_comparison_operator (new_op1, VOIDmode))
10804 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10805 ;; subsequent logical operations are used to imitate conditional moves.
10806 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10809 (define_insn "setcc_<mode>_sse"
10810 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10811 (match_operator:MODEF 3 "sse_comparison_operator"
10812 [(match_operand:MODEF 1 "register_operand" "0,x")
10813 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10814 "SSE_FLOAT_MODE_P (<MODE>mode)"
10816 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10817 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10818 [(set_attr "isa" "noavx,avx")
10819 (set_attr "type" "ssecmp")
10820 (set_attr "length_immediate" "1")
10821 (set_attr "prefix" "orig,vex")
10822 (set_attr "mode" "<MODE>")])
10824 ;; Basic conditional jump instructions.
10825 ;; We ignore the overflow flag for signed branch instructions.
10827 (define_insn "*jcc_1"
10829 (if_then_else (match_operator 1 "ix86_comparison_operator"
10830 [(reg FLAGS_REG) (const_int 0)])
10831 (label_ref (match_operand 0))
10835 [(set_attr "type" "ibr")
10836 (set_attr "modrm" "0")
10837 (set (attr "length")
10838 (if_then_else (and (ge (minus (match_dup 0) (pc))
10840 (lt (minus (match_dup 0) (pc))
10845 (define_insn "*jcc_2"
10847 (if_then_else (match_operator 1 "ix86_comparison_operator"
10848 [(reg FLAGS_REG) (const_int 0)])
10850 (label_ref (match_operand 0))))]
10853 [(set_attr "type" "ibr")
10854 (set_attr "modrm" "0")
10855 (set (attr "length")
10856 (if_then_else (and (ge (minus (match_dup 0) (pc))
10858 (lt (minus (match_dup 0) (pc))
10863 ;; In general it is not safe to assume too much about CCmode registers,
10864 ;; so simplify-rtx stops when it sees a second one. Under certain
10865 ;; conditions this is safe on x86, so help combine not create
10873 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10874 [(reg FLAGS_REG) (const_int 0)])
10876 (label_ref (match_operand 1))
10880 (if_then_else (match_dup 0)
10881 (label_ref (match_dup 1))
10883 "PUT_MODE (operands[0], VOIDmode);")
10887 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10888 [(reg FLAGS_REG) (const_int 0)])
10890 (label_ref (match_operand 1))
10894 (if_then_else (match_dup 0)
10895 (label_ref (match_dup 1))
10898 rtx new_op0 = copy_rtx (operands[0]);
10899 operands[0] = new_op0;
10900 PUT_MODE (new_op0, VOIDmode);
10901 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10902 GET_MODE (XEXP (new_op0, 0))));
10904 /* Make sure that (a) the CCmode we have for the flags is strong
10905 enough for the reversed compare or (b) we have a valid FP compare. */
10906 if (! ix86_comparison_operator (new_op0, VOIDmode))
10910 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10911 ;; pass generates from shift insn with QImode operand. Actually, the mode
10912 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10913 ;; appropriate modulo of the bit offset value.
10915 (define_insn_and_split "*jcc_bt<mode>"
10917 (if_then_else (match_operator 0 "bt_comparison_operator"
10918 [(zero_extract:SWI48
10919 (match_operand:SWI48 1 "register_operand" "r")
10922 (match_operand:QI 2 "register_operand" "r")))
10924 (label_ref (match_operand 3))
10926 (clobber (reg:CC FLAGS_REG))]
10927 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10930 [(set (reg:CCC FLAGS_REG)
10932 (zero_extract:SWI48
10938 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10939 (label_ref (match_dup 3))
10942 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10944 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10947 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10948 ;; also for DImode, this is what combine produces.
10949 (define_insn_and_split "*jcc_bt<mode>_mask"
10951 (if_then_else (match_operator 0 "bt_comparison_operator"
10952 [(zero_extract:SWI48
10953 (match_operand:SWI48 1 "register_operand" "r")
10956 (match_operand:SI 2 "register_operand" "r")
10957 (match_operand:SI 3 "const_int_operand" "n")))])
10958 (label_ref (match_operand 4))
10960 (clobber (reg:CC FLAGS_REG))]
10961 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10962 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10963 == GET_MODE_BITSIZE (<MODE>mode)-1"
10966 [(set (reg:CCC FLAGS_REG)
10968 (zero_extract:SWI48
10974 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10975 (label_ref (match_dup 4))
10978 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10980 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10983 (define_insn_and_split "*jcc_btsi_1"
10985 (if_then_else (match_operator 0 "bt_comparison_operator"
10988 (match_operand:SI 1 "register_operand" "r")
10989 (match_operand:QI 2 "register_operand" "r"))
10992 (label_ref (match_operand 3))
10994 (clobber (reg:CC FLAGS_REG))]
10995 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10998 [(set (reg:CCC FLAGS_REG)
11006 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11007 (label_ref (match_dup 3))
11010 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11012 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11015 ;; avoid useless masking of bit offset operand
11016 (define_insn_and_split "*jcc_btsi_mask_1"
11019 (match_operator 0 "bt_comparison_operator"
11022 (match_operand:SI 1 "register_operand" "r")
11025 (match_operand:SI 2 "register_operand" "r")
11026 (match_operand:SI 3 "const_int_operand" "n")) 0))
11029 (label_ref (match_operand 4))
11031 (clobber (reg:CC FLAGS_REG))]
11032 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11033 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11036 [(set (reg:CCC FLAGS_REG)
11044 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11045 (label_ref (match_dup 4))
11047 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11049 ;; Define combination compare-and-branch fp compare instructions to help
11052 (define_insn "*fp_jcc_1_387"
11054 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11055 [(match_operand 1 "register_operand" "f")
11056 (match_operand 2 "nonimmediate_operand" "fm")])
11057 (label_ref (match_operand 3))
11059 (clobber (reg:CCFP FPSR_REG))
11060 (clobber (reg:CCFP FLAGS_REG))
11061 (clobber (match_scratch:HI 4 "=a"))]
11063 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11064 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11065 && SELECT_CC_MODE (GET_CODE (operands[0]),
11066 operands[1], operands[2]) == CCFPmode
11070 (define_insn "*fp_jcc_1r_387"
11072 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11073 [(match_operand 1 "register_operand" "f")
11074 (match_operand 2 "nonimmediate_operand" "fm")])
11076 (label_ref (match_operand 3))))
11077 (clobber (reg:CCFP FPSR_REG))
11078 (clobber (reg:CCFP FLAGS_REG))
11079 (clobber (match_scratch:HI 4 "=a"))]
11081 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11082 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11083 && SELECT_CC_MODE (GET_CODE (operands[0]),
11084 operands[1], operands[2]) == CCFPmode
11088 (define_insn "*fp_jcc_2_387"
11090 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11091 [(match_operand 1 "register_operand" "f")
11092 (match_operand 2 "register_operand" "f")])
11093 (label_ref (match_operand 3))
11095 (clobber (reg:CCFP FPSR_REG))
11096 (clobber (reg:CCFP FLAGS_REG))
11097 (clobber (match_scratch:HI 4 "=a"))]
11098 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11099 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11103 (define_insn "*fp_jcc_2r_387"
11105 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11106 [(match_operand 1 "register_operand" "f")
11107 (match_operand 2 "register_operand" "f")])
11109 (label_ref (match_operand 3))))
11110 (clobber (reg:CCFP FPSR_REG))
11111 (clobber (reg:CCFP FLAGS_REG))
11112 (clobber (match_scratch:HI 4 "=a"))]
11113 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11114 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11118 (define_insn "*fp_jcc_3_387"
11120 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11121 [(match_operand 1 "register_operand" "f")
11122 (match_operand 2 "const0_operand")])
11123 (label_ref (match_operand 3))
11125 (clobber (reg:CCFP FPSR_REG))
11126 (clobber (reg:CCFP FLAGS_REG))
11127 (clobber (match_scratch:HI 4 "=a"))]
11128 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11129 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11130 && SELECT_CC_MODE (GET_CODE (operands[0]),
11131 operands[1], operands[2]) == CCFPmode
11137 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11138 [(match_operand 1 "register_operand")
11139 (match_operand 2 "nonimmediate_operand")])
11141 (match_operand 4)))
11142 (clobber (reg:CCFP FPSR_REG))
11143 (clobber (reg:CCFP FLAGS_REG))]
11147 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11148 operands[3], operands[4], NULL_RTX, NULL_RTX);
11154 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11155 [(match_operand 1 "register_operand")
11156 (match_operand 2 "general_operand")])
11158 (match_operand 4)))
11159 (clobber (reg:CCFP FPSR_REG))
11160 (clobber (reg:CCFP FLAGS_REG))
11161 (clobber (match_scratch:HI 5 "=a"))]
11165 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11166 operands[3], operands[4], operands[5], NULL_RTX);
11170 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11171 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11172 ;; with a precedence over other operators and is always put in the first
11173 ;; place. Swap condition and operands to match ficom instruction.
11175 (define_insn "*fp_jcc_4_<mode>_387"
11178 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11179 [(match_operator 1 "float_operator"
11180 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11181 (match_operand 3 "register_operand" "f,f")])
11182 (label_ref (match_operand 4))
11184 (clobber (reg:CCFP FPSR_REG))
11185 (clobber (reg:CCFP FLAGS_REG))
11186 (clobber (match_scratch:HI 5 "=a,a"))]
11187 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11188 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11189 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11190 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11197 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11198 [(match_operator 1 "float_operator"
11199 [(match_operand:SWI24 2 "memory_operand")])
11200 (match_operand 3 "register_operand")])
11202 (match_operand 5)))
11203 (clobber (reg:CCFP FPSR_REG))
11204 (clobber (reg:CCFP FLAGS_REG))
11205 (clobber (match_scratch:HI 6 "=a"))]
11209 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11211 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11212 operands[3], operands[7],
11213 operands[4], operands[5], operands[6], NULL_RTX);
11217 ;; %%% Kill this when reload knows how to do it.
11221 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11222 [(match_operator 1 "float_operator"
11223 [(match_operand:SWI24 2 "register_operand")])
11224 (match_operand 3 "register_operand")])
11226 (match_operand 5)))
11227 (clobber (reg:CCFP FPSR_REG))
11228 (clobber (reg:CCFP FLAGS_REG))
11229 (clobber (match_scratch:HI 6 "=a"))]
11233 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11234 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11236 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11237 operands[3], operands[7],
11238 operands[4], operands[5], operands[6], operands[2]);
11242 ;; Unconditional and other jump instructions
11244 (define_insn "jump"
11246 (label_ref (match_operand 0)))]
11249 [(set_attr "type" "ibr")
11250 (set (attr "length")
11251 (if_then_else (and (ge (minus (match_dup 0) (pc))
11253 (lt (minus (match_dup 0) (pc))
11257 (set_attr "modrm" "0")])
11259 (define_expand "indirect_jump"
11260 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11264 operands[0] = convert_memory_address (word_mode, operands[0]);
11267 (define_insn "*indirect_jump"
11268 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11271 [(set_attr "type" "ibr")
11272 (set_attr "length_immediate" "0")])
11274 (define_expand "tablejump"
11275 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11276 (use (label_ref (match_operand 1)))])]
11279 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11280 relative. Convert the relative address to an absolute address. */
11284 enum rtx_code code;
11286 /* We can't use @GOTOFF for text labels on VxWorks;
11287 see gotoff_operand. */
11288 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11292 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11294 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11298 op1 = pic_offset_table_rtx;
11303 op0 = pic_offset_table_rtx;
11307 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11312 operands[0] = convert_memory_address (word_mode, operands[0]);
11315 (define_insn "*tablejump_1"
11316 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11317 (use (label_ref (match_operand 1)))]
11320 [(set_attr "type" "ibr")
11321 (set_attr "length_immediate" "0")])
11323 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11326 [(set (reg FLAGS_REG) (match_operand 0))
11327 (set (match_operand:QI 1 "register_operand")
11328 (match_operator:QI 2 "ix86_comparison_operator"
11329 [(reg FLAGS_REG) (const_int 0)]))
11330 (set (match_operand 3 "q_regs_operand")
11331 (zero_extend (match_dup 1)))]
11332 "(peep2_reg_dead_p (3, operands[1])
11333 || operands_match_p (operands[1], operands[3]))
11334 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11335 [(set (match_dup 4) (match_dup 0))
11336 (set (strict_low_part (match_dup 5))
11339 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11340 operands[5] = gen_lowpart (QImode, operands[3]);
11341 ix86_expand_clear (operands[3]);
11345 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11346 (match_operand 4)])
11347 (set (match_operand:QI 1 "register_operand")
11348 (match_operator:QI 2 "ix86_comparison_operator"
11349 [(reg FLAGS_REG) (const_int 0)]))
11350 (set (match_operand 3 "q_regs_operand")
11351 (zero_extend (match_dup 1)))]
11352 "(peep2_reg_dead_p (3, operands[1])
11353 || operands_match_p (operands[1], operands[3]))
11354 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11355 [(parallel [(set (match_dup 5) (match_dup 0))
11357 (set (strict_low_part (match_dup 6))
11360 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11361 operands[6] = gen_lowpart (QImode, operands[3]);
11362 ix86_expand_clear (operands[3]);
11365 ;; Similar, but match zero extend with andsi3.
11368 [(set (reg FLAGS_REG) (match_operand 0))
11369 (set (match_operand:QI 1 "register_operand")
11370 (match_operator:QI 2 "ix86_comparison_operator"
11371 [(reg FLAGS_REG) (const_int 0)]))
11372 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11373 (and:SI (match_dup 3) (const_int 255)))
11374 (clobber (reg:CC FLAGS_REG))])]
11375 "REGNO (operands[1]) == REGNO (operands[3])
11376 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11377 [(set (match_dup 4) (match_dup 0))
11378 (set (strict_low_part (match_dup 5))
11381 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11382 operands[5] = gen_lowpart (QImode, operands[3]);
11383 ix86_expand_clear (operands[3]);
11387 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11388 (match_operand 4)])
11389 (set (match_operand:QI 1 "register_operand")
11390 (match_operator:QI 2 "ix86_comparison_operator"
11391 [(reg FLAGS_REG) (const_int 0)]))
11392 (parallel [(set (match_operand 3 "q_regs_operand")
11393 (zero_extend (match_dup 1)))
11394 (clobber (reg:CC FLAGS_REG))])]
11395 "(peep2_reg_dead_p (3, operands[1])
11396 || operands_match_p (operands[1], operands[3]))
11397 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11398 [(parallel [(set (match_dup 5) (match_dup 0))
11400 (set (strict_low_part (match_dup 6))
11403 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11404 operands[6] = gen_lowpart (QImode, operands[3]);
11405 ix86_expand_clear (operands[3]);
11408 ;; Call instructions.
11410 ;; The predicates normally associated with named expanders are not properly
11411 ;; checked for calls. This is a bug in the generic code, but it isn't that
11412 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11414 ;; P6 processors will jump to the address after the decrement when %esp
11415 ;; is used as a call operand, so they will execute return address as a code.
11416 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11418 ;; Register constraint for call instruction.
11419 (define_mode_attr c [(SI "l") (DI "r")])
11421 ;; Call subroutine returning no value.
11423 (define_expand "call"
11424 [(call (match_operand:QI 0)
11426 (use (match_operand 2))]
11429 ix86_expand_call (NULL, operands[0], operands[1],
11430 operands[2], NULL, false);
11434 (define_expand "sibcall"
11435 [(call (match_operand:QI 0)
11437 (use (match_operand 2))]
11440 ix86_expand_call (NULL, operands[0], operands[1],
11441 operands[2], NULL, true);
11445 (define_insn_and_split "*call_vzeroupper"
11446 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11448 (unspec [(match_operand 2 "const_int_operand")]
11449 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11450 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11452 "&& reload_completed"
11454 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11455 [(set_attr "type" "call")])
11457 (define_insn "*call"
11458 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11459 (match_operand 1))]
11460 "!SIBLING_CALL_P (insn)"
11461 "* return ix86_output_call_insn (insn, operands[0]);"
11462 [(set_attr "type" "call")])
11464 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11465 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11467 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11468 (clobber (reg:TI XMM6_REG))
11469 (clobber (reg:TI XMM7_REG))
11470 (clobber (reg:TI XMM8_REG))
11471 (clobber (reg:TI XMM9_REG))
11472 (clobber (reg:TI XMM10_REG))
11473 (clobber (reg:TI XMM11_REG))
11474 (clobber (reg:TI XMM12_REG))
11475 (clobber (reg:TI XMM13_REG))
11476 (clobber (reg:TI XMM14_REG))
11477 (clobber (reg:TI XMM15_REG))
11478 (clobber (reg:DI SI_REG))
11479 (clobber (reg:DI DI_REG))
11480 (unspec [(match_operand 2 "const_int_operand")]
11481 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11482 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11484 "&& reload_completed"
11486 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11487 [(set_attr "type" "call")])
11489 (define_insn "*call_rex64_ms_sysv"
11490 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11492 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11493 (clobber (reg:TI XMM6_REG))
11494 (clobber (reg:TI XMM7_REG))
11495 (clobber (reg:TI XMM8_REG))
11496 (clobber (reg:TI XMM9_REG))
11497 (clobber (reg:TI XMM10_REG))
11498 (clobber (reg:TI XMM11_REG))
11499 (clobber (reg:TI XMM12_REG))
11500 (clobber (reg:TI XMM13_REG))
11501 (clobber (reg:TI XMM14_REG))
11502 (clobber (reg:TI XMM15_REG))
11503 (clobber (reg:DI SI_REG))
11504 (clobber (reg:DI DI_REG))]
11505 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11506 "* return ix86_output_call_insn (insn, operands[0]);"
11507 [(set_attr "type" "call")])
11509 (define_insn_and_split "*sibcall_vzeroupper"
11510 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11512 (unspec [(match_operand 2 "const_int_operand")]
11513 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11514 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11516 "&& reload_completed"
11518 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11519 [(set_attr "type" "call")])
11521 (define_insn "*sibcall"
11522 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11523 (match_operand 1))]
11524 "SIBLING_CALL_P (insn)"
11525 "* return ix86_output_call_insn (insn, operands[0]);"
11526 [(set_attr "type" "call")])
11528 (define_expand "call_pop"
11529 [(parallel [(call (match_operand:QI 0)
11530 (match_operand:SI 1))
11531 (set (reg:SI SP_REG)
11532 (plus:SI (reg:SI SP_REG)
11533 (match_operand:SI 3)))])]
11536 ix86_expand_call (NULL, operands[0], operands[1],
11537 operands[2], operands[3], false);
11541 (define_insn_and_split "*call_pop_vzeroupper"
11542 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11544 (set (reg:SI SP_REG)
11545 (plus:SI (reg:SI SP_REG)
11546 (match_operand:SI 2 "immediate_operand" "i")))
11547 (unspec [(match_operand 3 "const_int_operand")]
11548 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11549 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11551 "&& reload_completed"
11553 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11554 [(set_attr "type" "call")])
11556 (define_insn "*call_pop"
11557 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11559 (set (reg:SI SP_REG)
11560 (plus:SI (reg:SI SP_REG)
11561 (match_operand:SI 2 "immediate_operand" "i")))]
11562 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11563 "* return ix86_output_call_insn (insn, operands[0]);"
11564 [(set_attr "type" "call")])
11566 (define_insn_and_split "*sibcall_pop_vzeroupper"
11567 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11569 (set (reg:SI SP_REG)
11570 (plus:SI (reg:SI SP_REG)
11571 (match_operand:SI 2 "immediate_operand" "i")))
11572 (unspec [(match_operand 3 "const_int_operand")]
11573 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11574 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11576 "&& reload_completed"
11578 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11579 [(set_attr "type" "call")])
11581 (define_insn "*sibcall_pop"
11582 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11584 (set (reg:SI SP_REG)
11585 (plus:SI (reg:SI SP_REG)
11586 (match_operand:SI 2 "immediate_operand" "i")))]
11587 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11588 "* return ix86_output_call_insn (insn, operands[0]);"
11589 [(set_attr "type" "call")])
11591 ;; Call subroutine, returning value in operand 0
11593 (define_expand "call_value"
11594 [(set (match_operand 0)
11595 (call (match_operand:QI 1)
11596 (match_operand 2)))
11597 (use (match_operand 3))]
11600 ix86_expand_call (operands[0], operands[1], operands[2],
11601 operands[3], NULL, false);
11605 (define_expand "sibcall_value"
11606 [(set (match_operand 0)
11607 (call (match_operand:QI 1)
11608 (match_operand 2)))
11609 (use (match_operand 3))]
11612 ix86_expand_call (operands[0], operands[1], operands[2],
11613 operands[3], NULL, true);
11617 (define_insn_and_split "*call_value_vzeroupper"
11618 [(set (match_operand 0)
11619 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11620 (match_operand 2)))
11621 (unspec [(match_operand 3 "const_int_operand")]
11622 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11623 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11625 "&& reload_completed"
11627 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11628 [(set_attr "type" "callv")])
11630 (define_insn "*call_value"
11631 [(set (match_operand 0)
11632 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11633 (match_operand 2)))]
11634 "!SIBLING_CALL_P (insn)"
11635 "* return ix86_output_call_insn (insn, operands[1]);"
11636 [(set_attr "type" "callv")])
11638 (define_insn_and_split "*sibcall_value_vzeroupper"
11639 [(set (match_operand 0)
11640 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11641 (match_operand 2)))
11642 (unspec [(match_operand 3 "const_int_operand")]
11643 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11644 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11646 "&& reload_completed"
11648 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11649 [(set_attr "type" "callv")])
11651 (define_insn "*sibcall_value"
11652 [(set (match_operand 0)
11653 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11654 (match_operand 2)))]
11655 "SIBLING_CALL_P (insn)"
11656 "* return ix86_output_call_insn (insn, operands[1]);"
11657 [(set_attr "type" "callv")])
11659 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11660 [(set (match_operand 0)
11661 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11662 (match_operand 2)))
11663 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11664 (clobber (reg:TI XMM6_REG))
11665 (clobber (reg:TI XMM7_REG))
11666 (clobber (reg:TI XMM8_REG))
11667 (clobber (reg:TI XMM9_REG))
11668 (clobber (reg:TI XMM10_REG))
11669 (clobber (reg:TI XMM11_REG))
11670 (clobber (reg:TI XMM12_REG))
11671 (clobber (reg:TI XMM13_REG))
11672 (clobber (reg:TI XMM14_REG))
11673 (clobber (reg:TI XMM15_REG))
11674 (clobber (reg:DI SI_REG))
11675 (clobber (reg:DI DI_REG))
11676 (unspec [(match_operand 3 "const_int_operand")]
11677 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11678 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11680 "&& reload_completed"
11682 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11683 [(set_attr "type" "callv")])
11685 (define_insn "*call_value_rex64_ms_sysv"
11686 [(set (match_operand 0)
11687 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11688 (match_operand 2)))
11689 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11690 (clobber (reg:TI XMM6_REG))
11691 (clobber (reg:TI XMM7_REG))
11692 (clobber (reg:TI XMM8_REG))
11693 (clobber (reg:TI XMM9_REG))
11694 (clobber (reg:TI XMM10_REG))
11695 (clobber (reg:TI XMM11_REG))
11696 (clobber (reg:TI XMM12_REG))
11697 (clobber (reg:TI XMM13_REG))
11698 (clobber (reg:TI XMM14_REG))
11699 (clobber (reg:TI XMM15_REG))
11700 (clobber (reg:DI SI_REG))
11701 (clobber (reg:DI DI_REG))]
11702 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11703 "* return ix86_output_call_insn (insn, operands[1]);"
11704 [(set_attr "type" "callv")])
11706 (define_expand "call_value_pop"
11707 [(parallel [(set (match_operand 0)
11708 (call (match_operand:QI 1)
11709 (match_operand:SI 2)))
11710 (set (reg:SI SP_REG)
11711 (plus:SI (reg:SI SP_REG)
11712 (match_operand:SI 4)))])]
11715 ix86_expand_call (operands[0], operands[1], operands[2],
11716 operands[3], operands[4], false);
11720 (define_insn_and_split "*call_value_pop_vzeroupper"
11721 [(set (match_operand 0)
11722 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11723 (match_operand 2)))
11724 (set (reg:SI SP_REG)
11725 (plus:SI (reg:SI SP_REG)
11726 (match_operand:SI 3 "immediate_operand" "i")))
11727 (unspec [(match_operand 4 "const_int_operand")]
11728 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11729 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11731 "&& reload_completed"
11733 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11734 [(set_attr "type" "callv")])
11736 (define_insn "*call_value_pop"
11737 [(set (match_operand 0)
11738 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11739 (match_operand 2)))
11740 (set (reg:SI SP_REG)
11741 (plus:SI (reg:SI SP_REG)
11742 (match_operand:SI 3 "immediate_operand" "i")))]
11743 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11744 "* return ix86_output_call_insn (insn, operands[1]);"
11745 [(set_attr "type" "callv")])
11747 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11748 [(set (match_operand 0)
11749 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11750 (match_operand 2)))
11751 (set (reg:SI SP_REG)
11752 (plus:SI (reg:SI SP_REG)
11753 (match_operand:SI 3 "immediate_operand" "i")))
11754 (unspec [(match_operand 4 "const_int_operand")]
11755 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11756 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11758 "&& reload_completed"
11760 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11761 [(set_attr "type" "callv")])
11763 (define_insn "*sibcall_value_pop"
11764 [(set (match_operand 0)
11765 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11766 (match_operand 2)))
11767 (set (reg:SI SP_REG)
11768 (plus:SI (reg:SI SP_REG)
11769 (match_operand:SI 3 "immediate_operand" "i")))]
11770 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11771 "* return ix86_output_call_insn (insn, operands[1]);"
11772 [(set_attr "type" "callv")])
11774 ;; Call subroutine returning any type.
11776 (define_expand "untyped_call"
11777 [(parallel [(call (match_operand 0)
11780 (match_operand 2)])]
11785 /* In order to give reg-stack an easier job in validating two
11786 coprocessor registers as containing a possible return value,
11787 simply pretend the untyped call returns a complex long double
11790 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11791 and should have the default ABI. */
11793 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11794 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11795 operands[0], const0_rtx,
11796 GEN_INT ((TARGET_64BIT
11797 ? (ix86_abi == SYSV_ABI
11798 ? X86_64_SSE_REGPARM_MAX
11799 : X86_64_MS_SSE_REGPARM_MAX)
11800 : X86_32_SSE_REGPARM_MAX)
11804 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11806 rtx set = XVECEXP (operands[2], 0, i);
11807 emit_move_insn (SET_DEST (set), SET_SRC (set));
11810 /* The optimizer does not know that the call sets the function value
11811 registers we stored in the result block. We avoid problems by
11812 claiming that all hard registers are used and clobbered at this
11814 emit_insn (gen_blockage ());
11819 ;; Prologue and epilogue instructions
11821 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11822 ;; all of memory. This blocks insns from being moved across this point.
11824 (define_insn "blockage"
11825 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11828 [(set_attr "length" "0")])
11830 ;; Do not schedule instructions accessing memory across this point.
11832 (define_expand "memory_blockage"
11833 [(set (match_dup 0)
11834 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11837 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11838 MEM_VOLATILE_P (operands[0]) = 1;
11841 (define_insn "*memory_blockage"
11842 [(set (match_operand:BLK 0)
11843 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11846 [(set_attr "length" "0")])
11848 ;; As USE insns aren't meaningful after reload, this is used instead
11849 ;; to prevent deleting instructions setting registers for PIC code
11850 (define_insn "prologue_use"
11851 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11854 [(set_attr "length" "0")])
11856 ;; Insn emitted into the body of a function to return from a function.
11857 ;; This is only done if the function's epilogue is known to be simple.
11858 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11860 (define_expand "return"
11862 "ix86_can_use_return_insn_p ()"
11864 ix86_maybe_emit_epilogue_vzeroupper ();
11865 if (crtl->args.pops_args)
11867 rtx popc = GEN_INT (crtl->args.pops_args);
11868 emit_jump_insn (gen_simple_return_pop_internal (popc));
11873 ;; We need to disable this for TARGET_SEH, as otherwise
11874 ;; shrink-wrapped prologue gets enabled too. This might exceed
11875 ;; the maximum size of prologue in unwind information.
11877 (define_expand "simple_return"
11881 ix86_maybe_emit_epilogue_vzeroupper ();
11882 if (crtl->args.pops_args)
11884 rtx popc = GEN_INT (crtl->args.pops_args);
11885 emit_jump_insn (gen_simple_return_pop_internal (popc));
11890 (define_insn "simple_return_internal"
11894 [(set_attr "length" "1")
11895 (set_attr "atom_unit" "jeu")
11896 (set_attr "length_immediate" "0")
11897 (set_attr "modrm" "0")])
11899 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11900 ;; instruction Athlon and K8 have.
11902 (define_insn "simple_return_internal_long"
11904 (unspec [(const_int 0)] UNSPEC_REP)]
11907 [(set_attr "length" "2")
11908 (set_attr "atom_unit" "jeu")
11909 (set_attr "length_immediate" "0")
11910 (set_attr "prefix_rep" "1")
11911 (set_attr "modrm" "0")])
11913 (define_insn "simple_return_pop_internal"
11915 (use (match_operand:SI 0 "const_int_operand"))]
11918 [(set_attr "length" "3")
11919 (set_attr "atom_unit" "jeu")
11920 (set_attr "length_immediate" "2")
11921 (set_attr "modrm" "0")])
11923 (define_insn "simple_return_indirect_internal"
11925 (use (match_operand:SI 0 "register_operand" "r"))]
11928 [(set_attr "type" "ibr")
11929 (set_attr "length_immediate" "0")])
11935 [(set_attr "length" "1")
11936 (set_attr "length_immediate" "0")
11937 (set_attr "modrm" "0")])
11939 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11940 (define_insn "nops"
11941 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11945 int num = INTVAL (operands[0]);
11947 gcc_assert (num >= 1 && num <= 8);
11950 fputs ("\tnop\n", asm_out_file);
11954 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11955 (set_attr "length_immediate" "0")
11956 (set_attr "modrm" "0")])
11958 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11959 ;; branch prediction penalty for the third jump in a 16-byte
11963 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11966 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11967 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11969 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11970 The align insn is used to avoid 3 jump instructions in the row to improve
11971 branch prediction and the benefits hardly outweigh the cost of extra 8
11972 nops on the average inserted by full alignment pseudo operation. */
11976 [(set_attr "length" "16")])
11978 (define_expand "prologue"
11981 "ix86_expand_prologue (); DONE;")
11983 (define_insn "set_got"
11984 [(set (match_operand:SI 0 "register_operand" "=r")
11985 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11986 (clobber (reg:CC FLAGS_REG))]
11988 "* return output_set_got (operands[0], NULL_RTX);"
11989 [(set_attr "type" "multi")
11990 (set_attr "length" "12")])
11992 (define_insn "set_got_labelled"
11993 [(set (match_operand:SI 0 "register_operand" "=r")
11994 (unspec:SI [(label_ref (match_operand 1))]
11996 (clobber (reg:CC FLAGS_REG))]
11998 "* return output_set_got (operands[0], operands[1]);"
11999 [(set_attr "type" "multi")
12000 (set_attr "length" "12")])
12002 (define_insn "set_got_rex64"
12003 [(set (match_operand:DI 0 "register_operand" "=r")
12004 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12006 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12007 [(set_attr "type" "lea")
12008 (set_attr "length_address" "4")
12009 (set_attr "mode" "DI")])
12011 (define_insn "set_rip_rex64"
12012 [(set (match_operand:DI 0 "register_operand" "=r")
12013 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12015 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12016 [(set_attr "type" "lea")
12017 (set_attr "length_address" "4")
12018 (set_attr "mode" "DI")])
12020 (define_insn "set_got_offset_rex64"
12021 [(set (match_operand:DI 0 "register_operand" "=r")
12023 [(label_ref (match_operand 1))]
12024 UNSPEC_SET_GOT_OFFSET))]
12026 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12027 [(set_attr "type" "imov")
12028 (set_attr "length_immediate" "0")
12029 (set_attr "length_address" "8")
12030 (set_attr "mode" "DI")])
12032 (define_expand "epilogue"
12035 "ix86_expand_epilogue (1); DONE;")
12037 (define_expand "sibcall_epilogue"
12040 "ix86_expand_epilogue (0); DONE;")
12042 (define_expand "eh_return"
12043 [(use (match_operand 0 "register_operand"))]
12046 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12048 /* Tricky bit: we write the address of the handler to which we will
12049 be returning into someone else's stack frame, one word below the
12050 stack address we wish to restore. */
12051 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12052 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12053 tmp = gen_rtx_MEM (Pmode, tmp);
12054 emit_move_insn (tmp, ra);
12056 emit_jump_insn (gen_eh_return_internal ());
12061 (define_insn_and_split "eh_return_internal"
12065 "epilogue_completed"
12067 "ix86_expand_epilogue (2); DONE;")
12069 (define_insn "leave"
12070 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12071 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12072 (clobber (mem:BLK (scratch)))]
12075 [(set_attr "type" "leave")])
12077 (define_insn "leave_rex64"
12078 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12079 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12080 (clobber (mem:BLK (scratch)))]
12083 [(set_attr "type" "leave")])
12085 ;; Handle -fsplit-stack.
12087 (define_expand "split_stack_prologue"
12091 ix86_expand_split_stack_prologue ();
12095 ;; In order to support the call/return predictor, we use a return
12096 ;; instruction which the middle-end doesn't see.
12097 (define_insn "split_stack_return"
12098 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12099 UNSPECV_SPLIT_STACK_RETURN)]
12102 if (operands[0] == const0_rtx)
12107 [(set_attr "atom_unit" "jeu")
12108 (set_attr "modrm" "0")
12109 (set (attr "length")
12110 (if_then_else (match_operand:SI 0 "const0_operand")
12113 (set (attr "length_immediate")
12114 (if_then_else (match_operand:SI 0 "const0_operand")
12118 ;; If there are operand 0 bytes available on the stack, jump to
12121 (define_expand "split_stack_space_check"
12122 [(set (pc) (if_then_else
12123 (ltu (minus (reg SP_REG)
12124 (match_operand 0 "register_operand"))
12125 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12126 (label_ref (match_operand 1))
12130 rtx reg, size, limit;
12132 reg = gen_reg_rtx (Pmode);
12133 size = force_reg (Pmode, operands[0]);
12134 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12135 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12136 UNSPEC_STACK_CHECK);
12137 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12138 ix86_expand_branch (GEU, reg, limit, operands[1]);
12143 ;; Bit manipulation instructions.
12145 (define_expand "ffs<mode>2"
12146 [(set (match_dup 2) (const_int -1))
12147 (parallel [(set (match_dup 3) (match_dup 4))
12148 (set (match_operand:SWI48 0 "register_operand")
12150 (match_operand:SWI48 1 "nonimmediate_operand")))])
12151 (set (match_dup 0) (if_then_else:SWI48
12152 (eq (match_dup 3) (const_int 0))
12155 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12156 (clobber (reg:CC FLAGS_REG))])]
12159 enum machine_mode flags_mode;
12161 if (<MODE>mode == SImode && !TARGET_CMOVE)
12163 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12167 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12169 operands[2] = gen_reg_rtx (<MODE>mode);
12170 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12171 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12174 (define_insn_and_split "ffssi2_no_cmove"
12175 [(set (match_operand:SI 0 "register_operand" "=r")
12176 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12177 (clobber (match_scratch:SI 2 "=&q"))
12178 (clobber (reg:CC FLAGS_REG))]
12181 "&& reload_completed"
12182 [(parallel [(set (match_dup 4) (match_dup 5))
12183 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12184 (set (strict_low_part (match_dup 3))
12185 (eq:QI (match_dup 4) (const_int 0)))
12186 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12187 (clobber (reg:CC FLAGS_REG))])
12188 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12189 (clobber (reg:CC FLAGS_REG))])
12190 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12191 (clobber (reg:CC FLAGS_REG))])]
12193 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12195 operands[3] = gen_lowpart (QImode, operands[2]);
12196 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12197 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12199 ix86_expand_clear (operands[2]);
12202 (define_insn "*tzcnt<mode>_1"
12203 [(set (reg:CCC FLAGS_REG)
12204 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12206 (set (match_operand:SWI48 0 "register_operand" "=r")
12207 (ctz:SWI48 (match_dup 1)))]
12209 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12210 [(set_attr "type" "alu1")
12211 (set_attr "prefix_0f" "1")
12212 (set_attr "prefix_rep" "1")
12213 (set_attr "mode" "<MODE>")])
12215 (define_insn "*bsf<mode>_1"
12216 [(set (reg:CCZ FLAGS_REG)
12217 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12219 (set (match_operand:SWI48 0 "register_operand" "=r")
12220 (ctz:SWI48 (match_dup 1)))]
12222 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12223 [(set_attr "type" "alu1")
12224 (set_attr "prefix_0f" "1")
12225 (set_attr "mode" "<MODE>")])
12227 (define_insn "ctz<mode>2"
12228 [(set (match_operand:SWI248 0 "register_operand" "=r")
12229 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12230 (clobber (reg:CC FLAGS_REG))]
12234 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12235 else if (optimize_function_for_size_p (cfun))
12237 else if (TARGET_GENERIC)
12238 /* tzcnt expands to rep;bsf and we can use it even if !TARGET_BMI. */
12239 return "rep; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12241 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12243 [(set_attr "type" "alu1")
12244 (set_attr "prefix_0f" "1")
12245 (set (attr "prefix_rep")
12247 (ior (match_test "TARGET_BMI")
12248 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12249 (match_test "TARGET_GENERIC")))
12251 (const_string "0")))
12252 (set_attr "mode" "<MODE>")])
12254 (define_expand "clz<mode>2"
12256 [(set (match_operand:SWI248 0 "register_operand")
12259 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12260 (clobber (reg:CC FLAGS_REG))])
12262 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12263 (clobber (reg:CC FLAGS_REG))])]
12268 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12271 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12274 (define_insn "clz<mode>2_lzcnt"
12275 [(set (match_operand:SWI248 0 "register_operand" "=r")
12276 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12277 (clobber (reg:CC FLAGS_REG))]
12279 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12280 [(set_attr "prefix_rep" "1")
12281 (set_attr "type" "bitmanip")
12282 (set_attr "mode" "<MODE>")])
12284 ;; BMI instructions.
12285 (define_insn "*bmi_andn_<mode>"
12286 [(set (match_operand:SWI48 0 "register_operand" "=r")
12289 (match_operand:SWI48 1 "register_operand" "r"))
12290 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12291 (clobber (reg:CC FLAGS_REG))]
12293 "andn\t{%2, %1, %0|%0, %1, %2}"
12294 [(set_attr "type" "bitmanip")
12295 (set_attr "mode" "<MODE>")])
12297 (define_insn "bmi_bextr_<mode>"
12298 [(set (match_operand:SWI48 0 "register_operand" "=r")
12299 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12300 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12302 (clobber (reg:CC FLAGS_REG))]
12304 "bextr\t{%2, %1, %0|%0, %1, %2}"
12305 [(set_attr "type" "bitmanip")
12306 (set_attr "mode" "<MODE>")])
12308 (define_insn "*bmi_blsi_<mode>"
12309 [(set (match_operand:SWI48 0 "register_operand" "=r")
12312 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12314 (clobber (reg:CC FLAGS_REG))]
12316 "blsi\t{%1, %0|%0, %1}"
12317 [(set_attr "type" "bitmanip")
12318 (set_attr "mode" "<MODE>")])
12320 (define_insn "*bmi_blsmsk_<mode>"
12321 [(set (match_operand:SWI48 0 "register_operand" "=r")
12324 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12327 (clobber (reg:CC FLAGS_REG))]
12329 "blsmsk\t{%1, %0|%0, %1}"
12330 [(set_attr "type" "bitmanip")
12331 (set_attr "mode" "<MODE>")])
12333 (define_insn "*bmi_blsr_<mode>"
12334 [(set (match_operand:SWI48 0 "register_operand" "=r")
12337 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12340 (clobber (reg:CC FLAGS_REG))]
12342 "blsr\t{%1, %0|%0, %1}"
12343 [(set_attr "type" "bitmanip")
12344 (set_attr "mode" "<MODE>")])
12346 ;; BMI2 instructions.
12347 (define_insn "bmi2_bzhi_<mode>3"
12348 [(set (match_operand:SWI48 0 "register_operand" "=r")
12349 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12350 (lshiftrt:SWI48 (const_int -1)
12351 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12352 (clobber (reg:CC FLAGS_REG))]
12354 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12355 [(set_attr "type" "bitmanip")
12356 (set_attr "prefix" "vex")
12357 (set_attr "mode" "<MODE>")])
12359 (define_insn "bmi2_pdep_<mode>3"
12360 [(set (match_operand:SWI48 0 "register_operand" "=r")
12361 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12362 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12365 "pdep\t{%2, %1, %0|%0, %1, %2}"
12366 [(set_attr "type" "bitmanip")
12367 (set_attr "prefix" "vex")
12368 (set_attr "mode" "<MODE>")])
12370 (define_insn "bmi2_pext_<mode>3"
12371 [(set (match_operand:SWI48 0 "register_operand" "=r")
12372 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12373 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12376 "pext\t{%2, %1, %0|%0, %1, %2}"
12377 [(set_attr "type" "bitmanip")
12378 (set_attr "prefix" "vex")
12379 (set_attr "mode" "<MODE>")])
12381 ;; TBM instructions.
12382 (define_insn "tbm_bextri_<mode>"
12383 [(set (match_operand:SWI48 0 "register_operand" "=r")
12384 (zero_extract:SWI48
12385 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12386 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12387 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12388 (clobber (reg:CC FLAGS_REG))]
12391 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12392 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12394 [(set_attr "type" "bitmanip")
12395 (set_attr "mode" "<MODE>")])
12397 (define_insn "*tbm_blcfill_<mode>"
12398 [(set (match_operand:SWI48 0 "register_operand" "=r")
12401 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12404 (clobber (reg:CC FLAGS_REG))]
12406 "blcfill\t{%1, %0|%0, %1}"
12407 [(set_attr "type" "bitmanip")
12408 (set_attr "mode" "<MODE>")])
12410 (define_insn "*tbm_blci_<mode>"
12411 [(set (match_operand:SWI48 0 "register_operand" "=r")
12415 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12418 (clobber (reg:CC FLAGS_REG))]
12420 "blci\t{%1, %0|%0, %1}"
12421 [(set_attr "type" "bitmanip")
12422 (set_attr "mode" "<MODE>")])
12424 (define_insn "*tbm_blcic_<mode>"
12425 [(set (match_operand:SWI48 0 "register_operand" "=r")
12428 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12432 (clobber (reg:CC FLAGS_REG))]
12434 "blcic\t{%1, %0|%0, %1}"
12435 [(set_attr "type" "bitmanip")
12436 (set_attr "mode" "<MODE>")])
12438 (define_insn "*tbm_blcmsk_<mode>"
12439 [(set (match_operand:SWI48 0 "register_operand" "=r")
12442 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12445 (clobber (reg:CC FLAGS_REG))]
12447 "blcmsk\t{%1, %0|%0, %1}"
12448 [(set_attr "type" "bitmanip")
12449 (set_attr "mode" "<MODE>")])
12451 (define_insn "*tbm_blcs_<mode>"
12452 [(set (match_operand:SWI48 0 "register_operand" "=r")
12455 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12458 (clobber (reg:CC FLAGS_REG))]
12460 "blcs\t{%1, %0|%0, %1}"
12461 [(set_attr "type" "bitmanip")
12462 (set_attr "mode" "<MODE>")])
12464 (define_insn "*tbm_blsfill_<mode>"
12465 [(set (match_operand:SWI48 0 "register_operand" "=r")
12468 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12471 (clobber (reg:CC FLAGS_REG))]
12473 "blsfill\t{%1, %0|%0, %1}"
12474 [(set_attr "type" "bitmanip")
12475 (set_attr "mode" "<MODE>")])
12477 (define_insn "*tbm_blsic_<mode>"
12478 [(set (match_operand:SWI48 0 "register_operand" "=r")
12481 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12485 (clobber (reg:CC FLAGS_REG))]
12487 "blsic\t{%1, %0|%0, %1}"
12488 [(set_attr "type" "bitmanip")
12489 (set_attr "mode" "<MODE>")])
12491 (define_insn "*tbm_t1mskc_<mode>"
12492 [(set (match_operand:SWI48 0 "register_operand" "=r")
12495 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12499 (clobber (reg:CC FLAGS_REG))]
12501 "t1mskc\t{%1, %0|%0, %1}"
12502 [(set_attr "type" "bitmanip")
12503 (set_attr "mode" "<MODE>")])
12505 (define_insn "*tbm_tzmsk_<mode>"
12506 [(set (match_operand:SWI48 0 "register_operand" "=r")
12509 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12513 (clobber (reg:CC FLAGS_REG))]
12515 "tzmsk\t{%1, %0|%0, %1}"
12516 [(set_attr "type" "bitmanip")
12517 (set_attr "mode" "<MODE>")])
12519 (define_insn "bsr_rex64"
12520 [(set (match_operand:DI 0 "register_operand" "=r")
12521 (minus:DI (const_int 63)
12522 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12523 (clobber (reg:CC FLAGS_REG))]
12525 "bsr{q}\t{%1, %0|%0, %1}"
12526 [(set_attr "type" "alu1")
12527 (set_attr "prefix_0f" "1")
12528 (set_attr "mode" "DI")])
12531 [(set (match_operand:SI 0 "register_operand" "=r")
12532 (minus:SI (const_int 31)
12533 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12534 (clobber (reg:CC FLAGS_REG))]
12536 "bsr{l}\t{%1, %0|%0, %1}"
12537 [(set_attr "type" "alu1")
12538 (set_attr "prefix_0f" "1")
12539 (set_attr "mode" "SI")])
12541 (define_insn "*bsrhi"
12542 [(set (match_operand:HI 0 "register_operand" "=r")
12543 (minus:HI (const_int 15)
12544 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12545 (clobber (reg:CC FLAGS_REG))]
12547 "bsr{w}\t{%1, %0|%0, %1}"
12548 [(set_attr "type" "alu1")
12549 (set_attr "prefix_0f" "1")
12550 (set_attr "mode" "HI")])
12552 (define_insn "popcount<mode>2"
12553 [(set (match_operand:SWI248 0 "register_operand" "=r")
12555 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12556 (clobber (reg:CC FLAGS_REG))]
12560 return "popcnt\t{%1, %0|%0, %1}";
12562 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12565 [(set_attr "prefix_rep" "1")
12566 (set_attr "type" "bitmanip")
12567 (set_attr "mode" "<MODE>")])
12569 (define_insn "*popcount<mode>2_cmp"
12570 [(set (reg FLAGS_REG)
12573 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12575 (set (match_operand:SWI248 0 "register_operand" "=r")
12576 (popcount:SWI248 (match_dup 1)))]
12577 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12580 return "popcnt\t{%1, %0|%0, %1}";
12582 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12585 [(set_attr "prefix_rep" "1")
12586 (set_attr "type" "bitmanip")
12587 (set_attr "mode" "<MODE>")])
12589 (define_insn "*popcountsi2_cmp_zext"
12590 [(set (reg FLAGS_REG)
12592 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12594 (set (match_operand:DI 0 "register_operand" "=r")
12595 (zero_extend:DI(popcount:SI (match_dup 1))))]
12596 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12599 return "popcnt\t{%1, %0|%0, %1}";
12601 return "popcnt{l}\t{%1, %0|%0, %1}";
12604 [(set_attr "prefix_rep" "1")
12605 (set_attr "type" "bitmanip")
12606 (set_attr "mode" "SI")])
12608 (define_expand "bswapdi2"
12609 [(set (match_operand:DI 0 "register_operand")
12610 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12613 if (TARGET_64BIT && !TARGET_MOVBE)
12614 operands[1] = force_reg (DImode, operands[1]);
12617 (define_insn_and_split "*bswapdi2_doubleword"
12618 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12620 (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12622 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12624 "&& reload_completed"
12625 [(set (match_dup 2)
12626 (bswap:SI (match_dup 1)))
12628 (bswap:SI (match_dup 3)))]
12630 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
12632 if (REG_P (operands[0]) && REG_P (operands[1]))
12634 emit_insn (gen_swapsi (operands[0], operands[2]));
12635 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12636 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12642 if (MEM_P (operands[0]))
12644 emit_insn (gen_bswapsi2 (operands[3], operands[3]));
12645 emit_insn (gen_bswapsi2 (operands[1], operands[1]));
12647 emit_move_insn (operands[0], operands[3]);
12648 emit_move_insn (operands[2], operands[1]);
12650 if (MEM_P (operands[1]))
12652 emit_move_insn (operands[2], operands[1]);
12653 emit_move_insn (operands[0], operands[3]);
12655 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12656 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12662 (define_expand "bswapsi2"
12663 [(set (match_operand:SI 0 "register_operand")
12664 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12669 else if (TARGET_BSWAP)
12670 operands[1] = force_reg (SImode, operands[1]);
12673 rtx x = operands[0];
12675 emit_move_insn (x, operands[1]);
12676 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12677 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12678 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12683 (define_insn "*bswap<mode>2_movbe"
12684 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12685 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12687 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12690 movbe\t{%1, %0|%0, %1}
12691 movbe\t{%1, %0|%0, %1}"
12692 [(set_attr "type" "bitmanip,imov,imov")
12693 (set_attr "modrm" "0,1,1")
12694 (set_attr "prefix_0f" "*,1,1")
12695 (set_attr "prefix_extra" "*,1,1")
12696 (set_attr "mode" "<MODE>")])
12698 (define_insn "*bswap<mode>2"
12699 [(set (match_operand:SWI48 0 "register_operand" "=r")
12700 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12703 [(set_attr "type" "bitmanip")
12704 (set_attr "modrm" "0")
12705 (set_attr "mode" "<MODE>")])
12707 (define_insn "*bswaphi_lowpart_1"
12708 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12709 (bswap:HI (match_dup 0)))
12710 (clobber (reg:CC FLAGS_REG))]
12711 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12713 xchg{b}\t{%h0, %b0|%b0, %h0}
12714 rol{w}\t{$8, %0|%0, 8}"
12715 [(set_attr "length" "2,4")
12716 (set_attr "mode" "QI,HI")])
12718 (define_insn "bswaphi_lowpart"
12719 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12720 (bswap:HI (match_dup 0)))
12721 (clobber (reg:CC FLAGS_REG))]
12723 "rol{w}\t{$8, %0|%0, 8}"
12724 [(set_attr "length" "4")
12725 (set_attr "mode" "HI")])
12727 (define_expand "paritydi2"
12728 [(set (match_operand:DI 0 "register_operand")
12729 (parity:DI (match_operand:DI 1 "register_operand")))]
12732 rtx scratch = gen_reg_rtx (QImode);
12735 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12736 NULL_RTX, operands[1]));
12738 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12739 gen_rtx_REG (CCmode, FLAGS_REG),
12741 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12744 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12747 rtx tmp = gen_reg_rtx (SImode);
12749 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12750 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12755 (define_expand "paritysi2"
12756 [(set (match_operand:SI 0 "register_operand")
12757 (parity:SI (match_operand:SI 1 "register_operand")))]
12760 rtx scratch = gen_reg_rtx (QImode);
12763 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12765 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12766 gen_rtx_REG (CCmode, FLAGS_REG),
12768 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12770 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12774 (define_insn_and_split "paritydi2_cmp"
12775 [(set (reg:CC FLAGS_REG)
12776 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12778 (clobber (match_scratch:DI 0 "=r"))
12779 (clobber (match_scratch:SI 1 "=&r"))
12780 (clobber (match_scratch:HI 2 "=Q"))]
12783 "&& reload_completed"
12785 [(set (match_dup 1)
12786 (xor:SI (match_dup 1) (match_dup 4)))
12787 (clobber (reg:CC FLAGS_REG))])
12789 [(set (reg:CC FLAGS_REG)
12790 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12791 (clobber (match_dup 1))
12792 (clobber (match_dup 2))])]
12794 operands[4] = gen_lowpart (SImode, operands[3]);
12798 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12799 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12802 operands[1] = gen_highpart (SImode, operands[3]);
12805 (define_insn_and_split "paritysi2_cmp"
12806 [(set (reg:CC FLAGS_REG)
12807 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12809 (clobber (match_scratch:SI 0 "=r"))
12810 (clobber (match_scratch:HI 1 "=&Q"))]
12813 "&& reload_completed"
12815 [(set (match_dup 1)
12816 (xor:HI (match_dup 1) (match_dup 3)))
12817 (clobber (reg:CC FLAGS_REG))])
12819 [(set (reg:CC FLAGS_REG)
12820 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12821 (clobber (match_dup 1))])]
12823 operands[3] = gen_lowpart (HImode, operands[2]);
12825 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12826 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12829 (define_insn "*parityhi2_cmp"
12830 [(set (reg:CC FLAGS_REG)
12831 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12833 (clobber (match_scratch:HI 0 "=Q"))]
12835 "xor{b}\t{%h0, %b0|%b0, %h0}"
12836 [(set_attr "length" "2")
12837 (set_attr "mode" "HI")])
12840 ;; Thread-local storage patterns for ELF.
12842 ;; Note that these code sequences must appear exactly as shown
12843 ;; in order to allow linker relaxation.
12845 (define_insn "*tls_global_dynamic_32_gnu"
12846 [(set (match_operand:SI 0 "register_operand" "=a")
12848 [(match_operand:SI 1 "register_operand" "b")
12849 (match_operand 2 "tls_symbolic_operand")
12850 (match_operand 3 "constant_call_address_operand" "z")]
12852 (clobber (match_scratch:SI 4 "=d"))
12853 (clobber (match_scratch:SI 5 "=c"))
12854 (clobber (reg:CC FLAGS_REG))]
12855 "!TARGET_64BIT && TARGET_GNU_TLS"
12858 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12859 if (TARGET_SUN_TLS)
12860 #ifdef HAVE_AS_IX86_TLSGDPLT
12861 return "call\t%a2@tlsgdplt";
12863 return "call\t%p3@plt";
12865 return "call\t%P3";
12867 [(set_attr "type" "multi")
12868 (set_attr "length" "12")])
12870 (define_expand "tls_global_dynamic_32"
12872 [(set (match_operand:SI 0 "register_operand")
12873 (unspec:SI [(match_operand:SI 2 "register_operand")
12874 (match_operand 1 "tls_symbolic_operand")
12875 (match_operand 3 "constant_call_address_operand")]
12877 (clobber (match_scratch:SI 4))
12878 (clobber (match_scratch:SI 5))
12879 (clobber (reg:CC FLAGS_REG))])])
12881 (define_insn "*tls_global_dynamic_64_<mode>"
12882 [(set (match_operand:P 0 "register_operand" "=a")
12884 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12885 (match_operand 3)))
12886 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12891 fputs (ASM_BYTE "0x66\n", asm_out_file);
12893 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12894 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12895 fputs ("\trex64\n", asm_out_file);
12896 if (TARGET_SUN_TLS)
12897 return "call\t%p2@plt";
12898 return "call\t%P2";
12900 [(set_attr "type" "multi")
12901 (set (attr "length")
12902 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12904 (define_expand "tls_global_dynamic_64_<mode>"
12906 [(set (match_operand:P 0 "register_operand")
12908 (mem:QI (match_operand 2 "constant_call_address_operand"))
12910 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12914 (define_insn "*tls_local_dynamic_base_32_gnu"
12915 [(set (match_operand:SI 0 "register_operand" "=a")
12917 [(match_operand:SI 1 "register_operand" "b")
12918 (match_operand 2 "constant_call_address_operand" "z")]
12919 UNSPEC_TLS_LD_BASE))
12920 (clobber (match_scratch:SI 3 "=d"))
12921 (clobber (match_scratch:SI 4 "=c"))
12922 (clobber (reg:CC FLAGS_REG))]
12923 "!TARGET_64BIT && TARGET_GNU_TLS"
12926 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12927 if (TARGET_SUN_TLS)
12928 #ifdef HAVE_AS_IX86_TLSLDMPLT
12929 return "call\t%&@tlsldmplt";
12931 return "call\t%p2@plt";
12933 return "call\t%P2";
12935 [(set_attr "type" "multi")
12936 (set_attr "length" "11")])
12938 (define_expand "tls_local_dynamic_base_32"
12940 [(set (match_operand:SI 0 "register_operand")
12942 [(match_operand:SI 1 "register_operand")
12943 (match_operand 2 "constant_call_address_operand")]
12944 UNSPEC_TLS_LD_BASE))
12945 (clobber (match_scratch:SI 3))
12946 (clobber (match_scratch:SI 4))
12947 (clobber (reg:CC FLAGS_REG))])])
12949 (define_insn "*tls_local_dynamic_base_64_<mode>"
12950 [(set (match_operand:P 0 "register_operand" "=a")
12952 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12953 (match_operand 2)))
12954 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12958 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12959 if (TARGET_SUN_TLS)
12960 return "call\t%p1@plt";
12961 return "call\t%P1";
12963 [(set_attr "type" "multi")
12964 (set_attr "length" "12")])
12966 (define_expand "tls_local_dynamic_base_64_<mode>"
12968 [(set (match_operand:P 0 "register_operand")
12970 (mem:QI (match_operand 1 "constant_call_address_operand"))
12972 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12975 ;; Local dynamic of a single variable is a lose. Show combine how
12976 ;; to convert that back to global dynamic.
12978 (define_insn_and_split "*tls_local_dynamic_32_once"
12979 [(set (match_operand:SI 0 "register_operand" "=a")
12981 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12982 (match_operand 2 "constant_call_address_operand" "z")]
12983 UNSPEC_TLS_LD_BASE)
12984 (const:SI (unspec:SI
12985 [(match_operand 3 "tls_symbolic_operand")]
12987 (clobber (match_scratch:SI 4 "=d"))
12988 (clobber (match_scratch:SI 5 "=c"))
12989 (clobber (reg:CC FLAGS_REG))]
12994 [(set (match_dup 0)
12995 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12997 (clobber (match_dup 4))
12998 (clobber (match_dup 5))
12999 (clobber (reg:CC FLAGS_REG))])])
13001 ;; Segment register for the thread base ptr load
13002 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13004 ;; Load and add the thread base pointer from %<tp_seg>:0.
13005 (define_insn "*load_tp_x32"
13006 [(set (match_operand:SI 0 "register_operand" "=r")
13007 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13009 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13010 [(set_attr "type" "imov")
13011 (set_attr "modrm" "0")
13012 (set_attr "length" "7")
13013 (set_attr "memory" "load")
13014 (set_attr "imm_disp" "false")])
13016 (define_insn "*load_tp_x32_zext"
13017 [(set (match_operand:DI 0 "register_operand" "=r")
13018 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13020 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13021 [(set_attr "type" "imov")
13022 (set_attr "modrm" "0")
13023 (set_attr "length" "7")
13024 (set_attr "memory" "load")
13025 (set_attr "imm_disp" "false")])
13027 (define_insn "*load_tp_<mode>"
13028 [(set (match_operand:P 0 "register_operand" "=r")
13029 (unspec:P [(const_int 0)] UNSPEC_TP))]
13031 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13032 [(set_attr "type" "imov")
13033 (set_attr "modrm" "0")
13034 (set_attr "length" "7")
13035 (set_attr "memory" "load")
13036 (set_attr "imm_disp" "false")])
13038 (define_insn "*add_tp_x32"
13039 [(set (match_operand:SI 0 "register_operand" "=r")
13040 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13041 (match_operand:SI 1 "register_operand" "0")))
13042 (clobber (reg:CC FLAGS_REG))]
13044 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13045 [(set_attr "type" "alu")
13046 (set_attr "modrm" "0")
13047 (set_attr "length" "7")
13048 (set_attr "memory" "load")
13049 (set_attr "imm_disp" "false")])
13051 (define_insn "*add_tp_x32_zext"
13052 [(set (match_operand:DI 0 "register_operand" "=r")
13054 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13055 (match_operand:SI 1 "register_operand" "0"))))
13056 (clobber (reg:CC FLAGS_REG))]
13058 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13059 [(set_attr "type" "alu")
13060 (set_attr "modrm" "0")
13061 (set_attr "length" "7")
13062 (set_attr "memory" "load")
13063 (set_attr "imm_disp" "false")])
13065 (define_insn "*add_tp_<mode>"
13066 [(set (match_operand:P 0 "register_operand" "=r")
13067 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13068 (match_operand:P 1 "register_operand" "0")))
13069 (clobber (reg:CC FLAGS_REG))]
13071 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13072 [(set_attr "type" "alu")
13073 (set_attr "modrm" "0")
13074 (set_attr "length" "7")
13075 (set_attr "memory" "load")
13076 (set_attr "imm_disp" "false")])
13078 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13079 ;; %rax as destination of the initial executable code sequence.
13080 (define_insn "tls_initial_exec_64_sun"
13081 [(set (match_operand:DI 0 "register_operand" "=a")
13083 [(match_operand 1 "tls_symbolic_operand")]
13084 UNSPEC_TLS_IE_SUN))
13085 (clobber (reg:CC FLAGS_REG))]
13086 "TARGET_64BIT && TARGET_SUN_TLS"
13089 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13090 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13092 [(set_attr "type" "multi")])
13094 ;; GNU2 TLS patterns can be split.
13096 (define_expand "tls_dynamic_gnu2_32"
13097 [(set (match_dup 3)
13098 (plus:SI (match_operand:SI 2 "register_operand")
13100 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13103 [(set (match_operand:SI 0 "register_operand")
13104 (unspec:SI [(match_dup 1) (match_dup 3)
13105 (match_dup 2) (reg:SI SP_REG)]
13107 (clobber (reg:CC FLAGS_REG))])]
13108 "!TARGET_64BIT && TARGET_GNU2_TLS"
13110 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13111 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13114 (define_insn "*tls_dynamic_gnu2_lea_32"
13115 [(set (match_operand:SI 0 "register_operand" "=r")
13116 (plus:SI (match_operand:SI 1 "register_operand" "b")
13118 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13119 UNSPEC_TLSDESC))))]
13120 "!TARGET_64BIT && TARGET_GNU2_TLS"
13121 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13122 [(set_attr "type" "lea")
13123 (set_attr "mode" "SI")
13124 (set_attr "length" "6")
13125 (set_attr "length_address" "4")])
13127 (define_insn "*tls_dynamic_gnu2_call_32"
13128 [(set (match_operand:SI 0 "register_operand" "=a")
13129 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13130 (match_operand:SI 2 "register_operand" "0")
13131 ;; we have to make sure %ebx still points to the GOT
13132 (match_operand:SI 3 "register_operand" "b")
13135 (clobber (reg:CC FLAGS_REG))]
13136 "!TARGET_64BIT && TARGET_GNU2_TLS"
13137 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13138 [(set_attr "type" "call")
13139 (set_attr "length" "2")
13140 (set_attr "length_address" "0")])
13142 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13143 [(set (match_operand:SI 0 "register_operand" "=&a")
13145 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13146 (match_operand:SI 4)
13147 (match_operand:SI 2 "register_operand" "b")
13150 (const:SI (unspec:SI
13151 [(match_operand 1 "tls_symbolic_operand")]
13153 (clobber (reg:CC FLAGS_REG))]
13154 "!TARGET_64BIT && TARGET_GNU2_TLS"
13157 [(set (match_dup 0) (match_dup 5))]
13159 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13160 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13163 (define_expand "tls_dynamic_gnu2_64"
13164 [(set (match_dup 2)
13165 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13168 [(set (match_operand:DI 0 "register_operand")
13169 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13171 (clobber (reg:CC FLAGS_REG))])]
13172 "TARGET_64BIT && TARGET_GNU2_TLS"
13174 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13175 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13178 (define_insn "*tls_dynamic_gnu2_lea_64"
13179 [(set (match_operand:DI 0 "register_operand" "=r")
13180 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13182 "TARGET_64BIT && TARGET_GNU2_TLS"
13183 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13184 [(set_attr "type" "lea")
13185 (set_attr "mode" "DI")
13186 (set_attr "length" "7")
13187 (set_attr "length_address" "4")])
13189 (define_insn "*tls_dynamic_gnu2_call_64"
13190 [(set (match_operand:DI 0 "register_operand" "=a")
13191 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13192 (match_operand:DI 2 "register_operand" "0")
13195 (clobber (reg:CC FLAGS_REG))]
13196 "TARGET_64BIT && TARGET_GNU2_TLS"
13197 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13198 [(set_attr "type" "call")
13199 (set_attr "length" "2")
13200 (set_attr "length_address" "0")])
13202 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13203 [(set (match_operand:DI 0 "register_operand" "=&a")
13205 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13206 (match_operand:DI 3)
13209 (const:DI (unspec:DI
13210 [(match_operand 1 "tls_symbolic_operand")]
13212 (clobber (reg:CC FLAGS_REG))]
13213 "TARGET_64BIT && TARGET_GNU2_TLS"
13216 [(set (match_dup 0) (match_dup 4))]
13218 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13219 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13222 ;; These patterns match the binary 387 instructions for addM3, subM3,
13223 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13224 ;; SFmode. The first is the normal insn, the second the same insn but
13225 ;; with one operand a conversion, and the third the same insn but with
13226 ;; the other operand a conversion. The conversion may be SFmode or
13227 ;; SImode if the target mode DFmode, but only SImode if the target mode
13230 ;; Gcc is slightly more smart about handling normal two address instructions
13231 ;; so use special patterns for add and mull.
13233 (define_insn "*fop_<mode>_comm_mixed"
13234 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13235 (match_operator:MODEF 3 "binary_fp_operator"
13236 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13237 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13238 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13239 && COMMUTATIVE_ARITH_P (operands[3])
13240 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13241 "* return output_387_binary_op (insn, operands);"
13242 [(set (attr "type")
13243 (if_then_else (eq_attr "alternative" "1,2")
13244 (if_then_else (match_operand:MODEF 3 "mult_operator")
13245 (const_string "ssemul")
13246 (const_string "sseadd"))
13247 (if_then_else (match_operand:MODEF 3 "mult_operator")
13248 (const_string "fmul")
13249 (const_string "fop"))))
13250 (set_attr "isa" "*,noavx,avx")
13251 (set_attr "prefix" "orig,orig,vex")
13252 (set_attr "mode" "<MODE>")])
13254 (define_insn "*fop_<mode>_comm_sse"
13255 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13256 (match_operator:MODEF 3 "binary_fp_operator"
13257 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13258 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13259 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13260 && COMMUTATIVE_ARITH_P (operands[3])
13261 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13262 "* return output_387_binary_op (insn, operands);"
13263 [(set (attr "type")
13264 (if_then_else (match_operand:MODEF 3 "mult_operator")
13265 (const_string "ssemul")
13266 (const_string "sseadd")))
13267 (set_attr "isa" "noavx,avx")
13268 (set_attr "prefix" "orig,vex")
13269 (set_attr "mode" "<MODE>")])
13271 (define_insn "*fop_<mode>_comm_i387"
13272 [(set (match_operand:MODEF 0 "register_operand" "=f")
13273 (match_operator:MODEF 3 "binary_fp_operator"
13274 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13275 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13276 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13277 && COMMUTATIVE_ARITH_P (operands[3])
13278 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13279 "* return output_387_binary_op (insn, operands);"
13280 [(set (attr "type")
13281 (if_then_else (match_operand:MODEF 3 "mult_operator")
13282 (const_string "fmul")
13283 (const_string "fop")))
13284 (set_attr "mode" "<MODE>")])
13286 (define_insn "*fop_<mode>_1_mixed"
13287 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13288 (match_operator:MODEF 3 "binary_fp_operator"
13289 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13290 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13291 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13292 && !COMMUTATIVE_ARITH_P (operands[3])
13293 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13294 "* return output_387_binary_op (insn, operands);"
13295 [(set (attr "type")
13296 (cond [(and (eq_attr "alternative" "2,3")
13297 (match_operand:MODEF 3 "mult_operator"))
13298 (const_string "ssemul")
13299 (and (eq_attr "alternative" "2,3")
13300 (match_operand:MODEF 3 "div_operator"))
13301 (const_string "ssediv")
13302 (eq_attr "alternative" "2,3")
13303 (const_string "sseadd")
13304 (match_operand:MODEF 3 "mult_operator")
13305 (const_string "fmul")
13306 (match_operand:MODEF 3 "div_operator")
13307 (const_string "fdiv")
13309 (const_string "fop")))
13310 (set_attr "isa" "*,*,noavx,avx")
13311 (set_attr "prefix" "orig,orig,orig,vex")
13312 (set_attr "mode" "<MODE>")])
13314 (define_insn "*rcpsf2_sse"
13315 [(set (match_operand:SF 0 "register_operand" "=x")
13316 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13319 "%vrcpss\t{%1, %d0|%d0, %1}"
13320 [(set_attr "type" "sse")
13321 (set_attr "atom_sse_attr" "rcp")
13322 (set_attr "prefix" "maybe_vex")
13323 (set_attr "mode" "SF")])
13325 (define_insn "*fop_<mode>_1_sse"
13326 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13327 (match_operator:MODEF 3 "binary_fp_operator"
13328 [(match_operand:MODEF 1 "register_operand" "0,x")
13329 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13330 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13331 && !COMMUTATIVE_ARITH_P (operands[3])"
13332 "* return output_387_binary_op (insn, operands);"
13333 [(set (attr "type")
13334 (cond [(match_operand:MODEF 3 "mult_operator")
13335 (const_string "ssemul")
13336 (match_operand:MODEF 3 "div_operator")
13337 (const_string "ssediv")
13339 (const_string "sseadd")))
13340 (set_attr "isa" "noavx,avx")
13341 (set_attr "prefix" "orig,vex")
13342 (set_attr "mode" "<MODE>")])
13344 ;; This pattern is not fully shadowed by the pattern above.
13345 (define_insn "*fop_<mode>_1_i387"
13346 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13347 (match_operator:MODEF 3 "binary_fp_operator"
13348 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13349 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13350 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13351 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13352 && !COMMUTATIVE_ARITH_P (operands[3])
13353 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13354 "* return output_387_binary_op (insn, operands);"
13355 [(set (attr "type")
13356 (cond [(match_operand:MODEF 3 "mult_operator")
13357 (const_string "fmul")
13358 (match_operand:MODEF 3 "div_operator")
13359 (const_string "fdiv")
13361 (const_string "fop")))
13362 (set_attr "mode" "<MODE>")])
13364 ;; ??? Add SSE splitters for these!
13365 (define_insn "*fop_<MODEF:mode>_2_i387"
13366 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13367 (match_operator:MODEF 3 "binary_fp_operator"
13369 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13370 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13371 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13372 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13373 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13374 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13375 [(set (attr "type")
13376 (cond [(match_operand:MODEF 3 "mult_operator")
13377 (const_string "fmul")
13378 (match_operand:MODEF 3 "div_operator")
13379 (const_string "fdiv")
13381 (const_string "fop")))
13382 (set_attr "fp_int_src" "true")
13383 (set_attr "mode" "<SWI24:MODE>")])
13385 (define_insn "*fop_<MODEF:mode>_3_i387"
13386 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13387 (match_operator:MODEF 3 "binary_fp_operator"
13388 [(match_operand:MODEF 1 "register_operand" "0,0")
13390 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13391 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13392 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13393 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13394 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13395 [(set (attr "type")
13396 (cond [(match_operand:MODEF 3 "mult_operator")
13397 (const_string "fmul")
13398 (match_operand:MODEF 3 "div_operator")
13399 (const_string "fdiv")
13401 (const_string "fop")))
13402 (set_attr "fp_int_src" "true")
13403 (set_attr "mode" "<MODE>")])
13405 (define_insn "*fop_df_4_i387"
13406 [(set (match_operand:DF 0 "register_operand" "=f,f")
13407 (match_operator:DF 3 "binary_fp_operator"
13409 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13410 (match_operand:DF 2 "register_operand" "0,f")]))]
13411 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13412 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13413 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13414 "* return output_387_binary_op (insn, operands);"
13415 [(set (attr "type")
13416 (cond [(match_operand:DF 3 "mult_operator")
13417 (const_string "fmul")
13418 (match_operand:DF 3 "div_operator")
13419 (const_string "fdiv")
13421 (const_string "fop")))
13422 (set_attr "mode" "SF")])
13424 (define_insn "*fop_df_5_i387"
13425 [(set (match_operand:DF 0 "register_operand" "=f,f")
13426 (match_operator:DF 3 "binary_fp_operator"
13427 [(match_operand:DF 1 "register_operand" "0,f")
13429 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13430 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13431 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13432 "* return output_387_binary_op (insn, operands);"
13433 [(set (attr "type")
13434 (cond [(match_operand:DF 3 "mult_operator")
13435 (const_string "fmul")
13436 (match_operand:DF 3 "div_operator")
13437 (const_string "fdiv")
13439 (const_string "fop")))
13440 (set_attr "mode" "SF")])
13442 (define_insn "*fop_df_6_i387"
13443 [(set (match_operand:DF 0 "register_operand" "=f,f")
13444 (match_operator:DF 3 "binary_fp_operator"
13446 (match_operand:SF 1 "register_operand" "0,f"))
13448 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13449 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13450 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13451 "* return output_387_binary_op (insn, operands);"
13452 [(set (attr "type")
13453 (cond [(match_operand:DF 3 "mult_operator")
13454 (const_string "fmul")
13455 (match_operand:DF 3 "div_operator")
13456 (const_string "fdiv")
13458 (const_string "fop")))
13459 (set_attr "mode" "SF")])
13461 (define_insn "*fop_xf_comm_i387"
13462 [(set (match_operand:XF 0 "register_operand" "=f")
13463 (match_operator:XF 3 "binary_fp_operator"
13464 [(match_operand:XF 1 "register_operand" "%0")
13465 (match_operand:XF 2 "register_operand" "f")]))]
13467 && COMMUTATIVE_ARITH_P (operands[3])"
13468 "* return output_387_binary_op (insn, operands);"
13469 [(set (attr "type")
13470 (if_then_else (match_operand:XF 3 "mult_operator")
13471 (const_string "fmul")
13472 (const_string "fop")))
13473 (set_attr "mode" "XF")])
13475 (define_insn "*fop_xf_1_i387"
13476 [(set (match_operand:XF 0 "register_operand" "=f,f")
13477 (match_operator:XF 3 "binary_fp_operator"
13478 [(match_operand:XF 1 "register_operand" "0,f")
13479 (match_operand:XF 2 "register_operand" "f,0")]))]
13481 && !COMMUTATIVE_ARITH_P (operands[3])"
13482 "* return output_387_binary_op (insn, operands);"
13483 [(set (attr "type")
13484 (cond [(match_operand:XF 3 "mult_operator")
13485 (const_string "fmul")
13486 (match_operand:XF 3 "div_operator")
13487 (const_string "fdiv")
13489 (const_string "fop")))
13490 (set_attr "mode" "XF")])
13492 (define_insn "*fop_xf_2_i387"
13493 [(set (match_operand:XF 0 "register_operand" "=f,f")
13494 (match_operator:XF 3 "binary_fp_operator"
13496 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13497 (match_operand:XF 2 "register_operand" "0,0")]))]
13498 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13499 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13500 [(set (attr "type")
13501 (cond [(match_operand:XF 3 "mult_operator")
13502 (const_string "fmul")
13503 (match_operand:XF 3 "div_operator")
13504 (const_string "fdiv")
13506 (const_string "fop")))
13507 (set_attr "fp_int_src" "true")
13508 (set_attr "mode" "<MODE>")])
13510 (define_insn "*fop_xf_3_i387"
13511 [(set (match_operand:XF 0 "register_operand" "=f,f")
13512 (match_operator:XF 3 "binary_fp_operator"
13513 [(match_operand:XF 1 "register_operand" "0,0")
13515 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13516 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13517 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13518 [(set (attr "type")
13519 (cond [(match_operand:XF 3 "mult_operator")
13520 (const_string "fmul")
13521 (match_operand:XF 3 "div_operator")
13522 (const_string "fdiv")
13524 (const_string "fop")))
13525 (set_attr "fp_int_src" "true")
13526 (set_attr "mode" "<MODE>")])
13528 (define_insn "*fop_xf_4_i387"
13529 [(set (match_operand:XF 0 "register_operand" "=f,f")
13530 (match_operator:XF 3 "binary_fp_operator"
13532 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13533 (match_operand:XF 2 "register_operand" "0,f")]))]
13535 "* return output_387_binary_op (insn, operands);"
13536 [(set (attr "type")
13537 (cond [(match_operand:XF 3 "mult_operator")
13538 (const_string "fmul")
13539 (match_operand:XF 3 "div_operator")
13540 (const_string "fdiv")
13542 (const_string "fop")))
13543 (set_attr "mode" "<MODE>")])
13545 (define_insn "*fop_xf_5_i387"
13546 [(set (match_operand:XF 0 "register_operand" "=f,f")
13547 (match_operator:XF 3 "binary_fp_operator"
13548 [(match_operand:XF 1 "register_operand" "0,f")
13550 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13552 "* return output_387_binary_op (insn, operands);"
13553 [(set (attr "type")
13554 (cond [(match_operand:XF 3 "mult_operator")
13555 (const_string "fmul")
13556 (match_operand:XF 3 "div_operator")
13557 (const_string "fdiv")
13559 (const_string "fop")))
13560 (set_attr "mode" "<MODE>")])
13562 (define_insn "*fop_xf_6_i387"
13563 [(set (match_operand:XF 0 "register_operand" "=f,f")
13564 (match_operator:XF 3 "binary_fp_operator"
13566 (match_operand:MODEF 1 "register_operand" "0,f"))
13568 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13570 "* return output_387_binary_op (insn, operands);"
13571 [(set (attr "type")
13572 (cond [(match_operand:XF 3 "mult_operator")
13573 (const_string "fmul")
13574 (match_operand:XF 3 "div_operator")
13575 (const_string "fdiv")
13577 (const_string "fop")))
13578 (set_attr "mode" "<MODE>")])
13581 [(set (match_operand 0 "register_operand")
13582 (match_operator 3 "binary_fp_operator"
13583 [(float (match_operand:SWI24 1 "register_operand"))
13584 (match_operand 2 "register_operand")]))]
13586 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13587 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13590 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13591 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13592 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13593 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13594 GET_MODE (operands[3]),
13597 ix86_free_from_memory (GET_MODE (operands[1]));
13602 [(set (match_operand 0 "register_operand")
13603 (match_operator 3 "binary_fp_operator"
13604 [(match_operand 1 "register_operand")
13605 (float (match_operand:SWI24 2 "register_operand"))]))]
13607 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13608 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13611 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13612 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13613 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13614 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13615 GET_MODE (operands[3]),
13618 ix86_free_from_memory (GET_MODE (operands[2]));
13622 ;; FPU special functions.
13624 ;; This pattern implements a no-op XFmode truncation for
13625 ;; all fancy i386 XFmode math functions.
13627 (define_insn "truncxf<mode>2_i387_noop_unspec"
13628 [(set (match_operand:MODEF 0 "register_operand" "=f")
13629 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13630 UNSPEC_TRUNC_NOOP))]
13631 "TARGET_USE_FANCY_MATH_387"
13632 "* return output_387_reg_move (insn, operands);"
13633 [(set_attr "type" "fmov")
13634 (set_attr "mode" "<MODE>")])
13636 (define_insn "sqrtxf2"
13637 [(set (match_operand:XF 0 "register_operand" "=f")
13638 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13639 "TARGET_USE_FANCY_MATH_387"
13641 [(set_attr "type" "fpspc")
13642 (set_attr "mode" "XF")
13643 (set_attr "athlon_decode" "direct")
13644 (set_attr "amdfam10_decode" "direct")
13645 (set_attr "bdver1_decode" "direct")])
13647 (define_insn "sqrt_extend<mode>xf2_i387"
13648 [(set (match_operand:XF 0 "register_operand" "=f")
13651 (match_operand:MODEF 1 "register_operand" "0"))))]
13652 "TARGET_USE_FANCY_MATH_387"
13654 [(set_attr "type" "fpspc")
13655 (set_attr "mode" "XF")
13656 (set_attr "athlon_decode" "direct")
13657 (set_attr "amdfam10_decode" "direct")
13658 (set_attr "bdver1_decode" "direct")])
13660 (define_insn "*rsqrtsf2_sse"
13661 [(set (match_operand:SF 0 "register_operand" "=x")
13662 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13665 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13666 [(set_attr "type" "sse")
13667 (set_attr "atom_sse_attr" "rcp")
13668 (set_attr "prefix" "maybe_vex")
13669 (set_attr "mode" "SF")])
13671 (define_expand "rsqrtsf2"
13672 [(set (match_operand:SF 0 "register_operand")
13673 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13677 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13681 (define_insn "*sqrt<mode>2_sse"
13682 [(set (match_operand:MODEF 0 "register_operand" "=x")
13684 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13685 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13686 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13687 [(set_attr "type" "sse")
13688 (set_attr "atom_sse_attr" "sqrt")
13689 (set_attr "prefix" "maybe_vex")
13690 (set_attr "mode" "<MODE>")
13691 (set_attr "athlon_decode" "*")
13692 (set_attr "amdfam10_decode" "*")
13693 (set_attr "bdver1_decode" "*")])
13695 (define_expand "sqrt<mode>2"
13696 [(set (match_operand:MODEF 0 "register_operand")
13698 (match_operand:MODEF 1 "nonimmediate_operand")))]
13699 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13700 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13702 if (<MODE>mode == SFmode
13704 && TARGET_RECIP_SQRT
13705 && !optimize_function_for_size_p (cfun)
13706 && flag_finite_math_only && !flag_trapping_math
13707 && flag_unsafe_math_optimizations)
13709 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13713 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13715 rtx op0 = gen_reg_rtx (XFmode);
13716 rtx op1 = force_reg (<MODE>mode, operands[1]);
13718 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13719 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13724 (define_insn "fpremxf4_i387"
13725 [(set (match_operand:XF 0 "register_operand" "=f")
13726 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13727 (match_operand:XF 3 "register_operand" "1")]
13729 (set (match_operand:XF 1 "register_operand" "=u")
13730 (unspec:XF [(match_dup 2) (match_dup 3)]
13732 (set (reg:CCFP FPSR_REG)
13733 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13735 "TARGET_USE_FANCY_MATH_387"
13737 [(set_attr "type" "fpspc")
13738 (set_attr "mode" "XF")])
13740 (define_expand "fmodxf3"
13741 [(use (match_operand:XF 0 "register_operand"))
13742 (use (match_operand:XF 1 "general_operand"))
13743 (use (match_operand:XF 2 "general_operand"))]
13744 "TARGET_USE_FANCY_MATH_387"
13746 rtx label = gen_label_rtx ();
13748 rtx op1 = gen_reg_rtx (XFmode);
13749 rtx op2 = gen_reg_rtx (XFmode);
13751 emit_move_insn (op2, operands[2]);
13752 emit_move_insn (op1, operands[1]);
13754 emit_label (label);
13755 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13756 ix86_emit_fp_unordered_jump (label);
13757 LABEL_NUSES (label) = 1;
13759 emit_move_insn (operands[0], op1);
13763 (define_expand "fmod<mode>3"
13764 [(use (match_operand:MODEF 0 "register_operand"))
13765 (use (match_operand:MODEF 1 "general_operand"))
13766 (use (match_operand:MODEF 2 "general_operand"))]
13767 "TARGET_USE_FANCY_MATH_387"
13769 rtx (*gen_truncxf) (rtx, rtx);
13771 rtx label = gen_label_rtx ();
13773 rtx op1 = gen_reg_rtx (XFmode);
13774 rtx op2 = gen_reg_rtx (XFmode);
13776 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13777 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13779 emit_label (label);
13780 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13781 ix86_emit_fp_unordered_jump (label);
13782 LABEL_NUSES (label) = 1;
13784 /* Truncate the result properly for strict SSE math. */
13785 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13786 && !TARGET_MIX_SSE_I387)
13787 gen_truncxf = gen_truncxf<mode>2;
13789 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13791 emit_insn (gen_truncxf (operands[0], op1));
13795 (define_insn "fprem1xf4_i387"
13796 [(set (match_operand:XF 0 "register_operand" "=f")
13797 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13798 (match_operand:XF 3 "register_operand" "1")]
13800 (set (match_operand:XF 1 "register_operand" "=u")
13801 (unspec:XF [(match_dup 2) (match_dup 3)]
13803 (set (reg:CCFP FPSR_REG)
13804 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13806 "TARGET_USE_FANCY_MATH_387"
13808 [(set_attr "type" "fpspc")
13809 (set_attr "mode" "XF")])
13811 (define_expand "remainderxf3"
13812 [(use (match_operand:XF 0 "register_operand"))
13813 (use (match_operand:XF 1 "general_operand"))
13814 (use (match_operand:XF 2 "general_operand"))]
13815 "TARGET_USE_FANCY_MATH_387"
13817 rtx label = gen_label_rtx ();
13819 rtx op1 = gen_reg_rtx (XFmode);
13820 rtx op2 = gen_reg_rtx (XFmode);
13822 emit_move_insn (op2, operands[2]);
13823 emit_move_insn (op1, operands[1]);
13825 emit_label (label);
13826 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13827 ix86_emit_fp_unordered_jump (label);
13828 LABEL_NUSES (label) = 1;
13830 emit_move_insn (operands[0], op1);
13834 (define_expand "remainder<mode>3"
13835 [(use (match_operand:MODEF 0 "register_operand"))
13836 (use (match_operand:MODEF 1 "general_operand"))
13837 (use (match_operand:MODEF 2 "general_operand"))]
13838 "TARGET_USE_FANCY_MATH_387"
13840 rtx (*gen_truncxf) (rtx, rtx);
13842 rtx label = gen_label_rtx ();
13844 rtx op1 = gen_reg_rtx (XFmode);
13845 rtx op2 = gen_reg_rtx (XFmode);
13847 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13848 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13850 emit_label (label);
13852 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13853 ix86_emit_fp_unordered_jump (label);
13854 LABEL_NUSES (label) = 1;
13856 /* Truncate the result properly for strict SSE math. */
13857 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13858 && !TARGET_MIX_SSE_I387)
13859 gen_truncxf = gen_truncxf<mode>2;
13861 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13863 emit_insn (gen_truncxf (operands[0], op1));
13867 (define_int_iterator SINCOS
13871 (define_int_attr sincos
13872 [(UNSPEC_SIN "sin")
13873 (UNSPEC_COS "cos")])
13875 (define_insn "*<sincos>xf2_i387"
13876 [(set (match_operand:XF 0 "register_operand" "=f")
13877 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13879 "TARGET_USE_FANCY_MATH_387
13880 && flag_unsafe_math_optimizations"
13882 [(set_attr "type" "fpspc")
13883 (set_attr "mode" "XF")])
13885 (define_insn "*<sincos>_extend<mode>xf2_i387"
13886 [(set (match_operand:XF 0 "register_operand" "=f")
13887 (unspec:XF [(float_extend:XF
13888 (match_operand:MODEF 1 "register_operand" "0"))]
13890 "TARGET_USE_FANCY_MATH_387
13891 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13892 || TARGET_MIX_SSE_I387)
13893 && flag_unsafe_math_optimizations"
13895 [(set_attr "type" "fpspc")
13896 (set_attr "mode" "XF")])
13898 ;; When sincos pattern is defined, sin and cos builtin functions will be
13899 ;; expanded to sincos pattern with one of its outputs left unused.
13900 ;; CSE pass will figure out if two sincos patterns can be combined,
13901 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13902 ;; depending on the unused output.
13904 (define_insn "sincosxf3"
13905 [(set (match_operand:XF 0 "register_operand" "=f")
13906 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13907 UNSPEC_SINCOS_COS))
13908 (set (match_operand:XF 1 "register_operand" "=u")
13909 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13910 "TARGET_USE_FANCY_MATH_387
13911 && flag_unsafe_math_optimizations"
13913 [(set_attr "type" "fpspc")
13914 (set_attr "mode" "XF")])
13917 [(set (match_operand:XF 0 "register_operand")
13918 (unspec:XF [(match_operand:XF 2 "register_operand")]
13919 UNSPEC_SINCOS_COS))
13920 (set (match_operand:XF 1 "register_operand")
13921 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13922 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13923 && can_create_pseudo_p ()"
13924 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13927 [(set (match_operand:XF 0 "register_operand")
13928 (unspec:XF [(match_operand:XF 2 "register_operand")]
13929 UNSPEC_SINCOS_COS))
13930 (set (match_operand:XF 1 "register_operand")
13931 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13932 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13933 && can_create_pseudo_p ()"
13934 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13936 (define_insn "sincos_extend<mode>xf3_i387"
13937 [(set (match_operand:XF 0 "register_operand" "=f")
13938 (unspec:XF [(float_extend:XF
13939 (match_operand:MODEF 2 "register_operand" "0"))]
13940 UNSPEC_SINCOS_COS))
13941 (set (match_operand:XF 1 "register_operand" "=u")
13942 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13943 "TARGET_USE_FANCY_MATH_387
13944 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13945 || TARGET_MIX_SSE_I387)
13946 && flag_unsafe_math_optimizations"
13948 [(set_attr "type" "fpspc")
13949 (set_attr "mode" "XF")])
13952 [(set (match_operand:XF 0 "register_operand")
13953 (unspec:XF [(float_extend:XF
13954 (match_operand:MODEF 2 "register_operand"))]
13955 UNSPEC_SINCOS_COS))
13956 (set (match_operand:XF 1 "register_operand")
13957 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13958 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13959 && can_create_pseudo_p ()"
13960 [(set (match_dup 1)
13961 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13964 [(set (match_operand:XF 0 "register_operand")
13965 (unspec:XF [(float_extend:XF
13966 (match_operand:MODEF 2 "register_operand"))]
13967 UNSPEC_SINCOS_COS))
13968 (set (match_operand:XF 1 "register_operand")
13969 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13970 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13971 && can_create_pseudo_p ()"
13972 [(set (match_dup 0)
13973 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13975 (define_expand "sincos<mode>3"
13976 [(use (match_operand:MODEF 0 "register_operand"))
13977 (use (match_operand:MODEF 1 "register_operand"))
13978 (use (match_operand:MODEF 2 "register_operand"))]
13979 "TARGET_USE_FANCY_MATH_387
13980 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13981 || TARGET_MIX_SSE_I387)
13982 && flag_unsafe_math_optimizations"
13984 rtx op0 = gen_reg_rtx (XFmode);
13985 rtx op1 = gen_reg_rtx (XFmode);
13987 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13988 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13989 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13993 (define_insn "fptanxf4_i387"
13994 [(set (match_operand:XF 0 "register_operand" "=f")
13995 (match_operand:XF 3 "const_double_operand" "F"))
13996 (set (match_operand:XF 1 "register_operand" "=u")
13997 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13999 "TARGET_USE_FANCY_MATH_387
14000 && flag_unsafe_math_optimizations
14001 && standard_80387_constant_p (operands[3]) == 2"
14003 [(set_attr "type" "fpspc")
14004 (set_attr "mode" "XF")])
14006 (define_insn "fptan_extend<mode>xf4_i387"
14007 [(set (match_operand:MODEF 0 "register_operand" "=f")
14008 (match_operand:MODEF 3 "const_double_operand" "F"))
14009 (set (match_operand:XF 1 "register_operand" "=u")
14010 (unspec:XF [(float_extend:XF
14011 (match_operand:MODEF 2 "register_operand" "0"))]
14013 "TARGET_USE_FANCY_MATH_387
14014 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14015 || TARGET_MIX_SSE_I387)
14016 && flag_unsafe_math_optimizations
14017 && standard_80387_constant_p (operands[3]) == 2"
14019 [(set_attr "type" "fpspc")
14020 (set_attr "mode" "XF")])
14022 (define_expand "tanxf2"
14023 [(use (match_operand:XF 0 "register_operand"))
14024 (use (match_operand:XF 1 "register_operand"))]
14025 "TARGET_USE_FANCY_MATH_387
14026 && flag_unsafe_math_optimizations"
14028 rtx one = gen_reg_rtx (XFmode);
14029 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14031 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14035 (define_expand "tan<mode>2"
14036 [(use (match_operand:MODEF 0 "register_operand"))
14037 (use (match_operand:MODEF 1 "register_operand"))]
14038 "TARGET_USE_FANCY_MATH_387
14039 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14040 || TARGET_MIX_SSE_I387)
14041 && flag_unsafe_math_optimizations"
14043 rtx op0 = gen_reg_rtx (XFmode);
14045 rtx one = gen_reg_rtx (<MODE>mode);
14046 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14048 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14049 operands[1], op2));
14050 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14054 (define_insn "*fpatanxf3_i387"
14055 [(set (match_operand:XF 0 "register_operand" "=f")
14056 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14057 (match_operand:XF 2 "register_operand" "u")]
14059 (clobber (match_scratch:XF 3 "=2"))]
14060 "TARGET_USE_FANCY_MATH_387
14061 && flag_unsafe_math_optimizations"
14063 [(set_attr "type" "fpspc")
14064 (set_attr "mode" "XF")])
14066 (define_insn "fpatan_extend<mode>xf3_i387"
14067 [(set (match_operand:XF 0 "register_operand" "=f")
14068 (unspec:XF [(float_extend:XF
14069 (match_operand:MODEF 1 "register_operand" "0"))
14071 (match_operand:MODEF 2 "register_operand" "u"))]
14073 (clobber (match_scratch:XF 3 "=2"))]
14074 "TARGET_USE_FANCY_MATH_387
14075 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14076 || TARGET_MIX_SSE_I387)
14077 && flag_unsafe_math_optimizations"
14079 [(set_attr "type" "fpspc")
14080 (set_attr "mode" "XF")])
14082 (define_expand "atan2xf3"
14083 [(parallel [(set (match_operand:XF 0 "register_operand")
14084 (unspec:XF [(match_operand:XF 2 "register_operand")
14085 (match_operand:XF 1 "register_operand")]
14087 (clobber (match_scratch:XF 3))])]
14088 "TARGET_USE_FANCY_MATH_387
14089 && flag_unsafe_math_optimizations")
14091 (define_expand "atan2<mode>3"
14092 [(use (match_operand:MODEF 0 "register_operand"))
14093 (use (match_operand:MODEF 1 "register_operand"))
14094 (use (match_operand:MODEF 2 "register_operand"))]
14095 "TARGET_USE_FANCY_MATH_387
14096 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14097 || TARGET_MIX_SSE_I387)
14098 && flag_unsafe_math_optimizations"
14100 rtx op0 = gen_reg_rtx (XFmode);
14102 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14103 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14107 (define_expand "atanxf2"
14108 [(parallel [(set (match_operand:XF 0 "register_operand")
14109 (unspec:XF [(match_dup 2)
14110 (match_operand:XF 1 "register_operand")]
14112 (clobber (match_scratch:XF 3))])]
14113 "TARGET_USE_FANCY_MATH_387
14114 && flag_unsafe_math_optimizations"
14116 operands[2] = gen_reg_rtx (XFmode);
14117 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14120 (define_expand "atan<mode>2"
14121 [(use (match_operand:MODEF 0 "register_operand"))
14122 (use (match_operand:MODEF 1 "register_operand"))]
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 rtx op0 = gen_reg_rtx (XFmode);
14130 rtx op2 = gen_reg_rtx (<MODE>mode);
14131 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14133 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14134 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14138 (define_expand "asinxf2"
14139 [(set (match_dup 2)
14140 (mult:XF (match_operand:XF 1 "register_operand")
14142 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14143 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14144 (parallel [(set (match_operand:XF 0 "register_operand")
14145 (unspec:XF [(match_dup 5) (match_dup 1)]
14147 (clobber (match_scratch:XF 6))])]
14148 "TARGET_USE_FANCY_MATH_387
14149 && flag_unsafe_math_optimizations"
14153 if (optimize_insn_for_size_p ())
14156 for (i = 2; i < 6; i++)
14157 operands[i] = gen_reg_rtx (XFmode);
14159 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14162 (define_expand "asin<mode>2"
14163 [(use (match_operand:MODEF 0 "register_operand"))
14164 (use (match_operand:MODEF 1 "general_operand"))]
14165 "TARGET_USE_FANCY_MATH_387
14166 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14167 || TARGET_MIX_SSE_I387)
14168 && flag_unsafe_math_optimizations"
14170 rtx op0 = gen_reg_rtx (XFmode);
14171 rtx op1 = gen_reg_rtx (XFmode);
14173 if (optimize_insn_for_size_p ())
14176 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14177 emit_insn (gen_asinxf2 (op0, op1));
14178 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14182 (define_expand "acosxf2"
14183 [(set (match_dup 2)
14184 (mult:XF (match_operand:XF 1 "register_operand")
14186 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14187 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14188 (parallel [(set (match_operand:XF 0 "register_operand")
14189 (unspec:XF [(match_dup 1) (match_dup 5)]
14191 (clobber (match_scratch:XF 6))])]
14192 "TARGET_USE_FANCY_MATH_387
14193 && flag_unsafe_math_optimizations"
14197 if (optimize_insn_for_size_p ())
14200 for (i = 2; i < 6; i++)
14201 operands[i] = gen_reg_rtx (XFmode);
14203 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14206 (define_expand "acos<mode>2"
14207 [(use (match_operand:MODEF 0 "register_operand"))
14208 (use (match_operand:MODEF 1 "general_operand"))]
14209 "TARGET_USE_FANCY_MATH_387
14210 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14211 || TARGET_MIX_SSE_I387)
14212 && flag_unsafe_math_optimizations"
14214 rtx op0 = gen_reg_rtx (XFmode);
14215 rtx op1 = gen_reg_rtx (XFmode);
14217 if (optimize_insn_for_size_p ())
14220 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14221 emit_insn (gen_acosxf2 (op0, op1));
14222 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14226 (define_insn "fyl2xxf3_i387"
14227 [(set (match_operand:XF 0 "register_operand" "=f")
14228 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14229 (match_operand:XF 2 "register_operand" "u")]
14231 (clobber (match_scratch:XF 3 "=2"))]
14232 "TARGET_USE_FANCY_MATH_387
14233 && flag_unsafe_math_optimizations"
14235 [(set_attr "type" "fpspc")
14236 (set_attr "mode" "XF")])
14238 (define_insn "fyl2x_extend<mode>xf3_i387"
14239 [(set (match_operand:XF 0 "register_operand" "=f")
14240 (unspec:XF [(float_extend:XF
14241 (match_operand:MODEF 1 "register_operand" "0"))
14242 (match_operand:XF 2 "register_operand" "u")]
14244 (clobber (match_scratch:XF 3 "=2"))]
14245 "TARGET_USE_FANCY_MATH_387
14246 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14247 || TARGET_MIX_SSE_I387)
14248 && flag_unsafe_math_optimizations"
14250 [(set_attr "type" "fpspc")
14251 (set_attr "mode" "XF")])
14253 (define_expand "logxf2"
14254 [(parallel [(set (match_operand:XF 0 "register_operand")
14255 (unspec:XF [(match_operand:XF 1 "register_operand")
14256 (match_dup 2)] UNSPEC_FYL2X))
14257 (clobber (match_scratch:XF 3))])]
14258 "TARGET_USE_FANCY_MATH_387
14259 && flag_unsafe_math_optimizations"
14261 operands[2] = gen_reg_rtx (XFmode);
14262 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14265 (define_expand "log<mode>2"
14266 [(use (match_operand:MODEF 0 "register_operand"))
14267 (use (match_operand:MODEF 1 "register_operand"))]
14268 "TARGET_USE_FANCY_MATH_387
14269 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14270 || TARGET_MIX_SSE_I387)
14271 && flag_unsafe_math_optimizations"
14273 rtx op0 = gen_reg_rtx (XFmode);
14275 rtx op2 = gen_reg_rtx (XFmode);
14276 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14278 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14279 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14283 (define_expand "log10xf2"
14284 [(parallel [(set (match_operand:XF 0 "register_operand")
14285 (unspec:XF [(match_operand:XF 1 "register_operand")
14286 (match_dup 2)] UNSPEC_FYL2X))
14287 (clobber (match_scratch:XF 3))])]
14288 "TARGET_USE_FANCY_MATH_387
14289 && flag_unsafe_math_optimizations"
14291 operands[2] = gen_reg_rtx (XFmode);
14292 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14295 (define_expand "log10<mode>2"
14296 [(use (match_operand:MODEF 0 "register_operand"))
14297 (use (match_operand:MODEF 1 "register_operand"))]
14298 "TARGET_USE_FANCY_MATH_387
14299 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14300 || TARGET_MIX_SSE_I387)
14301 && flag_unsafe_math_optimizations"
14303 rtx op0 = gen_reg_rtx (XFmode);
14305 rtx op2 = gen_reg_rtx (XFmode);
14306 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14308 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14309 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14313 (define_expand "log2xf2"
14314 [(parallel [(set (match_operand:XF 0 "register_operand")
14315 (unspec:XF [(match_operand:XF 1 "register_operand")
14316 (match_dup 2)] UNSPEC_FYL2X))
14317 (clobber (match_scratch:XF 3))])]
14318 "TARGET_USE_FANCY_MATH_387
14319 && flag_unsafe_math_optimizations"
14321 operands[2] = gen_reg_rtx (XFmode);
14322 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14325 (define_expand "log2<mode>2"
14326 [(use (match_operand:MODEF 0 "register_operand"))
14327 (use (match_operand:MODEF 1 "register_operand"))]
14328 "TARGET_USE_FANCY_MATH_387
14329 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14330 || TARGET_MIX_SSE_I387)
14331 && flag_unsafe_math_optimizations"
14333 rtx op0 = gen_reg_rtx (XFmode);
14335 rtx op2 = gen_reg_rtx (XFmode);
14336 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14338 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14339 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14343 (define_insn "fyl2xp1xf3_i387"
14344 [(set (match_operand:XF 0 "register_operand" "=f")
14345 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14346 (match_operand:XF 2 "register_operand" "u")]
14348 (clobber (match_scratch:XF 3 "=2"))]
14349 "TARGET_USE_FANCY_MATH_387
14350 && flag_unsafe_math_optimizations"
14352 [(set_attr "type" "fpspc")
14353 (set_attr "mode" "XF")])
14355 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14356 [(set (match_operand:XF 0 "register_operand" "=f")
14357 (unspec:XF [(float_extend:XF
14358 (match_operand:MODEF 1 "register_operand" "0"))
14359 (match_operand:XF 2 "register_operand" "u")]
14361 (clobber (match_scratch:XF 3 "=2"))]
14362 "TARGET_USE_FANCY_MATH_387
14363 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14364 || TARGET_MIX_SSE_I387)
14365 && flag_unsafe_math_optimizations"
14367 [(set_attr "type" "fpspc")
14368 (set_attr "mode" "XF")])
14370 (define_expand "log1pxf2"
14371 [(use (match_operand:XF 0 "register_operand"))
14372 (use (match_operand:XF 1 "register_operand"))]
14373 "TARGET_USE_FANCY_MATH_387
14374 && flag_unsafe_math_optimizations"
14376 if (optimize_insn_for_size_p ())
14379 ix86_emit_i387_log1p (operands[0], operands[1]);
14383 (define_expand "log1p<mode>2"
14384 [(use (match_operand:MODEF 0 "register_operand"))
14385 (use (match_operand:MODEF 1 "register_operand"))]
14386 "TARGET_USE_FANCY_MATH_387
14387 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14388 || TARGET_MIX_SSE_I387)
14389 && flag_unsafe_math_optimizations"
14393 if (optimize_insn_for_size_p ())
14396 op0 = gen_reg_rtx (XFmode);
14398 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14400 ix86_emit_i387_log1p (op0, operands[1]);
14401 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14405 (define_insn "fxtractxf3_i387"
14406 [(set (match_operand:XF 0 "register_operand" "=f")
14407 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14408 UNSPEC_XTRACT_FRACT))
14409 (set (match_operand:XF 1 "register_operand" "=u")
14410 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14411 "TARGET_USE_FANCY_MATH_387
14412 && flag_unsafe_math_optimizations"
14414 [(set_attr "type" "fpspc")
14415 (set_attr "mode" "XF")])
14417 (define_insn "fxtract_extend<mode>xf3_i387"
14418 [(set (match_operand:XF 0 "register_operand" "=f")
14419 (unspec:XF [(float_extend:XF
14420 (match_operand:MODEF 2 "register_operand" "0"))]
14421 UNSPEC_XTRACT_FRACT))
14422 (set (match_operand:XF 1 "register_operand" "=u")
14423 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14424 "TARGET_USE_FANCY_MATH_387
14425 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14426 || TARGET_MIX_SSE_I387)
14427 && flag_unsafe_math_optimizations"
14429 [(set_attr "type" "fpspc")
14430 (set_attr "mode" "XF")])
14432 (define_expand "logbxf2"
14433 [(parallel [(set (match_dup 2)
14434 (unspec:XF [(match_operand:XF 1 "register_operand")]
14435 UNSPEC_XTRACT_FRACT))
14436 (set (match_operand:XF 0 "register_operand")
14437 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14438 "TARGET_USE_FANCY_MATH_387
14439 && flag_unsafe_math_optimizations"
14440 "operands[2] = gen_reg_rtx (XFmode);")
14442 (define_expand "logb<mode>2"
14443 [(use (match_operand:MODEF 0 "register_operand"))
14444 (use (match_operand:MODEF 1 "register_operand"))]
14445 "TARGET_USE_FANCY_MATH_387
14446 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14447 || TARGET_MIX_SSE_I387)
14448 && flag_unsafe_math_optimizations"
14450 rtx op0 = gen_reg_rtx (XFmode);
14451 rtx op1 = gen_reg_rtx (XFmode);
14453 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14454 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14458 (define_expand "ilogbxf2"
14459 [(use (match_operand:SI 0 "register_operand"))
14460 (use (match_operand:XF 1 "register_operand"))]
14461 "TARGET_USE_FANCY_MATH_387
14462 && flag_unsafe_math_optimizations"
14466 if (optimize_insn_for_size_p ())
14469 op0 = gen_reg_rtx (XFmode);
14470 op1 = gen_reg_rtx (XFmode);
14472 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14473 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14477 (define_expand "ilogb<mode>2"
14478 [(use (match_operand:SI 0 "register_operand"))
14479 (use (match_operand:MODEF 1 "register_operand"))]
14480 "TARGET_USE_FANCY_MATH_387
14481 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14482 || TARGET_MIX_SSE_I387)
14483 && flag_unsafe_math_optimizations"
14487 if (optimize_insn_for_size_p ())
14490 op0 = gen_reg_rtx (XFmode);
14491 op1 = gen_reg_rtx (XFmode);
14493 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14494 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14498 (define_insn "*f2xm1xf2_i387"
14499 [(set (match_operand:XF 0 "register_operand" "=f")
14500 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14502 "TARGET_USE_FANCY_MATH_387
14503 && flag_unsafe_math_optimizations"
14505 [(set_attr "type" "fpspc")
14506 (set_attr "mode" "XF")])
14508 (define_insn "*fscalexf4_i387"
14509 [(set (match_operand:XF 0 "register_operand" "=f")
14510 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14511 (match_operand:XF 3 "register_operand" "1")]
14512 UNSPEC_FSCALE_FRACT))
14513 (set (match_operand:XF 1 "register_operand" "=u")
14514 (unspec:XF [(match_dup 2) (match_dup 3)]
14515 UNSPEC_FSCALE_EXP))]
14516 "TARGET_USE_FANCY_MATH_387
14517 && flag_unsafe_math_optimizations"
14519 [(set_attr "type" "fpspc")
14520 (set_attr "mode" "XF")])
14522 (define_expand "expNcorexf3"
14523 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14524 (match_operand:XF 2 "register_operand")))
14525 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14526 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14527 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14528 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14529 (parallel [(set (match_operand:XF 0 "register_operand")
14530 (unspec:XF [(match_dup 8) (match_dup 4)]
14531 UNSPEC_FSCALE_FRACT))
14533 (unspec:XF [(match_dup 8) (match_dup 4)]
14534 UNSPEC_FSCALE_EXP))])]
14535 "TARGET_USE_FANCY_MATH_387
14536 && flag_unsafe_math_optimizations"
14540 if (optimize_insn_for_size_p ())
14543 for (i = 3; i < 10; i++)
14544 operands[i] = gen_reg_rtx (XFmode);
14546 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14549 (define_expand "expxf2"
14550 [(use (match_operand:XF 0 "register_operand"))
14551 (use (match_operand:XF 1 "register_operand"))]
14552 "TARGET_USE_FANCY_MATH_387
14553 && flag_unsafe_math_optimizations"
14557 if (optimize_insn_for_size_p ())
14560 op2 = gen_reg_rtx (XFmode);
14561 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14563 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14567 (define_expand "exp<mode>2"
14568 [(use (match_operand:MODEF 0 "register_operand"))
14569 (use (match_operand:MODEF 1 "general_operand"))]
14570 "TARGET_USE_FANCY_MATH_387
14571 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14572 || TARGET_MIX_SSE_I387)
14573 && flag_unsafe_math_optimizations"
14577 if (optimize_insn_for_size_p ())
14580 op0 = gen_reg_rtx (XFmode);
14581 op1 = gen_reg_rtx (XFmode);
14583 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14584 emit_insn (gen_expxf2 (op0, op1));
14585 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14589 (define_expand "exp10xf2"
14590 [(use (match_operand:XF 0 "register_operand"))
14591 (use (match_operand:XF 1 "register_operand"))]
14592 "TARGET_USE_FANCY_MATH_387
14593 && flag_unsafe_math_optimizations"
14597 if (optimize_insn_for_size_p ())
14600 op2 = gen_reg_rtx (XFmode);
14601 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14603 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14607 (define_expand "exp10<mode>2"
14608 [(use (match_operand:MODEF 0 "register_operand"))
14609 (use (match_operand:MODEF 1 "general_operand"))]
14610 "TARGET_USE_FANCY_MATH_387
14611 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14612 || TARGET_MIX_SSE_I387)
14613 && flag_unsafe_math_optimizations"
14617 if (optimize_insn_for_size_p ())
14620 op0 = gen_reg_rtx (XFmode);
14621 op1 = gen_reg_rtx (XFmode);
14623 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14624 emit_insn (gen_exp10xf2 (op0, op1));
14625 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14629 (define_expand "exp2xf2"
14630 [(use (match_operand:XF 0 "register_operand"))
14631 (use (match_operand:XF 1 "register_operand"))]
14632 "TARGET_USE_FANCY_MATH_387
14633 && flag_unsafe_math_optimizations"
14637 if (optimize_insn_for_size_p ())
14640 op2 = gen_reg_rtx (XFmode);
14641 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14643 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14647 (define_expand "exp2<mode>2"
14648 [(use (match_operand:MODEF 0 "register_operand"))
14649 (use (match_operand:MODEF 1 "general_operand"))]
14650 "TARGET_USE_FANCY_MATH_387
14651 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14652 || TARGET_MIX_SSE_I387)
14653 && flag_unsafe_math_optimizations"
14657 if (optimize_insn_for_size_p ())
14660 op0 = gen_reg_rtx (XFmode);
14661 op1 = gen_reg_rtx (XFmode);
14663 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14664 emit_insn (gen_exp2xf2 (op0, op1));
14665 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14669 (define_expand "expm1xf2"
14670 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14672 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14673 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14674 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14675 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14676 (parallel [(set (match_dup 7)
14677 (unspec:XF [(match_dup 6) (match_dup 4)]
14678 UNSPEC_FSCALE_FRACT))
14680 (unspec:XF [(match_dup 6) (match_dup 4)]
14681 UNSPEC_FSCALE_EXP))])
14682 (parallel [(set (match_dup 10)
14683 (unspec:XF [(match_dup 9) (match_dup 8)]
14684 UNSPEC_FSCALE_FRACT))
14685 (set (match_dup 11)
14686 (unspec:XF [(match_dup 9) (match_dup 8)]
14687 UNSPEC_FSCALE_EXP))])
14688 (set (match_dup 12) (minus:XF (match_dup 10)
14689 (float_extend:XF (match_dup 13))))
14690 (set (match_operand:XF 0 "register_operand")
14691 (plus:XF (match_dup 12) (match_dup 7)))]
14692 "TARGET_USE_FANCY_MATH_387
14693 && flag_unsafe_math_optimizations"
14697 if (optimize_insn_for_size_p ())
14700 for (i = 2; i < 13; i++)
14701 operands[i] = gen_reg_rtx (XFmode);
14704 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14706 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14709 (define_expand "expm1<mode>2"
14710 [(use (match_operand:MODEF 0 "register_operand"))
14711 (use (match_operand:MODEF 1 "general_operand"))]
14712 "TARGET_USE_FANCY_MATH_387
14713 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14714 || TARGET_MIX_SSE_I387)
14715 && flag_unsafe_math_optimizations"
14719 if (optimize_insn_for_size_p ())
14722 op0 = gen_reg_rtx (XFmode);
14723 op1 = gen_reg_rtx (XFmode);
14725 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14726 emit_insn (gen_expm1xf2 (op0, op1));
14727 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14731 (define_expand "ldexpxf3"
14732 [(set (match_dup 3)
14733 (float:XF (match_operand:SI 2 "register_operand")))
14734 (parallel [(set (match_operand:XF 0 " register_operand")
14735 (unspec:XF [(match_operand:XF 1 "register_operand")
14737 UNSPEC_FSCALE_FRACT))
14739 (unspec:XF [(match_dup 1) (match_dup 3)]
14740 UNSPEC_FSCALE_EXP))])]
14741 "TARGET_USE_FANCY_MATH_387
14742 && flag_unsafe_math_optimizations"
14744 if (optimize_insn_for_size_p ())
14747 operands[3] = gen_reg_rtx (XFmode);
14748 operands[4] = gen_reg_rtx (XFmode);
14751 (define_expand "ldexp<mode>3"
14752 [(use (match_operand:MODEF 0 "register_operand"))
14753 (use (match_operand:MODEF 1 "general_operand"))
14754 (use (match_operand:SI 2 "register_operand"))]
14755 "TARGET_USE_FANCY_MATH_387
14756 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14757 || TARGET_MIX_SSE_I387)
14758 && flag_unsafe_math_optimizations"
14762 if (optimize_insn_for_size_p ())
14765 op0 = gen_reg_rtx (XFmode);
14766 op1 = gen_reg_rtx (XFmode);
14768 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14769 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14770 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14774 (define_expand "scalbxf3"
14775 [(parallel [(set (match_operand:XF 0 " register_operand")
14776 (unspec:XF [(match_operand:XF 1 "register_operand")
14777 (match_operand:XF 2 "register_operand")]
14778 UNSPEC_FSCALE_FRACT))
14780 (unspec:XF [(match_dup 1) (match_dup 2)]
14781 UNSPEC_FSCALE_EXP))])]
14782 "TARGET_USE_FANCY_MATH_387
14783 && flag_unsafe_math_optimizations"
14785 if (optimize_insn_for_size_p ())
14788 operands[3] = gen_reg_rtx (XFmode);
14791 (define_expand "scalb<mode>3"
14792 [(use (match_operand:MODEF 0 "register_operand"))
14793 (use (match_operand:MODEF 1 "general_operand"))
14794 (use (match_operand:MODEF 2 "general_operand"))]
14795 "TARGET_USE_FANCY_MATH_387
14796 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14797 || TARGET_MIX_SSE_I387)
14798 && flag_unsafe_math_optimizations"
14802 if (optimize_insn_for_size_p ())
14805 op0 = gen_reg_rtx (XFmode);
14806 op1 = gen_reg_rtx (XFmode);
14807 op2 = gen_reg_rtx (XFmode);
14809 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14810 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14811 emit_insn (gen_scalbxf3 (op0, op1, op2));
14812 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14816 (define_expand "significandxf2"
14817 [(parallel [(set (match_operand:XF 0 "register_operand")
14818 (unspec:XF [(match_operand:XF 1 "register_operand")]
14819 UNSPEC_XTRACT_FRACT))
14821 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14822 "TARGET_USE_FANCY_MATH_387
14823 && flag_unsafe_math_optimizations"
14824 "operands[2] = gen_reg_rtx (XFmode);")
14826 (define_expand "significand<mode>2"
14827 [(use (match_operand:MODEF 0 "register_operand"))
14828 (use (match_operand:MODEF 1 "register_operand"))]
14829 "TARGET_USE_FANCY_MATH_387
14830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14831 || TARGET_MIX_SSE_I387)
14832 && flag_unsafe_math_optimizations"
14834 rtx op0 = gen_reg_rtx (XFmode);
14835 rtx op1 = gen_reg_rtx (XFmode);
14837 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14838 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14843 (define_insn "sse4_1_round<mode>2"
14844 [(set (match_operand:MODEF 0 "register_operand" "=x")
14845 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14846 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14849 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14850 [(set_attr "type" "ssecvt")
14851 (set_attr "prefix_extra" "1")
14852 (set_attr "prefix" "maybe_vex")
14853 (set_attr "mode" "<MODE>")])
14855 (define_insn "rintxf2"
14856 [(set (match_operand:XF 0 "register_operand" "=f")
14857 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14859 "TARGET_USE_FANCY_MATH_387
14860 && flag_unsafe_math_optimizations"
14862 [(set_attr "type" "fpspc")
14863 (set_attr "mode" "XF")])
14865 (define_expand "rint<mode>2"
14866 [(use (match_operand:MODEF 0 "register_operand"))
14867 (use (match_operand:MODEF 1 "register_operand"))]
14868 "(TARGET_USE_FANCY_MATH_387
14869 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14870 || TARGET_MIX_SSE_I387)
14871 && flag_unsafe_math_optimizations)
14872 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14873 && !flag_trapping_math)"
14875 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14876 && !flag_trapping_math)
14879 emit_insn (gen_sse4_1_round<mode>2
14880 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14881 else if (optimize_insn_for_size_p ())
14884 ix86_expand_rint (operands[0], operands[1]);
14888 rtx op0 = gen_reg_rtx (XFmode);
14889 rtx op1 = gen_reg_rtx (XFmode);
14891 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14892 emit_insn (gen_rintxf2 (op0, op1));
14894 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14899 (define_expand "round<mode>2"
14900 [(match_operand:X87MODEF 0 "register_operand")
14901 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14902 "(TARGET_USE_FANCY_MATH_387
14903 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14904 || TARGET_MIX_SSE_I387)
14905 && flag_unsafe_math_optimizations)
14906 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14907 && !flag_trapping_math && !flag_rounding_math)"
14909 if (optimize_insn_for_size_p ())
14912 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14913 && !flag_trapping_math && !flag_rounding_math)
14917 operands[1] = force_reg (<MODE>mode, operands[1]);
14918 ix86_expand_round_sse4 (operands[0], operands[1]);
14920 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14921 ix86_expand_round (operands[0], operands[1]);
14923 ix86_expand_rounddf_32 (operands[0], operands[1]);
14927 operands[1] = force_reg (<MODE>mode, operands[1]);
14928 ix86_emit_i387_round (operands[0], operands[1]);
14933 (define_insn_and_split "*fistdi2_1"
14934 [(set (match_operand:DI 0 "nonimmediate_operand")
14935 (unspec:DI [(match_operand:XF 1 "register_operand")]
14937 "TARGET_USE_FANCY_MATH_387
14938 && can_create_pseudo_p ()"
14943 if (memory_operand (operands[0], VOIDmode))
14944 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14947 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14948 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14953 [(set_attr "type" "fpspc")
14954 (set_attr "mode" "DI")])
14956 (define_insn "fistdi2"
14957 [(set (match_operand:DI 0 "memory_operand" "=m")
14958 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14960 (clobber (match_scratch:XF 2 "=&1f"))]
14961 "TARGET_USE_FANCY_MATH_387"
14962 "* return output_fix_trunc (insn, operands, false);"
14963 [(set_attr "type" "fpspc")
14964 (set_attr "mode" "DI")])
14966 (define_insn "fistdi2_with_temp"
14967 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14968 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14970 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14971 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14972 "TARGET_USE_FANCY_MATH_387"
14974 [(set_attr "type" "fpspc")
14975 (set_attr "mode" "DI")])
14978 [(set (match_operand:DI 0 "register_operand")
14979 (unspec:DI [(match_operand:XF 1 "register_operand")]
14981 (clobber (match_operand:DI 2 "memory_operand"))
14982 (clobber (match_scratch 3))]
14984 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14985 (clobber (match_dup 3))])
14986 (set (match_dup 0) (match_dup 2))])
14989 [(set (match_operand:DI 0 "memory_operand")
14990 (unspec:DI [(match_operand:XF 1 "register_operand")]
14992 (clobber (match_operand:DI 2 "memory_operand"))
14993 (clobber (match_scratch 3))]
14995 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14996 (clobber (match_dup 3))])])
14998 (define_insn_and_split "*fist<mode>2_1"
14999 [(set (match_operand:SWI24 0 "register_operand")
15000 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15002 "TARGET_USE_FANCY_MATH_387
15003 && can_create_pseudo_p ()"
15008 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15009 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15013 [(set_attr "type" "fpspc")
15014 (set_attr "mode" "<MODE>")])
15016 (define_insn "fist<mode>2"
15017 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15018 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15020 "TARGET_USE_FANCY_MATH_387"
15021 "* return output_fix_trunc (insn, operands, false);"
15022 [(set_attr "type" "fpspc")
15023 (set_attr "mode" "<MODE>")])
15025 (define_insn "fist<mode>2_with_temp"
15026 [(set (match_operand:SWI24 0 "register_operand" "=r")
15027 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15029 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15030 "TARGET_USE_FANCY_MATH_387"
15032 [(set_attr "type" "fpspc")
15033 (set_attr "mode" "<MODE>")])
15036 [(set (match_operand:SWI24 0 "register_operand")
15037 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15039 (clobber (match_operand:SWI24 2 "memory_operand"))]
15041 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15042 (set (match_dup 0) (match_dup 2))])
15045 [(set (match_operand:SWI24 0 "memory_operand")
15046 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15048 (clobber (match_operand:SWI24 2 "memory_operand"))]
15050 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15052 (define_expand "lrintxf<mode>2"
15053 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15054 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15056 "TARGET_USE_FANCY_MATH_387")
15058 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
15059 [(set (match_operand:SWI48x 0 "nonimmediate_operand")
15060 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand")]
15061 UNSPEC_FIX_NOTRUNC))]
15062 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15063 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
15065 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15066 [(match_operand:SWI248x 0 "nonimmediate_operand")
15067 (match_operand:X87MODEF 1 "register_operand")]
15068 "(TARGET_USE_FANCY_MATH_387
15069 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15070 || TARGET_MIX_SSE_I387)
15071 && flag_unsafe_math_optimizations)
15072 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15073 && <SWI248x:MODE>mode != HImode
15074 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15075 && !flag_trapping_math && !flag_rounding_math)"
15077 if (optimize_insn_for_size_p ())
15080 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15081 && <SWI248x:MODE>mode != HImode
15082 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15083 && !flag_trapping_math && !flag_rounding_math)
15084 ix86_expand_lround (operands[0], operands[1]);
15086 ix86_emit_i387_round (operands[0], operands[1]);
15090 (define_int_iterator FRNDINT_ROUNDING
15091 [UNSPEC_FRNDINT_FLOOR
15092 UNSPEC_FRNDINT_CEIL
15093 UNSPEC_FRNDINT_TRUNC])
15095 (define_int_iterator FIST_ROUNDING
15099 ;; Base name for define_insn
15100 (define_int_attr rounding_insn
15101 [(UNSPEC_FRNDINT_FLOOR "floor")
15102 (UNSPEC_FRNDINT_CEIL "ceil")
15103 (UNSPEC_FRNDINT_TRUNC "btrunc")
15104 (UNSPEC_FIST_FLOOR "floor")
15105 (UNSPEC_FIST_CEIL "ceil")])
15107 (define_int_attr rounding
15108 [(UNSPEC_FRNDINT_FLOOR "floor")
15109 (UNSPEC_FRNDINT_CEIL "ceil")
15110 (UNSPEC_FRNDINT_TRUNC "trunc")
15111 (UNSPEC_FIST_FLOOR "floor")
15112 (UNSPEC_FIST_CEIL "ceil")])
15114 (define_int_attr ROUNDING
15115 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15116 (UNSPEC_FRNDINT_CEIL "CEIL")
15117 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15118 (UNSPEC_FIST_FLOOR "FLOOR")
15119 (UNSPEC_FIST_CEIL "CEIL")])
15121 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15122 (define_insn_and_split "frndintxf2_<rounding>"
15123 [(set (match_operand:XF 0 "register_operand")
15124 (unspec:XF [(match_operand:XF 1 "register_operand")]
15126 (clobber (reg:CC FLAGS_REG))]
15127 "TARGET_USE_FANCY_MATH_387
15128 && flag_unsafe_math_optimizations
15129 && can_create_pseudo_p ()"
15134 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15136 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15137 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15139 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15140 operands[2], operands[3]));
15143 [(set_attr "type" "frndint")
15144 (set_attr "i387_cw" "<rounding>")
15145 (set_attr "mode" "XF")])
15147 (define_insn "frndintxf2_<rounding>_i387"
15148 [(set (match_operand:XF 0 "register_operand" "=f")
15149 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15151 (use (match_operand:HI 2 "memory_operand" "m"))
15152 (use (match_operand:HI 3 "memory_operand" "m"))]
15153 "TARGET_USE_FANCY_MATH_387
15154 && flag_unsafe_math_optimizations"
15155 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15156 [(set_attr "type" "frndint")
15157 (set_attr "i387_cw" "<rounding>")
15158 (set_attr "mode" "XF")])
15160 (define_expand "<rounding_insn>xf2"
15161 [(parallel [(set (match_operand:XF 0 "register_operand")
15162 (unspec:XF [(match_operand:XF 1 "register_operand")]
15164 (clobber (reg:CC FLAGS_REG))])]
15165 "TARGET_USE_FANCY_MATH_387
15166 && flag_unsafe_math_optimizations
15167 && !optimize_insn_for_size_p ()")
15169 (define_expand "<rounding_insn><mode>2"
15170 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15171 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15173 (clobber (reg:CC FLAGS_REG))])]
15174 "(TARGET_USE_FANCY_MATH_387
15175 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15176 || TARGET_MIX_SSE_I387)
15177 && flag_unsafe_math_optimizations)
15178 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15179 && !flag_trapping_math)"
15181 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15182 && !flag_trapping_math)
15185 emit_insn (gen_sse4_1_round<mode>2
15186 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15187 else if (optimize_insn_for_size_p ())
15189 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15191 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15192 ix86_expand_floorceil (operands[0], operands[1], true);
15193 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15194 ix86_expand_floorceil (operands[0], operands[1], false);
15195 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15196 ix86_expand_trunc (operands[0], operands[1]);
15198 gcc_unreachable ();
15202 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15203 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15204 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15205 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15206 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15207 ix86_expand_truncdf_32 (operands[0], operands[1]);
15209 gcc_unreachable ();
15216 if (optimize_insn_for_size_p ())
15219 op0 = gen_reg_rtx (XFmode);
15220 op1 = gen_reg_rtx (XFmode);
15221 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15222 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15224 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15229 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15230 (define_insn_and_split "frndintxf2_mask_pm"
15231 [(set (match_operand:XF 0 "register_operand")
15232 (unspec:XF [(match_operand:XF 1 "register_operand")]
15233 UNSPEC_FRNDINT_MASK_PM))
15234 (clobber (reg:CC FLAGS_REG))]
15235 "TARGET_USE_FANCY_MATH_387
15236 && flag_unsafe_math_optimizations
15237 && can_create_pseudo_p ()"
15242 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15244 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15245 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15247 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15248 operands[2], operands[3]));
15251 [(set_attr "type" "frndint")
15252 (set_attr "i387_cw" "mask_pm")
15253 (set_attr "mode" "XF")])
15255 (define_insn "frndintxf2_mask_pm_i387"
15256 [(set (match_operand:XF 0 "register_operand" "=f")
15257 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15258 UNSPEC_FRNDINT_MASK_PM))
15259 (use (match_operand:HI 2 "memory_operand" "m"))
15260 (use (match_operand:HI 3 "memory_operand" "m"))]
15261 "TARGET_USE_FANCY_MATH_387
15262 && flag_unsafe_math_optimizations"
15263 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15264 [(set_attr "type" "frndint")
15265 (set_attr "i387_cw" "mask_pm")
15266 (set_attr "mode" "XF")])
15268 (define_expand "nearbyintxf2"
15269 [(parallel [(set (match_operand:XF 0 "register_operand")
15270 (unspec:XF [(match_operand:XF 1 "register_operand")]
15271 UNSPEC_FRNDINT_MASK_PM))
15272 (clobber (reg:CC FLAGS_REG))])]
15273 "TARGET_USE_FANCY_MATH_387
15274 && flag_unsafe_math_optimizations")
15276 (define_expand "nearbyint<mode>2"
15277 [(use (match_operand:MODEF 0 "register_operand"))
15278 (use (match_operand:MODEF 1 "register_operand"))]
15279 "TARGET_USE_FANCY_MATH_387
15280 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15281 || TARGET_MIX_SSE_I387)
15282 && flag_unsafe_math_optimizations"
15284 rtx op0 = gen_reg_rtx (XFmode);
15285 rtx op1 = gen_reg_rtx (XFmode);
15287 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15288 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15290 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15294 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15295 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15296 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15297 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15299 (clobber (reg:CC FLAGS_REG))]
15300 "TARGET_USE_FANCY_MATH_387
15301 && flag_unsafe_math_optimizations
15302 && can_create_pseudo_p ()"
15307 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15309 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15310 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15311 if (memory_operand (operands[0], VOIDmode))
15312 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15313 operands[2], operands[3]));
15316 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15317 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15318 (operands[0], operands[1], operands[2],
15319 operands[3], operands[4]));
15323 [(set_attr "type" "fistp")
15324 (set_attr "i387_cw" "<rounding>")
15325 (set_attr "mode" "<MODE>")])
15327 (define_insn "fistdi2_<rounding>"
15328 [(set (match_operand:DI 0 "memory_operand" "=m")
15329 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15331 (use (match_operand:HI 2 "memory_operand" "m"))
15332 (use (match_operand:HI 3 "memory_operand" "m"))
15333 (clobber (match_scratch:XF 4 "=&1f"))]
15334 "TARGET_USE_FANCY_MATH_387
15335 && flag_unsafe_math_optimizations"
15336 "* return output_fix_trunc (insn, operands, false);"
15337 [(set_attr "type" "fistp")
15338 (set_attr "i387_cw" "<rounding>")
15339 (set_attr "mode" "DI")])
15341 (define_insn "fistdi2_<rounding>_with_temp"
15342 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15343 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15345 (use (match_operand:HI 2 "memory_operand" "m,m"))
15346 (use (match_operand:HI 3 "memory_operand" "m,m"))
15347 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15348 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15349 "TARGET_USE_FANCY_MATH_387
15350 && flag_unsafe_math_optimizations"
15352 [(set_attr "type" "fistp")
15353 (set_attr "i387_cw" "<rounding>")
15354 (set_attr "mode" "DI")])
15357 [(set (match_operand:DI 0 "register_operand")
15358 (unspec:DI [(match_operand:XF 1 "register_operand")]
15360 (use (match_operand:HI 2 "memory_operand"))
15361 (use (match_operand:HI 3 "memory_operand"))
15362 (clobber (match_operand:DI 4 "memory_operand"))
15363 (clobber (match_scratch 5))]
15365 [(parallel [(set (match_dup 4)
15366 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15367 (use (match_dup 2))
15368 (use (match_dup 3))
15369 (clobber (match_dup 5))])
15370 (set (match_dup 0) (match_dup 4))])
15373 [(set (match_operand:DI 0 "memory_operand")
15374 (unspec:DI [(match_operand:XF 1 "register_operand")]
15376 (use (match_operand:HI 2 "memory_operand"))
15377 (use (match_operand:HI 3 "memory_operand"))
15378 (clobber (match_operand:DI 4 "memory_operand"))
15379 (clobber (match_scratch 5))]
15381 [(parallel [(set (match_dup 0)
15382 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15383 (use (match_dup 2))
15384 (use (match_dup 3))
15385 (clobber (match_dup 5))])])
15387 (define_insn "fist<mode>2_<rounding>"
15388 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15389 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15391 (use (match_operand:HI 2 "memory_operand" "m"))
15392 (use (match_operand:HI 3 "memory_operand" "m"))]
15393 "TARGET_USE_FANCY_MATH_387
15394 && flag_unsafe_math_optimizations"
15395 "* return output_fix_trunc (insn, operands, false);"
15396 [(set_attr "type" "fistp")
15397 (set_attr "i387_cw" "<rounding>")
15398 (set_attr "mode" "<MODE>")])
15400 (define_insn "fist<mode>2_<rounding>_with_temp"
15401 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15402 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15404 (use (match_operand:HI 2 "memory_operand" "m,m"))
15405 (use (match_operand:HI 3 "memory_operand" "m,m"))
15406 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15407 "TARGET_USE_FANCY_MATH_387
15408 && flag_unsafe_math_optimizations"
15410 [(set_attr "type" "fistp")
15411 (set_attr "i387_cw" "<rounding>")
15412 (set_attr "mode" "<MODE>")])
15415 [(set (match_operand:SWI24 0 "register_operand")
15416 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15418 (use (match_operand:HI 2 "memory_operand"))
15419 (use (match_operand:HI 3 "memory_operand"))
15420 (clobber (match_operand:SWI24 4 "memory_operand"))]
15422 [(parallel [(set (match_dup 4)
15423 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15424 (use (match_dup 2))
15425 (use (match_dup 3))])
15426 (set (match_dup 0) (match_dup 4))])
15429 [(set (match_operand:SWI24 0 "memory_operand")
15430 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15432 (use (match_operand:HI 2 "memory_operand"))
15433 (use (match_operand:HI 3 "memory_operand"))
15434 (clobber (match_operand:SWI24 4 "memory_operand"))]
15436 [(parallel [(set (match_dup 0)
15437 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15438 (use (match_dup 2))
15439 (use (match_dup 3))])])
15441 (define_expand "l<rounding_insn>xf<mode>2"
15442 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15443 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15445 (clobber (reg:CC FLAGS_REG))])]
15446 "TARGET_USE_FANCY_MATH_387
15447 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15448 && flag_unsafe_math_optimizations")
15450 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15451 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15452 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15454 (clobber (reg:CC FLAGS_REG))])]
15455 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15456 && !flag_trapping_math"
15458 if (TARGET_64BIT && optimize_insn_for_size_p ())
15461 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15462 ix86_expand_lfloorceil (operands[0], operands[1], true);
15463 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15464 ix86_expand_lfloorceil (operands[0], operands[1], false);
15466 gcc_unreachable ();
15471 (define_insn "fxam<mode>2_i387"
15472 [(set (match_operand:HI 0 "register_operand" "=a")
15474 [(match_operand:X87MODEF 1 "register_operand" "f")]
15476 "TARGET_USE_FANCY_MATH_387"
15477 "fxam\n\tfnstsw\t%0"
15478 [(set_attr "type" "multi")
15479 (set_attr "length" "4")
15480 (set_attr "unit" "i387")
15481 (set_attr "mode" "<MODE>")])
15483 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15484 [(set (match_operand:HI 0 "register_operand")
15486 [(match_operand:MODEF 1 "memory_operand")]
15488 "TARGET_USE_FANCY_MATH_387
15489 && can_create_pseudo_p ()"
15492 [(set (match_dup 2)(match_dup 1))
15494 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15496 operands[2] = gen_reg_rtx (<MODE>mode);
15498 MEM_VOLATILE_P (operands[1]) = 1;
15500 [(set_attr "type" "multi")
15501 (set_attr "unit" "i387")
15502 (set_attr "mode" "<MODE>")])
15504 (define_expand "isinfxf2"
15505 [(use (match_operand:SI 0 "register_operand"))
15506 (use (match_operand:XF 1 "register_operand"))]
15507 "TARGET_USE_FANCY_MATH_387
15508 && TARGET_C99_FUNCTIONS"
15510 rtx mask = GEN_INT (0x45);
15511 rtx val = GEN_INT (0x05);
15515 rtx scratch = gen_reg_rtx (HImode);
15516 rtx res = gen_reg_rtx (QImode);
15518 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15520 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15521 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15522 cond = gen_rtx_fmt_ee (EQ, QImode,
15523 gen_rtx_REG (CCmode, FLAGS_REG),
15525 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15526 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15530 (define_expand "isinf<mode>2"
15531 [(use (match_operand:SI 0 "register_operand"))
15532 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15533 "TARGET_USE_FANCY_MATH_387
15534 && TARGET_C99_FUNCTIONS
15535 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15537 rtx mask = GEN_INT (0x45);
15538 rtx val = GEN_INT (0x05);
15542 rtx scratch = gen_reg_rtx (HImode);
15543 rtx res = gen_reg_rtx (QImode);
15545 /* Remove excess precision by forcing value through memory. */
15546 if (memory_operand (operands[1], VOIDmode))
15547 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15550 enum ix86_stack_slot slot = (virtuals_instantiated
15553 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15555 emit_move_insn (temp, operands[1]);
15556 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15559 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15560 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15561 cond = gen_rtx_fmt_ee (EQ, QImode,
15562 gen_rtx_REG (CCmode, FLAGS_REG),
15564 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15565 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15569 (define_expand "signbitxf2"
15570 [(use (match_operand:SI 0 "register_operand"))
15571 (use (match_operand:XF 1 "register_operand"))]
15572 "TARGET_USE_FANCY_MATH_387"
15574 rtx scratch = gen_reg_rtx (HImode);
15576 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15577 emit_insn (gen_andsi3 (operands[0],
15578 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15582 (define_insn "movmsk_df"
15583 [(set (match_operand:SI 0 "register_operand" "=r")
15585 [(match_operand:DF 1 "register_operand" "x")]
15587 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15588 "%vmovmskpd\t{%1, %0|%0, %1}"
15589 [(set_attr "type" "ssemov")
15590 (set_attr "prefix" "maybe_vex")
15591 (set_attr "mode" "DF")])
15593 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15594 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15595 (define_expand "signbitdf2"
15596 [(use (match_operand:SI 0 "register_operand"))
15597 (use (match_operand:DF 1 "register_operand"))]
15598 "TARGET_USE_FANCY_MATH_387
15599 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15601 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15603 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15604 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15608 rtx scratch = gen_reg_rtx (HImode);
15610 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15611 emit_insn (gen_andsi3 (operands[0],
15612 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15617 (define_expand "signbitsf2"
15618 [(use (match_operand:SI 0 "register_operand"))
15619 (use (match_operand:SF 1 "register_operand"))]
15620 "TARGET_USE_FANCY_MATH_387
15621 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15623 rtx scratch = gen_reg_rtx (HImode);
15625 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15626 emit_insn (gen_andsi3 (operands[0],
15627 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15631 ;; Block operation instructions
15634 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15637 [(set_attr "length" "1")
15638 (set_attr "length_immediate" "0")
15639 (set_attr "modrm" "0")])
15641 (define_expand "movmem<mode>"
15642 [(use (match_operand:BLK 0 "memory_operand"))
15643 (use (match_operand:BLK 1 "memory_operand"))
15644 (use (match_operand:SWI48 2 "nonmemory_operand"))
15645 (use (match_operand:SWI48 3 "const_int_operand"))
15646 (use (match_operand:SI 4 "const_int_operand"))
15647 (use (match_operand:SI 5 "const_int_operand"))]
15650 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15651 operands[4], operands[5]))
15657 ;; Most CPUs don't like single string operations
15658 ;; Handle this case here to simplify previous expander.
15660 (define_expand "strmov"
15661 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15662 (set (match_operand 1 "memory_operand") (match_dup 4))
15663 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15664 (clobber (reg:CC FLAGS_REG))])
15665 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15666 (clobber (reg:CC FLAGS_REG))])]
15669 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15671 /* If .md ever supports :P for Pmode, these can be directly
15672 in the pattern above. */
15673 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15674 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15676 /* Can't use this if the user has appropriated esi or edi. */
15677 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15678 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15680 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15681 operands[2], operands[3],
15682 operands[5], operands[6]));
15686 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15689 (define_expand "strmov_singleop"
15690 [(parallel [(set (match_operand 1 "memory_operand")
15691 (match_operand 3 "memory_operand"))
15692 (set (match_operand 0 "register_operand")
15694 (set (match_operand 2 "register_operand")
15695 (match_operand 5))])]
15697 "ix86_current_function_needs_cld = 1;")
15699 (define_insn "*strmovdi_rex_1"
15700 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15701 (mem:DI (match_operand:P 3 "register_operand" "1")))
15702 (set (match_operand:P 0 "register_operand" "=D")
15703 (plus:P (match_dup 2)
15705 (set (match_operand:P 1 "register_operand" "=S")
15706 (plus:P (match_dup 3)
15709 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15711 [(set_attr "type" "str")
15712 (set_attr "memory" "both")
15713 (set_attr "mode" "DI")])
15715 (define_insn "*strmovsi_1"
15716 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15717 (mem:SI (match_operand:P 3 "register_operand" "1")))
15718 (set (match_operand:P 0 "register_operand" "=D")
15719 (plus:P (match_dup 2)
15721 (set (match_operand:P 1 "register_operand" "=S")
15722 (plus:P (match_dup 3)
15724 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15726 [(set_attr "type" "str")
15727 (set_attr "memory" "both")
15728 (set_attr "mode" "SI")])
15730 (define_insn "*strmovhi_1"
15731 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15732 (mem:HI (match_operand:P 3 "register_operand" "1")))
15733 (set (match_operand:P 0 "register_operand" "=D")
15734 (plus:P (match_dup 2)
15736 (set (match_operand:P 1 "register_operand" "=S")
15737 (plus:P (match_dup 3)
15739 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15741 [(set_attr "type" "str")
15742 (set_attr "memory" "both")
15743 (set_attr "mode" "HI")])
15745 (define_insn "*strmovqi_1"
15746 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15747 (mem:QI (match_operand:P 3 "register_operand" "1")))
15748 (set (match_operand:P 0 "register_operand" "=D")
15749 (plus:P (match_dup 2)
15751 (set (match_operand:P 1 "register_operand" "=S")
15752 (plus:P (match_dup 3)
15754 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15756 [(set_attr "type" "str")
15757 (set_attr "memory" "both")
15758 (set (attr "prefix_rex")
15760 (match_test "<P:MODE>mode == DImode")
15762 (const_string "*")))
15763 (set_attr "mode" "QI")])
15765 (define_expand "rep_mov"
15766 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15767 (set (match_operand 0 "register_operand")
15769 (set (match_operand 2 "register_operand")
15771 (set (match_operand 1 "memory_operand")
15772 (match_operand 3 "memory_operand"))
15773 (use (match_dup 4))])]
15775 "ix86_current_function_needs_cld = 1;")
15777 (define_insn "*rep_movdi_rex64"
15778 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15779 (set (match_operand:P 0 "register_operand" "=D")
15780 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15782 (match_operand:P 3 "register_operand" "0")))
15783 (set (match_operand:P 1 "register_operand" "=S")
15784 (plus:P (ashift:P (match_dup 5) (const_int 3))
15785 (match_operand:P 4 "register_operand" "1")))
15786 (set (mem:BLK (match_dup 3))
15787 (mem:BLK (match_dup 4)))
15788 (use (match_dup 5))]
15790 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15792 [(set_attr "type" "str")
15793 (set_attr "prefix_rep" "1")
15794 (set_attr "memory" "both")
15795 (set_attr "mode" "DI")])
15797 (define_insn "*rep_movsi"
15798 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15799 (set (match_operand:P 0 "register_operand" "=D")
15800 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15802 (match_operand:P 3 "register_operand" "0")))
15803 (set (match_operand:P 1 "register_operand" "=S")
15804 (plus:P (ashift:P (match_dup 5) (const_int 2))
15805 (match_operand:P 4 "register_operand" "1")))
15806 (set (mem:BLK (match_dup 3))
15807 (mem:BLK (match_dup 4)))
15808 (use (match_dup 5))]
15809 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15810 "%^rep{%;} movs{l|d}"
15811 [(set_attr "type" "str")
15812 (set_attr "prefix_rep" "1")
15813 (set_attr "memory" "both")
15814 (set_attr "mode" "SI")])
15816 (define_insn "*rep_movqi"
15817 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15818 (set (match_operand:P 0 "register_operand" "=D")
15819 (plus:P (match_operand:P 3 "register_operand" "0")
15820 (match_operand:P 5 "register_operand" "2")))
15821 (set (match_operand:P 1 "register_operand" "=S")
15822 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15823 (set (mem:BLK (match_dup 3))
15824 (mem:BLK (match_dup 4)))
15825 (use (match_dup 5))]
15826 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15828 [(set_attr "type" "str")
15829 (set_attr "prefix_rep" "1")
15830 (set_attr "memory" "both")
15831 (set_attr "mode" "QI")])
15833 (define_expand "setmem<mode>"
15834 [(use (match_operand:BLK 0 "memory_operand"))
15835 (use (match_operand:SWI48 1 "nonmemory_operand"))
15836 (use (match_operand:QI 2 "nonmemory_operand"))
15837 (use (match_operand 3 "const_int_operand"))
15838 (use (match_operand:SI 4 "const_int_operand"))
15839 (use (match_operand:SI 5 "const_int_operand"))]
15842 if (ix86_expand_setmem (operands[0], operands[1],
15843 operands[2], operands[3],
15844 operands[4], operands[5]))
15850 ;; Most CPUs don't like single string operations
15851 ;; Handle this case here to simplify previous expander.
15853 (define_expand "strset"
15854 [(set (match_operand 1 "memory_operand")
15855 (match_operand 2 "register_operand"))
15856 (parallel [(set (match_operand 0 "register_operand")
15858 (clobber (reg:CC FLAGS_REG))])]
15861 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15862 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15864 /* If .md ever supports :P for Pmode, this can be directly
15865 in the pattern above. */
15866 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15867 GEN_INT (GET_MODE_SIZE (GET_MODE
15869 /* Can't use this if the user has appropriated eax or edi. */
15870 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15871 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15873 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15879 (define_expand "strset_singleop"
15880 [(parallel [(set (match_operand 1 "memory_operand")
15881 (match_operand 2 "register_operand"))
15882 (set (match_operand 0 "register_operand")
15883 (match_operand 3))])]
15885 "ix86_current_function_needs_cld = 1;")
15887 (define_insn "*strsetdi_rex_1"
15888 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15889 (match_operand:DI 2 "register_operand" "a"))
15890 (set (match_operand:P 0 "register_operand" "=D")
15891 (plus:P (match_dup 1)
15894 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15896 [(set_attr "type" "str")
15897 (set_attr "memory" "store")
15898 (set_attr "mode" "DI")])
15900 (define_insn "*strsetsi_1"
15901 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15902 (match_operand:SI 2 "register_operand" "a"))
15903 (set (match_operand:P 0 "register_operand" "=D")
15904 (plus:P (match_dup 1)
15906 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15908 [(set_attr "type" "str")
15909 (set_attr "memory" "store")
15910 (set_attr "mode" "SI")])
15912 (define_insn "*strsethi_1"
15913 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15914 (match_operand:HI 2 "register_operand" "a"))
15915 (set (match_operand:P 0 "register_operand" "=D")
15916 (plus:P (match_dup 1)
15918 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15920 [(set_attr "type" "str")
15921 (set_attr "memory" "store")
15922 (set_attr "mode" "HI")])
15924 (define_insn "*strsetqi_1"
15925 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15926 (match_operand:QI 2 "register_operand" "a"))
15927 (set (match_operand:P 0 "register_operand" "=D")
15928 (plus:P (match_dup 1)
15930 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15932 [(set_attr "type" "str")
15933 (set_attr "memory" "store")
15934 (set (attr "prefix_rex")
15936 (match_test "<P:MODE>mode == DImode")
15938 (const_string "*")))
15939 (set_attr "mode" "QI")])
15941 (define_expand "rep_stos"
15942 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15943 (set (match_operand 0 "register_operand")
15945 (set (match_operand 2 "memory_operand") (const_int 0))
15946 (use (match_operand 3 "register_operand"))
15947 (use (match_dup 1))])]
15949 "ix86_current_function_needs_cld = 1;")
15951 (define_insn "*rep_stosdi_rex64"
15952 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15953 (set (match_operand:P 0 "register_operand" "=D")
15954 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15956 (match_operand:P 3 "register_operand" "0")))
15957 (set (mem:BLK (match_dup 3))
15959 (use (match_operand:DI 2 "register_operand" "a"))
15960 (use (match_dup 4))]
15962 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15964 [(set_attr "type" "str")
15965 (set_attr "prefix_rep" "1")
15966 (set_attr "memory" "store")
15967 (set_attr "mode" "DI")])
15969 (define_insn "*rep_stossi"
15970 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15971 (set (match_operand:P 0 "register_operand" "=D")
15972 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15974 (match_operand:P 3 "register_operand" "0")))
15975 (set (mem:BLK (match_dup 3))
15977 (use (match_operand:SI 2 "register_operand" "a"))
15978 (use (match_dup 4))]
15979 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15980 "%^rep{%;} stos{l|d}"
15981 [(set_attr "type" "str")
15982 (set_attr "prefix_rep" "1")
15983 (set_attr "memory" "store")
15984 (set_attr "mode" "SI")])
15986 (define_insn "*rep_stosqi"
15987 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15988 (set (match_operand:P 0 "register_operand" "=D")
15989 (plus:P (match_operand:P 3 "register_operand" "0")
15990 (match_operand:P 4 "register_operand" "1")))
15991 (set (mem:BLK (match_dup 3))
15993 (use (match_operand:QI 2 "register_operand" "a"))
15994 (use (match_dup 4))]
15995 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15997 [(set_attr "type" "str")
15998 (set_attr "prefix_rep" "1")
15999 (set_attr "memory" "store")
16000 (set (attr "prefix_rex")
16002 (match_test "<P:MODE>mode == DImode")
16004 (const_string "*")))
16005 (set_attr "mode" "QI")])
16007 (define_expand "cmpstrnsi"
16008 [(set (match_operand:SI 0 "register_operand")
16009 (compare:SI (match_operand:BLK 1 "general_operand")
16010 (match_operand:BLK 2 "general_operand")))
16011 (use (match_operand 3 "general_operand"))
16012 (use (match_operand 4 "immediate_operand"))]
16015 rtx addr1, addr2, out, outlow, count, countreg, align;
16017 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16020 /* Can't use this if the user has appropriated ecx, esi or edi. */
16021 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16026 out = gen_reg_rtx (SImode);
16028 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16029 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16030 if (addr1 != XEXP (operands[1], 0))
16031 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16032 if (addr2 != XEXP (operands[2], 0))
16033 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16035 count = operands[3];
16036 countreg = ix86_zero_extend_to_Pmode (count);
16038 /* %%% Iff we are testing strict equality, we can use known alignment
16039 to good advantage. This may be possible with combine, particularly
16040 once cc0 is dead. */
16041 align = operands[4];
16043 if (CONST_INT_P (count))
16045 if (INTVAL (count) == 0)
16047 emit_move_insn (operands[0], const0_rtx);
16050 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16051 operands[1], operands[2]));
16055 rtx (*gen_cmp) (rtx, rtx);
16057 gen_cmp = (TARGET_64BIT
16058 ? gen_cmpdi_1 : gen_cmpsi_1);
16060 emit_insn (gen_cmp (countreg, countreg));
16061 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16062 operands[1], operands[2]));
16065 outlow = gen_lowpart (QImode, out);
16066 emit_insn (gen_cmpintqi (outlow));
16067 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16069 if (operands[0] != out)
16070 emit_move_insn (operands[0], out);
16075 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16077 (define_expand "cmpintqi"
16078 [(set (match_dup 1)
16079 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16081 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16082 (parallel [(set (match_operand:QI 0 "register_operand")
16083 (minus:QI (match_dup 1)
16085 (clobber (reg:CC FLAGS_REG))])]
16088 operands[1] = gen_reg_rtx (QImode);
16089 operands[2] = gen_reg_rtx (QImode);
16092 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16093 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16095 (define_expand "cmpstrnqi_nz_1"
16096 [(parallel [(set (reg:CC FLAGS_REG)
16097 (compare:CC (match_operand 4 "memory_operand")
16098 (match_operand 5 "memory_operand")))
16099 (use (match_operand 2 "register_operand"))
16100 (use (match_operand:SI 3 "immediate_operand"))
16101 (clobber (match_operand 0 "register_operand"))
16102 (clobber (match_operand 1 "register_operand"))
16103 (clobber (match_dup 2))])]
16105 "ix86_current_function_needs_cld = 1;")
16107 (define_insn "*cmpstrnqi_nz_1"
16108 [(set (reg:CC FLAGS_REG)
16109 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16110 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16111 (use (match_operand:P 6 "register_operand" "2"))
16112 (use (match_operand:SI 3 "immediate_operand" "i"))
16113 (clobber (match_operand:P 0 "register_operand" "=S"))
16114 (clobber (match_operand:P 1 "register_operand" "=D"))
16115 (clobber (match_operand:P 2 "register_operand" "=c"))]
16116 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16118 [(set_attr "type" "str")
16119 (set_attr "mode" "QI")
16120 (set (attr "prefix_rex")
16122 (match_test "<P:MODE>mode == DImode")
16124 (const_string "*")))
16125 (set_attr "prefix_rep" "1")])
16127 ;; The same, but the count is not known to not be zero.
16129 (define_expand "cmpstrnqi_1"
16130 [(parallel [(set (reg:CC FLAGS_REG)
16131 (if_then_else:CC (ne (match_operand 2 "register_operand")
16133 (compare:CC (match_operand 4 "memory_operand")
16134 (match_operand 5 "memory_operand"))
16136 (use (match_operand:SI 3 "immediate_operand"))
16137 (use (reg:CC FLAGS_REG))
16138 (clobber (match_operand 0 "register_operand"))
16139 (clobber (match_operand 1 "register_operand"))
16140 (clobber (match_dup 2))])]
16142 "ix86_current_function_needs_cld = 1;")
16144 (define_insn "*cmpstrnqi_1"
16145 [(set (reg:CC FLAGS_REG)
16146 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16148 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16149 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16151 (use (match_operand:SI 3 "immediate_operand" "i"))
16152 (use (reg:CC FLAGS_REG))
16153 (clobber (match_operand:P 0 "register_operand" "=S"))
16154 (clobber (match_operand:P 1 "register_operand" "=D"))
16155 (clobber (match_operand:P 2 "register_operand" "=c"))]
16156 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16158 [(set_attr "type" "str")
16159 (set_attr "mode" "QI")
16160 (set (attr "prefix_rex")
16162 (match_test "<P:MODE>mode == DImode")
16164 (const_string "*")))
16165 (set_attr "prefix_rep" "1")])
16167 (define_expand "strlen<mode>"
16168 [(set (match_operand:P 0 "register_operand")
16169 (unspec:P [(match_operand:BLK 1 "general_operand")
16170 (match_operand:QI 2 "immediate_operand")
16171 (match_operand 3 "immediate_operand")]
16175 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16181 (define_expand "strlenqi_1"
16182 [(parallel [(set (match_operand 0 "register_operand")
16184 (clobber (match_operand 1 "register_operand"))
16185 (clobber (reg:CC FLAGS_REG))])]
16187 "ix86_current_function_needs_cld = 1;")
16189 (define_insn "*strlenqi_1"
16190 [(set (match_operand:P 0 "register_operand" "=&c")
16191 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16192 (match_operand:QI 2 "register_operand" "a")
16193 (match_operand:P 3 "immediate_operand" "i")
16194 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16195 (clobber (match_operand:P 1 "register_operand" "=D"))
16196 (clobber (reg:CC FLAGS_REG))]
16197 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16198 "%^repnz{%;} scasb"
16199 [(set_attr "type" "str")
16200 (set_attr "mode" "QI")
16201 (set (attr "prefix_rex")
16203 (match_test "<P:MODE>mode == DImode")
16205 (const_string "*")))
16206 (set_attr "prefix_rep" "1")])
16208 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16209 ;; handled in combine, but it is not currently up to the task.
16210 ;; When used for their truth value, the cmpstrn* expanders generate
16219 ;; The intermediate three instructions are unnecessary.
16221 ;; This one handles cmpstrn*_nz_1...
16224 (set (reg:CC FLAGS_REG)
16225 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16226 (mem:BLK (match_operand 5 "register_operand"))))
16227 (use (match_operand 6 "register_operand"))
16228 (use (match_operand:SI 3 "immediate_operand"))
16229 (clobber (match_operand 0 "register_operand"))
16230 (clobber (match_operand 1 "register_operand"))
16231 (clobber (match_operand 2 "register_operand"))])
16232 (set (match_operand:QI 7 "register_operand")
16233 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16234 (set (match_operand:QI 8 "register_operand")
16235 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16236 (set (reg FLAGS_REG)
16237 (compare (match_dup 7) (match_dup 8)))
16239 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16241 (set (reg:CC FLAGS_REG)
16242 (compare:CC (mem:BLK (match_dup 4))
16243 (mem:BLK (match_dup 5))))
16244 (use (match_dup 6))
16245 (use (match_dup 3))
16246 (clobber (match_dup 0))
16247 (clobber (match_dup 1))
16248 (clobber (match_dup 2))])])
16250 ;; ...and this one handles cmpstrn*_1.
16253 (set (reg:CC FLAGS_REG)
16254 (if_then_else:CC (ne (match_operand 6 "register_operand")
16256 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16257 (mem:BLK (match_operand 5 "register_operand")))
16259 (use (match_operand:SI 3 "immediate_operand"))
16260 (use (reg:CC FLAGS_REG))
16261 (clobber (match_operand 0 "register_operand"))
16262 (clobber (match_operand 1 "register_operand"))
16263 (clobber (match_operand 2 "register_operand"))])
16264 (set (match_operand:QI 7 "register_operand")
16265 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16266 (set (match_operand:QI 8 "register_operand")
16267 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16268 (set (reg FLAGS_REG)
16269 (compare (match_dup 7) (match_dup 8)))
16271 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16273 (set (reg:CC FLAGS_REG)
16274 (if_then_else:CC (ne (match_dup 6)
16276 (compare:CC (mem:BLK (match_dup 4))
16277 (mem:BLK (match_dup 5)))
16279 (use (match_dup 3))
16280 (use (reg:CC FLAGS_REG))
16281 (clobber (match_dup 0))
16282 (clobber (match_dup 1))
16283 (clobber (match_dup 2))])])
16285 ;; Conditional move instructions.
16287 (define_expand "mov<mode>cc"
16288 [(set (match_operand:SWIM 0 "register_operand")
16289 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator")
16290 (match_operand:SWIM 2 "<general_operand>")
16291 (match_operand:SWIM 3 "<general_operand>")))]
16293 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16295 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16296 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16297 ;; So just document what we're doing explicitly.
16299 (define_expand "x86_mov<mode>cc_0_m1"
16301 [(set (match_operand:SWI48 0 "register_operand")
16302 (if_then_else:SWI48
16303 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16304 [(match_operand 1 "flags_reg_operand")
16308 (clobber (reg:CC FLAGS_REG))])])
16310 (define_insn "*x86_mov<mode>cc_0_m1"
16311 [(set (match_operand:SWI48 0 "register_operand" "=r")
16312 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16313 [(reg FLAGS_REG) (const_int 0)])
16316 (clobber (reg:CC FLAGS_REG))]
16318 "sbb{<imodesuffix>}\t%0, %0"
16319 ; Since we don't have the proper number of operands for an alu insn,
16320 ; fill in all the blanks.
16321 [(set_attr "type" "alu")
16322 (set_attr "use_carry" "1")
16323 (set_attr "pent_pair" "pu")
16324 (set_attr "memory" "none")
16325 (set_attr "imm_disp" "false")
16326 (set_attr "mode" "<MODE>")
16327 (set_attr "length_immediate" "0")])
16329 (define_insn "*x86_mov<mode>cc_0_m1_se"
16330 [(set (match_operand:SWI48 0 "register_operand" "=r")
16331 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16332 [(reg FLAGS_REG) (const_int 0)])
16335 (clobber (reg:CC FLAGS_REG))]
16337 "sbb{<imodesuffix>}\t%0, %0"
16338 [(set_attr "type" "alu")
16339 (set_attr "use_carry" "1")
16340 (set_attr "pent_pair" "pu")
16341 (set_attr "memory" "none")
16342 (set_attr "imm_disp" "false")
16343 (set_attr "mode" "<MODE>")
16344 (set_attr "length_immediate" "0")])
16346 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16347 [(set (match_operand:SWI48 0 "register_operand" "=r")
16348 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16349 [(reg FLAGS_REG) (const_int 0)])))
16350 (clobber (reg:CC FLAGS_REG))]
16352 "sbb{<imodesuffix>}\t%0, %0"
16353 [(set_attr "type" "alu")
16354 (set_attr "use_carry" "1")
16355 (set_attr "pent_pair" "pu")
16356 (set_attr "memory" "none")
16357 (set_attr "imm_disp" "false")
16358 (set_attr "mode" "<MODE>")
16359 (set_attr "length_immediate" "0")])
16361 (define_insn "*mov<mode>cc_noc"
16362 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16363 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16364 [(reg FLAGS_REG) (const_int 0)])
16365 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16366 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16367 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16369 cmov%O2%C1\t{%2, %0|%0, %2}
16370 cmov%O2%c1\t{%3, %0|%0, %3}"
16371 [(set_attr "type" "icmov")
16372 (set_attr "mode" "<MODE>")])
16374 (define_insn_and_split "*movqicc_noc"
16375 [(set (match_operand:QI 0 "register_operand" "=r,r")
16376 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16377 [(match_operand 4 "flags_reg_operand")
16379 (match_operand:QI 2 "register_operand" "r,0")
16380 (match_operand:QI 3 "register_operand" "0,r")))]
16381 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16383 "&& reload_completed"
16384 [(set (match_dup 0)
16385 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16388 "operands[0] = gen_lowpart (SImode, operands[0]);
16389 operands[2] = gen_lowpart (SImode, operands[2]);
16390 operands[3] = gen_lowpart (SImode, operands[3]);"
16391 [(set_attr "type" "icmov")
16392 (set_attr "mode" "SI")])
16394 (define_expand "mov<mode>cc"
16395 [(set (match_operand:X87MODEF 0 "register_operand")
16396 (if_then_else:X87MODEF
16397 (match_operand 1 "ix86_fp_comparison_operator")
16398 (match_operand:X87MODEF 2 "register_operand")
16399 (match_operand:X87MODEF 3 "register_operand")))]
16400 "(TARGET_80387 && TARGET_CMOVE)
16401 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16402 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16404 (define_insn "*movxfcc_1"
16405 [(set (match_operand:XF 0 "register_operand" "=f,f")
16406 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16407 [(reg FLAGS_REG) (const_int 0)])
16408 (match_operand:XF 2 "register_operand" "f,0")
16409 (match_operand:XF 3 "register_operand" "0,f")))]
16410 "TARGET_80387 && TARGET_CMOVE"
16412 fcmov%F1\t{%2, %0|%0, %2}
16413 fcmov%f1\t{%3, %0|%0, %3}"
16414 [(set_attr "type" "fcmov")
16415 (set_attr "mode" "XF")])
16417 (define_insn "*movdfcc_1_rex64"
16418 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16419 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16420 [(reg FLAGS_REG) (const_int 0)])
16421 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16422 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16423 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16424 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16426 fcmov%F1\t{%2, %0|%0, %2}
16427 fcmov%f1\t{%3, %0|%0, %3}
16428 cmov%O2%C1\t{%2, %0|%0, %2}
16429 cmov%O2%c1\t{%3, %0|%0, %3}"
16430 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16431 (set_attr "mode" "DF,DF,DI,DI")])
16433 (define_insn "*movdfcc_1"
16434 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16435 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16436 [(reg FLAGS_REG) (const_int 0)])
16437 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16438 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16439 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16440 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16442 fcmov%F1\t{%2, %0|%0, %2}
16443 fcmov%f1\t{%3, %0|%0, %3}
16446 [(set_attr "type" "fcmov,fcmov,multi,multi")
16447 (set_attr "mode" "DF,DF,DI,DI")])
16450 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16451 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16452 [(match_operand 4 "flags_reg_operand")
16454 (match_operand:DF 2 "nonimmediate_operand")
16455 (match_operand:DF 3 "nonimmediate_operand")))]
16456 "!TARGET_64BIT && reload_completed"
16457 [(set (match_dup 2)
16458 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16462 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16466 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16467 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16470 (define_insn "*movsfcc_1_387"
16471 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16472 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16473 [(reg FLAGS_REG) (const_int 0)])
16474 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16475 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16476 "TARGET_80387 && TARGET_CMOVE
16477 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16479 fcmov%F1\t{%2, %0|%0, %2}
16480 fcmov%f1\t{%3, %0|%0, %3}
16481 cmov%O2%C1\t{%2, %0|%0, %2}
16482 cmov%O2%c1\t{%3, %0|%0, %3}"
16483 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16484 (set_attr "mode" "SF,SF,SI,SI")])
16486 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16487 ;; the scalar versions to have only XMM registers as operands.
16489 ;; XOP conditional move
16490 (define_insn "*xop_pcmov_<mode>"
16491 [(set (match_operand:MODEF 0 "register_operand" "=x")
16492 (if_then_else:MODEF
16493 (match_operand:MODEF 1 "register_operand" "x")
16494 (match_operand:MODEF 2 "register_operand" "x")
16495 (match_operand:MODEF 3 "register_operand" "x")))]
16497 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16498 [(set_attr "type" "sse4arg")])
16500 ;; These versions of the min/max patterns are intentionally ignorant of
16501 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16502 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16503 ;; are undefined in this condition, we're certain this is correct.
16505 (define_insn "<code><mode>3"
16506 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16508 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16509 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16510 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16512 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16513 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16514 [(set_attr "isa" "noavx,avx")
16515 (set_attr "prefix" "orig,vex")
16516 (set_attr "type" "sseadd")
16517 (set_attr "mode" "<MODE>")])
16519 ;; These versions of the min/max patterns implement exactly the operations
16520 ;; min = (op1 < op2 ? op1 : op2)
16521 ;; max = (!(op1 < op2) ? op1 : op2)
16522 ;; Their operands are not commutative, and thus they may be used in the
16523 ;; presence of -0.0 and NaN.
16525 (define_int_iterator IEEE_MAXMIN
16529 (define_int_attr ieee_maxmin
16530 [(UNSPEC_IEEE_MAX "max")
16531 (UNSPEC_IEEE_MIN "min")])
16533 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16534 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16536 [(match_operand:MODEF 1 "register_operand" "0,x")
16537 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16539 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16541 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16542 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16543 [(set_attr "isa" "noavx,avx")
16544 (set_attr "prefix" "orig,vex")
16545 (set_attr "type" "sseadd")
16546 (set_attr "mode" "<MODE>")])
16548 ;; Make two stack loads independent:
16550 ;; fld %st(0) -> fld bb
16551 ;; fmul bb fmul %st(1), %st
16553 ;; Actually we only match the last two instructions for simplicity.
16555 [(set (match_operand 0 "fp_register_operand")
16556 (match_operand 1 "fp_register_operand"))
16558 (match_operator 2 "binary_fp_operator"
16560 (match_operand 3 "memory_operand")]))]
16561 "REGNO (operands[0]) != REGNO (operands[1])"
16562 [(set (match_dup 0) (match_dup 3))
16563 (set (match_dup 0) (match_dup 4))]
16565 ;; The % modifier is not operational anymore in peephole2's, so we have to
16566 ;; swap the operands manually in the case of addition and multiplication.
16570 if (COMMUTATIVE_ARITH_P (operands[2]))
16571 op0 = operands[0], op1 = operands[1];
16573 op0 = operands[1], op1 = operands[0];
16575 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16576 GET_MODE (operands[2]),
16580 ;; Conditional addition patterns
16581 (define_expand "add<mode>cc"
16582 [(match_operand:SWI 0 "register_operand")
16583 (match_operand 1 "ordered_comparison_operator")
16584 (match_operand:SWI 2 "register_operand")
16585 (match_operand:SWI 3 "const_int_operand")]
16587 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16589 ;; Misc patterns (?)
16591 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16592 ;; Otherwise there will be nothing to keep
16594 ;; [(set (reg ebp) (reg esp))]
16595 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16596 ;; (clobber (eflags)]
16597 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16599 ;; in proper program order.
16601 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16602 [(set (match_operand:P 0 "register_operand" "=r,r")
16603 (plus:P (match_operand:P 1 "register_operand" "0,r")
16604 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16605 (clobber (reg:CC FLAGS_REG))
16606 (clobber (mem:BLK (scratch)))]
16609 switch (get_attr_type (insn))
16612 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16615 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16616 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16617 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16619 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16622 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16623 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16626 [(set (attr "type")
16627 (cond [(and (eq_attr "alternative" "0")
16628 (not (match_test "TARGET_OPT_AGU")))
16629 (const_string "alu")
16630 (match_operand:<MODE> 2 "const0_operand")
16631 (const_string "imov")
16633 (const_string "lea")))
16634 (set (attr "length_immediate")
16635 (cond [(eq_attr "type" "imov")
16637 (and (eq_attr "type" "alu")
16638 (match_operand 2 "const128_operand"))
16641 (const_string "*")))
16642 (set_attr "mode" "<MODE>")])
16644 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16645 [(set (match_operand:P 0 "register_operand" "=r")
16646 (minus:P (match_operand:P 1 "register_operand" "0")
16647 (match_operand:P 2 "register_operand" "r")))
16648 (clobber (reg:CC FLAGS_REG))
16649 (clobber (mem:BLK (scratch)))]
16651 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16652 [(set_attr "type" "alu")
16653 (set_attr "mode" "<MODE>")])
16655 (define_insn "allocate_stack_worker_probe_<mode>"
16656 [(set (match_operand:P 0 "register_operand" "=a")
16657 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16658 UNSPECV_STACK_PROBE))
16659 (clobber (reg:CC FLAGS_REG))]
16660 "ix86_target_stack_probe ()"
16661 "call\t___chkstk_ms"
16662 [(set_attr "type" "multi")
16663 (set_attr "length" "5")])
16665 (define_expand "allocate_stack"
16666 [(match_operand 0 "register_operand")
16667 (match_operand 1 "general_operand")]
16668 "ix86_target_stack_probe ()"
16672 #ifndef CHECK_STACK_LIMIT
16673 #define CHECK_STACK_LIMIT 0
16676 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16677 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16681 rtx (*insn) (rtx, rtx);
16683 x = copy_to_mode_reg (Pmode, operands[1]);
16685 insn = (TARGET_64BIT
16686 ? gen_allocate_stack_worker_probe_di
16687 : gen_allocate_stack_worker_probe_si);
16689 emit_insn (insn (x, x));
16692 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16693 stack_pointer_rtx, 0, OPTAB_DIRECT);
16695 if (x != stack_pointer_rtx)
16696 emit_move_insn (stack_pointer_rtx, x);
16698 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16702 ;; Use IOR for stack probes, this is shorter.
16703 (define_expand "probe_stack"
16704 [(match_operand 0 "memory_operand")]
16707 rtx (*gen_ior3) (rtx, rtx, rtx);
16709 gen_ior3 = (GET_MODE (operands[0]) == DImode
16710 ? gen_iordi3 : gen_iorsi3);
16712 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16716 (define_insn "adjust_stack_and_probe<mode>"
16717 [(set (match_operand:P 0 "register_operand" "=r")
16718 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16719 UNSPECV_PROBE_STACK_RANGE))
16720 (set (reg:P SP_REG)
16721 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16722 (clobber (reg:CC FLAGS_REG))
16723 (clobber (mem:BLK (scratch)))]
16725 "* return output_adjust_stack_and_probe (operands[0]);"
16726 [(set_attr "type" "multi")])
16728 (define_insn "probe_stack_range<mode>"
16729 [(set (match_operand:P 0 "register_operand" "=r")
16730 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16731 (match_operand:P 2 "const_int_operand" "n")]
16732 UNSPECV_PROBE_STACK_RANGE))
16733 (clobber (reg:CC FLAGS_REG))]
16735 "* return output_probe_stack_range (operands[0], operands[2]);"
16736 [(set_attr "type" "multi")])
16738 (define_expand "builtin_setjmp_receiver"
16739 [(label_ref (match_operand 0))]
16740 "!TARGET_64BIT && flag_pic"
16746 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16747 rtx label_rtx = gen_label_rtx ();
16748 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16749 xops[0] = xops[1] = picreg;
16750 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16751 ix86_expand_binary_operator (MINUS, SImode, xops);
16755 emit_insn (gen_set_got (pic_offset_table_rtx));
16759 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16762 [(set (match_operand 0 "register_operand")
16763 (match_operator 3 "promotable_binary_operator"
16764 [(match_operand 1 "register_operand")
16765 (match_operand 2 "aligned_operand")]))
16766 (clobber (reg:CC FLAGS_REG))]
16767 "! TARGET_PARTIAL_REG_STALL && reload_completed
16768 && ((GET_MODE (operands[0]) == HImode
16769 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16770 /* ??? next two lines just !satisfies_constraint_K (...) */
16771 || !CONST_INT_P (operands[2])
16772 || satisfies_constraint_K (operands[2])))
16773 || (GET_MODE (operands[0]) == QImode
16774 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16775 [(parallel [(set (match_dup 0)
16776 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16777 (clobber (reg:CC FLAGS_REG))])]
16779 operands[0] = gen_lowpart (SImode, operands[0]);
16780 operands[1] = gen_lowpart (SImode, operands[1]);
16781 if (GET_CODE (operands[3]) != ASHIFT)
16782 operands[2] = gen_lowpart (SImode, operands[2]);
16783 PUT_MODE (operands[3], SImode);
16786 ; Promote the QImode tests, as i386 has encoding of the AND
16787 ; instruction with 32-bit sign-extended immediate and thus the
16788 ; instruction size is unchanged, except in the %eax case for
16789 ; which it is increased by one byte, hence the ! optimize_size.
16791 [(set (match_operand 0 "flags_reg_operand")
16792 (match_operator 2 "compare_operator"
16793 [(and (match_operand 3 "aligned_operand")
16794 (match_operand 4 "const_int_operand"))
16796 (set (match_operand 1 "register_operand")
16797 (and (match_dup 3) (match_dup 4)))]
16798 "! TARGET_PARTIAL_REG_STALL && reload_completed
16799 && optimize_insn_for_speed_p ()
16800 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16801 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16802 /* Ensure that the operand will remain sign-extended immediate. */
16803 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16804 [(parallel [(set (match_dup 0)
16805 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16808 (and:SI (match_dup 3) (match_dup 4)))])]
16811 = gen_int_mode (INTVAL (operands[4])
16812 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16813 operands[1] = gen_lowpart (SImode, operands[1]);
16814 operands[3] = gen_lowpart (SImode, operands[3]);
16817 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16818 ; the TEST instruction with 32-bit sign-extended immediate and thus
16819 ; the instruction size would at least double, which is not what we
16820 ; want even with ! optimize_size.
16822 [(set (match_operand 0 "flags_reg_operand")
16823 (match_operator 1 "compare_operator"
16824 [(and (match_operand:HI 2 "aligned_operand")
16825 (match_operand:HI 3 "const_int_operand"))
16827 "! TARGET_PARTIAL_REG_STALL && reload_completed
16828 && ! TARGET_FAST_PREFIX
16829 && optimize_insn_for_speed_p ()
16830 /* Ensure that the operand will remain sign-extended immediate. */
16831 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16832 [(set (match_dup 0)
16833 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16837 = gen_int_mode (INTVAL (operands[3])
16838 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16839 operands[2] = gen_lowpart (SImode, operands[2]);
16843 [(set (match_operand 0 "register_operand")
16844 (neg (match_operand 1 "register_operand")))
16845 (clobber (reg:CC FLAGS_REG))]
16846 "! TARGET_PARTIAL_REG_STALL && reload_completed
16847 && (GET_MODE (operands[0]) == HImode
16848 || (GET_MODE (operands[0]) == QImode
16849 && (TARGET_PROMOTE_QImode
16850 || optimize_insn_for_size_p ())))"
16851 [(parallel [(set (match_dup 0)
16852 (neg:SI (match_dup 1)))
16853 (clobber (reg:CC FLAGS_REG))])]
16855 operands[0] = gen_lowpart (SImode, operands[0]);
16856 operands[1] = gen_lowpart (SImode, operands[1]);
16860 [(set (match_operand 0 "register_operand")
16861 (not (match_operand 1 "register_operand")))]
16862 "! TARGET_PARTIAL_REG_STALL && reload_completed
16863 && (GET_MODE (operands[0]) == HImode
16864 || (GET_MODE (operands[0]) == QImode
16865 && (TARGET_PROMOTE_QImode
16866 || optimize_insn_for_size_p ())))"
16867 [(set (match_dup 0)
16868 (not:SI (match_dup 1)))]
16870 operands[0] = gen_lowpart (SImode, operands[0]);
16871 operands[1] = gen_lowpart (SImode, operands[1]);
16875 [(set (match_operand 0 "register_operand")
16876 (if_then_else (match_operator 1 "ordered_comparison_operator"
16877 [(reg FLAGS_REG) (const_int 0)])
16878 (match_operand 2 "register_operand")
16879 (match_operand 3 "register_operand")))]
16880 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16881 && (GET_MODE (operands[0]) == HImode
16882 || (GET_MODE (operands[0]) == QImode
16883 && (TARGET_PROMOTE_QImode
16884 || optimize_insn_for_size_p ())))"
16885 [(set (match_dup 0)
16886 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16888 operands[0] = gen_lowpart (SImode, operands[0]);
16889 operands[2] = gen_lowpart (SImode, operands[2]);
16890 operands[3] = gen_lowpart (SImode, operands[3]);
16893 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16894 ;; transform a complex memory operation into two memory to register operations.
16896 ;; Don't push memory operands
16898 [(set (match_operand:SWI 0 "push_operand")
16899 (match_operand:SWI 1 "memory_operand"))
16900 (match_scratch:SWI 2 "<r>")]
16901 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16902 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16903 [(set (match_dup 2) (match_dup 1))
16904 (set (match_dup 0) (match_dup 2))])
16906 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16909 [(set (match_operand:SF 0 "push_operand")
16910 (match_operand:SF 1 "memory_operand"))
16911 (match_scratch:SF 2 "r")]
16912 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16913 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16914 [(set (match_dup 2) (match_dup 1))
16915 (set (match_dup 0) (match_dup 2))])
16917 ;; Don't move an immediate directly to memory when the instruction
16918 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16920 [(match_scratch:SWI124 1 "<r>")
16921 (set (match_operand:SWI124 0 "memory_operand")
16923 "optimize_insn_for_speed_p ()
16924 && ((<MODE>mode == HImode
16925 && TARGET_LCP_STALL)
16926 || (!TARGET_USE_MOV0
16927 && TARGET_SPLIT_LONG_MOVES
16928 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16929 && peep2_regno_dead_p (0, FLAGS_REG)"
16930 [(parallel [(set (match_dup 2) (const_int 0))
16931 (clobber (reg:CC FLAGS_REG))])
16932 (set (match_dup 0) (match_dup 1))]
16933 "operands[2] = gen_lowpart (SImode, operands[1]);")
16936 [(match_scratch:SWI124 2 "<r>")
16937 (set (match_operand:SWI124 0 "memory_operand")
16938 (match_operand:SWI124 1 "immediate_operand"))]
16939 "optimize_insn_for_speed_p ()
16940 && ((<MODE>mode == HImode
16941 && TARGET_LCP_STALL)
16942 || (TARGET_SPLIT_LONG_MOVES
16943 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16944 [(set (match_dup 2) (match_dup 1))
16945 (set (match_dup 0) (match_dup 2))])
16947 ;; Don't compare memory with zero, load and use a test instead.
16949 [(set (match_operand 0 "flags_reg_operand")
16950 (match_operator 1 "compare_operator"
16951 [(match_operand:SI 2 "memory_operand")
16953 (match_scratch:SI 3 "r")]
16954 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16955 [(set (match_dup 3) (match_dup 2))
16956 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16958 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16959 ;; Don't split NOTs with a displacement operand, because resulting XOR
16960 ;; will not be pairable anyway.
16962 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16963 ;; represented using a modRM byte. The XOR replacement is long decoded,
16964 ;; so this split helps here as well.
16966 ;; Note: Can't do this as a regular split because we can't get proper
16967 ;; lifetime information then.
16970 [(set (match_operand:SWI124 0 "nonimmediate_operand")
16971 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16972 "optimize_insn_for_speed_p ()
16973 && ((TARGET_NOT_UNPAIRABLE
16974 && (!MEM_P (operands[0])
16975 || !memory_displacement_operand (operands[0], <MODE>mode)))
16976 || (TARGET_NOT_VECTORMODE
16977 && long_memory_operand (operands[0], <MODE>mode)))
16978 && peep2_regno_dead_p (0, FLAGS_REG)"
16979 [(parallel [(set (match_dup 0)
16980 (xor:SWI124 (match_dup 1) (const_int -1)))
16981 (clobber (reg:CC FLAGS_REG))])])
16983 ;; Non pairable "test imm, reg" instructions can be translated to
16984 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16985 ;; byte opcode instead of two, have a short form for byte operands),
16986 ;; so do it for other CPUs as well. Given that the value was dead,
16987 ;; this should not create any new dependencies. Pass on the sub-word
16988 ;; versions if we're concerned about partial register stalls.
16991 [(set (match_operand 0 "flags_reg_operand")
16992 (match_operator 1 "compare_operator"
16993 [(and:SI (match_operand:SI 2 "register_operand")
16994 (match_operand:SI 3 "immediate_operand"))
16996 "ix86_match_ccmode (insn, CCNOmode)
16997 && (true_regnum (operands[2]) != AX_REG
16998 || satisfies_constraint_K (operands[3]))
16999 && peep2_reg_dead_p (1, operands[2])"
17001 [(set (match_dup 0)
17002 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17005 (and:SI (match_dup 2) (match_dup 3)))])])
17007 ;; We don't need to handle HImode case, because it will be promoted to SImode
17008 ;; on ! TARGET_PARTIAL_REG_STALL
17011 [(set (match_operand 0 "flags_reg_operand")
17012 (match_operator 1 "compare_operator"
17013 [(and:QI (match_operand:QI 2 "register_operand")
17014 (match_operand:QI 3 "immediate_operand"))
17016 "! TARGET_PARTIAL_REG_STALL
17017 && ix86_match_ccmode (insn, CCNOmode)
17018 && true_regnum (operands[2]) != AX_REG
17019 && peep2_reg_dead_p (1, operands[2])"
17021 [(set (match_dup 0)
17022 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17025 (and:QI (match_dup 2) (match_dup 3)))])])
17028 [(set (match_operand 0 "flags_reg_operand")
17029 (match_operator 1 "compare_operator"
17032 (match_operand 2 "ext_register_operand")
17035 (match_operand 3 "const_int_operand"))
17037 "! TARGET_PARTIAL_REG_STALL
17038 && ix86_match_ccmode (insn, CCNOmode)
17039 && true_regnum (operands[2]) != AX_REG
17040 && peep2_reg_dead_p (1, operands[2])"
17041 [(parallel [(set (match_dup 0)
17050 (set (zero_extract:SI (match_dup 2)
17058 (match_dup 3)))])])
17060 ;; Don't do logical operations with memory inputs.
17062 [(match_scratch:SI 2 "r")
17063 (parallel [(set (match_operand:SI 0 "register_operand")
17064 (match_operator:SI 3 "arith_or_logical_operator"
17066 (match_operand:SI 1 "memory_operand")]))
17067 (clobber (reg:CC FLAGS_REG))])]
17068 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17069 [(set (match_dup 2) (match_dup 1))
17070 (parallel [(set (match_dup 0)
17071 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17072 (clobber (reg:CC FLAGS_REG))])])
17075 [(match_scratch:SI 2 "r")
17076 (parallel [(set (match_operand:SI 0 "register_operand")
17077 (match_operator:SI 3 "arith_or_logical_operator"
17078 [(match_operand:SI 1 "memory_operand")
17080 (clobber (reg:CC FLAGS_REG))])]
17081 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17082 [(set (match_dup 2) (match_dup 1))
17083 (parallel [(set (match_dup 0)
17084 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17085 (clobber (reg:CC FLAGS_REG))])])
17087 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17088 ;; refers to the destination of the load!
17091 [(set (match_operand:SI 0 "register_operand")
17092 (match_operand:SI 1 "register_operand"))
17093 (parallel [(set (match_dup 0)
17094 (match_operator:SI 3 "commutative_operator"
17096 (match_operand:SI 2 "memory_operand")]))
17097 (clobber (reg:CC FLAGS_REG))])]
17098 "REGNO (operands[0]) != REGNO (operands[1])
17099 && GENERAL_REGNO_P (REGNO (operands[0]))
17100 && GENERAL_REGNO_P (REGNO (operands[1]))"
17101 [(set (match_dup 0) (match_dup 4))
17102 (parallel [(set (match_dup 0)
17103 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17104 (clobber (reg:CC FLAGS_REG))])]
17105 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17108 [(set (match_operand 0 "register_operand")
17109 (match_operand 1 "register_operand"))
17111 (match_operator 3 "commutative_operator"
17113 (match_operand 2 "memory_operand")]))]
17114 "REGNO (operands[0]) != REGNO (operands[1])
17115 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17116 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17117 [(set (match_dup 0) (match_dup 2))
17119 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17121 ; Don't do logical operations with memory outputs
17123 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17124 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17125 ; the same decoder scheduling characteristics as the original.
17128 [(match_scratch:SI 2 "r")
17129 (parallel [(set (match_operand:SI 0 "memory_operand")
17130 (match_operator:SI 3 "arith_or_logical_operator"
17132 (match_operand:SI 1 "nonmemory_operand")]))
17133 (clobber (reg:CC FLAGS_REG))])]
17134 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17135 /* Do not split stack checking probes. */
17136 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17137 [(set (match_dup 2) (match_dup 0))
17138 (parallel [(set (match_dup 2)
17139 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17140 (clobber (reg:CC FLAGS_REG))])
17141 (set (match_dup 0) (match_dup 2))])
17144 [(match_scratch:SI 2 "r")
17145 (parallel [(set (match_operand:SI 0 "memory_operand")
17146 (match_operator:SI 3 "arith_or_logical_operator"
17147 [(match_operand:SI 1 "nonmemory_operand")
17149 (clobber (reg:CC FLAGS_REG))])]
17150 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17151 /* Do not split stack checking probes. */
17152 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17153 [(set (match_dup 2) (match_dup 0))
17154 (parallel [(set (match_dup 2)
17155 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17156 (clobber (reg:CC FLAGS_REG))])
17157 (set (match_dup 0) (match_dup 2))])
17159 ;; Attempt to use arith or logical operations with memory outputs with
17160 ;; setting of flags.
17162 [(set (match_operand:SWI 0 "register_operand")
17163 (match_operand:SWI 1 "memory_operand"))
17164 (parallel [(set (match_dup 0)
17165 (match_operator:SWI 3 "plusminuslogic_operator"
17167 (match_operand:SWI 2 "<nonmemory_operand>")]))
17168 (clobber (reg:CC FLAGS_REG))])
17169 (set (match_dup 1) (match_dup 0))
17170 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17171 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17172 && peep2_reg_dead_p (4, operands[0])
17173 && !reg_overlap_mentioned_p (operands[0], operands[1])
17174 && (<MODE>mode != QImode
17175 || immediate_operand (operands[2], QImode)
17176 || q_regs_operand (operands[2], QImode))
17177 && ix86_match_ccmode (peep2_next_insn (3),
17178 (GET_CODE (operands[3]) == PLUS
17179 || GET_CODE (operands[3]) == MINUS)
17180 ? CCGOCmode : CCNOmode)"
17181 [(parallel [(set (match_dup 4) (match_dup 5))
17182 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17183 (match_dup 2)]))])]
17185 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17186 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17187 copy_rtx (operands[1]),
17188 copy_rtx (operands[2]));
17189 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17190 operands[5], const0_rtx);
17194 [(parallel [(set (match_operand:SWI 0 "register_operand")
17195 (match_operator:SWI 2 "plusminuslogic_operator"
17197 (match_operand:SWI 1 "memory_operand")]))
17198 (clobber (reg:CC FLAGS_REG))])
17199 (set (match_dup 1) (match_dup 0))
17200 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17201 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17202 && GET_CODE (operands[2]) != MINUS
17203 && peep2_reg_dead_p (3, operands[0])
17204 && !reg_overlap_mentioned_p (operands[0], operands[1])
17205 && ix86_match_ccmode (peep2_next_insn (2),
17206 GET_CODE (operands[2]) == PLUS
17207 ? CCGOCmode : CCNOmode)"
17208 [(parallel [(set (match_dup 3) (match_dup 4))
17209 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17210 (match_dup 0)]))])]
17212 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17213 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17214 copy_rtx (operands[1]),
17215 copy_rtx (operands[0]));
17216 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17217 operands[4], const0_rtx);
17221 [(set (match_operand:SWI12 0 "register_operand")
17222 (match_operand:SWI12 1 "memory_operand"))
17223 (parallel [(set (match_operand:SI 4 "register_operand")
17224 (match_operator:SI 3 "plusminuslogic_operator"
17226 (match_operand:SI 2 "nonmemory_operand")]))
17227 (clobber (reg:CC FLAGS_REG))])
17228 (set (match_dup 1) (match_dup 0))
17229 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17230 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17231 && REG_P (operands[0]) && REG_P (operands[4])
17232 && REGNO (operands[0]) == REGNO (operands[4])
17233 && peep2_reg_dead_p (4, operands[0])
17234 && (<MODE>mode != QImode
17235 || immediate_operand (operands[2], SImode)
17236 || q_regs_operand (operands[2], SImode))
17237 && !reg_overlap_mentioned_p (operands[0], operands[1])
17238 && ix86_match_ccmode (peep2_next_insn (3),
17239 (GET_CODE (operands[3]) == PLUS
17240 || GET_CODE (operands[3]) == MINUS)
17241 ? CCGOCmode : CCNOmode)"
17242 [(parallel [(set (match_dup 4) (match_dup 5))
17243 (set (match_dup 1) (match_dup 6))])]
17245 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17246 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17247 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17248 copy_rtx (operands[1]), operands[2]);
17249 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17250 operands[5], const0_rtx);
17251 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17252 copy_rtx (operands[1]),
17253 copy_rtx (operands[2]));
17256 ;; Attempt to always use XOR for zeroing registers.
17258 [(set (match_operand 0 "register_operand")
17259 (match_operand 1 "const0_operand"))]
17260 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17261 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17262 && GENERAL_REG_P (operands[0])
17263 && peep2_regno_dead_p (0, FLAGS_REG)"
17264 [(parallel [(set (match_dup 0) (const_int 0))
17265 (clobber (reg:CC FLAGS_REG))])]
17266 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17269 [(set (strict_low_part (match_operand 0 "register_operand"))
17271 "(GET_MODE (operands[0]) == QImode
17272 || GET_MODE (operands[0]) == HImode)
17273 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17274 && peep2_regno_dead_p (0, FLAGS_REG)"
17275 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17276 (clobber (reg:CC FLAGS_REG))])])
17278 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17280 [(set (match_operand:SWI248 0 "register_operand")
17282 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17283 && peep2_regno_dead_p (0, FLAGS_REG)"
17284 [(parallel [(set (match_dup 0) (const_int -1))
17285 (clobber (reg:CC FLAGS_REG))])]
17287 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17288 operands[0] = gen_lowpart (SImode, operands[0]);
17291 ;; Attempt to convert simple lea to add/shift.
17292 ;; These can be created by move expanders.
17295 [(set (match_operand:SWI48 0 "register_operand")
17296 (plus:SWI48 (match_dup 0)
17297 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17298 "peep2_regno_dead_p (0, FLAGS_REG)"
17299 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17300 (clobber (reg:CC FLAGS_REG))])])
17303 [(set (match_operand:SI 0 "register_operand")
17304 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand")
17305 (match_operand:DI 2 "nonmemory_operand")) 0))]
17307 && peep2_regno_dead_p (0, FLAGS_REG)
17308 && REGNO (operands[0]) == REGNO (operands[1])"
17309 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17310 (clobber (reg:CC FLAGS_REG))])]
17311 "operands[2] = gen_lowpart (SImode, operands[2]);")
17314 [(set (match_operand:SWI48 0 "register_operand")
17315 (mult:SWI48 (match_dup 0)
17316 (match_operand:SWI48 1 "const_int_operand")))]
17317 "exact_log2 (INTVAL (operands[1])) >= 0
17318 && peep2_regno_dead_p (0, FLAGS_REG)"
17319 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17320 (clobber (reg:CC FLAGS_REG))])]
17321 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17324 [(set (match_operand:SI 0 "register_operand")
17325 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand")
17326 (match_operand:DI 2 "const_int_operand")) 0))]
17328 && exact_log2 (INTVAL (operands[2])) >= 0
17329 && REGNO (operands[0]) == REGNO (operands[1])
17330 && peep2_regno_dead_p (0, FLAGS_REG)"
17331 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17332 (clobber (reg:CC FLAGS_REG))])]
17333 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17335 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17336 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17337 ;; On many CPUs it is also faster, since special hardware to avoid esp
17338 ;; dependencies is present.
17340 ;; While some of these conversions may be done using splitters, we use
17341 ;; peepholes in order to allow combine_stack_adjustments pass to see
17342 ;; nonobfuscated RTL.
17344 ;; Convert prologue esp subtractions to push.
17345 ;; We need register to push. In order to keep verify_flow_info happy we have
17347 ;; - use scratch and clobber it in order to avoid dependencies
17348 ;; - use already live register
17349 ;; We can't use the second way right now, since there is no reliable way how to
17350 ;; verify that given register is live. First choice will also most likely in
17351 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17352 ;; call clobbered registers are dead. We may want to use base pointer as an
17353 ;; alternative when no register is available later.
17356 [(match_scratch:W 1 "r")
17357 (parallel [(set (reg:P SP_REG)
17358 (plus:P (reg:P SP_REG)
17359 (match_operand:P 0 "const_int_operand")))
17360 (clobber (reg:CC FLAGS_REG))
17361 (clobber (mem:BLK (scratch)))])]
17362 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17363 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17364 [(clobber (match_dup 1))
17365 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17366 (clobber (mem:BLK (scratch)))])])
17369 [(match_scratch:W 1 "r")
17370 (parallel [(set (reg:P SP_REG)
17371 (plus:P (reg:P SP_REG)
17372 (match_operand:P 0 "const_int_operand")))
17373 (clobber (reg:CC FLAGS_REG))
17374 (clobber (mem:BLK (scratch)))])]
17375 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17376 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17377 [(clobber (match_dup 1))
17378 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17379 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17380 (clobber (mem:BLK (scratch)))])])
17382 ;; Convert esp subtractions to push.
17384 [(match_scratch:W 1 "r")
17385 (parallel [(set (reg:P SP_REG)
17386 (plus:P (reg:P SP_REG)
17387 (match_operand:P 0 "const_int_operand")))
17388 (clobber (reg:CC FLAGS_REG))])]
17389 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17390 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17391 [(clobber (match_dup 1))
17392 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17395 [(match_scratch:W 1 "r")
17396 (parallel [(set (reg:P SP_REG)
17397 (plus:P (reg:P SP_REG)
17398 (match_operand:P 0 "const_int_operand")))
17399 (clobber (reg:CC FLAGS_REG))])]
17400 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17401 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17402 [(clobber (match_dup 1))
17403 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17404 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17406 ;; Convert epilogue deallocator to pop.
17408 [(match_scratch:W 1 "r")
17409 (parallel [(set (reg:P SP_REG)
17410 (plus:P (reg:P SP_REG)
17411 (match_operand:P 0 "const_int_operand")))
17412 (clobber (reg:CC FLAGS_REG))
17413 (clobber (mem:BLK (scratch)))])]
17414 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17415 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17416 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17417 (clobber (mem:BLK (scratch)))])])
17419 ;; Two pops case is tricky, since pop causes dependency
17420 ;; on destination register. We use two registers if available.
17422 [(match_scratch:W 1 "r")
17423 (match_scratch:W 2 "r")
17424 (parallel [(set (reg:P SP_REG)
17425 (plus:P (reg:P SP_REG)
17426 (match_operand:P 0 "const_int_operand")))
17427 (clobber (reg:CC FLAGS_REG))
17428 (clobber (mem:BLK (scratch)))])]
17429 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17430 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17431 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17432 (clobber (mem:BLK (scratch)))])
17433 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17436 [(match_scratch:W 1 "r")
17437 (parallel [(set (reg:P SP_REG)
17438 (plus:P (reg:P SP_REG)
17439 (match_operand:P 0 "const_int_operand")))
17440 (clobber (reg:CC FLAGS_REG))
17441 (clobber (mem:BLK (scratch)))])]
17442 "optimize_insn_for_size_p ()
17443 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17444 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17445 (clobber (mem:BLK (scratch)))])
17446 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17448 ;; Convert esp additions to pop.
17450 [(match_scratch:W 1 "r")
17451 (parallel [(set (reg:P SP_REG)
17452 (plus:P (reg:P SP_REG)
17453 (match_operand:P 0 "const_int_operand")))
17454 (clobber (reg:CC FLAGS_REG))])]
17455 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17456 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17458 ;; Two pops case is tricky, since pop causes dependency
17459 ;; on destination register. We use two registers if available.
17461 [(match_scratch:W 1 "r")
17462 (match_scratch:W 2 "r")
17463 (parallel [(set (reg:P SP_REG)
17464 (plus:P (reg:P SP_REG)
17465 (match_operand:P 0 "const_int_operand")))
17466 (clobber (reg:CC FLAGS_REG))])]
17467 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17468 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17469 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17472 [(match_scratch:W 1 "r")
17473 (parallel [(set (reg:P SP_REG)
17474 (plus:P (reg:P SP_REG)
17475 (match_operand:P 0 "const_int_operand")))
17476 (clobber (reg:CC FLAGS_REG))])]
17477 "optimize_insn_for_size_p ()
17478 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17479 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17480 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17482 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17483 ;; required and register dies. Similarly for 128 to -128.
17485 [(set (match_operand 0 "flags_reg_operand")
17486 (match_operator 1 "compare_operator"
17487 [(match_operand 2 "register_operand")
17488 (match_operand 3 "const_int_operand")]))]
17489 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17490 && incdec_operand (operands[3], GET_MODE (operands[3])))
17491 || (!TARGET_FUSE_CMP_AND_BRANCH
17492 && INTVAL (operands[3]) == 128))
17493 && ix86_match_ccmode (insn, CCGCmode)
17494 && peep2_reg_dead_p (1, operands[2])"
17495 [(parallel [(set (match_dup 0)
17496 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17497 (clobber (match_dup 2))])])
17499 ;; Convert imul by three, five and nine into lea
17502 [(set (match_operand:SWI48 0 "register_operand")
17503 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17504 (match_operand:SWI48 2 "const359_operand")))
17505 (clobber (reg:CC FLAGS_REG))])]
17506 "!TARGET_PARTIAL_REG_STALL
17507 || <MODE>mode == SImode
17508 || optimize_function_for_size_p (cfun)"
17509 [(set (match_dup 0)
17510 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17512 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17516 [(set (match_operand:SWI48 0 "register_operand")
17517 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17518 (match_operand:SWI48 2 "const359_operand")))
17519 (clobber (reg:CC FLAGS_REG))])]
17520 "optimize_insn_for_speed_p ()
17521 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17522 [(set (match_dup 0) (match_dup 1))
17524 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17526 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17528 ;; imul $32bit_imm, mem, reg is vector decoded, while
17529 ;; imul $32bit_imm, reg, reg is direct decoded.
17531 [(match_scratch:SWI48 3 "r")
17532 (parallel [(set (match_operand:SWI48 0 "register_operand")
17533 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17534 (match_operand:SWI48 2 "immediate_operand")))
17535 (clobber (reg:CC FLAGS_REG))])]
17536 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17537 && !satisfies_constraint_K (operands[2])"
17538 [(set (match_dup 3) (match_dup 1))
17539 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17540 (clobber (reg:CC FLAGS_REG))])])
17543 [(match_scratch:SI 3 "r")
17544 (parallel [(set (match_operand:DI 0 "register_operand")
17546 (mult:SI (match_operand:SI 1 "memory_operand")
17547 (match_operand:SI 2 "immediate_operand"))))
17548 (clobber (reg:CC FLAGS_REG))])]
17550 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17551 && !satisfies_constraint_K (operands[2])"
17552 [(set (match_dup 3) (match_dup 1))
17553 (parallel [(set (match_dup 0)
17554 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17555 (clobber (reg:CC FLAGS_REG))])])
17557 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17558 ;; Convert it into imul reg, reg
17559 ;; It would be better to force assembler to encode instruction using long
17560 ;; immediate, but there is apparently no way to do so.
17562 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17564 (match_operand:SWI248 1 "nonimmediate_operand")
17565 (match_operand:SWI248 2 "const_int_operand")))
17566 (clobber (reg:CC FLAGS_REG))])
17567 (match_scratch:SWI248 3 "r")]
17568 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17569 && satisfies_constraint_K (operands[2])"
17570 [(set (match_dup 3) (match_dup 2))
17571 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17572 (clobber (reg:CC FLAGS_REG))])]
17574 if (!rtx_equal_p (operands[0], operands[1]))
17575 emit_move_insn (operands[0], operands[1]);
17578 ;; After splitting up read-modify operations, array accesses with memory
17579 ;; operands might end up in form:
17581 ;; movl 4(%esp), %edx
17583 ;; instead of pre-splitting:
17585 ;; addl 4(%esp), %eax
17587 ;; movl 4(%esp), %edx
17588 ;; leal (%edx,%eax,4), %eax
17591 [(match_scratch:W 5 "r")
17592 (parallel [(set (match_operand 0 "register_operand")
17593 (ashift (match_operand 1 "register_operand")
17594 (match_operand 2 "const_int_operand")))
17595 (clobber (reg:CC FLAGS_REG))])
17596 (parallel [(set (match_operand 3 "register_operand")
17597 (plus (match_dup 0)
17598 (match_operand 4 "x86_64_general_operand")))
17599 (clobber (reg:CC FLAGS_REG))])]
17600 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17601 /* Validate MODE for lea. */
17602 && ((!TARGET_PARTIAL_REG_STALL
17603 && (GET_MODE (operands[0]) == QImode
17604 || GET_MODE (operands[0]) == HImode))
17605 || GET_MODE (operands[0]) == SImode
17606 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17607 && (rtx_equal_p (operands[0], operands[3])
17608 || peep2_reg_dead_p (2, operands[0]))
17609 /* We reorder load and the shift. */
17610 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17611 [(set (match_dup 5) (match_dup 4))
17612 (set (match_dup 0) (match_dup 1))]
17614 enum machine_mode op1mode = GET_MODE (operands[1]);
17615 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17616 int scale = 1 << INTVAL (operands[2]);
17617 rtx index = gen_lowpart (word_mode, operands[1]);
17618 rtx base = gen_lowpart (word_mode, operands[5]);
17619 rtx dest = gen_lowpart (mode, operands[3]);
17621 operands[1] = gen_rtx_PLUS (word_mode, base,
17622 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17623 operands[5] = base;
17624 if (mode != word_mode)
17625 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17626 if (op1mode != word_mode)
17627 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17628 operands[0] = dest;
17631 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17632 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17633 ;; caught for use by garbage collectors and the like. Using an insn that
17634 ;; maps to SIGILL makes it more likely the program will rightfully die.
17635 ;; Keeping with tradition, "6" is in honor of #UD.
17636 (define_insn "trap"
17637 [(trap_if (const_int 1) (const_int 6))]
17639 { return ASM_SHORT "0x0b0f"; }
17640 [(set_attr "length" "2")])
17642 (define_expand "prefetch"
17643 [(prefetch (match_operand 0 "address_operand")
17644 (match_operand:SI 1 "const_int_operand")
17645 (match_operand:SI 2 "const_int_operand"))]
17646 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17648 int rw = INTVAL (operands[1]);
17649 int locality = INTVAL (operands[2]);
17651 gcc_assert (rw == 0 || rw == 1);
17652 gcc_assert (locality >= 0 && locality <= 3);
17653 gcc_assert (GET_MODE (operands[0]) == Pmode
17654 || GET_MODE (operands[0]) == VOIDmode);
17656 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17657 supported by SSE counterpart or the SSE prefetch is not available
17658 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17660 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17661 operands[2] = GEN_INT (3);
17663 operands[1] = const0_rtx;
17666 (define_insn "*prefetch_sse_<mode>"
17667 [(prefetch (match_operand:P 0 "address_operand" "p")
17669 (match_operand:SI 1 "const_int_operand"))]
17670 "TARGET_PREFETCH_SSE"
17672 static const char * const patterns[4] = {
17673 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17676 int locality = INTVAL (operands[1]);
17677 gcc_assert (locality >= 0 && locality <= 3);
17679 return patterns[locality];
17681 [(set_attr "type" "sse")
17682 (set_attr "atom_sse_attr" "prefetch")
17683 (set (attr "length_address")
17684 (symbol_ref "memory_address_length (operands[0])"))
17685 (set_attr "memory" "none")])
17687 (define_insn "*prefetch_3dnow_<mode>"
17688 [(prefetch (match_operand:P 0 "address_operand" "p")
17689 (match_operand:SI 1 "const_int_operand" "n")
17693 if (INTVAL (operands[1]) == 0)
17694 return "prefetch\t%a0";
17696 return "prefetchw\t%a0";
17698 [(set_attr "type" "mmx")
17699 (set (attr "length_address")
17700 (symbol_ref "memory_address_length (operands[0])"))
17701 (set_attr "memory" "none")])
17703 (define_expand "stack_protect_set"
17704 [(match_operand 0 "memory_operand")
17705 (match_operand 1 "memory_operand")]
17708 rtx (*insn)(rtx, rtx);
17710 #ifdef TARGET_THREAD_SSP_OFFSET
17711 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17712 insn = (TARGET_LP64
17713 ? gen_stack_tls_protect_set_di
17714 : gen_stack_tls_protect_set_si);
17716 insn = (TARGET_LP64
17717 ? gen_stack_protect_set_di
17718 : gen_stack_protect_set_si);
17721 emit_insn (insn (operands[0], operands[1]));
17725 (define_insn "stack_protect_set_<mode>"
17726 [(set (match_operand:PTR 0 "memory_operand" "=m")
17727 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17729 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17730 (clobber (reg:CC FLAGS_REG))]
17732 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17733 [(set_attr "type" "multi")])
17735 (define_insn "stack_tls_protect_set_<mode>"
17736 [(set (match_operand:PTR 0 "memory_operand" "=m")
17737 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17738 UNSPEC_SP_TLS_SET))
17739 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17740 (clobber (reg:CC FLAGS_REG))]
17742 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17743 [(set_attr "type" "multi")])
17745 (define_expand "stack_protect_test"
17746 [(match_operand 0 "memory_operand")
17747 (match_operand 1 "memory_operand")
17751 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17753 rtx (*insn)(rtx, rtx, rtx);
17755 #ifdef TARGET_THREAD_SSP_OFFSET
17756 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17757 insn = (TARGET_LP64
17758 ? gen_stack_tls_protect_test_di
17759 : gen_stack_tls_protect_test_si);
17761 insn = (TARGET_LP64
17762 ? gen_stack_protect_test_di
17763 : gen_stack_protect_test_si);
17766 emit_insn (insn (flags, operands[0], operands[1]));
17768 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17769 flags, const0_rtx, operands[2]));
17773 (define_insn "stack_protect_test_<mode>"
17774 [(set (match_operand:CCZ 0 "flags_reg_operand")
17775 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17776 (match_operand:PTR 2 "memory_operand" "m")]
17778 (clobber (match_scratch:PTR 3 "=&r"))]
17780 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17781 [(set_attr "type" "multi")])
17783 (define_insn "stack_tls_protect_test_<mode>"
17784 [(set (match_operand:CCZ 0 "flags_reg_operand")
17785 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17786 (match_operand:PTR 2 "const_int_operand" "i")]
17787 UNSPEC_SP_TLS_TEST))
17788 (clobber (match_scratch:PTR 3 "=r"))]
17790 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17791 [(set_attr "type" "multi")])
17793 (define_insn "sse4_2_crc32<mode>"
17794 [(set (match_operand:SI 0 "register_operand" "=r")
17796 [(match_operand:SI 1 "register_operand" "0")
17797 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17799 "TARGET_SSE4_2 || TARGET_CRC32"
17800 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17801 [(set_attr "type" "sselog1")
17802 (set_attr "prefix_rep" "1")
17803 (set_attr "prefix_extra" "1")
17804 (set (attr "prefix_data16")
17805 (if_then_else (match_operand:HI 2)
17807 (const_string "*")))
17808 (set (attr "prefix_rex")
17809 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17811 (const_string "*")))
17812 (set_attr "mode" "SI")])
17814 (define_insn "sse4_2_crc32di"
17815 [(set (match_operand:DI 0 "register_operand" "=r")
17817 [(match_operand:DI 1 "register_operand" "0")
17818 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17820 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17821 "crc32{q}\t{%2, %0|%0, %2}"
17822 [(set_attr "type" "sselog1")
17823 (set_attr "prefix_rep" "1")
17824 (set_attr "prefix_extra" "1")
17825 (set_attr "mode" "DI")])
17827 (define_expand "rdpmc"
17828 [(match_operand:DI 0 "register_operand")
17829 (match_operand:SI 1 "register_operand")]
17832 rtx reg = gen_reg_rtx (DImode);
17835 /* Force operand 1 into ECX. */
17836 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17837 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17838 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17843 rtvec vec = rtvec_alloc (2);
17844 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17845 rtx upper = gen_reg_rtx (DImode);
17846 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17847 gen_rtvec (1, const0_rtx),
17849 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17850 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17852 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17853 NULL, 1, OPTAB_DIRECT);
17854 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17858 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17859 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17863 (define_insn "*rdpmc"
17864 [(set (match_operand:DI 0 "register_operand" "=A")
17865 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17869 [(set_attr "type" "other")
17870 (set_attr "length" "2")])
17872 (define_insn "*rdpmc_rex64"
17873 [(set (match_operand:DI 0 "register_operand" "=a")
17874 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17876 (set (match_operand:DI 1 "register_operand" "=d")
17877 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17880 [(set_attr "type" "other")
17881 (set_attr "length" "2")])
17883 (define_expand "rdtsc"
17884 [(set (match_operand:DI 0 "register_operand")
17885 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17890 rtvec vec = rtvec_alloc (2);
17891 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17892 rtx upper = gen_reg_rtx (DImode);
17893 rtx lower = gen_reg_rtx (DImode);
17894 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17895 gen_rtvec (1, const0_rtx),
17897 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17898 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17900 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17901 NULL, 1, OPTAB_DIRECT);
17902 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17904 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17909 (define_insn "*rdtsc"
17910 [(set (match_operand:DI 0 "register_operand" "=A")
17911 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17914 [(set_attr "type" "other")
17915 (set_attr "length" "2")])
17917 (define_insn "*rdtsc_rex64"
17918 [(set (match_operand:DI 0 "register_operand" "=a")
17919 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17920 (set (match_operand:DI 1 "register_operand" "=d")
17921 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17924 [(set_attr "type" "other")
17925 (set_attr "length" "2")])
17927 (define_expand "rdtscp"
17928 [(match_operand:DI 0 "register_operand")
17929 (match_operand:SI 1 "memory_operand")]
17932 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17933 gen_rtvec (1, const0_rtx),
17935 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17936 gen_rtvec (1, const0_rtx),
17938 rtx reg = gen_reg_rtx (DImode);
17939 rtx tmp = gen_reg_rtx (SImode);
17943 rtvec vec = rtvec_alloc (3);
17944 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17945 rtx upper = gen_reg_rtx (DImode);
17946 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17947 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17948 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17950 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17951 NULL, 1, OPTAB_DIRECT);
17952 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17957 rtvec vec = rtvec_alloc (2);
17958 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17959 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17960 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17963 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17964 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17968 (define_insn "*rdtscp"
17969 [(set (match_operand:DI 0 "register_operand" "=A")
17970 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17971 (set (match_operand:SI 1 "register_operand" "=c")
17972 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17975 [(set_attr "type" "other")
17976 (set_attr "length" "3")])
17978 (define_insn "*rdtscp_rex64"
17979 [(set (match_operand:DI 0 "register_operand" "=a")
17980 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17981 (set (match_operand:DI 1 "register_operand" "=d")
17982 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17983 (set (match_operand:SI 2 "register_operand" "=c")
17984 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17987 [(set_attr "type" "other")
17988 (set_attr "length" "3")])
17990 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17992 ;; LWP instructions
17994 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17996 (define_expand "lwp_llwpcb"
17997 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17998 UNSPECV_LLWP_INTRINSIC)]
18001 (define_insn "*lwp_llwpcb<mode>1"
18002 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18003 UNSPECV_LLWP_INTRINSIC)]
18006 [(set_attr "type" "lwp")
18007 (set_attr "mode" "<MODE>")
18008 (set_attr "length" "5")])
18010 (define_expand "lwp_slwpcb"
18011 [(set (match_operand 0 "register_operand" "=r")
18012 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18017 insn = (Pmode == DImode
18019 : gen_lwp_slwpcbsi);
18021 emit_insn (insn (operands[0]));
18025 (define_insn "lwp_slwpcb<mode>"
18026 [(set (match_operand:P 0 "register_operand" "=r")
18027 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18030 [(set_attr "type" "lwp")
18031 (set_attr "mode" "<MODE>")
18032 (set_attr "length" "5")])
18034 (define_expand "lwp_lwpval<mode>3"
18035 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18036 (match_operand:SI 2 "nonimmediate_operand" "rm")
18037 (match_operand:SI 3 "const_int_operand" "i")]
18038 UNSPECV_LWPVAL_INTRINSIC)]
18040 ;; Avoid unused variable warning.
18041 "(void) operands[0];")
18043 (define_insn "*lwp_lwpval<mode>3_1"
18044 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18045 (match_operand:SI 1 "nonimmediate_operand" "rm")
18046 (match_operand:SI 2 "const_int_operand" "i")]
18047 UNSPECV_LWPVAL_INTRINSIC)]
18049 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18050 [(set_attr "type" "lwp")
18051 (set_attr "mode" "<MODE>")
18052 (set (attr "length")
18053 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18055 (define_expand "lwp_lwpins<mode>3"
18056 [(set (reg:CCC FLAGS_REG)
18057 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18058 (match_operand:SI 2 "nonimmediate_operand" "rm")
18059 (match_operand:SI 3 "const_int_operand" "i")]
18060 UNSPECV_LWPINS_INTRINSIC))
18061 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18062 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18065 (define_insn "*lwp_lwpins<mode>3_1"
18066 [(set (reg:CCC FLAGS_REG)
18067 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18068 (match_operand:SI 1 "nonimmediate_operand" "rm")
18069 (match_operand:SI 2 "const_int_operand" "i")]
18070 UNSPECV_LWPINS_INTRINSIC))]
18072 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18073 [(set_attr "type" "lwp")
18074 (set_attr "mode" "<MODE>")
18075 (set (attr "length")
18076 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18078 (define_int_iterator RDFSGSBASE
18082 (define_int_iterator WRFSGSBASE
18086 (define_int_attr fsgs
18087 [(UNSPECV_RDFSBASE "fs")
18088 (UNSPECV_RDGSBASE "gs")
18089 (UNSPECV_WRFSBASE "fs")
18090 (UNSPECV_WRGSBASE "gs")])
18092 (define_insn "rd<fsgs>base<mode>"
18093 [(set (match_operand:SWI48 0 "register_operand" "=r")
18094 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18095 "TARGET_64BIT && TARGET_FSGSBASE"
18097 [(set_attr "type" "other")
18098 (set_attr "prefix_extra" "2")])
18100 (define_insn "wr<fsgs>base<mode>"
18101 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18103 "TARGET_64BIT && TARGET_FSGSBASE"
18105 [(set_attr "type" "other")
18106 (set_attr "prefix_extra" "2")])
18108 (define_insn "rdrand<mode>_1"
18109 [(set (match_operand:SWI248 0 "register_operand" "=r")
18110 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18111 (set (reg:CCC FLAGS_REG)
18112 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18115 [(set_attr "type" "other")
18116 (set_attr "prefix_extra" "1")])
18118 (define_expand "pause"
18119 [(set (match_dup 0)
18120 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18123 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18124 MEM_VOLATILE_P (operands[0]) = 1;
18127 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18128 ;; They have the same encoding.
18129 (define_insn "*pause"
18130 [(set (match_operand:BLK 0)
18131 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18134 [(set_attr "length" "2")
18135 (set_attr "memory" "unknown")])
18137 (define_expand "xbegin"
18138 [(set (match_operand:SI 0 "register_operand")
18139 (unspec_volatile:SI [(match_dup 1)] UNSPECV_XBEGIN))]
18142 rtx label = gen_label_rtx ();
18144 operands[1] = force_reg (SImode, constm1_rtx);
18146 emit_jump_insn (gen_xbegin_1 (operands[1], label));
18148 emit_label (label);
18149 LABEL_NUSES (label) = 1;
18151 emit_move_insn (operands[0], operands[1]);
18156 (define_insn "xbegin_1"
18158 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18160 (label_ref (match_operand 1))
18162 (set (match_operand:SI 0 "register_operand" "+a")
18163 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18166 [(set_attr "type" "other")
18167 (set_attr "length" "6")])
18169 (define_insn "xend"
18170 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18173 [(set_attr "type" "other")
18174 (set_attr "length" "3")])
18176 (define_insn "xabort"
18177 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18181 [(set_attr "type" "other")
18182 (set_attr "length" "3")])
18184 (define_expand "xtest"
18185 [(set (match_operand:QI 0 "register_operand")
18186 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18189 emit_insn (gen_xtest_1 ());
18191 ix86_expand_setcc (operands[0], NE,
18192 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18196 (define_insn "xtest_1"
18197 [(set (reg:CCZ FLAGS_REG)
18198 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18201 [(set_attr "type" "other")
18202 (set_attr "length" "3")])
18206 (include "sync.md")