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,btver2"
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")])
747 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
749 ;; All integer modes.
750 (define_mode_iterator SWI1248x [QI HI SI DI])
752 ;; All integer modes without QImode.
753 (define_mode_iterator SWI248x [HI SI DI])
755 ;; All integer modes without QImode and HImode.
756 (define_mode_iterator SWI48x [SI DI])
758 ;; All integer modes without SImode and DImode.
759 (define_mode_iterator SWI12 [QI HI])
761 ;; All integer modes without DImode.
762 (define_mode_iterator SWI124 [QI HI SI])
764 ;; All integer modes without QImode and DImode.
765 (define_mode_iterator SWI24 [HI SI])
767 ;; Single word integer modes.
768 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
770 ;; Single word integer modes without QImode.
771 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
773 ;; Single word integer modes without QImode and HImode.
774 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
776 ;; All math-dependant single and double word integer modes.
777 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
778 (HI "TARGET_HIMODE_MATH")
779 SI DI (TI "TARGET_64BIT")])
781 ;; Math-dependant single word integer modes.
782 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
783 (HI "TARGET_HIMODE_MATH")
784 SI (DI "TARGET_64BIT")])
786 ;; Math-dependant integer modes without DImode.
787 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
788 (HI "TARGET_HIMODE_MATH")
791 ;; Math-dependant single word integer modes without QImode.
792 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
793 SI (DI "TARGET_64BIT")])
795 ;; Double word integer modes.
796 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
797 (TI "TARGET_64BIT")])
799 ;; Double word integer modes as mode attribute.
800 (define_mode_attr DWI [(SI "DI") (DI "TI")])
801 (define_mode_attr dwi [(SI "di") (DI "ti")])
803 ;; Half mode for double word integer modes.
804 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
805 (DI "TARGET_64BIT")])
807 ;; Instruction suffix for integer modes.
808 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
810 ;; Pointer size prefix for integer modes (Intel asm dialect)
811 (define_mode_attr iptrsize [(QI "BYTE")
816 ;; Register class for integer modes.
817 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
819 ;; Immediate operand constraint for integer modes.
820 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
822 ;; General operand constraint for word modes.
823 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
825 ;; Immediate operand constraint for double integer modes.
826 (define_mode_attr di [(SI "nF") (DI "e")])
828 ;; Immediate operand constraint for shifts.
829 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
831 ;; General operand predicate for integer modes.
832 (define_mode_attr general_operand
833 [(QI "general_operand")
834 (HI "general_operand")
835 (SI "x86_64_general_operand")
836 (DI "x86_64_general_operand")
837 (TI "x86_64_general_operand")])
839 ;; General sign/zero extend operand predicate for integer modes.
840 (define_mode_attr general_szext_operand
841 [(QI "general_operand")
842 (HI "general_operand")
843 (SI "x86_64_szext_general_operand")
844 (DI "x86_64_szext_general_operand")])
846 ;; Immediate operand predicate for integer modes.
847 (define_mode_attr immediate_operand
848 [(QI "immediate_operand")
849 (HI "immediate_operand")
850 (SI "x86_64_immediate_operand")
851 (DI "x86_64_immediate_operand")])
853 ;; Nonmemory operand predicate for integer modes.
854 (define_mode_attr nonmemory_operand
855 [(QI "nonmemory_operand")
856 (HI "nonmemory_operand")
857 (SI "x86_64_nonmemory_operand")
858 (DI "x86_64_nonmemory_operand")])
860 ;; Operand predicate for shifts.
861 (define_mode_attr shift_operand
862 [(QI "nonimmediate_operand")
863 (HI "nonimmediate_operand")
864 (SI "nonimmediate_operand")
865 (DI "shiftdi_operand")
866 (TI "register_operand")])
868 ;; Operand predicate for shift argument.
869 (define_mode_attr shift_immediate_operand
870 [(QI "const_1_to_31_operand")
871 (HI "const_1_to_31_operand")
872 (SI "const_1_to_31_operand")
873 (DI "const_1_to_63_operand")])
875 ;; Input operand predicate for arithmetic left shifts.
876 (define_mode_attr ashl_input_operand
877 [(QI "nonimmediate_operand")
878 (HI "nonimmediate_operand")
879 (SI "nonimmediate_operand")
880 (DI "ashldi_input_operand")
881 (TI "reg_or_pm1_operand")])
883 ;; SSE and x87 SFmode and DFmode floating point modes
884 (define_mode_iterator MODEF [SF DF])
886 ;; All x87 floating point modes
887 (define_mode_iterator X87MODEF [SF DF XF])
889 ;; SSE instruction suffix for various modes
890 (define_mode_attr ssemodesuffix
892 (V8SF "ps") (V4DF "pd")
893 (V4SF "ps") (V2DF "pd")
894 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
895 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
897 ;; SSE vector suffix for floating point modes
898 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
900 ;; SSE vector mode corresponding to a scalar mode
901 (define_mode_attr ssevecmode
902 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
904 ;; Instruction suffix for REX 64bit operators.
905 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
907 ;; This mode iterator allows :P to be used for patterns that operate on
908 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
909 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
911 ;; This mode iterator allows :W to be used for patterns that operate on
912 ;; word_mode sized quantities.
913 (define_mode_iterator W
914 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
916 ;; This mode iterator allows :PTR to be used for patterns that operate on
917 ;; ptr_mode sized quantities.
918 (define_mode_iterator PTR
919 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
921 ;; Scheduling descriptions
923 (include "pentium.md")
926 (include "athlon.md")
927 (include "bdver1.md")
933 ;; Operand and operator predicates and constraints
935 (include "predicates.md")
936 (include "constraints.md")
939 ;; Compare and branch/compare and store instructions.
941 (define_expand "cbranch<mode>4"
942 [(set (reg:CC FLAGS_REG)
943 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
944 (match_operand:SDWIM 2 "<general_operand>")))
945 (set (pc) (if_then_else
946 (match_operator 0 "ordered_comparison_operator"
947 [(reg:CC FLAGS_REG) (const_int 0)])
948 (label_ref (match_operand 3))
952 if (MEM_P (operands[1]) && MEM_P (operands[2]))
953 operands[1] = force_reg (<MODE>mode, operands[1]);
954 ix86_expand_branch (GET_CODE (operands[0]),
955 operands[1], operands[2], operands[3]);
959 (define_expand "cstore<mode>4"
960 [(set (reg:CC FLAGS_REG)
961 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
962 (match_operand:SWIM 3 "<general_operand>")))
963 (set (match_operand:QI 0 "register_operand")
964 (match_operator 1 "ordered_comparison_operator"
965 [(reg:CC FLAGS_REG) (const_int 0)]))]
968 if (MEM_P (operands[2]) && MEM_P (operands[3]))
969 operands[2] = force_reg (<MODE>mode, operands[2]);
970 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
971 operands[2], operands[3]);
975 (define_expand "cmp<mode>_1"
976 [(set (reg:CC FLAGS_REG)
977 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
978 (match_operand:SWI48 1 "<general_operand>")))])
980 (define_insn "*cmp<mode>_ccno_1"
981 [(set (reg FLAGS_REG)
982 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
983 (match_operand:SWI 1 "const0_operand")))]
984 "ix86_match_ccmode (insn, CCNOmode)"
986 test{<imodesuffix>}\t%0, %0
987 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
988 [(set_attr "type" "test,icmp")
989 (set_attr "length_immediate" "0,1")
990 (set_attr "mode" "<MODE>")])
992 (define_insn "*cmp<mode>_1"
993 [(set (reg FLAGS_REG)
994 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
995 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
996 "ix86_match_ccmode (insn, CCmode)"
997 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
998 [(set_attr "type" "icmp")
999 (set_attr "mode" "<MODE>")])
1001 (define_insn "*cmp<mode>_minus_1"
1002 [(set (reg FLAGS_REG)
1004 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1005 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1007 "ix86_match_ccmode (insn, CCGOCmode)"
1008 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1009 [(set_attr "type" "icmp")
1010 (set_attr "mode" "<MODE>")])
1012 (define_insn "*cmpqi_ext_1"
1013 [(set (reg FLAGS_REG)
1015 (match_operand:QI 0 "general_operand" "Qm")
1018 (match_operand 1 "ext_register_operand" "Q")
1020 (const_int 8)) 0)))]
1021 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1022 "cmp{b}\t{%h1, %0|%0, %h1}"
1023 [(set_attr "type" "icmp")
1024 (set_attr "mode" "QI")])
1026 (define_insn "*cmpqi_ext_1_rex64"
1027 [(set (reg FLAGS_REG)
1029 (match_operand:QI 0 "register_operand" "Q")
1032 (match_operand 1 "ext_register_operand" "Q")
1034 (const_int 8)) 0)))]
1035 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1036 "cmp{b}\t{%h1, %0|%0, %h1}"
1037 [(set_attr "type" "icmp")
1038 (set_attr "mode" "QI")])
1040 (define_insn "*cmpqi_ext_2"
1041 [(set (reg FLAGS_REG)
1045 (match_operand 0 "ext_register_operand" "Q")
1048 (match_operand:QI 1 "const0_operand")))]
1049 "ix86_match_ccmode (insn, CCNOmode)"
1051 [(set_attr "type" "test")
1052 (set_attr "length_immediate" "0")
1053 (set_attr "mode" "QI")])
1055 (define_expand "cmpqi_ext_3"
1056 [(set (reg:CC FLAGS_REG)
1060 (match_operand 0 "ext_register_operand")
1063 (match_operand:QI 1 "immediate_operand")))])
1065 (define_insn "*cmpqi_ext_3_insn"
1066 [(set (reg FLAGS_REG)
1070 (match_operand 0 "ext_register_operand" "Q")
1073 (match_operand:QI 1 "general_operand" "Qmn")))]
1074 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1075 "cmp{b}\t{%1, %h0|%h0, %1}"
1076 [(set_attr "type" "icmp")
1077 (set_attr "modrm" "1")
1078 (set_attr "mode" "QI")])
1080 (define_insn "*cmpqi_ext_3_insn_rex64"
1081 [(set (reg FLAGS_REG)
1085 (match_operand 0 "ext_register_operand" "Q")
1088 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1089 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1090 "cmp{b}\t{%1, %h0|%h0, %1}"
1091 [(set_attr "type" "icmp")
1092 (set_attr "modrm" "1")
1093 (set_attr "mode" "QI")])
1095 (define_insn "*cmpqi_ext_4"
1096 [(set (reg FLAGS_REG)
1100 (match_operand 0 "ext_register_operand" "Q")
1105 (match_operand 1 "ext_register_operand" "Q")
1107 (const_int 8)) 0)))]
1108 "ix86_match_ccmode (insn, CCmode)"
1109 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1110 [(set_attr "type" "icmp")
1111 (set_attr "mode" "QI")])
1113 ;; These implement float point compares.
1114 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1115 ;; which would allow mix and match FP modes on the compares. Which is what
1116 ;; the old patterns did, but with many more of them.
1118 (define_expand "cbranchxf4"
1119 [(set (reg:CC FLAGS_REG)
1120 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1121 (match_operand:XF 2 "nonmemory_operand")))
1122 (set (pc) (if_then_else
1123 (match_operator 0 "ix86_fp_comparison_operator"
1126 (label_ref (match_operand 3))
1130 ix86_expand_branch (GET_CODE (operands[0]),
1131 operands[1], operands[2], operands[3]);
1135 (define_expand "cstorexf4"
1136 [(set (reg:CC FLAGS_REG)
1137 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1138 (match_operand:XF 3 "nonmemory_operand")))
1139 (set (match_operand:QI 0 "register_operand")
1140 (match_operator 1 "ix86_fp_comparison_operator"
1145 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1146 operands[2], operands[3]);
1150 (define_expand "cbranch<mode>4"
1151 [(set (reg:CC FLAGS_REG)
1152 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1153 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1154 (set (pc) (if_then_else
1155 (match_operator 0 "ix86_fp_comparison_operator"
1158 (label_ref (match_operand 3))
1160 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1162 ix86_expand_branch (GET_CODE (operands[0]),
1163 operands[1], operands[2], operands[3]);
1167 (define_expand "cstore<mode>4"
1168 [(set (reg:CC FLAGS_REG)
1169 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1170 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1171 (set (match_operand:QI 0 "register_operand")
1172 (match_operator 1 "ix86_fp_comparison_operator"
1175 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1177 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1178 operands[2], operands[3]);
1182 (define_expand "cbranchcc4"
1183 [(set (pc) (if_then_else
1184 (match_operator 0 "comparison_operator"
1185 [(match_operand 1 "flags_reg_operand")
1186 (match_operand 2 "const0_operand")])
1187 (label_ref (match_operand 3))
1191 ix86_expand_branch (GET_CODE (operands[0]),
1192 operands[1], operands[2], operands[3]);
1196 (define_expand "cstorecc4"
1197 [(set (match_operand:QI 0 "register_operand")
1198 (match_operator 1 "comparison_operator"
1199 [(match_operand 2 "flags_reg_operand")
1200 (match_operand 3 "const0_operand")]))]
1203 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1204 operands[2], operands[3]);
1209 ;; FP compares, step 1:
1210 ;; Set the FP condition codes.
1212 ;; CCFPmode compare with exceptions
1213 ;; CCFPUmode compare with no exceptions
1215 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1216 ;; used to manage the reg stack popping would not be preserved.
1218 (define_insn "*cmpfp_0"
1219 [(set (match_operand:HI 0 "register_operand" "=a")
1222 (match_operand 1 "register_operand" "f")
1223 (match_operand 2 "const0_operand"))]
1225 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1226 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1227 "* return output_fp_compare (insn, operands, false, false);"
1228 [(set_attr "type" "multi")
1229 (set_attr "unit" "i387")
1231 (cond [(match_operand:SF 1)
1233 (match_operand:DF 1)
1236 (const_string "XF")))])
1238 (define_insn_and_split "*cmpfp_0_cc"
1239 [(set (reg:CCFP FLAGS_REG)
1241 (match_operand 1 "register_operand" "f")
1242 (match_operand 2 "const0_operand")))
1243 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1244 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1245 && TARGET_SAHF && !TARGET_CMOVE
1246 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1248 "&& reload_completed"
1251 [(compare:CCFP (match_dup 1)(match_dup 2))]
1253 (set (reg:CC FLAGS_REG)
1254 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1256 [(set_attr "type" "multi")
1257 (set_attr "unit" "i387")
1259 (cond [(match_operand:SF 1)
1261 (match_operand:DF 1)
1264 (const_string "XF")))])
1266 (define_insn "*cmpfp_xf"
1267 [(set (match_operand:HI 0 "register_operand" "=a")
1270 (match_operand:XF 1 "register_operand" "f")
1271 (match_operand:XF 2 "register_operand" "f"))]
1274 "* return output_fp_compare (insn, operands, false, false);"
1275 [(set_attr "type" "multi")
1276 (set_attr "unit" "i387")
1277 (set_attr "mode" "XF")])
1279 (define_insn_and_split "*cmpfp_xf_cc"
1280 [(set (reg:CCFP FLAGS_REG)
1282 (match_operand:XF 1 "register_operand" "f")
1283 (match_operand:XF 2 "register_operand" "f")))
1284 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1286 && TARGET_SAHF && !TARGET_CMOVE"
1288 "&& reload_completed"
1291 [(compare:CCFP (match_dup 1)(match_dup 2))]
1293 (set (reg:CC FLAGS_REG)
1294 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1296 [(set_attr "type" "multi")
1297 (set_attr "unit" "i387")
1298 (set_attr "mode" "XF")])
1300 (define_insn "*cmpfp_<mode>"
1301 [(set (match_operand:HI 0 "register_operand" "=a")
1304 (match_operand:MODEF 1 "register_operand" "f")
1305 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1308 "* return output_fp_compare (insn, operands, false, false);"
1309 [(set_attr "type" "multi")
1310 (set_attr "unit" "i387")
1311 (set_attr "mode" "<MODE>")])
1313 (define_insn_and_split "*cmpfp_<mode>_cc"
1314 [(set (reg:CCFP FLAGS_REG)
1316 (match_operand:MODEF 1 "register_operand" "f")
1317 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1318 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1320 && TARGET_SAHF && !TARGET_CMOVE"
1322 "&& reload_completed"
1325 [(compare:CCFP (match_dup 1)(match_dup 2))]
1327 (set (reg:CC FLAGS_REG)
1328 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1330 [(set_attr "type" "multi")
1331 (set_attr "unit" "i387")
1332 (set_attr "mode" "<MODE>")])
1334 (define_insn "*cmpfp_u"
1335 [(set (match_operand:HI 0 "register_operand" "=a")
1338 (match_operand 1 "register_operand" "f")
1339 (match_operand 2 "register_operand" "f"))]
1341 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1342 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1343 "* return output_fp_compare (insn, operands, false, true);"
1344 [(set_attr "type" "multi")
1345 (set_attr "unit" "i387")
1347 (cond [(match_operand:SF 1)
1349 (match_operand:DF 1)
1352 (const_string "XF")))])
1354 (define_insn_and_split "*cmpfp_u_cc"
1355 [(set (reg:CCFPU FLAGS_REG)
1357 (match_operand 1 "register_operand" "f")
1358 (match_operand 2 "register_operand" "f")))
1359 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1360 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1361 && TARGET_SAHF && !TARGET_CMOVE
1362 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1364 "&& reload_completed"
1367 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1369 (set (reg:CC FLAGS_REG)
1370 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1372 [(set_attr "type" "multi")
1373 (set_attr "unit" "i387")
1375 (cond [(match_operand:SF 1)
1377 (match_operand:DF 1)
1380 (const_string "XF")))])
1382 (define_insn "*cmpfp_<mode>"
1383 [(set (match_operand:HI 0 "register_operand" "=a")
1386 (match_operand 1 "register_operand" "f")
1387 (match_operator 3 "float_operator"
1388 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1390 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1391 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1392 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1393 "* return output_fp_compare (insn, operands, false, false);"
1394 [(set_attr "type" "multi")
1395 (set_attr "unit" "i387")
1396 (set_attr "fp_int_src" "true")
1397 (set_attr "mode" "<MODE>")])
1399 (define_insn_and_split "*cmpfp_<mode>_cc"
1400 [(set (reg:CCFP FLAGS_REG)
1402 (match_operand 1 "register_operand" "f")
1403 (match_operator 3 "float_operator"
1404 [(match_operand:SWI24 2 "memory_operand" "m")])))
1405 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1406 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1407 && TARGET_SAHF && !TARGET_CMOVE
1408 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1409 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1411 "&& reload_completed"
1416 (match_op_dup 3 [(match_dup 2)]))]
1418 (set (reg:CC FLAGS_REG)
1419 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1421 [(set_attr "type" "multi")
1422 (set_attr "unit" "i387")
1423 (set_attr "fp_int_src" "true")
1424 (set_attr "mode" "<MODE>")])
1426 ;; FP compares, step 2
1427 ;; Move the fpsw to ax.
1429 (define_insn "x86_fnstsw_1"
1430 [(set (match_operand:HI 0 "register_operand" "=a")
1431 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1434 [(set (attr "length")
1435 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1436 (set_attr "mode" "SI")
1437 (set_attr "unit" "i387")])
1439 ;; FP compares, step 3
1440 ;; Get ax into flags, general case.
1442 (define_insn "x86_sahf_1"
1443 [(set (reg:CC FLAGS_REG)
1444 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1448 #ifndef HAVE_AS_IX86_SAHF
1450 return ASM_BYTE "0x9e";
1455 [(set_attr "length" "1")
1456 (set_attr "athlon_decode" "vector")
1457 (set_attr "amdfam10_decode" "direct")
1458 (set_attr "bdver1_decode" "direct")
1459 (set_attr "mode" "SI")])
1461 ;; Pentium Pro can do steps 1 through 3 in one go.
1462 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1463 ;; (these i387 instructions set flags directly)
1464 (define_insn "*cmpfp_i_mixed"
1465 [(set (reg:CCFP FLAGS_REG)
1466 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1467 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1468 "TARGET_MIX_SSE_I387
1469 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1470 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1471 "* return output_fp_compare (insn, operands, true, false);"
1472 [(set_attr "type" "fcmp,ssecomi")
1473 (set_attr "prefix" "orig,maybe_vex")
1475 (if_then_else (match_operand:SF 1)
1477 (const_string "DF")))
1478 (set (attr "prefix_rep")
1479 (if_then_else (eq_attr "type" "ssecomi")
1481 (const_string "*")))
1482 (set (attr "prefix_data16")
1483 (cond [(eq_attr "type" "fcmp")
1485 (eq_attr "mode" "DF")
1488 (const_string "0")))
1489 (set_attr "athlon_decode" "vector")
1490 (set_attr "amdfam10_decode" "direct")
1491 (set_attr "bdver1_decode" "double")])
1493 (define_insn "*cmpfp_i_sse"
1494 [(set (reg:CCFP FLAGS_REG)
1495 (compare:CCFP (match_operand 0 "register_operand" "x")
1496 (match_operand 1 "nonimmediate_operand" "xm")))]
1498 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1499 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1500 "* return output_fp_compare (insn, operands, true, false);"
1501 [(set_attr "type" "ssecomi")
1502 (set_attr "prefix" "maybe_vex")
1504 (if_then_else (match_operand:SF 1)
1506 (const_string "DF")))
1507 (set_attr "prefix_rep" "0")
1508 (set (attr "prefix_data16")
1509 (if_then_else (eq_attr "mode" "DF")
1511 (const_string "0")))
1512 (set_attr "athlon_decode" "vector")
1513 (set_attr "amdfam10_decode" "direct")
1514 (set_attr "bdver1_decode" "double")])
1516 (define_insn "*cmpfp_i_i387"
1517 [(set (reg:CCFP FLAGS_REG)
1518 (compare:CCFP (match_operand 0 "register_operand" "f")
1519 (match_operand 1 "register_operand" "f")))]
1520 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1522 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1523 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1524 "* return output_fp_compare (insn, operands, true, false);"
1525 [(set_attr "type" "fcmp")
1527 (cond [(match_operand:SF 1)
1529 (match_operand:DF 1)
1532 (const_string "XF")))
1533 (set_attr "athlon_decode" "vector")
1534 (set_attr "amdfam10_decode" "direct")
1535 (set_attr "bdver1_decode" "double")])
1537 (define_insn "*cmpfp_iu_mixed"
1538 [(set (reg:CCFPU FLAGS_REG)
1539 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1540 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1541 "TARGET_MIX_SSE_I387
1542 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1543 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1544 "* return output_fp_compare (insn, operands, true, true);"
1545 [(set_attr "type" "fcmp,ssecomi")
1546 (set_attr "prefix" "orig,maybe_vex")
1548 (if_then_else (match_operand:SF 1)
1550 (const_string "DF")))
1551 (set (attr "prefix_rep")
1552 (if_then_else (eq_attr "type" "ssecomi")
1554 (const_string "*")))
1555 (set (attr "prefix_data16")
1556 (cond [(eq_attr "type" "fcmp")
1558 (eq_attr "mode" "DF")
1561 (const_string "0")))
1562 (set_attr "athlon_decode" "vector")
1563 (set_attr "amdfam10_decode" "direct")
1564 (set_attr "bdver1_decode" "double")])
1566 (define_insn "*cmpfp_iu_sse"
1567 [(set (reg:CCFPU FLAGS_REG)
1568 (compare:CCFPU (match_operand 0 "register_operand" "x")
1569 (match_operand 1 "nonimmediate_operand" "xm")))]
1571 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1572 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1573 "* return output_fp_compare (insn, operands, true, true);"
1574 [(set_attr "type" "ssecomi")
1575 (set_attr "prefix" "maybe_vex")
1577 (if_then_else (match_operand:SF 1)
1579 (const_string "DF")))
1580 (set_attr "prefix_rep" "0")
1581 (set (attr "prefix_data16")
1582 (if_then_else (eq_attr "mode" "DF")
1584 (const_string "0")))
1585 (set_attr "athlon_decode" "vector")
1586 (set_attr "amdfam10_decode" "direct")
1587 (set_attr "bdver1_decode" "double")])
1589 (define_insn "*cmpfp_iu_387"
1590 [(set (reg:CCFPU FLAGS_REG)
1591 (compare:CCFPU (match_operand 0 "register_operand" "f")
1592 (match_operand 1 "register_operand" "f")))]
1593 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1595 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1596 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1597 "* return output_fp_compare (insn, operands, true, true);"
1598 [(set_attr "type" "fcmp")
1600 (cond [(match_operand:SF 1)
1602 (match_operand:DF 1)
1605 (const_string "XF")))
1606 (set_attr "athlon_decode" "vector")
1607 (set_attr "amdfam10_decode" "direct")
1608 (set_attr "bdver1_decode" "direct")])
1610 ;; Push/pop instructions.
1612 (define_insn "*push<mode>2"
1613 [(set (match_operand:DWI 0 "push_operand" "=<")
1614 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1617 [(set_attr "type" "multi")
1618 (set_attr "mode" "<MODE>")])
1621 [(set (match_operand:TI 0 "push_operand")
1622 (match_operand:TI 1 "general_operand"))]
1623 "TARGET_64BIT && reload_completed
1624 && !SSE_REG_P (operands[1])"
1626 "ix86_split_long_move (operands); DONE;")
1628 (define_insn "*pushdi2_rex64"
1629 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1630 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1635 [(set_attr "type" "push,multi")
1636 (set_attr "mode" "DI")])
1638 ;; Convert impossible pushes of immediate to existing instructions.
1639 ;; First try to get scratch register and go through it. In case this
1640 ;; fails, push sign extended lower part first and then overwrite
1641 ;; upper part by 32bit move.
1643 [(match_scratch:DI 2 "r")
1644 (set (match_operand:DI 0 "push_operand")
1645 (match_operand:DI 1 "immediate_operand"))]
1646 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1647 && !x86_64_immediate_operand (operands[1], DImode)"
1648 [(set (match_dup 2) (match_dup 1))
1649 (set (match_dup 0) (match_dup 2))])
1651 ;; We need to define this as both peepholer and splitter for case
1652 ;; peephole2 pass is not run.
1653 ;; "&& 1" is needed to keep it from matching the previous pattern.
1655 [(set (match_operand:DI 0 "push_operand")
1656 (match_operand:DI 1 "immediate_operand"))]
1657 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1658 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1659 [(set (match_dup 0) (match_dup 1))
1660 (set (match_dup 2) (match_dup 3))]
1662 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1664 operands[1] = gen_lowpart (DImode, operands[2]);
1665 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1670 [(set (match_operand:DI 0 "push_operand")
1671 (match_operand:DI 1 "immediate_operand"))]
1672 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1673 ? epilogue_completed : reload_completed)
1674 && !symbolic_operand (operands[1], DImode)
1675 && !x86_64_immediate_operand (operands[1], DImode)"
1676 [(set (match_dup 0) (match_dup 1))
1677 (set (match_dup 2) (match_dup 3))]
1679 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1681 operands[1] = gen_lowpart (DImode, operands[2]);
1682 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1687 [(set (match_operand:DI 0 "push_operand")
1688 (match_operand:DI 1 "general_operand"))]
1689 "!TARGET_64BIT && reload_completed
1690 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1692 "ix86_split_long_move (operands); DONE;")
1694 (define_insn "*pushsi2"
1695 [(set (match_operand:SI 0 "push_operand" "=<")
1696 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1699 [(set_attr "type" "push")
1700 (set_attr "mode" "SI")])
1702 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1703 ;; "push a byte/word". But actually we use pushl, which has the effect
1704 ;; of rounding the amount pushed up to a word.
1706 ;; For TARGET_64BIT we always round up to 8 bytes.
1707 (define_insn "*push<mode>2_rex64"
1708 [(set (match_operand:SWI124 0 "push_operand" "=X")
1709 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1712 [(set_attr "type" "push")
1713 (set_attr "mode" "DI")])
1715 (define_insn "*push<mode>2"
1716 [(set (match_operand:SWI12 0 "push_operand" "=X")
1717 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1720 [(set_attr "type" "push")
1721 (set_attr "mode" "SI")])
1723 (define_insn "*push<mode>2_prologue"
1724 [(set (match_operand:W 0 "push_operand" "=<")
1725 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1726 (clobber (mem:BLK (scratch)))]
1728 "push{<imodesuffix>}\t%1"
1729 [(set_attr "type" "push")
1730 (set_attr "mode" "<MODE>")])
1732 (define_insn "*pop<mode>1"
1733 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1734 (match_operand:W 1 "pop_operand" ">"))]
1736 "pop{<imodesuffix>}\t%0"
1737 [(set_attr "type" "pop")
1738 (set_attr "mode" "<MODE>")])
1740 (define_insn "*pop<mode>1_epilogue"
1741 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1742 (match_operand:W 1 "pop_operand" ">"))
1743 (clobber (mem:BLK (scratch)))]
1745 "pop{<imodesuffix>}\t%0"
1746 [(set_attr "type" "pop")
1747 (set_attr "mode" "<MODE>")])
1749 ;; Move instructions.
1751 (define_expand "movoi"
1752 [(set (match_operand:OI 0 "nonimmediate_operand")
1753 (match_operand:OI 1 "general_operand"))]
1755 "ix86_expand_move (OImode, operands); DONE;")
1757 (define_expand "movti"
1758 [(set (match_operand:TI 0 "nonimmediate_operand")
1759 (match_operand:TI 1 "nonimmediate_operand"))]
1760 "TARGET_64BIT || TARGET_SSE"
1763 ix86_expand_move (TImode, operands);
1764 else if (push_operand (operands[0], TImode))
1765 ix86_expand_push (TImode, operands[1]);
1767 ix86_expand_vector_move (TImode, operands);
1771 ;; This expands to what emit_move_complex would generate if we didn't
1772 ;; have a movti pattern. Having this avoids problems with reload on
1773 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1774 ;; to have around all the time.
1775 (define_expand "movcdi"
1776 [(set (match_operand:CDI 0 "nonimmediate_operand")
1777 (match_operand:CDI 1 "general_operand"))]
1780 if (push_operand (operands[0], CDImode))
1781 emit_move_complex_push (CDImode, operands[0], operands[1]);
1783 emit_move_complex_parts (operands[0], operands[1]);
1787 (define_expand "mov<mode>"
1788 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1789 (match_operand:SWI1248x 1 "general_operand"))]
1791 "ix86_expand_move (<MODE>mode, operands); DONE;")
1793 (define_insn "*mov<mode>_xor"
1794 [(set (match_operand:SWI48 0 "register_operand" "=r")
1795 (match_operand:SWI48 1 "const0_operand"))
1796 (clobber (reg:CC FLAGS_REG))]
1799 [(set_attr "type" "alu1")
1800 (set_attr "mode" "SI")
1801 (set_attr "length_immediate" "0")])
1803 (define_insn "*mov<mode>_or"
1804 [(set (match_operand:SWI48 0 "register_operand" "=r")
1805 (match_operand:SWI48 1 "const_int_operand"))
1806 (clobber (reg:CC FLAGS_REG))]
1808 && operands[1] == constm1_rtx"
1809 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1810 [(set_attr "type" "alu1")
1811 (set_attr "mode" "<MODE>")
1812 (set_attr "length_immediate" "1")])
1814 (define_insn "*movoi_internal_avx"
1815 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1816 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1817 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1819 switch (which_alternative)
1822 return standard_sse_constant_opcode (insn, operands[1]);
1825 if (misaligned_operand (operands[0], OImode)
1826 || misaligned_operand (operands[1], OImode))
1828 if (get_attr_mode (insn) == MODE_V8SF)
1829 return "vmovups\t{%1, %0|%0, %1}";
1831 return "vmovdqu\t{%1, %0|%0, %1}";
1835 if (get_attr_mode (insn) == MODE_V8SF)
1836 return "vmovaps\t{%1, %0|%0, %1}";
1838 return "vmovdqa\t{%1, %0|%0, %1}";
1844 [(set_attr "type" "sselog1,ssemov,ssemov")
1845 (set_attr "prefix" "vex")
1847 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1848 (const_string "V8SF")
1849 (and (eq_attr "alternative" "2")
1850 (match_test "TARGET_SSE_TYPELESS_STORES"))
1851 (const_string "V8SF")
1853 (const_string "OI")))])
1855 (define_insn "*movti_internal_rex64"
1856 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1857 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1858 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1860 switch (which_alternative)
1866 return standard_sse_constant_opcode (insn, operands[1]);
1869 /* TDmode values are passed as TImode on the stack. Moving them
1870 to stack may result in unaligned memory access. */
1871 if (misaligned_operand (operands[0], TImode)
1872 || misaligned_operand (operands[1], TImode))
1874 if (get_attr_mode (insn) == MODE_V4SF)
1875 return "%vmovups\t{%1, %0|%0, %1}";
1877 return "%vmovdqu\t{%1, %0|%0, %1}";
1881 if (get_attr_mode (insn) == MODE_V4SF)
1882 return "%vmovaps\t{%1, %0|%0, %1}";
1884 return "%vmovdqa\t{%1, %0|%0, %1}";
1890 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1891 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1893 (cond [(eq_attr "alternative" "0,1")
1895 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1896 (const_string "V4SF")
1897 (and (eq_attr "alternative" "4")
1898 (match_test "TARGET_SSE_TYPELESS_STORES"))
1899 (const_string "V4SF")
1900 (match_test "TARGET_AVX")
1902 (match_test "optimize_function_for_size_p (cfun)")
1903 (const_string "V4SF")
1905 (const_string "TI")))])
1908 [(set (match_operand:TI 0 "nonimmediate_operand")
1909 (match_operand:TI 1 "general_operand"))]
1911 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1913 "ix86_split_long_move (operands); DONE;")
1915 (define_insn "*movti_internal_sse"
1916 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x ,m")
1917 (match_operand:TI 1 "vector_move_operand" "C ,xm,x"))]
1918 "TARGET_SSE && !TARGET_64BIT
1919 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1921 switch (which_alternative)
1924 return standard_sse_constant_opcode (insn, operands[1]);
1927 /* TDmode values are passed as TImode on the stack. Moving them
1928 to stack may result in unaligned memory access. */
1929 if (misaligned_operand (operands[0], TImode)
1930 || misaligned_operand (operands[1], TImode))
1932 if (get_attr_mode (insn) == MODE_V4SF)
1933 return "%vmovups\t{%1, %0|%0, %1}";
1935 return "%vmovdqu\t{%1, %0|%0, %1}";
1939 if (get_attr_mode (insn) == MODE_V4SF)
1940 return "%vmovaps\t{%1, %0|%0, %1}";
1942 return "%vmovdqa\t{%1, %0|%0, %1}";
1948 [(set_attr "type" "sselog1,ssemov,ssemov")
1949 (set_attr "prefix" "maybe_vex")
1951 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1952 (const_string "V4SF")
1953 (and (eq_attr "alternative" "2")
1954 (match_test "TARGET_SSE_TYPELESS_STORES"))
1955 (const_string "V4SF")
1956 (match_test "TARGET_AVX")
1958 (ior (not (match_test "TARGET_SSE2"))
1959 (match_test "optimize_function_for_size_p (cfun)"))
1960 (const_string "V4SF")
1962 (const_string "TI")))])
1964 (define_insn "*movdi_internal_rex64"
1965 [(set (match_operand:DI 0 "nonimmediate_operand"
1966 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1967 (match_operand:DI 1 "general_operand"
1968 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1969 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1971 switch (get_attr_type (insn))
1974 if (SSE_REG_P (operands[0]))
1975 return "movq2dq\t{%1, %0|%0, %1}";
1977 return "movdq2q\t{%1, %0|%0, %1}";
1980 if (get_attr_mode (insn) == MODE_V4SF)
1981 return "%vmovaps\t{%1, %0|%0, %1}";
1982 else if (get_attr_mode (insn) == MODE_TI)
1983 return "%vmovdqa\t{%1, %0|%0, %1}";
1985 /* Handle broken assemblers that require movd instead of movq. */
1986 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1987 return "%vmovd\t{%1, %0|%0, %1}";
1989 return "%vmovq\t{%1, %0|%0, %1}";
1992 /* Handle broken assemblers that require movd instead of movq. */
1993 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1994 return "movd\t{%1, %0|%0, %1}";
1996 return "movq\t{%1, %0|%0, %1}";
1999 return standard_sse_constant_opcode (insn, operands[1]);
2002 return "pxor\t%0, %0";
2008 return "lea{q}\t{%E1, %0|%0, %E1}";
2011 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2012 if (get_attr_mode (insn) == MODE_SI)
2013 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2014 else if (which_alternative == 2)
2015 return "movabs{q}\t{%1, %0|%0, %1}";
2016 else if (ix86_use_lea_for_mov (insn, operands))
2017 return "lea{q}\t{%E1, %0|%0, %E1}";
2019 return "mov{q}\t{%1, %0|%0, %1}";
2023 (cond [(eq_attr "alternative" "4")
2024 (const_string "multi")
2025 (eq_attr "alternative" "5")
2026 (const_string "mmx")
2027 (eq_attr "alternative" "6,7,8,9")
2028 (const_string "mmxmov")
2029 (eq_attr "alternative" "10")
2030 (const_string "sselog1")
2031 (eq_attr "alternative" "11,12,13,14,15")
2032 (const_string "ssemov")
2033 (eq_attr "alternative" "16,17")
2034 (const_string "ssecvt")
2035 (match_operand 1 "pic_32bit_operand")
2036 (const_string "lea")
2038 (const_string "imov")))
2041 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2043 (const_string "*")))
2044 (set (attr "length_immediate")
2046 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2048 (const_string "*")))
2049 (set (attr "prefix_rex")
2050 (if_then_else (eq_attr "alternative" "8,9")
2052 (const_string "*")))
2053 (set (attr "prefix_data16")
2054 (if_then_else (eq_attr "alternative" "11")
2056 (const_string "*")))
2057 (set (attr "prefix")
2058 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2059 (const_string "maybe_vex")
2060 (const_string "orig")))
2062 (cond [(eq_attr "alternative" "0,4")
2064 (eq_attr "alternative" "10,12")
2065 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2066 (const_string "V4SF")
2067 (match_test "TARGET_AVX")
2069 (match_test "optimize_function_for_size_p (cfun)")
2070 (const_string "V4SF")
2072 (const_string "TI"))
2074 (const_string "DI")))])
2076 ;; Reload patterns to support multi-word load/store
2077 ;; with non-offsetable address.
2078 (define_expand "reload_noff_store"
2079 [(parallel [(match_operand 0 "memory_operand" "=m")
2080 (match_operand 1 "register_operand" "r")
2081 (match_operand:DI 2 "register_operand" "=&r")])]
2084 rtx mem = operands[0];
2085 rtx addr = XEXP (mem, 0);
2087 emit_move_insn (operands[2], addr);
2088 mem = replace_equiv_address_nv (mem, operands[2]);
2090 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2094 (define_expand "reload_noff_load"
2095 [(parallel [(match_operand 0 "register_operand" "=r")
2096 (match_operand 1 "memory_operand" "m")
2097 (match_operand:DI 2 "register_operand" "=r")])]
2100 rtx mem = operands[1];
2101 rtx addr = XEXP (mem, 0);
2103 emit_move_insn (operands[2], addr);
2104 mem = replace_equiv_address_nv (mem, operands[2]);
2106 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2110 ;; Convert impossible stores of immediate to existing instructions.
2111 ;; First try to get scratch register and go through it. In case this
2112 ;; fails, move by 32bit parts.
2114 [(match_scratch:DI 2 "r")
2115 (set (match_operand:DI 0 "memory_operand")
2116 (match_operand:DI 1 "immediate_operand"))]
2117 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2118 && !x86_64_immediate_operand (operands[1], DImode)"
2119 [(set (match_dup 2) (match_dup 1))
2120 (set (match_dup 0) (match_dup 2))])
2122 ;; We need to define this as both peepholer and splitter for case
2123 ;; peephole2 pass is not run.
2124 ;; "&& 1" is needed to keep it from matching the previous pattern.
2126 [(set (match_operand:DI 0 "memory_operand")
2127 (match_operand:DI 1 "immediate_operand"))]
2128 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2129 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2130 [(set (match_dup 2) (match_dup 3))
2131 (set (match_dup 4) (match_dup 5))]
2132 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2135 [(set (match_operand:DI 0 "memory_operand")
2136 (match_operand:DI 1 "immediate_operand"))]
2137 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2138 ? epilogue_completed : reload_completed)
2139 && !symbolic_operand (operands[1], DImode)
2140 && !x86_64_immediate_operand (operands[1], DImode)"
2141 [(set (match_dup 2) (match_dup 3))
2142 (set (match_dup 4) (match_dup 5))]
2143 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2145 (define_insn "*movdi_internal"
2146 [(set (match_operand:DI 0 "nonimmediate_operand"
2147 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2148 (match_operand:DI 1 "general_operand"
2149 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2150 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2152 switch (get_attr_type (insn))
2155 if (SSE_REG_P (operands[0]))
2156 return "movq2dq\t{%1, %0|%0, %1}";
2158 return "movdq2q\t{%1, %0|%0, %1}";
2161 switch (get_attr_mode (insn))
2164 return "%vmovdqa\t{%1, %0|%0, %1}";
2166 return "%vmovq\t{%1, %0|%0, %1}";
2168 return "%vmovaps\t{%1, %0|%0, %1}";
2170 return "movlps\t{%1, %0|%0, %1}";
2176 return "movq\t{%1, %0|%0, %1}";
2179 return standard_sse_constant_opcode (insn, operands[1]);
2182 return "pxor\t%0, %0";
2192 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2193 (const_string "sse2")
2194 (eq_attr "alternative" "9,10,11,12")
2195 (const_string "noavx")
2197 (const_string "*")))
2199 (cond [(eq_attr "alternative" "0,1")
2200 (const_string "multi")
2201 (eq_attr "alternative" "2")
2202 (const_string "mmx")
2203 (eq_attr "alternative" "3,4")
2204 (const_string "mmxmov")
2205 (eq_attr "alternative" "5,9")
2206 (const_string "sselog1")
2207 (eq_attr "alternative" "13,14")
2208 (const_string "ssecvt")
2210 (const_string "ssemov")))
2211 (set (attr "prefix")
2212 (if_then_else (eq_attr "alternative" "5,6,7,8")
2213 (const_string "maybe_vex")
2214 (const_string "orig")))
2216 (cond [(eq_attr "alternative" "9,11")
2217 (const_string "V4SF")
2218 (eq_attr "alternative" "10,12")
2219 (const_string "V2SF")
2220 (eq_attr "alternative" "5,7")
2221 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2222 (const_string "V4SF")
2223 (match_test "TARGET_AVX")
2225 (match_test "optimize_function_for_size_p (cfun)")
2226 (const_string "V4SF")
2228 (const_string "TI"))
2230 (const_string "DI")))])
2233 [(set (match_operand:DI 0 "nonimmediate_operand")
2234 (match_operand:DI 1 "general_operand"))]
2235 "!TARGET_64BIT && reload_completed
2236 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2237 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2239 "ix86_split_long_move (operands); DONE;")
2241 (define_insn "*movsi_internal"
2242 [(set (match_operand:SI 0 "nonimmediate_operand"
2243 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2244 (match_operand:SI 1 "general_operand"
2245 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2246 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2248 switch (get_attr_type (insn))
2251 return standard_sse_constant_opcode (insn, operands[1]);
2254 switch (get_attr_mode (insn))
2257 return "%vmovdqa\t{%1, %0|%0, %1}";
2259 return "%vmovaps\t{%1, %0|%0, %1}";
2261 return "%vmovd\t{%1, %0|%0, %1}";
2263 return "%vmovss\t{%1, %0|%0, %1}";
2269 return "pxor\t%0, %0";
2272 if (get_attr_mode (insn) == MODE_DI)
2273 return "movq\t{%1, %0|%0, %1}";
2274 return "movd\t{%1, %0|%0, %1}";
2277 return "lea{l}\t{%E1, %0|%0, %E1}";
2280 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2281 if (ix86_use_lea_for_mov (insn, operands))
2282 return "lea{l}\t{%E1, %0|%0, %E1}";
2284 return "mov{l}\t{%1, %0|%0, %1}";
2288 (cond [(eq_attr "alternative" "2")
2289 (const_string "mmx")
2290 (eq_attr "alternative" "3,4,5")
2291 (const_string "mmxmov")
2292 (eq_attr "alternative" "6")
2293 (const_string "sselog1")
2294 (eq_attr "alternative" "7,8,9,10,11")
2295 (const_string "ssemov")
2296 (match_operand 1 "pic_32bit_operand")
2297 (const_string "lea")
2299 (const_string "imov")))
2300 (set (attr "prefix")
2301 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2302 (const_string "orig")
2303 (const_string "maybe_vex")))
2304 (set (attr "prefix_data16")
2305 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2307 (const_string "*")))
2309 (cond [(eq_attr "alternative" "2,3")
2311 (eq_attr "alternative" "6,7")
2312 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2313 (const_string "V4SF")
2314 (match_test "TARGET_AVX")
2316 (ior (not (match_test "TARGET_SSE2"))
2317 (match_test "optimize_function_for_size_p (cfun)"))
2318 (const_string "V4SF")
2320 (const_string "TI"))
2321 (and (eq_attr "alternative" "8,9,10,11")
2322 (not (match_test "TARGET_SSE2")))
2325 (const_string "SI")))])
2327 (define_insn "*movhi_internal"
2328 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2329 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2330 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2332 switch (get_attr_type (insn))
2335 /* movzwl is faster than movw on p2 due to partial word stalls,
2336 though not as fast as an aligned movl. */
2337 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2339 if (get_attr_mode (insn) == MODE_SI)
2340 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2342 return "mov{w}\t{%1, %0|%0, %1}";
2346 (cond [(match_test "optimize_function_for_size_p (cfun)")
2347 (const_string "imov")
2348 (and (eq_attr "alternative" "0")
2349 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2350 (not (match_test "TARGET_HIMODE_MATH"))))
2351 (const_string "imov")
2352 (and (eq_attr "alternative" "1,2")
2353 (match_operand:HI 1 "aligned_operand"))
2354 (const_string "imov")
2355 (and (match_test "TARGET_MOVX")
2356 (eq_attr "alternative" "0,2"))
2357 (const_string "imovx")
2359 (const_string "imov")))
2361 (cond [(eq_attr "type" "imovx")
2363 (and (eq_attr "alternative" "1,2")
2364 (match_operand:HI 1 "aligned_operand"))
2366 (and (eq_attr "alternative" "0")
2367 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2368 (not (match_test "TARGET_HIMODE_MATH"))))
2371 (const_string "HI")))])
2373 ;; Situation is quite tricky about when to choose full sized (SImode) move
2374 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2375 ;; partial register dependency machines (such as AMD Athlon), where QImode
2376 ;; moves issue extra dependency and for partial register stalls machines
2377 ;; that don't use QImode patterns (and QImode move cause stall on the next
2380 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2381 ;; register stall machines with, where we use QImode instructions, since
2382 ;; partial register stall can be caused there. Then we use movzx.
2383 (define_insn "*movqi_internal"
2384 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2385 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2386 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2388 switch (get_attr_type (insn))
2391 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2392 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2394 if (get_attr_mode (insn) == MODE_SI)
2395 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2397 return "mov{b}\t{%1, %0|%0, %1}";
2401 (cond [(and (eq_attr "alternative" "5")
2402 (not (match_operand:QI 1 "aligned_operand")))
2403 (const_string "imovx")
2404 (match_test "optimize_function_for_size_p (cfun)")
2405 (const_string "imov")
2406 (and (eq_attr "alternative" "3")
2407 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2408 (not (match_test "TARGET_QIMODE_MATH"))))
2409 (const_string "imov")
2410 (eq_attr "alternative" "3,5")
2411 (const_string "imovx")
2412 (and (match_test "TARGET_MOVX")
2413 (eq_attr "alternative" "2"))
2414 (const_string "imovx")
2416 (const_string "imov")))
2418 (cond [(eq_attr "alternative" "3,4,5")
2420 (eq_attr "alternative" "6")
2422 (eq_attr "type" "imovx")
2424 (and (eq_attr "type" "imov")
2425 (and (eq_attr "alternative" "0,1")
2426 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2427 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2428 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2430 ;; Avoid partial register stalls when not using QImode arithmetic
2431 (and (eq_attr "type" "imov")
2432 (and (eq_attr "alternative" "0,1")
2433 (and (match_test "TARGET_PARTIAL_REG_STALL")
2434 (not (match_test "TARGET_QIMODE_MATH")))))
2437 (const_string "QI")))])
2439 ;; Stores and loads of ax to arbitrary constant address.
2440 ;; We fake an second form of instruction to force reload to load address
2441 ;; into register when rax is not available
2442 (define_insn "*movabs<mode>_1"
2443 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2444 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2445 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2447 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2448 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2449 [(set_attr "type" "imov")
2450 (set_attr "modrm" "0,*")
2451 (set_attr "length_address" "8,0")
2452 (set_attr "length_immediate" "0,*")
2453 (set_attr "memory" "store")
2454 (set_attr "mode" "<MODE>")])
2456 (define_insn "*movabs<mode>_2"
2457 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2458 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2459 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2461 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2462 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2463 [(set_attr "type" "imov")
2464 (set_attr "modrm" "0,*")
2465 (set_attr "length_address" "8,0")
2466 (set_attr "length_immediate" "0")
2467 (set_attr "memory" "load")
2468 (set_attr "mode" "<MODE>")])
2470 (define_insn "swap<mode>"
2471 [(set (match_operand:SWI48 0 "register_operand" "+r")
2472 (match_operand:SWI48 1 "register_operand" "+r"))
2476 "xchg{<imodesuffix>}\t%1, %0"
2477 [(set_attr "type" "imov")
2478 (set_attr "mode" "<MODE>")
2479 (set_attr "pent_pair" "np")
2480 (set_attr "athlon_decode" "vector")
2481 (set_attr "amdfam10_decode" "double")
2482 (set_attr "bdver1_decode" "double")])
2484 (define_insn "*swap<mode>_1"
2485 [(set (match_operand:SWI12 0 "register_operand" "+r")
2486 (match_operand:SWI12 1 "register_operand" "+r"))
2489 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2491 [(set_attr "type" "imov")
2492 (set_attr "mode" "SI")
2493 (set_attr "pent_pair" "np")
2494 (set_attr "athlon_decode" "vector")
2495 (set_attr "amdfam10_decode" "double")
2496 (set_attr "bdver1_decode" "double")])
2498 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2499 ;; is disabled for AMDFAM10
2500 (define_insn "*swap<mode>_2"
2501 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2502 (match_operand:SWI12 1 "register_operand" "+<r>"))
2505 "TARGET_PARTIAL_REG_STALL"
2506 "xchg{<imodesuffix>}\t%1, %0"
2507 [(set_attr "type" "imov")
2508 (set_attr "mode" "<MODE>")
2509 (set_attr "pent_pair" "np")
2510 (set_attr "athlon_decode" "vector")])
2512 (define_expand "movstrict<mode>"
2513 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2514 (match_operand:SWI12 1 "general_operand"))]
2517 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2519 if (GET_CODE (operands[0]) == SUBREG
2520 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2522 /* Don't generate memory->memory moves, go through a register */
2523 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2524 operands[1] = force_reg (<MODE>mode, operands[1]);
2527 (define_insn "*movstrict<mode>_1"
2528 [(set (strict_low_part
2529 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2530 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2531 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2532 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2533 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2534 [(set_attr "type" "imov")
2535 (set_attr "mode" "<MODE>")])
2537 (define_insn "*movstrict<mode>_xor"
2538 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2539 (match_operand:SWI12 1 "const0_operand"))
2540 (clobber (reg:CC FLAGS_REG))]
2542 "xor{<imodesuffix>}\t%0, %0"
2543 [(set_attr "type" "alu1")
2544 (set_attr "mode" "<MODE>")
2545 (set_attr "length_immediate" "0")])
2547 (define_insn "*mov<mode>_extv_1"
2548 [(set (match_operand:SWI24 0 "register_operand" "=R")
2549 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2553 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2554 [(set_attr "type" "imovx")
2555 (set_attr "mode" "SI")])
2557 (define_insn "*movqi_extv_1_rex64"
2558 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2559 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2564 switch (get_attr_type (insn))
2567 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2569 return "mov{b}\t{%h1, %0|%0, %h1}";
2573 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2574 (match_test "TARGET_MOVX"))
2575 (const_string "imovx")
2576 (const_string "imov")))
2578 (if_then_else (eq_attr "type" "imovx")
2580 (const_string "QI")))])
2582 (define_insn "*movqi_extv_1"
2583 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2584 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2589 switch (get_attr_type (insn))
2592 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2594 return "mov{b}\t{%h1, %0|%0, %h1}";
2598 (if_then_else (and (match_operand:QI 0 "register_operand")
2599 (ior (not (match_operand:QI 0 "QIreg_operand"))
2600 (match_test "TARGET_MOVX")))
2601 (const_string "imovx")
2602 (const_string "imov")))
2604 (if_then_else (eq_attr "type" "imovx")
2606 (const_string "QI")))])
2608 (define_insn "*mov<mode>_extzv_1"
2609 [(set (match_operand:SWI48 0 "register_operand" "=R")
2610 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2614 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2615 [(set_attr "type" "imovx")
2616 (set_attr "mode" "SI")])
2618 (define_insn "*movqi_extzv_2_rex64"
2619 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2621 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2626 switch (get_attr_type (insn))
2629 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2631 return "mov{b}\t{%h1, %0|%0, %h1}";
2635 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2636 (match_test "TARGET_MOVX"))
2637 (const_string "imovx")
2638 (const_string "imov")))
2640 (if_then_else (eq_attr "type" "imovx")
2642 (const_string "QI")))])
2644 (define_insn "*movqi_extzv_2"
2645 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2647 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2652 switch (get_attr_type (insn))
2655 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2657 return "mov{b}\t{%h1, %0|%0, %h1}";
2661 (if_then_else (and (match_operand:QI 0 "register_operand")
2662 (ior (not (match_operand:QI 0 "QIreg_operand"))
2663 (match_test "TARGET_MOVX")))
2664 (const_string "imovx")
2665 (const_string "imov")))
2667 (if_then_else (eq_attr "type" "imovx")
2669 (const_string "QI")))])
2671 (define_expand "mov<mode>_insv_1"
2672 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2675 (match_operand:SWI48 1 "nonmemory_operand"))])
2677 (define_insn "*mov<mode>_insv_1_rex64"
2678 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2681 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2683 "mov{b}\t{%b1, %h0|%h0, %b1}"
2684 [(set_attr "type" "imov")
2685 (set_attr "mode" "QI")])
2687 (define_insn "*movsi_insv_1"
2688 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2691 (match_operand:SI 1 "general_operand" "Qmn"))]
2693 "mov{b}\t{%b1, %h0|%h0, %b1}"
2694 [(set_attr "type" "imov")
2695 (set_attr "mode" "QI")])
2697 (define_insn "*movqi_insv_2"
2698 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2701 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2704 "mov{b}\t{%h1, %h0|%h0, %h1}"
2705 [(set_attr "type" "imov")
2706 (set_attr "mode" "QI")])
2708 ;; Floating point push instructions.
2710 (define_insn "*pushtf"
2711 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2712 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2715 /* This insn should be already split before reg-stack. */
2718 [(set_attr "type" "multi")
2719 (set_attr "unit" "sse,*,*")
2720 (set_attr "mode" "TF,SI,SI")])
2722 ;; %%% Kill this when call knows how to work this out.
2724 [(set (match_operand:TF 0 "push_operand")
2725 (match_operand:TF 1 "sse_reg_operand"))]
2726 "TARGET_SSE && reload_completed"
2727 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2728 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2730 (define_insn "*pushxf"
2731 [(set (match_operand:XF 0 "push_operand" "=<,<")
2732 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2733 "optimize_function_for_speed_p (cfun)"
2735 /* This insn should be already split before reg-stack. */
2738 [(set_attr "type" "multi")
2739 (set_attr "unit" "i387,*")
2740 (set_attr "mode" "XF,SI")])
2742 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2743 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2744 ;; Pushing using integer instructions is longer except for constants
2745 ;; and direct memory references (assuming that any given constant is pushed
2746 ;; only once, but this ought to be handled elsewhere).
2748 (define_insn "*pushxf_nointeger"
2749 [(set (match_operand:XF 0 "push_operand" "=<,<")
2750 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2751 "optimize_function_for_size_p (cfun)"
2753 /* This insn should be already split before reg-stack. */
2756 [(set_attr "type" "multi")
2757 (set_attr "unit" "i387,*")
2758 (set_attr "mode" "XF,SI")])
2760 ;; %%% Kill this when call knows how to work this out.
2762 [(set (match_operand:XF 0 "push_operand")
2763 (match_operand:XF 1 "fp_register_operand"))]
2765 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2766 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2767 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2769 (define_insn "*pushdf_rex64"
2770 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2771 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2774 /* This insn should be already split before reg-stack. */
2777 [(set_attr "type" "multi")
2778 (set_attr "unit" "i387,*,*")
2779 (set_attr "mode" "DF,DI,DF")])
2781 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2782 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2783 ;; On the average, pushdf using integers can be still shorter.
2785 (define_insn "*pushdf"
2786 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2787 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2790 /* This insn should be already split before reg-stack. */
2793 [(set_attr "isa" "*,*,sse2")
2794 (set_attr "type" "multi")
2795 (set_attr "unit" "i387,*,*")
2796 (set_attr "mode" "DF,DI,DF")])
2798 ;; %%% Kill this when call knows how to work this out.
2800 [(set (match_operand:DF 0 "push_operand")
2801 (match_operand:DF 1 "any_fp_register_operand"))]
2803 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2804 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2806 (define_insn "*pushsf_rex64"
2807 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2808 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2811 /* Anything else should be already split before reg-stack. */
2812 gcc_assert (which_alternative == 1);
2813 return "push{q}\t%q1";
2815 [(set_attr "type" "multi,push,multi")
2816 (set_attr "unit" "i387,*,*")
2817 (set_attr "mode" "SF,DI,SF")])
2819 (define_insn "*pushsf"
2820 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2821 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2824 /* Anything else should be already split before reg-stack. */
2825 gcc_assert (which_alternative == 1);
2826 return "push{l}\t%1";
2828 [(set_attr "type" "multi,push,multi")
2829 (set_attr "unit" "i387,*,*")
2830 (set_attr "mode" "SF,SI,SF")])
2832 ;; %%% Kill this when call knows how to work this out.
2834 [(set (match_operand:SF 0 "push_operand")
2835 (match_operand:SF 1 "any_fp_register_operand"))]
2837 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2838 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2839 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2842 [(set (match_operand:SF 0 "push_operand")
2843 (match_operand:SF 1 "memory_operand"))]
2845 && (operands[2] = find_constant_src (insn))"
2846 [(set (match_dup 0) (match_dup 2))])
2849 [(set (match_operand 0 "push_operand")
2850 (match_operand 1 "general_operand"))]
2852 && (GET_MODE (operands[0]) == TFmode
2853 || GET_MODE (operands[0]) == XFmode
2854 || GET_MODE (operands[0]) == DFmode)
2855 && !ANY_FP_REG_P (operands[1])"
2857 "ix86_split_long_move (operands); DONE;")
2859 ;; Floating point move instructions.
2861 (define_expand "movtf"
2862 [(set (match_operand:TF 0 "nonimmediate_operand")
2863 (match_operand:TF 1 "nonimmediate_operand"))]
2866 ix86_expand_move (TFmode, operands);
2870 (define_expand "mov<mode>"
2871 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2872 (match_operand:X87MODEF 1 "general_operand"))]
2874 "ix86_expand_move (<MODE>mode, operands); DONE;")
2876 (define_insn "*movtf_internal"
2877 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2878 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,F*r"))]
2880 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2881 && (!can_create_pseudo_p ()
2882 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2883 || GET_CODE (operands[1]) != CONST_DOUBLE
2884 || (optimize_function_for_size_p (cfun)
2885 && standard_sse_constant_p (operands[1])
2886 && !memory_operand (operands[0], TFmode))
2887 || (!TARGET_MEMORY_MISMATCH_STALL
2888 && memory_operand (operands[0], TFmode)))"
2890 switch (which_alternative)
2893 return standard_sse_constant_opcode (insn, operands[1]);
2896 /* Handle misaligned load/store since we
2897 don't have movmisaligntf pattern. */
2898 if (misaligned_operand (operands[0], TFmode)
2899 || misaligned_operand (operands[1], TFmode))
2901 if (get_attr_mode (insn) == MODE_V4SF)
2902 return "%vmovups\t{%1, %0|%0, %1}";
2904 return "%vmovdqu\t{%1, %0|%0, %1}";
2908 if (get_attr_mode (insn) == MODE_V4SF)
2909 return "%vmovaps\t{%1, %0|%0, %1}";
2911 return "%vmovdqa\t{%1, %0|%0, %1}";
2922 [(set_attr "type" "sselog1,ssemov,ssemov,*,*")
2923 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2925 (cond [(eq_attr "alternative" "3,4")
2927 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2928 (const_string "V4SF")
2929 (and (eq_attr "alternative" "2")
2930 (match_test "TARGET_SSE_TYPELESS_STORES"))
2931 (const_string "V4SF")
2932 (match_test "TARGET_AVX")
2934 (ior (not (match_test "TARGET_SSE2"))
2935 (match_test "optimize_function_for_size_p (cfun)"))
2936 (const_string "V4SF")
2938 (const_string "TI")))])
2940 ;; Possible store forwarding (partial memory) stall in alternative 4.
2941 (define_insn "*movxf_internal"
2942 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2943 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2944 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2945 && (!can_create_pseudo_p ()
2946 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2947 || GET_CODE (operands[1]) != CONST_DOUBLE
2948 || (optimize_function_for_size_p (cfun)
2949 && standard_80387_constant_p (operands[1]) > 0
2950 && !memory_operand (operands[0], XFmode))
2951 || (!TARGET_MEMORY_MISMATCH_STALL
2952 && memory_operand (operands[0], XFmode)))"
2954 switch (which_alternative)
2958 return output_387_reg_move (insn, operands);
2961 return standard_80387_constant_opcode (operands[1]);
2971 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2972 (set_attr "mode" "XF,XF,XF,SI,SI")])
2974 (define_insn "*movdf_internal_rex64"
2975 [(set (match_operand:DF 0 "nonimmediate_operand"
2976 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2977 (match_operand:DF 1 "general_operand"
2978 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2979 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2980 && (!can_create_pseudo_p ()
2981 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2982 || GET_CODE (operands[1]) != CONST_DOUBLE
2983 || (optimize_function_for_size_p (cfun)
2984 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2985 && standard_80387_constant_p (operands[1]) > 0)
2986 || (TARGET_SSE2 && TARGET_SSE_MATH
2987 && standard_sse_constant_p (operands[1]))))
2988 || memory_operand (operands[0], DFmode))"
2990 switch (which_alternative)
2994 return output_387_reg_move (insn, operands);
2997 return standard_80387_constant_opcode (operands[1]);
3001 return "mov{q}\t{%1, %0|%0, %1}";
3004 return "movabs{q}\t{%1, %0|%0, %1}";
3010 return standard_sse_constant_opcode (insn, operands[1]);
3015 switch (get_attr_mode (insn))
3018 return "%vmovapd\t{%1, %0|%0, %1}";
3020 return "%vmovaps\t{%1, %0|%0, %1}";
3023 return "%vmovq\t{%1, %0|%0, %1}";
3025 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3026 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3027 return "%vmovsd\t{%1, %0|%0, %1}";
3029 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3031 return "%vmovlps\t{%1, %d0|%d0, %1}";
3038 /* Handle broken assemblers that require movd instead of movq. */
3039 return "%vmovd\t{%1, %0|%0, %1}";
3046 (cond [(eq_attr "alternative" "0,1,2")
3047 (const_string "fmov")
3048 (eq_attr "alternative" "3,4,5")
3049 (const_string "imov")
3050 (eq_attr "alternative" "6")
3051 (const_string "multi")
3052 (eq_attr "alternative" "7")
3053 (const_string "sselog1")
3055 (const_string "ssemov")))
3058 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3060 (const_string "*")))
3061 (set (attr "length_immediate")
3063 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3065 (const_string "*")))
3066 (set (attr "prefix")
3067 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3068 (const_string "orig")
3069 (const_string "maybe_vex")))
3070 (set (attr "prefix_data16")
3071 (if_then_else (eq_attr "mode" "V1DF")
3073 (const_string "*")))
3075 (cond [(eq_attr "alternative" "0,1,2")
3077 (eq_attr "alternative" "3,4,5,6,11,12")
3080 /* xorps is one byte shorter for !TARGET_AVX. */
3081 (eq_attr "alternative" "7")
3082 (cond [(match_test "TARGET_AVX")
3083 (const_string "V2DF")
3084 (match_test "optimize_function_for_size_p (cfun)")
3085 (const_string "V4SF")
3086 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3089 (const_string "V2DF"))
3091 /* For architectures resolving dependencies on
3092 whole SSE registers use APD move to break dependency
3093 chains, otherwise use short move to avoid extra work.
3095 movaps encodes one byte shorter for !TARGET_AVX. */
3096 (eq_attr "alternative" "8")
3097 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3098 (const_string "V4SF")
3099 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3100 (const_string "V2DF")
3101 (match_test "TARGET_AVX")
3103 (match_test "optimize_function_for_size_p (cfun)")
3104 (const_string "V4SF")
3106 (const_string "DF"))
3107 /* For architectures resolving dependencies on register
3108 parts we may avoid extra work to zero out upper part
3110 (eq_attr "alternative" "9")
3112 (match_test "TARGET_SSE_SPLIT_REGS")
3113 (const_string "V1DF")
3114 (const_string "DF"))
3116 (const_string "DF")))])
3118 ;; Possible store forwarding (partial memory) stall in alternative 4.
3119 (define_insn "*movdf_internal"
3120 [(set (match_operand:DF 0 "nonimmediate_operand"
3121 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3122 (match_operand:DF 1 "general_operand"
3123 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3124 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3125 && (!can_create_pseudo_p ()
3126 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3127 || GET_CODE (operands[1]) != CONST_DOUBLE
3128 || (optimize_function_for_size_p (cfun)
3129 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3130 && standard_80387_constant_p (operands[1]) > 0)
3131 || (TARGET_SSE2 && TARGET_SSE_MATH
3132 && standard_sse_constant_p (operands[1])))
3133 && !memory_operand (operands[0], DFmode))
3134 || (!TARGET_MEMORY_MISMATCH_STALL
3135 && memory_operand (operands[0], DFmode)))"
3137 switch (which_alternative)
3141 return output_387_reg_move (insn, operands);
3144 return standard_80387_constant_opcode (operands[1]);
3152 return standard_sse_constant_opcode (insn, operands[1]);
3160 switch (get_attr_mode (insn))
3163 return "%vmovapd\t{%1, %0|%0, %1}";
3165 return "%vmovaps\t{%1, %0|%0, %1}";
3168 return "%vmovq\t{%1, %0|%0, %1}";
3170 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3171 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3172 return "%vmovsd\t{%1, %0|%0, %1}";
3174 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3176 return "%vmovlps\t{%1, %d0|%d0, %1}";
3186 (if_then_else (eq_attr "alternative" "5,6,7,8")
3187 (const_string "sse2")
3188 (const_string "*")))
3190 (cond [(eq_attr "alternative" "0,1,2")
3191 (const_string "fmov")
3192 (eq_attr "alternative" "3,4")
3193 (const_string "multi")
3194 (eq_attr "alternative" "5,9")
3195 (const_string "sselog1")
3197 (const_string "ssemov")))
3198 (set (attr "prefix")
3199 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3200 (const_string "orig")
3201 (const_string "maybe_vex")))
3202 (set (attr "prefix_data16")
3203 (if_then_else (eq_attr "mode" "V1DF")
3205 (const_string "*")))
3207 (cond [(eq_attr "alternative" "0,1,2")
3209 (eq_attr "alternative" "3,4")
3212 /* For SSE1, we have many fewer alternatives. */
3213 (not (match_test "TARGET_SSE2"))
3215 (eq_attr "alternative" "5,6,9,10")
3216 (const_string "V4SF")
3217 (const_string "V2SF"))
3219 /* xorps is one byte shorter for !TARGET_AVX. */
3220 (eq_attr "alternative" "5,9")
3221 (cond [(match_test "TARGET_AVX")
3222 (const_string "V2DF")
3223 (match_test "optimize_function_for_size_p (cfun)")
3224 (const_string "V4SF")
3225 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3228 (const_string "V2DF"))
3230 /* For architectures resolving dependencies on
3231 whole SSE registers use APD move to break dependency
3232 chains, otherwise use short move to avoid extra work.
3234 movaps encodes one byte shorter for !TARGET_AVX. */
3235 (eq_attr "alternative" "6,10")
3236 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3237 (const_string "V4SF")
3238 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3239 (const_string "V2DF")
3240 (match_test "TARGET_AVX")
3242 (match_test "optimize_function_for_size_p (cfun)")
3243 (const_string "V4SF")
3245 (const_string "DF"))
3247 /* For architectures resolving dependencies on register
3248 parts we may avoid extra work to zero out upper part
3250 (eq_attr "alternative" "7,11")
3252 (match_test "TARGET_SSE_SPLIT_REGS")
3253 (const_string "V1DF")
3254 (const_string "DF"))
3256 (const_string "DF")))])
3258 (define_insn "*movsf_internal"
3259 [(set (match_operand:SF 0 "nonimmediate_operand"
3260 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3261 (match_operand:SF 1 "general_operand"
3262 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3263 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3264 && (!can_create_pseudo_p ()
3265 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3266 || GET_CODE (operands[1]) != CONST_DOUBLE
3267 || (optimize_function_for_size_p (cfun)
3268 && ((!TARGET_SSE_MATH
3269 && standard_80387_constant_p (operands[1]) > 0)
3271 && standard_sse_constant_p (operands[1]))))
3272 || memory_operand (operands[0], SFmode))"
3274 switch (which_alternative)
3278 return output_387_reg_move (insn, operands);
3281 return standard_80387_constant_opcode (operands[1]);
3285 return "mov{l}\t{%1, %0|%0, %1}";
3288 return standard_sse_constant_opcode (insn, operands[1]);
3291 if (get_attr_mode (insn) == MODE_V4SF)
3292 return "%vmovaps\t{%1, %0|%0, %1}";
3294 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3298 return "%vmovss\t{%1, %0|%0, %1}";
3304 return "movd\t{%1, %0|%0, %1}";
3307 return "movq\t{%1, %0|%0, %1}";
3311 return "%vmovd\t{%1, %0|%0, %1}";
3318 (cond [(eq_attr "alternative" "0,1,2")
3319 (const_string "fmov")
3320 (eq_attr "alternative" "3,4")
3321 (const_string "multi")
3322 (eq_attr "alternative" "5")
3323 (const_string "sselog1")
3324 (eq_attr "alternative" "9,10,11,14,15")
3325 (const_string "mmxmov")
3327 (const_string "ssemov")))
3328 (set (attr "prefix")
3329 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3330 (const_string "maybe_vex")
3331 (const_string "orig")))
3333 (cond [(eq_attr "alternative" "3,4,9,10")
3335 (eq_attr "alternative" "5")
3336 (cond [(match_test "TARGET_AVX")
3337 (const_string "V4SF")
3338 (ior (not (match_test "TARGET_SSE2"))
3339 (match_test "optimize_function_for_size_p (cfun)"))
3340 (const_string "V4SF")
3341 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3344 (const_string "V4SF"))
3346 /* For architectures resolving dependencies on
3347 whole SSE registers use APS move to break dependency
3348 chains, otherwise use short move to avoid extra work.
3350 Do the same for architectures resolving dependencies on
3351 the parts. While in DF mode it is better to always handle
3352 just register parts, the SF mode is different due to lack
3353 of instructions to load just part of the register. It is
3354 better to maintain the whole registers in single format
3355 to avoid problems on using packed logical operations. */
3356 (eq_attr "alternative" "6")
3358 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3359 (match_test "TARGET_SSE_SPLIT_REGS"))
3360 (const_string "V4SF")
3361 (const_string "SF"))
3362 (eq_attr "alternative" "11")
3363 (const_string "DI")]
3364 (const_string "SF")))])
3367 [(set (match_operand 0 "any_fp_register_operand")
3368 (match_operand 1 "memory_operand"))]
3370 && (GET_MODE (operands[0]) == TFmode
3371 || GET_MODE (operands[0]) == XFmode
3372 || GET_MODE (operands[0]) == DFmode
3373 || GET_MODE (operands[0]) == SFmode)
3374 && (operands[2] = find_constant_src (insn))"
3375 [(set (match_dup 0) (match_dup 2))]
3377 rtx c = operands[2];
3378 int r = REGNO (operands[0]);
3380 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3381 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3386 [(set (match_operand 0 "any_fp_register_operand")
3387 (float_extend (match_operand 1 "memory_operand")))]
3389 && (GET_MODE (operands[0]) == TFmode
3390 || GET_MODE (operands[0]) == XFmode
3391 || GET_MODE (operands[0]) == DFmode)
3392 && (operands[2] = find_constant_src (insn))"
3393 [(set (match_dup 0) (match_dup 2))]
3395 rtx c = operands[2];
3396 int r = REGNO (operands[0]);
3398 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3399 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3403 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3405 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3406 (match_operand:X87MODEF 1 "immediate_operand"))]
3408 && (standard_80387_constant_p (operands[1]) == 8
3409 || standard_80387_constant_p (operands[1]) == 9)"
3410 [(set (match_dup 0)(match_dup 1))
3412 (neg:X87MODEF (match_dup 0)))]
3416 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3417 if (real_isnegzero (&r))
3418 operands[1] = CONST0_RTX (<MODE>mode);
3420 operands[1] = CONST1_RTX (<MODE>mode);
3424 [(set (match_operand 0 "nonimmediate_operand")
3425 (match_operand 1 "general_operand"))]
3427 && (GET_MODE (operands[0]) == TFmode
3428 || GET_MODE (operands[0]) == XFmode
3429 || GET_MODE (operands[0]) == DFmode)
3430 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3432 "ix86_split_long_move (operands); DONE;")
3434 (define_insn "swapxf"
3435 [(set (match_operand:XF 0 "register_operand" "+f")
3436 (match_operand:XF 1 "register_operand" "+f"))
3441 if (STACK_TOP_P (operands[0]))
3446 [(set_attr "type" "fxch")
3447 (set_attr "mode" "XF")])
3449 (define_insn "*swap<mode>"
3450 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3451 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3454 "TARGET_80387 || reload_completed"
3456 if (STACK_TOP_P (operands[0]))
3461 [(set_attr "type" "fxch")
3462 (set_attr "mode" "<MODE>")])
3464 ;; Zero extension instructions
3466 (define_expand "zero_extendsidi2"
3467 [(set (match_operand:DI 0 "nonimmediate_operand")
3468 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3470 (define_insn "*zero_extendsidi2_rex64"
3471 [(set (match_operand:DI 0 "nonimmediate_operand"
3472 "=r ,o,?*Ym,?*y,?*Yi,?*x")
3474 (match_operand:SI 1 "x86_64_zext_general_operand"
3475 "rmWz,0,r ,m ,r ,m")))]
3478 switch (get_attr_type (insn))
3481 if (ix86_use_lea_for_mov (insn, operands))
3482 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3484 return "mov{l}\t{%1, %k0|%k0, %1}";
3490 return "movd\t{%1, %0|%0, %1}";
3493 return "%vmovd\t{%1, %0|%0, %1}";
3499 [(set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3500 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3501 (set_attr "prefix_0f" "0,*,*,*,*,*")
3502 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3504 (define_insn "*zero_extendsidi2"
3505 [(set (match_operand:DI 0 "nonimmediate_operand"
3506 "=ro,?r,?o,?*Ym,?*y,?*Yi,?*x")
3507 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3508 "0 ,rm,r ,r ,m ,r ,m")))]
3514 movd\t{%1, %0|%0, %1}
3515 movd\t{%1, %0|%0, %1}
3516 %vmovd\t{%1, %0|%0, %1}
3517 %vmovd\t{%1, %0|%0, %1}"
3518 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3519 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3520 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3521 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3524 [(set (match_operand:DI 0 "memory_operand")
3525 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3527 [(set (match_dup 4) (const_int 0))]
3528 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3531 [(set (match_operand:DI 0 "register_operand")
3532 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3533 "!TARGET_64BIT && reload_completed
3534 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3535 && true_regnum (operands[0]) == true_regnum (operands[1])"
3536 [(set (match_dup 4) (const_int 0))]
3537 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3540 [(set (match_operand:DI 0 "nonimmediate_operand")
3541 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3542 "!TARGET_64BIT && reload_completed
3543 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3544 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3545 [(set (match_dup 3) (match_dup 1))
3546 (set (match_dup 4) (const_int 0))]
3547 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3549 (define_insn "zero_extend<mode>di2"
3550 [(set (match_operand:DI 0 "register_operand" "=r")
3552 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3554 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3555 [(set_attr "type" "imovx")
3556 (set_attr "mode" "SI")])
3558 (define_expand "zero_extend<mode>si2"
3559 [(set (match_operand:SI 0 "register_operand")
3560 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3563 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3565 operands[1] = force_reg (<MODE>mode, operands[1]);
3566 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3571 (define_insn_and_split "zero_extend<mode>si2_and"
3572 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3574 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3575 (clobber (reg:CC FLAGS_REG))]
3576 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3578 "&& reload_completed"
3579 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3580 (clobber (reg:CC FLAGS_REG))])]
3582 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3584 ix86_expand_clear (operands[0]);
3586 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3587 emit_insn (gen_movstrict<mode>
3588 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3592 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3594 [(set_attr "type" "alu1")
3595 (set_attr "mode" "SI")])
3597 (define_insn "*zero_extend<mode>si2"
3598 [(set (match_operand:SI 0 "register_operand" "=r")
3600 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3601 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3602 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3603 [(set_attr "type" "imovx")
3604 (set_attr "mode" "SI")])
3606 (define_expand "zero_extendqihi2"
3607 [(set (match_operand:HI 0 "register_operand")
3608 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3611 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3613 operands[1] = force_reg (QImode, operands[1]);
3614 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3619 (define_insn_and_split "zero_extendqihi2_and"
3620 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3621 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3622 (clobber (reg:CC FLAGS_REG))]
3623 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3625 "&& reload_completed"
3626 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3627 (clobber (reg:CC FLAGS_REG))])]
3629 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3631 ix86_expand_clear (operands[0]);
3633 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3634 emit_insn (gen_movstrictqi
3635 (gen_lowpart (QImode, operands[0]), operands[1]));
3639 operands[0] = gen_lowpart (SImode, operands[0]);
3641 [(set_attr "type" "alu1")
3642 (set_attr "mode" "SI")])
3644 ; zero extend to SImode to avoid partial register stalls
3645 (define_insn "*zero_extendqihi2"
3646 [(set (match_operand:HI 0 "register_operand" "=r")
3647 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3648 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3649 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3650 [(set_attr "type" "imovx")
3651 (set_attr "mode" "SI")])
3653 ;; Sign extension instructions
3655 (define_expand "extendsidi2"
3656 [(set (match_operand:DI 0 "register_operand")
3657 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3662 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3667 (define_insn "*extendsidi2_rex64"
3668 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3669 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3673 movs{lq|x}\t{%1, %0|%0, %1}"
3674 [(set_attr "type" "imovx")
3675 (set_attr "mode" "DI")
3676 (set_attr "prefix_0f" "0")
3677 (set_attr "modrm" "0,1")])
3679 (define_insn "extendsidi2_1"
3680 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3681 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3682 (clobber (reg:CC FLAGS_REG))
3683 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3687 ;; Extend to memory case when source register does die.
3689 [(set (match_operand:DI 0 "memory_operand")
3690 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3691 (clobber (reg:CC FLAGS_REG))
3692 (clobber (match_operand:SI 2 "register_operand"))]
3694 && dead_or_set_p (insn, operands[1])
3695 && !reg_mentioned_p (operands[1], operands[0]))"
3696 [(set (match_dup 3) (match_dup 1))
3697 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3698 (clobber (reg:CC FLAGS_REG))])
3699 (set (match_dup 4) (match_dup 1))]
3700 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3702 ;; Extend to memory case when source register does not die.
3704 [(set (match_operand:DI 0 "memory_operand")
3705 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3706 (clobber (reg:CC FLAGS_REG))
3707 (clobber (match_operand:SI 2 "register_operand"))]
3711 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3713 emit_move_insn (operands[3], operands[1]);
3715 /* Generate a cltd if possible and doing so it profitable. */
3716 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3717 && true_regnum (operands[1]) == AX_REG
3718 && true_regnum (operands[2]) == DX_REG)
3720 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3724 emit_move_insn (operands[2], operands[1]);
3725 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3727 emit_move_insn (operands[4], operands[2]);
3731 ;; Extend to register case. Optimize case where source and destination
3732 ;; registers match and cases where we can use cltd.
3734 [(set (match_operand:DI 0 "register_operand")
3735 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3736 (clobber (reg:CC FLAGS_REG))
3737 (clobber (match_scratch:SI 2))]
3741 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3743 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3744 emit_move_insn (operands[3], operands[1]);
3746 /* Generate a cltd if possible and doing so it profitable. */
3747 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3748 && true_regnum (operands[3]) == AX_REG
3749 && true_regnum (operands[4]) == DX_REG)
3751 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3755 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3756 emit_move_insn (operands[4], operands[1]);
3758 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3762 (define_insn "extend<mode>di2"
3763 [(set (match_operand:DI 0 "register_operand" "=r")
3765 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3767 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3768 [(set_attr "type" "imovx")
3769 (set_attr "mode" "DI")])
3771 (define_insn "extendhisi2"
3772 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3773 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3776 switch (get_attr_prefix_0f (insn))
3779 return "{cwtl|cwde}";
3781 return "movs{wl|x}\t{%1, %0|%0, %1}";
3784 [(set_attr "type" "imovx")
3785 (set_attr "mode" "SI")
3786 (set (attr "prefix_0f")
3787 ;; movsx is short decodable while cwtl is vector decoded.
3788 (if_then_else (and (eq_attr "cpu" "!k6")
3789 (eq_attr "alternative" "0"))
3791 (const_string "1")))
3793 (if_then_else (eq_attr "prefix_0f" "0")
3795 (const_string "1")))])
3797 (define_insn "*extendhisi2_zext"
3798 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3801 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3804 switch (get_attr_prefix_0f (insn))
3807 return "{cwtl|cwde}";
3809 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3812 [(set_attr "type" "imovx")
3813 (set_attr "mode" "SI")
3814 (set (attr "prefix_0f")
3815 ;; movsx is short decodable while cwtl is vector decoded.
3816 (if_then_else (and (eq_attr "cpu" "!k6")
3817 (eq_attr "alternative" "0"))
3819 (const_string "1")))
3821 (if_then_else (eq_attr "prefix_0f" "0")
3823 (const_string "1")))])
3825 (define_insn "extendqisi2"
3826 [(set (match_operand:SI 0 "register_operand" "=r")
3827 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3829 "movs{bl|x}\t{%1, %0|%0, %1}"
3830 [(set_attr "type" "imovx")
3831 (set_attr "mode" "SI")])
3833 (define_insn "*extendqisi2_zext"
3834 [(set (match_operand:DI 0 "register_operand" "=r")
3836 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3838 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3839 [(set_attr "type" "imovx")
3840 (set_attr "mode" "SI")])
3842 (define_insn "extendqihi2"
3843 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3844 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3847 switch (get_attr_prefix_0f (insn))
3850 return "{cbtw|cbw}";
3852 return "movs{bw|x}\t{%1, %0|%0, %1}";
3855 [(set_attr "type" "imovx")
3856 (set_attr "mode" "HI")
3857 (set (attr "prefix_0f")
3858 ;; movsx is short decodable while cwtl is vector decoded.
3859 (if_then_else (and (eq_attr "cpu" "!k6")
3860 (eq_attr "alternative" "0"))
3862 (const_string "1")))
3864 (if_then_else (eq_attr "prefix_0f" "0")
3866 (const_string "1")))])
3868 ;; Conversions between float and double.
3870 ;; These are all no-ops in the model used for the 80387.
3871 ;; So just emit moves.
3873 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3875 [(set (match_operand:DF 0 "push_operand")
3876 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3878 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3879 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3882 [(set (match_operand:XF 0 "push_operand")
3883 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3885 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3886 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3887 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3889 (define_expand "extendsfdf2"
3890 [(set (match_operand:DF 0 "nonimmediate_operand")
3891 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3892 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3894 /* ??? Needed for compress_float_constant since all fp constants
3895 are TARGET_LEGITIMATE_CONSTANT_P. */
3896 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3898 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3899 && standard_80387_constant_p (operands[1]) > 0)
3901 operands[1] = simplify_const_unary_operation
3902 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3903 emit_move_insn_1 (operands[0], operands[1]);
3906 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3910 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3912 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3914 We do the conversion post reload to avoid producing of 128bit spills
3915 that might lead to ICE on 32bit target. The sequence unlikely combine
3918 [(set (match_operand:DF 0 "register_operand")
3920 (match_operand:SF 1 "nonimmediate_operand")))]
3921 "TARGET_USE_VECTOR_FP_CONVERTS
3922 && optimize_insn_for_speed_p ()
3923 && reload_completed && SSE_REG_P (operands[0])"
3928 (parallel [(const_int 0) (const_int 1)]))))]
3930 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3931 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3932 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3933 Try to avoid move when unpacking can be done in source. */
3934 if (REG_P (operands[1]))
3936 /* If it is unsafe to overwrite upper half of source, we need
3937 to move to destination and unpack there. */
3938 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3939 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3940 && true_regnum (operands[0]) != true_regnum (operands[1]))
3942 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3943 emit_move_insn (tmp, operands[1]);
3946 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3947 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3951 emit_insn (gen_vec_setv4sf_0 (operands[3],
3952 CONST0_RTX (V4SFmode), operands[1]));
3955 (define_insn "*extendsfdf2_mixed"
3956 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3958 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3959 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3961 switch (which_alternative)
3965 return output_387_reg_move (insn, operands);
3968 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3974 [(set_attr "type" "fmov,fmov,ssecvt")
3975 (set_attr "prefix" "orig,orig,maybe_vex")
3976 (set_attr "mode" "SF,XF,DF")])
3978 (define_insn "*extendsfdf2_sse"
3979 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3980 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3981 "TARGET_SSE2 && TARGET_SSE_MATH"
3982 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3983 [(set_attr "type" "ssecvt")
3984 (set_attr "prefix" "maybe_vex")
3985 (set_attr "mode" "DF")])
3987 (define_insn "*extendsfdf2_i387"
3988 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3989 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3991 "* return output_387_reg_move (insn, operands);"
3992 [(set_attr "type" "fmov")
3993 (set_attr "mode" "SF,XF")])
3995 (define_expand "extend<mode>xf2"
3996 [(set (match_operand:XF 0 "nonimmediate_operand")
3997 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4000 /* ??? Needed for compress_float_constant since all fp constants
4001 are TARGET_LEGITIMATE_CONSTANT_P. */
4002 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4004 if (standard_80387_constant_p (operands[1]) > 0)
4006 operands[1] = simplify_const_unary_operation
4007 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4008 emit_move_insn_1 (operands[0], operands[1]);
4011 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4015 (define_insn "*extend<mode>xf2_i387"
4016 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4018 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4020 "* return output_387_reg_move (insn, operands);"
4021 [(set_attr "type" "fmov")
4022 (set_attr "mode" "<MODE>,XF")])
4024 ;; %%% This seems bad bad news.
4025 ;; This cannot output into an f-reg because there is no way to be sure
4026 ;; of truncating in that case. Otherwise this is just like a simple move
4027 ;; insn. So we pretend we can output to a reg in order to get better
4028 ;; register preferencing, but we really use a stack slot.
4030 ;; Conversion from DFmode to SFmode.
4032 (define_expand "truncdfsf2"
4033 [(set (match_operand:SF 0 "nonimmediate_operand")
4035 (match_operand:DF 1 "nonimmediate_operand")))]
4036 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4038 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4040 else if (flag_unsafe_math_optimizations)
4044 enum ix86_stack_slot slot = (virtuals_instantiated
4047 rtx temp = assign_386_stack_local (SFmode, slot);
4048 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4053 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4055 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4057 We do the conversion post reload to avoid producing of 128bit spills
4058 that might lead to ICE on 32bit target. The sequence unlikely combine
4061 [(set (match_operand:SF 0 "register_operand")
4063 (match_operand:DF 1 "nonimmediate_operand")))]
4064 "TARGET_USE_VECTOR_FP_CONVERTS
4065 && optimize_insn_for_speed_p ()
4066 && reload_completed && SSE_REG_P (operands[0])"
4069 (float_truncate:V2SF
4073 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4074 operands[3] = CONST0_RTX (V2SFmode);
4075 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4076 /* Use movsd for loading from memory, unpcklpd for registers.
4077 Try to avoid move when unpacking can be done in source, or SSE3
4078 movddup is available. */
4079 if (REG_P (operands[1]))
4082 && true_regnum (operands[0]) != true_regnum (operands[1])
4083 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4084 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4086 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4087 emit_move_insn (tmp, operands[1]);
4090 else if (!TARGET_SSE3)
4091 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4092 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4095 emit_insn (gen_sse2_loadlpd (operands[4],
4096 CONST0_RTX (V2DFmode), operands[1]));
4099 (define_expand "truncdfsf2_with_temp"
4100 [(parallel [(set (match_operand:SF 0)
4101 (float_truncate:SF (match_operand:DF 1)))
4102 (clobber (match_operand:SF 2))])])
4104 (define_insn "*truncdfsf_fast_mixed"
4105 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4107 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4108 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4110 switch (which_alternative)
4113 return output_387_reg_move (insn, operands);
4115 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4120 [(set_attr "type" "fmov,ssecvt")
4121 (set_attr "prefix" "orig,maybe_vex")
4122 (set_attr "mode" "SF")])
4124 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4125 ;; because nothing we do here is unsafe.
4126 (define_insn "*truncdfsf_fast_sse"
4127 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4129 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4130 "TARGET_SSE2 && TARGET_SSE_MATH"
4131 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4132 [(set_attr "type" "ssecvt")
4133 (set_attr "prefix" "maybe_vex")
4134 (set_attr "mode" "SF")])
4136 (define_insn "*truncdfsf_fast_i387"
4137 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4139 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4140 "TARGET_80387 && flag_unsafe_math_optimizations"
4141 "* return output_387_reg_move (insn, operands);"
4142 [(set_attr "type" "fmov")
4143 (set_attr "mode" "SF")])
4145 (define_insn "*truncdfsf_mixed"
4146 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4148 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4149 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4150 "TARGET_MIX_SSE_I387"
4152 switch (which_alternative)
4155 return output_387_reg_move (insn, operands);
4157 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4163 [(set_attr "isa" "*,sse2,*,*,*")
4164 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4165 (set_attr "unit" "*,*,i387,i387,i387")
4166 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4167 (set_attr "mode" "SF")])
4169 (define_insn "*truncdfsf_i387"
4170 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4172 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4173 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4176 switch (which_alternative)
4179 return output_387_reg_move (insn, operands);
4185 [(set_attr "type" "fmov,multi,multi,multi")
4186 (set_attr "unit" "*,i387,i387,i387")
4187 (set_attr "mode" "SF")])
4189 (define_insn "*truncdfsf2_i387_1"
4190 [(set (match_operand:SF 0 "memory_operand" "=m")
4192 (match_operand:DF 1 "register_operand" "f")))]
4194 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4195 && !TARGET_MIX_SSE_I387"
4196 "* return output_387_reg_move (insn, operands);"
4197 [(set_attr "type" "fmov")
4198 (set_attr "mode" "SF")])
4201 [(set (match_operand:SF 0 "register_operand")
4203 (match_operand:DF 1 "fp_register_operand")))
4204 (clobber (match_operand 2))]
4206 [(set (match_dup 2) (match_dup 1))
4207 (set (match_dup 0) (match_dup 2))]
4208 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4210 ;; Conversion from XFmode to {SF,DF}mode
4212 (define_expand "truncxf<mode>2"
4213 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4214 (float_truncate:MODEF
4215 (match_operand:XF 1 "register_operand")))
4216 (clobber (match_dup 2))])]
4219 if (flag_unsafe_math_optimizations)
4221 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4222 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4223 if (reg != operands[0])
4224 emit_move_insn (operands[0], reg);
4229 enum ix86_stack_slot slot = (virtuals_instantiated
4232 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4236 (define_insn "*truncxfsf2_mixed"
4237 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4239 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4240 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4243 gcc_assert (!which_alternative);
4244 return output_387_reg_move (insn, operands);
4246 [(set_attr "type" "fmov,multi,multi,multi")
4247 (set_attr "unit" "*,i387,i387,i387")
4248 (set_attr "mode" "SF")])
4250 (define_insn "*truncxfdf2_mixed"
4251 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4253 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4254 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4257 gcc_assert (!which_alternative);
4258 return output_387_reg_move (insn, operands);
4260 [(set_attr "isa" "*,*,sse2,*")
4261 (set_attr "type" "fmov,multi,multi,multi")
4262 (set_attr "unit" "*,i387,i387,i387")
4263 (set_attr "mode" "DF")])
4265 (define_insn "truncxf<mode>2_i387_noop"
4266 [(set (match_operand:MODEF 0 "register_operand" "=f")
4267 (float_truncate:MODEF
4268 (match_operand:XF 1 "register_operand" "f")))]
4269 "TARGET_80387 && flag_unsafe_math_optimizations"
4270 "* return output_387_reg_move (insn, operands);"
4271 [(set_attr "type" "fmov")
4272 (set_attr "mode" "<MODE>")])
4274 (define_insn "*truncxf<mode>2_i387"
4275 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4276 (float_truncate:MODEF
4277 (match_operand:XF 1 "register_operand" "f")))]
4279 "* return output_387_reg_move (insn, operands);"
4280 [(set_attr "type" "fmov")
4281 (set_attr "mode" "<MODE>")])
4284 [(set (match_operand:MODEF 0 "register_operand")
4285 (float_truncate:MODEF
4286 (match_operand:XF 1 "register_operand")))
4287 (clobber (match_operand:MODEF 2 "memory_operand"))]
4288 "TARGET_80387 && reload_completed"
4289 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4290 (set (match_dup 0) (match_dup 2))])
4293 [(set (match_operand:MODEF 0 "memory_operand")
4294 (float_truncate:MODEF
4295 (match_operand:XF 1 "register_operand")))
4296 (clobber (match_operand:MODEF 2 "memory_operand"))]
4298 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4300 ;; Signed conversion to DImode.
4302 (define_expand "fix_truncxfdi2"
4303 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4304 (fix:DI (match_operand:XF 1 "register_operand")))
4305 (clobber (reg:CC FLAGS_REG))])]
4310 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4315 (define_expand "fix_trunc<mode>di2"
4316 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4317 (fix:DI (match_operand:MODEF 1 "register_operand")))
4318 (clobber (reg:CC FLAGS_REG))])]
4319 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4322 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4324 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4327 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4329 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4330 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4331 if (out != operands[0])
4332 emit_move_insn (operands[0], out);
4337 ;; Signed conversion to SImode.
4339 (define_expand "fix_truncxfsi2"
4340 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4341 (fix:SI (match_operand:XF 1 "register_operand")))
4342 (clobber (reg:CC FLAGS_REG))])]
4347 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4352 (define_expand "fix_trunc<mode>si2"
4353 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4354 (fix:SI (match_operand:MODEF 1 "register_operand")))
4355 (clobber (reg:CC FLAGS_REG))])]
4356 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4359 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4361 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4364 if (SSE_FLOAT_MODE_P (<MODE>mode))
4366 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4367 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4368 if (out != operands[0])
4369 emit_move_insn (operands[0], out);
4374 ;; Signed conversion to HImode.
4376 (define_expand "fix_trunc<mode>hi2"
4377 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4378 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4379 (clobber (reg:CC FLAGS_REG))])]
4381 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4385 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4390 ;; Unsigned conversion to SImode.
4392 (define_expand "fixuns_trunc<mode>si2"
4394 [(set (match_operand:SI 0 "register_operand")
4396 (match_operand:MODEF 1 "nonimmediate_operand")))
4398 (clobber (match_scratch:<ssevecmode> 3))
4399 (clobber (match_scratch:<ssevecmode> 4))])]
4400 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4402 enum machine_mode mode = <MODE>mode;
4403 enum machine_mode vecmode = <ssevecmode>mode;
4404 REAL_VALUE_TYPE TWO31r;
4407 if (optimize_insn_for_size_p ())
4410 real_ldexp (&TWO31r, &dconst1, 31);
4411 two31 = const_double_from_real_value (TWO31r, mode);
4412 two31 = ix86_build_const_vector (vecmode, true, two31);
4413 operands[2] = force_reg (vecmode, two31);
4416 (define_insn_and_split "*fixuns_trunc<mode>_1"
4417 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4419 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4420 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4421 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4422 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4423 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4424 && optimize_function_for_speed_p (cfun)"
4426 "&& reload_completed"
4429 ix86_split_convert_uns_si_sse (operands);
4433 ;; Unsigned conversion to HImode.
4434 ;; Without these patterns, we'll try the unsigned SI conversion which
4435 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4437 (define_expand "fixuns_trunc<mode>hi2"
4439 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4440 (set (match_operand:HI 0 "nonimmediate_operand")
4441 (subreg:HI (match_dup 2) 0))]
4442 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4443 "operands[2] = gen_reg_rtx (SImode);")
4445 ;; When SSE is available, it is always faster to use it!
4446 (define_insn "fix_trunc<mode>di_sse"
4447 [(set (match_operand:DI 0 "register_operand" "=r,r")
4448 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4449 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4450 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4451 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4452 [(set_attr "type" "sseicvt")
4453 (set_attr "prefix" "maybe_vex")
4454 (set_attr "prefix_rex" "1")
4455 (set_attr "mode" "<MODE>")
4456 (set_attr "athlon_decode" "double,vector")
4457 (set_attr "amdfam10_decode" "double,double")
4458 (set_attr "bdver1_decode" "double,double")])
4460 (define_insn "fix_trunc<mode>si_sse"
4461 [(set (match_operand:SI 0 "register_operand" "=r,r")
4462 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4463 "SSE_FLOAT_MODE_P (<MODE>mode)
4464 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4465 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4466 [(set_attr "type" "sseicvt")
4467 (set_attr "prefix" "maybe_vex")
4468 (set_attr "mode" "<MODE>")
4469 (set_attr "athlon_decode" "double,vector")
4470 (set_attr "amdfam10_decode" "double,double")
4471 (set_attr "bdver1_decode" "double,double")])
4473 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4475 [(set (match_operand:MODEF 0 "register_operand")
4476 (match_operand:MODEF 1 "memory_operand"))
4477 (set (match_operand:SWI48x 2 "register_operand")
4478 (fix:SWI48x (match_dup 0)))]
4479 "TARGET_SHORTEN_X87_SSE
4480 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4481 && peep2_reg_dead_p (2, operands[0])"
4482 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4484 ;; Avoid vector decoded forms of the instruction.
4486 [(match_scratch:DF 2 "x")
4487 (set (match_operand:SWI48x 0 "register_operand")
4488 (fix:SWI48x (match_operand:DF 1 "memory_operand")))]
4489 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4490 [(set (match_dup 2) (match_dup 1))
4491 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4494 [(match_scratch:SF 2 "x")
4495 (set (match_operand:SWI48x 0 "register_operand")
4496 (fix:SWI48x (match_operand:SF 1 "memory_operand")))]
4497 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4498 [(set (match_dup 2) (match_dup 1))
4499 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4501 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4502 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4503 (fix:SWI248x (match_operand 1 "register_operand")))]
4504 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4506 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4507 && (TARGET_64BIT || <MODE>mode != DImode))
4509 && can_create_pseudo_p ()"
4514 if (memory_operand (operands[0], VOIDmode))
4515 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4518 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4519 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4525 [(set_attr "type" "fisttp")
4526 (set_attr "mode" "<MODE>")])
4528 (define_insn "fix_trunc<mode>_i387_fisttp"
4529 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4530 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4531 (clobber (match_scratch:XF 2 "=&1f"))]
4532 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4534 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4535 && (TARGET_64BIT || <MODE>mode != DImode))
4536 && TARGET_SSE_MATH)"
4537 "* return output_fix_trunc (insn, operands, true);"
4538 [(set_attr "type" "fisttp")
4539 (set_attr "mode" "<MODE>")])
4541 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4542 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4543 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4544 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4545 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4546 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4548 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4549 && (TARGET_64BIT || <MODE>mode != DImode))
4550 && TARGET_SSE_MATH)"
4552 [(set_attr "type" "fisttp")
4553 (set_attr "mode" "<MODE>")])
4556 [(set (match_operand:SWI248x 0 "register_operand")
4557 (fix:SWI248x (match_operand 1 "register_operand")))
4558 (clobber (match_operand:SWI248x 2 "memory_operand"))
4559 (clobber (match_scratch 3))]
4561 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4562 (clobber (match_dup 3))])
4563 (set (match_dup 0) (match_dup 2))])
4566 [(set (match_operand:SWI248x 0 "memory_operand")
4567 (fix:SWI248x (match_operand 1 "register_operand")))
4568 (clobber (match_operand:SWI248x 2 "memory_operand"))
4569 (clobber (match_scratch 3))]
4571 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4572 (clobber (match_dup 3))])])
4574 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4575 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4576 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4577 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4578 ;; function in i386.c.
4579 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4580 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4581 (fix:SWI248x (match_operand 1 "register_operand")))
4582 (clobber (reg:CC FLAGS_REG))]
4583 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4585 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4586 && (TARGET_64BIT || <MODE>mode != DImode))
4587 && can_create_pseudo_p ()"
4592 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4594 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4595 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4596 if (memory_operand (operands[0], VOIDmode))
4597 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4598 operands[2], operands[3]));
4601 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4602 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4603 operands[2], operands[3],
4608 [(set_attr "type" "fistp")
4609 (set_attr "i387_cw" "trunc")
4610 (set_attr "mode" "<MODE>")])
4612 (define_insn "fix_truncdi_i387"
4613 [(set (match_operand:DI 0 "memory_operand" "=m")
4614 (fix:DI (match_operand 1 "register_operand" "f")))
4615 (use (match_operand:HI 2 "memory_operand" "m"))
4616 (use (match_operand:HI 3 "memory_operand" "m"))
4617 (clobber (match_scratch:XF 4 "=&1f"))]
4618 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4620 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4621 "* return output_fix_trunc (insn, operands, false);"
4622 [(set_attr "type" "fistp")
4623 (set_attr "i387_cw" "trunc")
4624 (set_attr "mode" "DI")])
4626 (define_insn "fix_truncdi_i387_with_temp"
4627 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4628 (fix:DI (match_operand 1 "register_operand" "f,f")))
4629 (use (match_operand:HI 2 "memory_operand" "m,m"))
4630 (use (match_operand:HI 3 "memory_operand" "m,m"))
4631 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4632 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4633 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4635 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4637 [(set_attr "type" "fistp")
4638 (set_attr "i387_cw" "trunc")
4639 (set_attr "mode" "DI")])
4642 [(set (match_operand:DI 0 "register_operand")
4643 (fix:DI (match_operand 1 "register_operand")))
4644 (use (match_operand:HI 2 "memory_operand"))
4645 (use (match_operand:HI 3 "memory_operand"))
4646 (clobber (match_operand:DI 4 "memory_operand"))
4647 (clobber (match_scratch 5))]
4649 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4652 (clobber (match_dup 5))])
4653 (set (match_dup 0) (match_dup 4))])
4656 [(set (match_operand:DI 0 "memory_operand")
4657 (fix:DI (match_operand 1 "register_operand")))
4658 (use (match_operand:HI 2 "memory_operand"))
4659 (use (match_operand:HI 3 "memory_operand"))
4660 (clobber (match_operand:DI 4 "memory_operand"))
4661 (clobber (match_scratch 5))]
4663 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4666 (clobber (match_dup 5))])])
4668 (define_insn "fix_trunc<mode>_i387"
4669 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4670 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4671 (use (match_operand:HI 2 "memory_operand" "m"))
4672 (use (match_operand:HI 3 "memory_operand" "m"))]
4673 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4675 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4676 "* return output_fix_trunc (insn, operands, false);"
4677 [(set_attr "type" "fistp")
4678 (set_attr "i387_cw" "trunc")
4679 (set_attr "mode" "<MODE>")])
4681 (define_insn "fix_trunc<mode>_i387_with_temp"
4682 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4683 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4684 (use (match_operand:HI 2 "memory_operand" "m,m"))
4685 (use (match_operand:HI 3 "memory_operand" "m,m"))
4686 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4687 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4689 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4691 [(set_attr "type" "fistp")
4692 (set_attr "i387_cw" "trunc")
4693 (set_attr "mode" "<MODE>")])
4696 [(set (match_operand:SWI24 0 "register_operand")
4697 (fix:SWI24 (match_operand 1 "register_operand")))
4698 (use (match_operand:HI 2 "memory_operand"))
4699 (use (match_operand:HI 3 "memory_operand"))
4700 (clobber (match_operand:SWI24 4 "memory_operand"))]
4702 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4704 (use (match_dup 3))])
4705 (set (match_dup 0) (match_dup 4))])
4708 [(set (match_operand:SWI24 0 "memory_operand")
4709 (fix:SWI24 (match_operand 1 "register_operand")))
4710 (use (match_operand:HI 2 "memory_operand"))
4711 (use (match_operand:HI 3 "memory_operand"))
4712 (clobber (match_operand:SWI24 4 "memory_operand"))]
4714 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4716 (use (match_dup 3))])])
4718 (define_insn "x86_fnstcw_1"
4719 [(set (match_operand:HI 0 "memory_operand" "=m")
4720 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4723 [(set (attr "length")
4724 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4725 (set_attr "mode" "HI")
4726 (set_attr "unit" "i387")
4727 (set_attr "bdver1_decode" "vector")])
4729 (define_insn "x86_fldcw_1"
4730 [(set (reg:HI FPCR_REG)
4731 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4734 [(set (attr "length")
4735 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4736 (set_attr "mode" "HI")
4737 (set_attr "unit" "i387")
4738 (set_attr "athlon_decode" "vector")
4739 (set_attr "amdfam10_decode" "vector")
4740 (set_attr "bdver1_decode" "vector")])
4742 ;; Conversion between fixed point and floating point.
4744 ;; Even though we only accept memory inputs, the backend _really_
4745 ;; wants to be able to do this between registers.
4747 (define_expand "floathi<mode>2"
4748 [(set (match_operand:X87MODEF 0 "register_operand")
4749 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4751 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4752 || TARGET_MIX_SSE_I387)")
4754 ;; Pre-reload splitter to add memory clobber to the pattern.
4755 (define_insn_and_split "*floathi<mode>2_1"
4756 [(set (match_operand:X87MODEF 0 "register_operand")
4757 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4759 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4760 || TARGET_MIX_SSE_I387)
4761 && can_create_pseudo_p ()"
4764 [(parallel [(set (match_dup 0)
4765 (float:X87MODEF (match_dup 1)))
4766 (clobber (match_dup 2))])]
4767 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4769 (define_insn "*floathi<mode>2_i387_with_temp"
4770 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4771 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4772 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4774 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4775 || TARGET_MIX_SSE_I387)"
4777 [(set_attr "type" "fmov,multi")
4778 (set_attr "mode" "<MODE>")
4779 (set_attr "unit" "*,i387")
4780 (set_attr "fp_int_src" "true")])
4782 (define_insn "*floathi<mode>2_i387"
4783 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4784 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4786 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4787 || TARGET_MIX_SSE_I387)"
4789 [(set_attr "type" "fmov")
4790 (set_attr "mode" "<MODE>")
4791 (set_attr "fp_int_src" "true")])
4794 [(set (match_operand:X87MODEF 0 "register_operand")
4795 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4796 (clobber (match_operand:HI 2 "memory_operand"))]
4798 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4799 || TARGET_MIX_SSE_I387)
4800 && reload_completed"
4801 [(set (match_dup 2) (match_dup 1))
4802 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4805 [(set (match_operand:X87MODEF 0 "register_operand")
4806 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4807 (clobber (match_operand:HI 2 "memory_operand"))]
4809 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4810 || TARGET_MIX_SSE_I387)
4811 && reload_completed"
4812 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4814 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4815 [(set (match_operand:X87MODEF 0 "register_operand")
4817 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4819 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4820 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4822 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4823 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4824 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4826 rtx reg = gen_reg_rtx (XFmode);
4827 rtx (*insn)(rtx, rtx);
4829 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4831 if (<X87MODEF:MODE>mode == SFmode)
4832 insn = gen_truncxfsf2;
4833 else if (<X87MODEF:MODE>mode == DFmode)
4834 insn = gen_truncxfdf2;
4838 emit_insn (insn (operands[0], reg));
4843 ;; Pre-reload splitter to add memory clobber to the pattern.
4844 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4845 [(set (match_operand:X87MODEF 0 "register_operand")
4846 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4848 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4849 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4850 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4851 || TARGET_MIX_SSE_I387))
4852 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4853 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4854 && ((<SWI48x:MODE>mode == SImode
4855 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4856 && optimize_function_for_speed_p (cfun)
4857 && flag_trapping_math)
4858 || !(TARGET_INTER_UNIT_CONVERSIONS
4859 || optimize_function_for_size_p (cfun)))))
4860 && can_create_pseudo_p ()"
4863 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4864 (clobber (match_dup 2))])]
4866 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4868 /* Avoid store forwarding (partial memory) stall penalty
4869 by passing DImode value through XMM registers. */
4870 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4871 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4872 && optimize_function_for_speed_p (cfun))
4874 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4881 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4882 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4884 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4885 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4886 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4887 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4889 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4890 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4891 (set_attr "unit" "*,i387,*,*,*")
4892 (set_attr "athlon_decode" "*,*,double,direct,double")
4893 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4894 (set_attr "bdver1_decode" "*,*,double,direct,double")
4895 (set_attr "fp_int_src" "true")])
4897 (define_insn "*floatsi<mode>2_vector_mixed"
4898 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4899 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4900 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4901 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4905 [(set_attr "type" "fmov,sseicvt")
4906 (set_attr "mode" "<MODE>,<ssevecmode>")
4907 (set_attr "unit" "i387,*")
4908 (set_attr "athlon_decode" "*,direct")
4909 (set_attr "amdfam10_decode" "*,double")
4910 (set_attr "bdver1_decode" "*,direct")
4911 (set_attr "fp_int_src" "true")])
4913 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4914 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4916 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4917 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4918 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4919 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4921 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4922 (set_attr "mode" "<MODEF:MODE>")
4923 (set_attr "unit" "*,i387,*,*")
4924 (set_attr "athlon_decode" "*,*,double,direct")
4925 (set_attr "amdfam10_decode" "*,*,vector,double")
4926 (set_attr "bdver1_decode" "*,*,double,direct")
4927 (set_attr "fp_int_src" "true")])
4930 [(set (match_operand:MODEF 0 "register_operand")
4931 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4932 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4933 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4934 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4935 && TARGET_INTER_UNIT_CONVERSIONS
4937 && (SSE_REG_P (operands[0])
4938 || (GET_CODE (operands[0]) == SUBREG
4939 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4940 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4943 [(set (match_operand:MODEF 0 "register_operand")
4944 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4945 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4946 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4947 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4948 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4950 && (SSE_REG_P (operands[0])
4951 || (GET_CODE (operands[0]) == SUBREG
4952 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4953 [(set (match_dup 2) (match_dup 1))
4954 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4956 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4957 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4959 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4960 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4961 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4962 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4965 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4966 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4967 [(set_attr "type" "fmov,sseicvt,sseicvt")
4968 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4969 (set_attr "mode" "<MODEF:MODE>")
4970 (set (attr "prefix_rex")
4972 (and (eq_attr "prefix" "maybe_vex")
4973 (match_test "<SWI48x:MODE>mode == DImode"))
4975 (const_string "*")))
4976 (set_attr "unit" "i387,*,*")
4977 (set_attr "athlon_decode" "*,double,direct")
4978 (set_attr "amdfam10_decode" "*,vector,double")
4979 (set_attr "bdver1_decode" "*,double,direct")
4980 (set_attr "fp_int_src" "true")])
4982 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4983 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4985 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4986 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4987 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4988 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4991 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4992 [(set_attr "type" "fmov,sseicvt")
4993 (set_attr "prefix" "orig,maybe_vex")
4994 (set_attr "mode" "<MODEF:MODE>")
4995 (set (attr "prefix_rex")
4997 (and (eq_attr "prefix" "maybe_vex")
4998 (match_test "<SWI48x:MODE>mode == DImode"))
5000 (const_string "*")))
5001 (set_attr "athlon_decode" "*,direct")
5002 (set_attr "amdfam10_decode" "*,double")
5003 (set_attr "bdver1_decode" "*,direct")
5004 (set_attr "fp_int_src" "true")])
5006 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5007 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5009 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5010 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5011 "TARGET_SSE2 && TARGET_SSE_MATH
5012 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5014 [(set_attr "type" "sseicvt")
5015 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5016 (set_attr "athlon_decode" "double,direct,double")
5017 (set_attr "amdfam10_decode" "vector,double,double")
5018 (set_attr "bdver1_decode" "double,direct,double")
5019 (set_attr "fp_int_src" "true")])
5021 (define_insn "*floatsi<mode>2_vector_sse"
5022 [(set (match_operand:MODEF 0 "register_operand" "=x")
5023 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5024 "TARGET_SSE2 && TARGET_SSE_MATH
5025 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5027 [(set_attr "type" "sseicvt")
5028 (set_attr "mode" "<MODE>")
5029 (set_attr "athlon_decode" "direct")
5030 (set_attr "amdfam10_decode" "double")
5031 (set_attr "bdver1_decode" "direct")
5032 (set_attr "fp_int_src" "true")])
5035 [(set (match_operand:MODEF 0 "register_operand")
5036 (float:MODEF (match_operand:SI 1 "register_operand")))
5037 (clobber (match_operand:SI 2 "memory_operand"))]
5038 "TARGET_SSE2 && TARGET_SSE_MATH
5039 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5041 && (SSE_REG_P (operands[0])
5042 || (GET_CODE (operands[0]) == SUBREG
5043 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5046 rtx op1 = operands[1];
5048 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5050 if (GET_CODE (op1) == SUBREG)
5051 op1 = SUBREG_REG (op1);
5053 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5055 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5056 emit_insn (gen_sse2_loadld (operands[4],
5057 CONST0_RTX (V4SImode), operands[1]));
5059 /* We can ignore possible trapping value in the
5060 high part of SSE register for non-trapping math. */
5061 else if (SSE_REG_P (op1) && !flag_trapping_math)
5062 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5065 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5066 emit_move_insn (operands[2], operands[1]);
5067 emit_insn (gen_sse2_loadld (operands[4],
5068 CONST0_RTX (V4SImode), operands[2]));
5070 if (<ssevecmode>mode == V4SFmode)
5071 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5073 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5078 [(set (match_operand:MODEF 0 "register_operand")
5079 (float:MODEF (match_operand:SI 1 "memory_operand")))
5080 (clobber (match_operand:SI 2 "memory_operand"))]
5081 "TARGET_SSE2 && TARGET_SSE_MATH
5082 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5084 && (SSE_REG_P (operands[0])
5085 || (GET_CODE (operands[0]) == SUBREG
5086 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5089 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5091 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5093 emit_insn (gen_sse2_loadld (operands[4],
5094 CONST0_RTX (V4SImode), operands[1]));
5095 if (<ssevecmode>mode == V4SFmode)
5096 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5098 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5103 [(set (match_operand:MODEF 0 "register_operand")
5104 (float:MODEF (match_operand:SI 1 "register_operand")))]
5105 "TARGET_SSE2 && TARGET_SSE_MATH
5106 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5108 && (SSE_REG_P (operands[0])
5109 || (GET_CODE (operands[0]) == SUBREG
5110 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5113 rtx op1 = operands[1];
5115 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5117 if (GET_CODE (op1) == SUBREG)
5118 op1 = SUBREG_REG (op1);
5120 if (GENERAL_REG_P (op1))
5122 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5123 if (TARGET_INTER_UNIT_MOVES)
5124 emit_insn (gen_sse2_loadld (operands[4],
5125 CONST0_RTX (V4SImode), operands[1]));
5128 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5130 emit_insn (gen_sse2_loadld (operands[4],
5131 CONST0_RTX (V4SImode), operands[5]));
5132 ix86_free_from_memory (GET_MODE (operands[1]));
5135 /* We can ignore possible trapping value in the
5136 high part of SSE register for non-trapping math. */
5137 else if (SSE_REG_P (op1) && !flag_trapping_math)
5138 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5141 if (<ssevecmode>mode == V4SFmode)
5142 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5144 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5149 [(set (match_operand:MODEF 0 "register_operand")
5150 (float:MODEF (match_operand:SI 1 "memory_operand")))]
5151 "TARGET_SSE2 && TARGET_SSE_MATH
5152 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5154 && (SSE_REG_P (operands[0])
5155 || (GET_CODE (operands[0]) == SUBREG
5156 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5159 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5161 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5163 emit_insn (gen_sse2_loadld (operands[4],
5164 CONST0_RTX (V4SImode), operands[1]));
5165 if (<ssevecmode>mode == V4SFmode)
5166 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5168 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5172 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5173 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5175 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5176 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5177 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5178 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5180 [(set_attr "type" "sseicvt")
5181 (set_attr "mode" "<MODEF:MODE>")
5182 (set_attr "athlon_decode" "double,direct")
5183 (set_attr "amdfam10_decode" "vector,double")
5184 (set_attr "bdver1_decode" "double,direct")
5185 (set_attr "fp_int_src" "true")])
5187 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5188 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5190 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5191 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5192 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5193 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5194 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5195 [(set_attr "type" "sseicvt")
5196 (set_attr "prefix" "maybe_vex")
5197 (set_attr "mode" "<MODEF:MODE>")
5198 (set (attr "prefix_rex")
5200 (and (eq_attr "prefix" "maybe_vex")
5201 (match_test "<SWI48x:MODE>mode == DImode"))
5203 (const_string "*")))
5204 (set_attr "athlon_decode" "double,direct")
5205 (set_attr "amdfam10_decode" "vector,double")
5206 (set_attr "bdver1_decode" "double,direct")
5207 (set_attr "fp_int_src" "true")])
5210 [(set (match_operand:MODEF 0 "register_operand")
5211 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))
5212 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5213 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5214 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5215 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5217 && (SSE_REG_P (operands[0])
5218 || (GET_CODE (operands[0]) == SUBREG
5219 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5220 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5222 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5223 [(set (match_operand:MODEF 0 "register_operand" "=x")
5225 (match_operand:SWI48x 1 "memory_operand" "m")))]
5226 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5227 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5228 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5229 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5230 [(set_attr "type" "sseicvt")
5231 (set_attr "prefix" "maybe_vex")
5232 (set_attr "mode" "<MODEF:MODE>")
5233 (set (attr "prefix_rex")
5235 (and (eq_attr "prefix" "maybe_vex")
5236 (match_test "<SWI48x:MODE>mode == DImode"))
5238 (const_string "*")))
5239 (set_attr "athlon_decode" "direct")
5240 (set_attr "amdfam10_decode" "double")
5241 (set_attr "bdver1_decode" "direct")
5242 (set_attr "fp_int_src" "true")])
5245 [(set (match_operand:MODEF 0 "register_operand")
5246 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
5247 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5248 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5249 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5250 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5252 && (SSE_REG_P (operands[0])
5253 || (GET_CODE (operands[0]) == SUBREG
5254 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5255 [(set (match_dup 2) (match_dup 1))
5256 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5259 [(set (match_operand:MODEF 0 "register_operand")
5260 (float:MODEF (match_operand:SWI48x 1 "memory_operand")))
5261 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5262 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5263 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5265 && (SSE_REG_P (operands[0])
5266 || (GET_CODE (operands[0]) == SUBREG
5267 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5268 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5270 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5271 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5273 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5274 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5276 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5280 [(set_attr "type" "fmov,multi")
5281 (set_attr "mode" "<X87MODEF:MODE>")
5282 (set_attr "unit" "*,i387")
5283 (set_attr "fp_int_src" "true")])
5285 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5286 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5288 (match_operand:SWI48x 1 "memory_operand" "m")))]
5290 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5292 [(set_attr "type" "fmov")
5293 (set_attr "mode" "<X87MODEF:MODE>")
5294 (set_attr "fp_int_src" "true")])
5297 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5298 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5299 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5301 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5302 && reload_completed"
5303 [(set (match_dup 2) (match_dup 1))
5304 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5307 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5308 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5309 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5311 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5312 && reload_completed"
5313 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5315 ;; Avoid store forwarding (partial memory) stall penalty
5316 ;; by passing DImode value through XMM registers. */
5318 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5319 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5321 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5322 (clobber (match_scratch:V4SI 3 "=X,x"))
5323 (clobber (match_scratch:V4SI 4 "=X,x"))
5324 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5325 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5326 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5327 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5329 [(set_attr "type" "multi")
5330 (set_attr "mode" "<X87MODEF:MODE>")
5331 (set_attr "unit" "i387")
5332 (set_attr "fp_int_src" "true")])
5335 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5336 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5337 (clobber (match_scratch:V4SI 3))
5338 (clobber (match_scratch:V4SI 4))
5339 (clobber (match_operand:DI 2 "memory_operand"))]
5340 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5341 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5342 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5343 && reload_completed"
5344 [(set (match_dup 2) (match_dup 3))
5345 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5347 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5348 Assemble the 64-bit DImode value in an xmm register. */
5349 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5350 gen_rtx_SUBREG (SImode, operands[1], 0)));
5351 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5352 gen_rtx_SUBREG (SImode, operands[1], 4)));
5353 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5356 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5360 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5361 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5362 (clobber (match_scratch:V4SI 3))
5363 (clobber (match_scratch:V4SI 4))
5364 (clobber (match_operand:DI 2 "memory_operand"))]
5365 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5366 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5367 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5368 && reload_completed"
5369 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5371 ;; Avoid store forwarding (partial memory) stall penalty by extending
5372 ;; SImode value to DImode through XMM register instead of pushing two
5373 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5374 ;; targets benefit from this optimization. Also note that fild
5375 ;; loads from memory only.
5377 (define_insn "*floatunssi<mode>2_1"
5378 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5379 (unsigned_float:X87MODEF
5380 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5381 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5382 (clobber (match_scratch:SI 3 "=X,x"))]
5384 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5387 [(set_attr "type" "multi")
5388 (set_attr "mode" "<MODE>")])
5391 [(set (match_operand:X87MODEF 0 "register_operand")
5392 (unsigned_float:X87MODEF
5393 (match_operand:SI 1 "register_operand")))
5394 (clobber (match_operand:DI 2 "memory_operand"))
5395 (clobber (match_scratch:SI 3))]
5397 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5399 && reload_completed"
5400 [(set (match_dup 2) (match_dup 1))
5402 (float:X87MODEF (match_dup 2)))]
5403 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5406 [(set (match_operand:X87MODEF 0 "register_operand")
5407 (unsigned_float:X87MODEF
5408 (match_operand:SI 1 "memory_operand")))
5409 (clobber (match_operand:DI 2 "memory_operand"))
5410 (clobber (match_scratch:SI 3))]
5412 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5414 && reload_completed"
5415 [(set (match_dup 2) (match_dup 3))
5417 (float:X87MODEF (match_dup 2)))]
5419 emit_move_insn (operands[3], operands[1]);
5420 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5423 (define_expand "floatunssi<mode>2"
5425 [(set (match_operand:X87MODEF 0 "register_operand")
5426 (unsigned_float:X87MODEF
5427 (match_operand:SI 1 "nonimmediate_operand")))
5428 (clobber (match_dup 2))
5429 (clobber (match_scratch:SI 3))])]
5431 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5433 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5435 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5437 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5442 enum ix86_stack_slot slot = (virtuals_instantiated
5445 operands[2] = assign_386_stack_local (DImode, slot);
5449 (define_expand "floatunsdisf2"
5450 [(use (match_operand:SF 0 "register_operand"))
5451 (use (match_operand:DI 1 "nonimmediate_operand"))]
5452 "TARGET_64BIT && TARGET_SSE_MATH"
5453 "x86_emit_floatuns (operands); DONE;")
5455 (define_expand "floatunsdidf2"
5456 [(use (match_operand:DF 0 "register_operand"))
5457 (use (match_operand:DI 1 "nonimmediate_operand"))]
5458 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5459 && TARGET_SSE2 && TARGET_SSE_MATH"
5462 x86_emit_floatuns (operands);
5464 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5468 ;; Load effective address instructions
5470 (define_insn_and_split "*lea<mode>"
5471 [(set (match_operand:SWI48 0 "register_operand" "=r")
5472 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5475 rtx addr = operands[1];
5477 if (GET_CODE (addr) == SUBREG)
5479 gcc_assert (TARGET_64BIT);
5480 gcc_assert (<MODE>mode == SImode);
5481 gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
5482 return "lea{l}\t{%E1, %0|%0, %E1}";
5484 else if (GET_CODE (addr) == ZERO_EXTEND
5485 || GET_CODE (addr) == AND)
5487 gcc_assert (TARGET_64BIT);
5488 gcc_assert (<MODE>mode == DImode);
5489 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5492 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5494 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5497 enum machine_mode mode = <MODE>mode;
5500 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5501 change operands[] array behind our back. */
5502 pat = PATTERN (curr_insn);
5504 operands[0] = SET_DEST (pat);
5505 operands[1] = SET_SRC (pat);
5507 /* Emit all operations in SImode for zero-extended addresses. Recall
5508 that x86_64 inheretly zero-extends SImode operations to DImode. */
5509 if (GET_CODE (operands[1]) == ZERO_EXTEND
5510 || GET_CODE (operands[1]) == AND)
5513 ix86_split_lea_for_addr (operands, mode);
5516 [(set_attr "type" "lea")
5517 (set_attr "mode" "<MODE>")])
5521 (define_expand "add<mode>3"
5522 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5523 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5524 (match_operand:SDWIM 2 "<general_operand>")))]
5526 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5528 (define_insn_and_split "*add<dwi>3_doubleword"
5529 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5531 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5532 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5533 (clobber (reg:CC FLAGS_REG))]
5534 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5537 [(parallel [(set (reg:CC FLAGS_REG)
5538 (unspec:CC [(match_dup 1) (match_dup 2)]
5541 (plus:DWIH (match_dup 1) (match_dup 2)))])
5542 (parallel [(set (match_dup 3)
5546 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5548 (clobber (reg:CC FLAGS_REG))])]
5549 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5551 (define_insn "*add<mode>3_cc"
5552 [(set (reg:CC FLAGS_REG)
5554 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5555 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5557 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5558 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5559 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5560 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5561 [(set_attr "type" "alu")
5562 (set_attr "mode" "<MODE>")])
5564 (define_insn "addqi3_cc"
5565 [(set (reg:CC FLAGS_REG)
5567 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5568 (match_operand:QI 2 "general_operand" "qn,qm")]
5570 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5571 (plus:QI (match_dup 1) (match_dup 2)))]
5572 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5573 "add{b}\t{%2, %0|%0, %2}"
5574 [(set_attr "type" "alu")
5575 (set_attr "mode" "QI")])
5577 (define_insn "*add<mode>_1"
5578 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5580 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5581 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5582 (clobber (reg:CC FLAGS_REG))]
5583 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5585 switch (get_attr_type (insn))
5591 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5592 if (operands[2] == const1_rtx)
5593 return "inc{<imodesuffix>}\t%0";
5596 gcc_assert (operands[2] == constm1_rtx);
5597 return "dec{<imodesuffix>}\t%0";
5601 /* For most processors, ADD is faster than LEA. This alternative
5602 was added to use ADD as much as possible. */
5603 if (which_alternative == 2)
5606 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5609 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5610 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5611 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5613 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5617 (cond [(eq_attr "alternative" "3")
5618 (const_string "lea")
5619 (match_operand:SWI48 2 "incdec_operand")
5620 (const_string "incdec")
5622 (const_string "alu")))
5623 (set (attr "length_immediate")
5625 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5627 (const_string "*")))
5628 (set_attr "mode" "<MODE>")])
5630 ;; It may seem that nonimmediate operand is proper one for operand 1.
5631 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5632 ;; we take care in ix86_binary_operator_ok to not allow two memory
5633 ;; operands so proper swapping will be done in reload. This allow
5634 ;; patterns constructed from addsi_1 to match.
5636 (define_insn "addsi_1_zext"
5637 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5639 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5640 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5641 (clobber (reg:CC FLAGS_REG))]
5642 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5644 switch (get_attr_type (insn))
5650 if (operands[2] == const1_rtx)
5651 return "inc{l}\t%k0";
5654 gcc_assert (operands[2] == constm1_rtx);
5655 return "dec{l}\t%k0";
5659 /* For most processors, ADD is faster than LEA. This alternative
5660 was added to use ADD as much as possible. */
5661 if (which_alternative == 1)
5664 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5667 if (x86_maybe_negate_const_int (&operands[2], SImode))
5668 return "sub{l}\t{%2, %k0|%k0, %2}";
5670 return "add{l}\t{%2, %k0|%k0, %2}";
5674 (cond [(eq_attr "alternative" "2")
5675 (const_string "lea")
5676 (match_operand:SI 2 "incdec_operand")
5677 (const_string "incdec")
5679 (const_string "alu")))
5680 (set (attr "length_immediate")
5682 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5684 (const_string "*")))
5685 (set_attr "mode" "SI")])
5687 (define_insn "*addhi_1"
5688 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5689 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5690 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5691 (clobber (reg:CC FLAGS_REG))]
5692 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5694 switch (get_attr_type (insn))
5700 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5701 if (operands[2] == const1_rtx)
5702 return "inc{w}\t%0";
5705 gcc_assert (operands[2] == constm1_rtx);
5706 return "dec{w}\t%0";
5710 /* For most processors, ADD is faster than LEA. This alternative
5711 was added to use ADD as much as possible. */
5712 if (which_alternative == 2)
5715 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5718 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5719 if (x86_maybe_negate_const_int (&operands[2], HImode))
5720 return "sub{w}\t{%2, %0|%0, %2}";
5722 return "add{w}\t{%2, %0|%0, %2}";
5726 (cond [(eq_attr "alternative" "3")
5727 (const_string "lea")
5728 (match_operand:HI 2 "incdec_operand")
5729 (const_string "incdec")
5731 (const_string "alu")))
5732 (set (attr "length_immediate")
5734 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5736 (const_string "*")))
5737 (set_attr "mode" "HI,HI,HI,SI")])
5739 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5740 (define_insn "*addqi_1"
5741 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5742 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5743 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5744 (clobber (reg:CC FLAGS_REG))]
5745 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5747 bool widen = (which_alternative == 3 || which_alternative == 4);
5749 switch (get_attr_type (insn))
5755 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5756 if (operands[2] == const1_rtx)
5757 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5760 gcc_assert (operands[2] == constm1_rtx);
5761 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5765 /* For most processors, ADD is faster than LEA. These alternatives
5766 were added to use ADD as much as possible. */
5767 if (which_alternative == 2 || which_alternative == 4)
5770 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5773 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5774 if (x86_maybe_negate_const_int (&operands[2], QImode))
5777 return "sub{l}\t{%2, %k0|%k0, %2}";
5779 return "sub{b}\t{%2, %0|%0, %2}";
5782 return "add{l}\t{%k2, %k0|%k0, %k2}";
5784 return "add{b}\t{%2, %0|%0, %2}";
5788 (cond [(eq_attr "alternative" "5")
5789 (const_string "lea")
5790 (match_operand:QI 2 "incdec_operand")
5791 (const_string "incdec")
5793 (const_string "alu")))
5794 (set (attr "length_immediate")
5796 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5798 (const_string "*")))
5799 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5801 (define_insn "*addqi_1_slp"
5802 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5803 (plus:QI (match_dup 0)
5804 (match_operand:QI 1 "general_operand" "qn,qm")))
5805 (clobber (reg:CC FLAGS_REG))]
5806 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5807 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5809 switch (get_attr_type (insn))
5812 if (operands[1] == const1_rtx)
5813 return "inc{b}\t%0";
5816 gcc_assert (operands[1] == constm1_rtx);
5817 return "dec{b}\t%0";
5821 if (x86_maybe_negate_const_int (&operands[1], QImode))
5822 return "sub{b}\t{%1, %0|%0, %1}";
5824 return "add{b}\t{%1, %0|%0, %1}";
5828 (if_then_else (match_operand:QI 1 "incdec_operand")
5829 (const_string "incdec")
5830 (const_string "alu1")))
5831 (set (attr "memory")
5832 (if_then_else (match_operand 1 "memory_operand")
5833 (const_string "load")
5834 (const_string "none")))
5835 (set_attr "mode" "QI")])
5837 ;; Split non destructive adds if we cannot use lea.
5839 [(set (match_operand:SWI48 0 "register_operand")
5840 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5841 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5842 (clobber (reg:CC FLAGS_REG))]
5843 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5844 [(set (match_dup 0) (match_dup 1))
5845 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5846 (clobber (reg:CC FLAGS_REG))])])
5848 ;; Convert add to the lea pattern to avoid flags dependency.
5850 [(set (match_operand:SWI 0 "register_operand")
5851 (plus:SWI (match_operand:SWI 1 "register_operand")
5852 (match_operand:SWI 2 "<nonmemory_operand>")))
5853 (clobber (reg:CC FLAGS_REG))]
5854 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5857 enum machine_mode mode = <MODE>mode;
5860 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5863 operands[0] = gen_lowpart (mode, operands[0]);
5864 operands[1] = gen_lowpart (mode, operands[1]);
5865 operands[2] = gen_lowpart (mode, operands[2]);
5868 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5870 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5874 ;; Split non destructive adds if we cannot use lea.
5876 [(set (match_operand:DI 0 "register_operand")
5878 (plus:SI (match_operand:SI 1 "register_operand")
5879 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5880 (clobber (reg:CC FLAGS_REG))]
5882 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5883 [(set (match_dup 3) (match_dup 1))
5884 (parallel [(set (match_dup 0)
5885 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5886 (clobber (reg:CC FLAGS_REG))])]
5887 "operands[3] = gen_lowpart (SImode, operands[0]);")
5889 ;; Convert add to the lea pattern to avoid flags dependency.
5891 [(set (match_operand:DI 0 "register_operand")
5893 (plus:SI (match_operand:SI 1 "register_operand")
5894 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5895 (clobber (reg:CC FLAGS_REG))]
5896 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5898 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5900 (define_insn "*add<mode>_2"
5901 [(set (reg FLAGS_REG)
5904 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5905 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5907 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5908 (plus:SWI (match_dup 1) (match_dup 2)))]
5909 "ix86_match_ccmode (insn, CCGOCmode)
5910 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5912 switch (get_attr_type (insn))
5915 if (operands[2] == const1_rtx)
5916 return "inc{<imodesuffix>}\t%0";
5919 gcc_assert (operands[2] == constm1_rtx);
5920 return "dec{<imodesuffix>}\t%0";
5924 if (which_alternative == 2)
5927 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5930 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5931 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5932 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5934 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5938 (if_then_else (match_operand:SWI 2 "incdec_operand")
5939 (const_string "incdec")
5940 (const_string "alu")))
5941 (set (attr "length_immediate")
5943 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5945 (const_string "*")))
5946 (set_attr "mode" "<MODE>")])
5948 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5949 (define_insn "*addsi_2_zext"
5950 [(set (reg FLAGS_REG)
5952 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5953 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5955 (set (match_operand:DI 0 "register_operand" "=r,r")
5956 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5957 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5958 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5960 switch (get_attr_type (insn))
5963 if (operands[2] == const1_rtx)
5964 return "inc{l}\t%k0";
5967 gcc_assert (operands[2] == constm1_rtx);
5968 return "dec{l}\t%k0";
5972 if (which_alternative == 1)
5975 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5978 if (x86_maybe_negate_const_int (&operands[2], SImode))
5979 return "sub{l}\t{%2, %k0|%k0, %2}";
5981 return "add{l}\t{%2, %k0|%k0, %2}";
5985 (if_then_else (match_operand:SI 2 "incdec_operand")
5986 (const_string "incdec")
5987 (const_string "alu")))
5988 (set (attr "length_immediate")
5990 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5992 (const_string "*")))
5993 (set_attr "mode" "SI")])
5995 (define_insn "*add<mode>_3"
5996 [(set (reg FLAGS_REG)
5998 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5999 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6000 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6001 "ix86_match_ccmode (insn, CCZmode)
6002 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6004 switch (get_attr_type (insn))
6007 if (operands[2] == const1_rtx)
6008 return "inc{<imodesuffix>}\t%0";
6011 gcc_assert (operands[2] == constm1_rtx);
6012 return "dec{<imodesuffix>}\t%0";
6016 if (which_alternative == 1)
6019 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6022 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6023 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6024 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6026 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6030 (if_then_else (match_operand:SWI 2 "incdec_operand")
6031 (const_string "incdec")
6032 (const_string "alu")))
6033 (set (attr "length_immediate")
6035 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6037 (const_string "*")))
6038 (set_attr "mode" "<MODE>")])
6040 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6041 (define_insn "*addsi_3_zext"
6042 [(set (reg FLAGS_REG)
6044 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6045 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6046 (set (match_operand:DI 0 "register_operand" "=r,r")
6047 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6048 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6049 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6051 switch (get_attr_type (insn))
6054 if (operands[2] == const1_rtx)
6055 return "inc{l}\t%k0";
6058 gcc_assert (operands[2] == constm1_rtx);
6059 return "dec{l}\t%k0";
6063 if (which_alternative == 1)
6066 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6069 if (x86_maybe_negate_const_int (&operands[2], SImode))
6070 return "sub{l}\t{%2, %k0|%k0, %2}";
6072 return "add{l}\t{%2, %k0|%k0, %2}";
6076 (if_then_else (match_operand:SI 2 "incdec_operand")
6077 (const_string "incdec")
6078 (const_string "alu")))
6079 (set (attr "length_immediate")
6081 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6083 (const_string "*")))
6084 (set_attr "mode" "SI")])
6086 ; For comparisons against 1, -1 and 128, we may generate better code
6087 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6088 ; is matched then. We can't accept general immediate, because for
6089 ; case of overflows, the result is messed up.
6090 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6091 ; only for comparisons not depending on it.
6093 (define_insn "*adddi_4"
6094 [(set (reg FLAGS_REG)
6096 (match_operand:DI 1 "nonimmediate_operand" "0")
6097 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6098 (clobber (match_scratch:DI 0 "=rm"))]
6100 && ix86_match_ccmode (insn, CCGCmode)"
6102 switch (get_attr_type (insn))
6105 if (operands[2] == constm1_rtx)
6106 return "inc{q}\t%0";
6109 gcc_assert (operands[2] == const1_rtx);
6110 return "dec{q}\t%0";
6114 if (x86_maybe_negate_const_int (&operands[2], DImode))
6115 return "add{q}\t{%2, %0|%0, %2}";
6117 return "sub{q}\t{%2, %0|%0, %2}";
6121 (if_then_else (match_operand:DI 2 "incdec_operand")
6122 (const_string "incdec")
6123 (const_string "alu")))
6124 (set (attr "length_immediate")
6126 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6128 (const_string "*")))
6129 (set_attr "mode" "DI")])
6131 ; For comparisons against 1, -1 and 128, we may generate better code
6132 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6133 ; is matched then. We can't accept general immediate, because for
6134 ; case of overflows, the result is messed up.
6135 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6136 ; only for comparisons not depending on it.
6138 (define_insn "*add<mode>_4"
6139 [(set (reg FLAGS_REG)
6141 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6142 (match_operand:SWI124 2 "const_int_operand" "n")))
6143 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6144 "ix86_match_ccmode (insn, CCGCmode)"
6146 switch (get_attr_type (insn))
6149 if (operands[2] == constm1_rtx)
6150 return "inc{<imodesuffix>}\t%0";
6153 gcc_assert (operands[2] == const1_rtx);
6154 return "dec{<imodesuffix>}\t%0";
6158 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6159 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6161 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6165 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6166 (const_string "incdec")
6167 (const_string "alu")))
6168 (set (attr "length_immediate")
6170 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6172 (const_string "*")))
6173 (set_attr "mode" "<MODE>")])
6175 (define_insn "*add<mode>_5"
6176 [(set (reg FLAGS_REG)
6179 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6180 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6182 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6183 "ix86_match_ccmode (insn, CCGOCmode)
6184 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6186 switch (get_attr_type (insn))
6189 if (operands[2] == const1_rtx)
6190 return "inc{<imodesuffix>}\t%0";
6193 gcc_assert (operands[2] == constm1_rtx);
6194 return "dec{<imodesuffix>}\t%0";
6198 if (which_alternative == 1)
6201 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6204 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6205 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6206 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6208 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6212 (if_then_else (match_operand:SWI 2 "incdec_operand")
6213 (const_string "incdec")
6214 (const_string "alu")))
6215 (set (attr "length_immediate")
6217 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6219 (const_string "*")))
6220 (set_attr "mode" "<MODE>")])
6222 (define_insn "*addqi_ext_1_rex64"
6223 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6228 (match_operand 1 "ext_register_operand" "0")
6231 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6232 (clobber (reg:CC FLAGS_REG))]
6235 switch (get_attr_type (insn))
6238 if (operands[2] == const1_rtx)
6239 return "inc{b}\t%h0";
6242 gcc_assert (operands[2] == constm1_rtx);
6243 return "dec{b}\t%h0";
6247 return "add{b}\t{%2, %h0|%h0, %2}";
6251 (if_then_else (match_operand:QI 2 "incdec_operand")
6252 (const_string "incdec")
6253 (const_string "alu")))
6254 (set_attr "modrm" "1")
6255 (set_attr "mode" "QI")])
6257 (define_insn "addqi_ext_1"
6258 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6263 (match_operand 1 "ext_register_operand" "0")
6266 (match_operand:QI 2 "general_operand" "Qmn")))
6267 (clobber (reg:CC FLAGS_REG))]
6270 switch (get_attr_type (insn))
6273 if (operands[2] == const1_rtx)
6274 return "inc{b}\t%h0";
6277 gcc_assert (operands[2] == constm1_rtx);
6278 return "dec{b}\t%h0";
6282 return "add{b}\t{%2, %h0|%h0, %2}";
6286 (if_then_else (match_operand:QI 2 "incdec_operand")
6287 (const_string "incdec")
6288 (const_string "alu")))
6289 (set_attr "modrm" "1")
6290 (set_attr "mode" "QI")])
6292 (define_insn "*addqi_ext_2"
6293 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6298 (match_operand 1 "ext_register_operand" "%0")
6302 (match_operand 2 "ext_register_operand" "Q")
6305 (clobber (reg:CC FLAGS_REG))]
6307 "add{b}\t{%h2, %h0|%h0, %h2}"
6308 [(set_attr "type" "alu")
6309 (set_attr "mode" "QI")])
6311 ;; The lea patterns for modes less than 32 bits need to be matched by
6312 ;; several insns converted to real lea by splitters.
6314 (define_insn_and_split "*lea_general_1"
6315 [(set (match_operand 0 "register_operand" "=r")
6316 (plus (plus (match_operand 1 "index_register_operand" "l")
6317 (match_operand 2 "register_operand" "r"))
6318 (match_operand 3 "immediate_operand" "i")))]
6319 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6320 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6321 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6322 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6323 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6324 || GET_MODE (operands[3]) == VOIDmode)"
6326 "&& reload_completed"
6329 enum machine_mode mode = SImode;
6332 operands[0] = gen_lowpart (mode, operands[0]);
6333 operands[1] = gen_lowpart (mode, operands[1]);
6334 operands[2] = gen_lowpart (mode, operands[2]);
6335 operands[3] = gen_lowpart (mode, operands[3]);
6337 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6340 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6343 [(set_attr "type" "lea")
6344 (set_attr "mode" "SI")])
6346 (define_insn_and_split "*lea_general_2"
6347 [(set (match_operand 0 "register_operand" "=r")
6348 (plus (mult (match_operand 1 "index_register_operand" "l")
6349 (match_operand 2 "const248_operand" "n"))
6350 (match_operand 3 "nonmemory_operand" "ri")))]
6351 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6352 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6353 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6354 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6355 || GET_MODE (operands[3]) == VOIDmode)"
6357 "&& reload_completed"
6360 enum machine_mode mode = SImode;
6363 operands[0] = gen_lowpart (mode, operands[0]);
6364 operands[1] = gen_lowpart (mode, operands[1]);
6365 operands[3] = gen_lowpart (mode, operands[3]);
6367 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6370 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6373 [(set_attr "type" "lea")
6374 (set_attr "mode" "SI")])
6376 (define_insn_and_split "*lea_general_3"
6377 [(set (match_operand 0 "register_operand" "=r")
6378 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6379 (match_operand 2 "const248_operand" "n"))
6380 (match_operand 3 "register_operand" "r"))
6381 (match_operand 4 "immediate_operand" "i")))]
6382 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6383 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6384 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6385 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6387 "&& reload_completed"
6390 enum machine_mode mode = SImode;
6393 operands[0] = gen_lowpart (mode, operands[0]);
6394 operands[1] = gen_lowpart (mode, operands[1]);
6395 operands[3] = gen_lowpart (mode, operands[3]);
6396 operands[4] = gen_lowpart (mode, operands[4]);
6398 pat = gen_rtx_PLUS (mode,
6400 gen_rtx_MULT (mode, operands[1],
6405 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6408 [(set_attr "type" "lea")
6409 (set_attr "mode" "SI")])
6411 (define_insn_and_split "*lea_general_4"
6412 [(set (match_operand 0 "register_operand" "=r")
6414 (match_operand 1 "index_register_operand" "l")
6415 (match_operand 2 "const_int_operand" "n"))
6416 (match_operand 3 "const_int_operand" "n")))]
6417 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6418 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6419 || GET_MODE (operands[0]) == SImode
6420 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6421 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6422 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6423 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6424 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6426 "&& reload_completed"
6429 enum machine_mode mode = GET_MODE (operands[0]);
6432 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6435 operands[0] = gen_lowpart (mode, operands[0]);
6436 operands[1] = gen_lowpart (mode, operands[1]);
6439 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6441 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6442 INTVAL (operands[3]));
6444 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6447 [(set_attr "type" "lea")
6449 (if_then_else (match_operand:DI 0)
6451 (const_string "SI")))])
6453 ;; Subtract instructions
6455 (define_expand "sub<mode>3"
6456 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6457 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6458 (match_operand:SDWIM 2 "<general_operand>")))]
6460 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6462 (define_insn_and_split "*sub<dwi>3_doubleword"
6463 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6465 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6466 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6467 (clobber (reg:CC FLAGS_REG))]
6468 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6471 [(parallel [(set (reg:CC FLAGS_REG)
6472 (compare:CC (match_dup 1) (match_dup 2)))
6474 (minus:DWIH (match_dup 1) (match_dup 2)))])
6475 (parallel [(set (match_dup 3)
6479 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6481 (clobber (reg:CC FLAGS_REG))])]
6482 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6484 (define_insn "*sub<mode>_1"
6485 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6487 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6488 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6489 (clobber (reg:CC FLAGS_REG))]
6490 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6491 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6492 [(set_attr "type" "alu")
6493 (set_attr "mode" "<MODE>")])
6495 (define_insn "*subsi_1_zext"
6496 [(set (match_operand:DI 0 "register_operand" "=r")
6498 (minus:SI (match_operand:SI 1 "register_operand" "0")
6499 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6500 (clobber (reg:CC FLAGS_REG))]
6501 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6502 "sub{l}\t{%2, %k0|%k0, %2}"
6503 [(set_attr "type" "alu")
6504 (set_attr "mode" "SI")])
6506 (define_insn "*subqi_1_slp"
6507 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6508 (minus:QI (match_dup 0)
6509 (match_operand:QI 1 "general_operand" "qn,qm")))
6510 (clobber (reg:CC FLAGS_REG))]
6511 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6512 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6513 "sub{b}\t{%1, %0|%0, %1}"
6514 [(set_attr "type" "alu1")
6515 (set_attr "mode" "QI")])
6517 (define_insn "*sub<mode>_2"
6518 [(set (reg FLAGS_REG)
6521 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6522 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6524 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6525 (minus:SWI (match_dup 1) (match_dup 2)))]
6526 "ix86_match_ccmode (insn, CCGOCmode)
6527 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6528 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6529 [(set_attr "type" "alu")
6530 (set_attr "mode" "<MODE>")])
6532 (define_insn "*subsi_2_zext"
6533 [(set (reg FLAGS_REG)
6535 (minus:SI (match_operand:SI 1 "register_operand" "0")
6536 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6538 (set (match_operand:DI 0 "register_operand" "=r")
6540 (minus:SI (match_dup 1)
6542 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6543 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6544 "sub{l}\t{%2, %k0|%k0, %2}"
6545 [(set_attr "type" "alu")
6546 (set_attr "mode" "SI")])
6548 (define_insn "*sub<mode>_3"
6549 [(set (reg FLAGS_REG)
6550 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6551 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6552 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6553 (minus:SWI (match_dup 1) (match_dup 2)))]
6554 "ix86_match_ccmode (insn, CCmode)
6555 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6556 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6557 [(set_attr "type" "alu")
6558 (set_attr "mode" "<MODE>")])
6560 (define_insn "*subsi_3_zext"
6561 [(set (reg FLAGS_REG)
6562 (compare (match_operand:SI 1 "register_operand" "0")
6563 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6564 (set (match_operand:DI 0 "register_operand" "=r")
6566 (minus:SI (match_dup 1)
6568 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6569 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6570 "sub{l}\t{%2, %1|%1, %2}"
6571 [(set_attr "type" "alu")
6572 (set_attr "mode" "SI")])
6574 ;; Add with carry and subtract with borrow
6576 (define_expand "<plusminus_insn><mode>3_carry"
6578 [(set (match_operand:SWI 0 "nonimmediate_operand")
6580 (match_operand:SWI 1 "nonimmediate_operand")
6581 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6582 [(match_operand 3 "flags_reg_operand")
6584 (match_operand:SWI 2 "<general_operand>"))))
6585 (clobber (reg:CC FLAGS_REG))])]
6586 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6588 (define_insn "*<plusminus_insn><mode>3_carry"
6589 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6591 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6593 (match_operator 3 "ix86_carry_flag_operator"
6594 [(reg FLAGS_REG) (const_int 0)])
6595 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6596 (clobber (reg:CC FLAGS_REG))]
6597 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6598 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6599 [(set_attr "type" "alu")
6600 (set_attr "use_carry" "1")
6601 (set_attr "pent_pair" "pu")
6602 (set_attr "mode" "<MODE>")])
6604 (define_insn "*addsi3_carry_zext"
6605 [(set (match_operand:DI 0 "register_operand" "=r")
6607 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6608 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6609 [(reg FLAGS_REG) (const_int 0)])
6610 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6611 (clobber (reg:CC FLAGS_REG))]
6612 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6613 "adc{l}\t{%2, %k0|%k0, %2}"
6614 [(set_attr "type" "alu")
6615 (set_attr "use_carry" "1")
6616 (set_attr "pent_pair" "pu")
6617 (set_attr "mode" "SI")])
6619 (define_insn "*subsi3_carry_zext"
6620 [(set (match_operand:DI 0 "register_operand" "=r")
6622 (minus:SI (match_operand:SI 1 "register_operand" "0")
6623 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6624 [(reg FLAGS_REG) (const_int 0)])
6625 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6626 (clobber (reg:CC FLAGS_REG))]
6627 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6628 "sbb{l}\t{%2, %k0|%k0, %2}"
6629 [(set_attr "type" "alu")
6630 (set_attr "pent_pair" "pu")
6631 (set_attr "mode" "SI")])
6633 ;; Overflow setting add and subtract instructions
6635 (define_insn "*add<mode>3_cconly_overflow"
6636 [(set (reg:CCC FLAGS_REG)
6639 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6640 (match_operand:SWI 2 "<general_operand>" "<g>"))
6642 (clobber (match_scratch:SWI 0 "=<r>"))]
6643 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6644 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6645 [(set_attr "type" "alu")
6646 (set_attr "mode" "<MODE>")])
6648 (define_insn "*sub<mode>3_cconly_overflow"
6649 [(set (reg:CCC FLAGS_REG)
6652 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6653 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6656 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6657 [(set_attr "type" "icmp")
6658 (set_attr "mode" "<MODE>")])
6660 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6661 [(set (reg:CCC FLAGS_REG)
6664 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6665 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6667 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6668 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6669 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6670 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6671 [(set_attr "type" "alu")
6672 (set_attr "mode" "<MODE>")])
6674 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6675 [(set (reg:CCC FLAGS_REG)
6678 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6679 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6681 (set (match_operand:DI 0 "register_operand" "=r")
6682 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6683 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6684 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6685 [(set_attr "type" "alu")
6686 (set_attr "mode" "SI")])
6688 ;; The patterns that match these are at the end of this file.
6690 (define_expand "<plusminus_insn>xf3"
6691 [(set (match_operand:XF 0 "register_operand")
6693 (match_operand:XF 1 "register_operand")
6694 (match_operand:XF 2 "register_operand")))]
6697 (define_expand "<plusminus_insn><mode>3"
6698 [(set (match_operand:MODEF 0 "register_operand")
6700 (match_operand:MODEF 1 "register_operand")
6701 (match_operand:MODEF 2 "nonimmediate_operand")))]
6702 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6703 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6705 ;; Multiply instructions
6707 (define_expand "mul<mode>3"
6708 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6710 (match_operand:SWIM248 1 "register_operand")
6711 (match_operand:SWIM248 2 "<general_operand>")))
6712 (clobber (reg:CC FLAGS_REG))])])
6714 (define_expand "mulqi3"
6715 [(parallel [(set (match_operand:QI 0 "register_operand")
6717 (match_operand:QI 1 "register_operand")
6718 (match_operand:QI 2 "nonimmediate_operand")))
6719 (clobber (reg:CC FLAGS_REG))])]
6720 "TARGET_QIMODE_MATH")
6723 ;; IMUL reg32/64, reg32/64, imm8 Direct
6724 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6725 ;; IMUL reg32/64, reg32/64, imm32 Direct
6726 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6727 ;; IMUL reg32/64, reg32/64 Direct
6728 ;; IMUL reg32/64, mem32/64 Direct
6730 ;; On BDVER1, all above IMULs use DirectPath
6732 (define_insn "*mul<mode>3_1"
6733 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6735 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6736 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6737 (clobber (reg:CC FLAGS_REG))]
6738 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6740 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6741 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6742 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6743 [(set_attr "type" "imul")
6744 (set_attr "prefix_0f" "0,0,1")
6745 (set (attr "athlon_decode")
6746 (cond [(eq_attr "cpu" "athlon")
6747 (const_string "vector")
6748 (eq_attr "alternative" "1")
6749 (const_string "vector")
6750 (and (eq_attr "alternative" "2")
6751 (match_operand 1 "memory_operand"))
6752 (const_string "vector")]
6753 (const_string "direct")))
6754 (set (attr "amdfam10_decode")
6755 (cond [(and (eq_attr "alternative" "0,1")
6756 (match_operand 1 "memory_operand"))
6757 (const_string "vector")]
6758 (const_string "direct")))
6759 (set_attr "bdver1_decode" "direct")
6760 (set_attr "mode" "<MODE>")])
6762 (define_insn "*mulsi3_1_zext"
6763 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6765 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6766 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6767 (clobber (reg:CC FLAGS_REG))]
6769 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6771 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6772 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6773 imul{l}\t{%2, %k0|%k0, %2}"
6774 [(set_attr "type" "imul")
6775 (set_attr "prefix_0f" "0,0,1")
6776 (set (attr "athlon_decode")
6777 (cond [(eq_attr "cpu" "athlon")
6778 (const_string "vector")
6779 (eq_attr "alternative" "1")
6780 (const_string "vector")
6781 (and (eq_attr "alternative" "2")
6782 (match_operand 1 "memory_operand"))
6783 (const_string "vector")]
6784 (const_string "direct")))
6785 (set (attr "amdfam10_decode")
6786 (cond [(and (eq_attr "alternative" "0,1")
6787 (match_operand 1 "memory_operand"))
6788 (const_string "vector")]
6789 (const_string "direct")))
6790 (set_attr "bdver1_decode" "direct")
6791 (set_attr "mode" "SI")])
6794 ;; IMUL reg16, reg16, imm8 VectorPath
6795 ;; IMUL reg16, mem16, imm8 VectorPath
6796 ;; IMUL reg16, reg16, imm16 VectorPath
6797 ;; IMUL reg16, mem16, imm16 VectorPath
6798 ;; IMUL reg16, reg16 Direct
6799 ;; IMUL reg16, mem16 Direct
6801 ;; On BDVER1, all HI MULs use DoublePath
6803 (define_insn "*mulhi3_1"
6804 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6805 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6806 (match_operand:HI 2 "general_operand" "K,n,mr")))
6807 (clobber (reg:CC FLAGS_REG))]
6809 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6811 imul{w}\t{%2, %1, %0|%0, %1, %2}
6812 imul{w}\t{%2, %1, %0|%0, %1, %2}
6813 imul{w}\t{%2, %0|%0, %2}"
6814 [(set_attr "type" "imul")
6815 (set_attr "prefix_0f" "0,0,1")
6816 (set (attr "athlon_decode")
6817 (cond [(eq_attr "cpu" "athlon")
6818 (const_string "vector")
6819 (eq_attr "alternative" "1,2")
6820 (const_string "vector")]
6821 (const_string "direct")))
6822 (set (attr "amdfam10_decode")
6823 (cond [(eq_attr "alternative" "0,1")
6824 (const_string "vector")]
6825 (const_string "direct")))
6826 (set_attr "bdver1_decode" "double")
6827 (set_attr "mode" "HI")])
6829 ;;On AMDFAM10 and BDVER1
6833 (define_insn "*mulqi3_1"
6834 [(set (match_operand:QI 0 "register_operand" "=a")
6835 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6836 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6837 (clobber (reg:CC FLAGS_REG))]
6839 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6841 [(set_attr "type" "imul")
6842 (set_attr "length_immediate" "0")
6843 (set (attr "athlon_decode")
6844 (if_then_else (eq_attr "cpu" "athlon")
6845 (const_string "vector")
6846 (const_string "direct")))
6847 (set_attr "amdfam10_decode" "direct")
6848 (set_attr "bdver1_decode" "direct")
6849 (set_attr "mode" "QI")])
6851 (define_expand "<u>mul<mode><dwi>3"
6852 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6855 (match_operand:DWIH 1 "nonimmediate_operand"))
6857 (match_operand:DWIH 2 "register_operand"))))
6858 (clobber (reg:CC FLAGS_REG))])])
6860 (define_expand "<u>mulqihi3"
6861 [(parallel [(set (match_operand:HI 0 "register_operand")
6864 (match_operand:QI 1 "nonimmediate_operand"))
6866 (match_operand:QI 2 "register_operand"))))
6867 (clobber (reg:CC FLAGS_REG))])]
6868 "TARGET_QIMODE_MATH")
6870 (define_insn "*bmi2_umulditi3_1"
6871 [(set (match_operand:DI 0 "register_operand" "=r")
6873 (match_operand:DI 2 "nonimmediate_operand" "%d")
6874 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6875 (set (match_operand:DI 1 "register_operand" "=r")
6878 (mult:TI (zero_extend:TI (match_dup 2))
6879 (zero_extend:TI (match_dup 3)))
6881 "TARGET_64BIT && TARGET_BMI2
6882 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6883 "mulx\t{%3, %0, %1|%1, %0, %3}"
6884 [(set_attr "type" "imulx")
6885 (set_attr "prefix" "vex")
6886 (set_attr "mode" "DI")])
6888 (define_insn "*bmi2_umulsidi3_1"
6889 [(set (match_operand:SI 0 "register_operand" "=r")
6891 (match_operand:SI 2 "nonimmediate_operand" "%d")
6892 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6893 (set (match_operand:SI 1 "register_operand" "=r")
6896 (mult:DI (zero_extend:DI (match_dup 2))
6897 (zero_extend:DI (match_dup 3)))
6899 "!TARGET_64BIT && TARGET_BMI2
6900 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6901 "mulx\t{%3, %0, %1|%1, %0, %3}"
6902 [(set_attr "type" "imulx")
6903 (set_attr "prefix" "vex")
6904 (set_attr "mode" "SI")])
6906 (define_insn "*umul<mode><dwi>3_1"
6907 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6910 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6912 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6913 (clobber (reg:CC FLAGS_REG))]
6914 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6917 mul{<imodesuffix>}\t%2"
6918 [(set_attr "isa" "bmi2,*")
6919 (set_attr "type" "imulx,imul")
6920 (set_attr "length_immediate" "*,0")
6921 (set (attr "athlon_decode")
6922 (cond [(eq_attr "alternative" "1")
6923 (if_then_else (eq_attr "cpu" "athlon")
6924 (const_string "vector")
6925 (const_string "double"))]
6926 (const_string "*")))
6927 (set_attr "amdfam10_decode" "*,double")
6928 (set_attr "bdver1_decode" "*,direct")
6929 (set_attr "prefix" "vex,orig")
6930 (set_attr "mode" "<MODE>")])
6932 ;; Convert mul to the mulx pattern to avoid flags dependency.
6934 [(set (match_operand:<DWI> 0 "register_operand")
6937 (match_operand:DWIH 1 "register_operand"))
6939 (match_operand:DWIH 2 "nonimmediate_operand"))))
6940 (clobber (reg:CC FLAGS_REG))]
6941 "TARGET_BMI2 && reload_completed
6942 && true_regnum (operands[1]) == DX_REG"
6943 [(parallel [(set (match_dup 3)
6944 (mult:DWIH (match_dup 1) (match_dup 2)))
6948 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6949 (zero_extend:<DWI> (match_dup 2)))
6952 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6954 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6957 (define_insn "*mul<mode><dwi>3_1"
6958 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6961 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6963 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6964 (clobber (reg:CC FLAGS_REG))]
6965 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6966 "imul{<imodesuffix>}\t%2"
6967 [(set_attr "type" "imul")
6968 (set_attr "length_immediate" "0")
6969 (set (attr "athlon_decode")
6970 (if_then_else (eq_attr "cpu" "athlon")
6971 (const_string "vector")
6972 (const_string "double")))
6973 (set_attr "amdfam10_decode" "double")
6974 (set_attr "bdver1_decode" "direct")
6975 (set_attr "mode" "<MODE>")])
6977 (define_insn "*<u>mulqihi3_1"
6978 [(set (match_operand:HI 0 "register_operand" "=a")
6981 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6983 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6984 (clobber (reg:CC FLAGS_REG))]
6986 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6987 "<sgnprefix>mul{b}\t%2"
6988 [(set_attr "type" "imul")
6989 (set_attr "length_immediate" "0")
6990 (set (attr "athlon_decode")
6991 (if_then_else (eq_attr "cpu" "athlon")
6992 (const_string "vector")
6993 (const_string "direct")))
6994 (set_attr "amdfam10_decode" "direct")
6995 (set_attr "bdver1_decode" "direct")
6996 (set_attr "mode" "QI")])
6998 (define_expand "<s>mul<mode>3_highpart"
6999 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7004 (match_operand:SWI48 1 "nonimmediate_operand"))
7006 (match_operand:SWI48 2 "register_operand")))
7008 (clobber (match_scratch:SWI48 3))
7009 (clobber (reg:CC FLAGS_REG))])]
7011 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7013 (define_insn "*<s>muldi3_highpart_1"
7014 [(set (match_operand:DI 0 "register_operand" "=d")
7019 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7021 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7023 (clobber (match_scratch:DI 3 "=1"))
7024 (clobber (reg:CC FLAGS_REG))]
7026 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7027 "<sgnprefix>mul{q}\t%2"
7028 [(set_attr "type" "imul")
7029 (set_attr "length_immediate" "0")
7030 (set (attr "athlon_decode")
7031 (if_then_else (eq_attr "cpu" "athlon")
7032 (const_string "vector")
7033 (const_string "double")))
7034 (set_attr "amdfam10_decode" "double")
7035 (set_attr "bdver1_decode" "direct")
7036 (set_attr "mode" "DI")])
7038 (define_insn "*<s>mulsi3_highpart_1"
7039 [(set (match_operand:SI 0 "register_operand" "=d")
7044 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7046 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7048 (clobber (match_scratch:SI 3 "=1"))
7049 (clobber (reg:CC FLAGS_REG))]
7050 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7051 "<sgnprefix>mul{l}\t%2"
7052 [(set_attr "type" "imul")
7053 (set_attr "length_immediate" "0")
7054 (set (attr "athlon_decode")
7055 (if_then_else (eq_attr "cpu" "athlon")
7056 (const_string "vector")
7057 (const_string "double")))
7058 (set_attr "amdfam10_decode" "double")
7059 (set_attr "bdver1_decode" "direct")
7060 (set_attr "mode" "SI")])
7062 (define_insn "*<s>mulsi3_highpart_zext"
7063 [(set (match_operand:DI 0 "register_operand" "=d")
7064 (zero_extend:DI (truncate:SI
7066 (mult:DI (any_extend:DI
7067 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7069 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7071 (clobber (match_scratch:SI 3 "=1"))
7072 (clobber (reg:CC FLAGS_REG))]
7074 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7075 "<sgnprefix>mul{l}\t%2"
7076 [(set_attr "type" "imul")
7077 (set_attr "length_immediate" "0")
7078 (set (attr "athlon_decode")
7079 (if_then_else (eq_attr "cpu" "athlon")
7080 (const_string "vector")
7081 (const_string "double")))
7082 (set_attr "amdfam10_decode" "double")
7083 (set_attr "bdver1_decode" "direct")
7084 (set_attr "mode" "SI")])
7086 ;; The patterns that match these are at the end of this file.
7088 (define_expand "mulxf3"
7089 [(set (match_operand:XF 0 "register_operand")
7090 (mult:XF (match_operand:XF 1 "register_operand")
7091 (match_operand:XF 2 "register_operand")))]
7094 (define_expand "mul<mode>3"
7095 [(set (match_operand:MODEF 0 "register_operand")
7096 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7097 (match_operand:MODEF 2 "nonimmediate_operand")))]
7098 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7099 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7101 ;; Divide instructions
7103 ;; The patterns that match these are at the end of this file.
7105 (define_expand "divxf3"
7106 [(set (match_operand:XF 0 "register_operand")
7107 (div:XF (match_operand:XF 1 "register_operand")
7108 (match_operand:XF 2 "register_operand")))]
7111 (define_expand "divdf3"
7112 [(set (match_operand:DF 0 "register_operand")
7113 (div:DF (match_operand:DF 1 "register_operand")
7114 (match_operand:DF 2 "nonimmediate_operand")))]
7115 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7116 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7118 (define_expand "divsf3"
7119 [(set (match_operand:SF 0 "register_operand")
7120 (div:SF (match_operand:SF 1 "register_operand")
7121 (match_operand:SF 2 "nonimmediate_operand")))]
7122 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7127 && optimize_insn_for_speed_p ()
7128 && flag_finite_math_only && !flag_trapping_math
7129 && flag_unsafe_math_optimizations)
7131 ix86_emit_swdivsf (operands[0], operands[1],
7132 operands[2], SFmode);
7137 ;; Divmod instructions.
7139 (define_expand "divmod<mode>4"
7140 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7142 (match_operand:SWIM248 1 "register_operand")
7143 (match_operand:SWIM248 2 "nonimmediate_operand")))
7144 (set (match_operand:SWIM248 3 "register_operand")
7145 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7146 (clobber (reg:CC FLAGS_REG))])])
7148 ;; Split with 8bit unsigned divide:
7149 ;; if (dividend an divisor are in [0-255])
7150 ;; use 8bit unsigned integer divide
7152 ;; use original integer divide
7154 [(set (match_operand:SWI48 0 "register_operand")
7155 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7156 (match_operand:SWI48 3 "nonimmediate_operand")))
7157 (set (match_operand:SWI48 1 "register_operand")
7158 (mod:SWI48 (match_dup 2) (match_dup 3)))
7159 (clobber (reg:CC FLAGS_REG))]
7160 "TARGET_USE_8BIT_IDIV
7161 && TARGET_QIMODE_MATH
7162 && can_create_pseudo_p ()
7163 && !optimize_insn_for_size_p ()"
7165 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7167 (define_insn_and_split "divmod<mode>4_1"
7168 [(set (match_operand:SWI48 0 "register_operand" "=a")
7169 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7170 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7171 (set (match_operand:SWI48 1 "register_operand" "=&d")
7172 (mod:SWI48 (match_dup 2) (match_dup 3)))
7173 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7174 (clobber (reg:CC FLAGS_REG))]
7178 [(parallel [(set (match_dup 1)
7179 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7180 (clobber (reg:CC FLAGS_REG))])
7181 (parallel [(set (match_dup 0)
7182 (div:SWI48 (match_dup 2) (match_dup 3)))
7184 (mod:SWI48 (match_dup 2) (match_dup 3)))
7186 (clobber (reg:CC FLAGS_REG))])]
7188 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7190 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7191 operands[4] = operands[2];
7194 /* Avoid use of cltd in favor of a mov+shift. */
7195 emit_move_insn (operands[1], operands[2]);
7196 operands[4] = operands[1];
7199 [(set_attr "type" "multi")
7200 (set_attr "mode" "<MODE>")])
7202 (define_insn_and_split "*divmod<mode>4"
7203 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7204 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7205 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7206 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7207 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7208 (clobber (reg:CC FLAGS_REG))]
7212 [(parallel [(set (match_dup 1)
7213 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7214 (clobber (reg:CC FLAGS_REG))])
7215 (parallel [(set (match_dup 0)
7216 (div:SWIM248 (match_dup 2) (match_dup 3)))
7218 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7220 (clobber (reg:CC FLAGS_REG))])]
7222 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7224 if (<MODE>mode != HImode
7225 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7226 operands[4] = operands[2];
7229 /* Avoid use of cltd in favor of a mov+shift. */
7230 emit_move_insn (operands[1], operands[2]);
7231 operands[4] = operands[1];
7234 [(set_attr "type" "multi")
7235 (set_attr "mode" "<MODE>")])
7237 (define_insn "*divmod<mode>4_noext"
7238 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7239 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7240 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7241 (set (match_operand:SWIM248 1 "register_operand" "=d")
7242 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7243 (use (match_operand:SWIM248 4 "register_operand" "1"))
7244 (clobber (reg:CC FLAGS_REG))]
7246 "idiv{<imodesuffix>}\t%3"
7247 [(set_attr "type" "idiv")
7248 (set_attr "mode" "<MODE>")])
7250 (define_expand "divmodqi4"
7251 [(parallel [(set (match_operand:QI 0 "register_operand")
7253 (match_operand:QI 1 "register_operand")
7254 (match_operand:QI 2 "nonimmediate_operand")))
7255 (set (match_operand:QI 3 "register_operand")
7256 (mod:QI (match_dup 1) (match_dup 2)))
7257 (clobber (reg:CC FLAGS_REG))])]
7258 "TARGET_QIMODE_MATH"
7263 tmp0 = gen_reg_rtx (HImode);
7264 tmp1 = gen_reg_rtx (HImode);
7266 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7268 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7269 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7271 /* Extract remainder from AH. */
7272 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7273 insn = emit_move_insn (operands[3], tmp1);
7275 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7276 set_unique_reg_note (insn, REG_EQUAL, mod);
7278 /* Extract quotient from AL. */
7279 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7281 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7282 set_unique_reg_note (insn, REG_EQUAL, div);
7287 ;; Divide AX by r/m8, with result stored in
7290 ;; Change div/mod to HImode and extend the second argument to HImode
7291 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7292 ;; combine may fail.
7293 (define_insn "divmodhiqi3"
7294 [(set (match_operand:HI 0 "register_operand" "=a")
7299 (mod:HI (match_operand:HI 1 "register_operand" "0")
7301 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7305 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7306 (clobber (reg:CC FLAGS_REG))]
7307 "TARGET_QIMODE_MATH"
7309 [(set_attr "type" "idiv")
7310 (set_attr "mode" "QI")])
7312 (define_expand "udivmod<mode>4"
7313 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7315 (match_operand:SWIM248 1 "register_operand")
7316 (match_operand:SWIM248 2 "nonimmediate_operand")))
7317 (set (match_operand:SWIM248 3 "register_operand")
7318 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7319 (clobber (reg:CC FLAGS_REG))])])
7321 ;; Split with 8bit unsigned divide:
7322 ;; if (dividend an divisor are in [0-255])
7323 ;; use 8bit unsigned integer divide
7325 ;; use original integer divide
7327 [(set (match_operand:SWI48 0 "register_operand")
7328 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7329 (match_operand:SWI48 3 "nonimmediate_operand")))
7330 (set (match_operand:SWI48 1 "register_operand")
7331 (umod:SWI48 (match_dup 2) (match_dup 3)))
7332 (clobber (reg:CC FLAGS_REG))]
7333 "TARGET_USE_8BIT_IDIV
7334 && TARGET_QIMODE_MATH
7335 && can_create_pseudo_p ()
7336 && !optimize_insn_for_size_p ()"
7338 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7340 (define_insn_and_split "udivmod<mode>4_1"
7341 [(set (match_operand:SWI48 0 "register_operand" "=a")
7342 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7343 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7344 (set (match_operand:SWI48 1 "register_operand" "=&d")
7345 (umod:SWI48 (match_dup 2) (match_dup 3)))
7346 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7347 (clobber (reg:CC FLAGS_REG))]
7351 [(set (match_dup 1) (const_int 0))
7352 (parallel [(set (match_dup 0)
7353 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7355 (umod:SWI48 (match_dup 2) (match_dup 3)))
7357 (clobber (reg:CC FLAGS_REG))])]
7359 [(set_attr "type" "multi")
7360 (set_attr "mode" "<MODE>")])
7362 (define_insn_and_split "*udivmod<mode>4"
7363 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7364 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7365 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7366 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7367 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7368 (clobber (reg:CC FLAGS_REG))]
7372 [(set (match_dup 1) (const_int 0))
7373 (parallel [(set (match_dup 0)
7374 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7376 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7378 (clobber (reg:CC FLAGS_REG))])]
7380 [(set_attr "type" "multi")
7381 (set_attr "mode" "<MODE>")])
7383 (define_insn "*udivmod<mode>4_noext"
7384 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7385 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7386 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7387 (set (match_operand:SWIM248 1 "register_operand" "=d")
7388 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7389 (use (match_operand:SWIM248 4 "register_operand" "1"))
7390 (clobber (reg:CC FLAGS_REG))]
7392 "div{<imodesuffix>}\t%3"
7393 [(set_attr "type" "idiv")
7394 (set_attr "mode" "<MODE>")])
7396 (define_expand "udivmodqi4"
7397 [(parallel [(set (match_operand:QI 0 "register_operand")
7399 (match_operand:QI 1 "register_operand")
7400 (match_operand:QI 2 "nonimmediate_operand")))
7401 (set (match_operand:QI 3 "register_operand")
7402 (umod:QI (match_dup 1) (match_dup 2)))
7403 (clobber (reg:CC FLAGS_REG))])]
7404 "TARGET_QIMODE_MATH"
7409 tmp0 = gen_reg_rtx (HImode);
7410 tmp1 = gen_reg_rtx (HImode);
7412 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7414 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7415 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7417 /* Extract remainder from AH. */
7418 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7419 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7420 insn = emit_move_insn (operands[3], tmp1);
7422 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7423 set_unique_reg_note (insn, REG_EQUAL, mod);
7425 /* Extract quotient from AL. */
7426 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7428 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7429 set_unique_reg_note (insn, REG_EQUAL, div);
7434 (define_insn "udivmodhiqi3"
7435 [(set (match_operand:HI 0 "register_operand" "=a")
7440 (mod:HI (match_operand:HI 1 "register_operand" "0")
7442 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7446 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7447 (clobber (reg:CC FLAGS_REG))]
7448 "TARGET_QIMODE_MATH"
7450 [(set_attr "type" "idiv")
7451 (set_attr "mode" "QI")])
7453 ;; We cannot use div/idiv for double division, because it causes
7454 ;; "division by zero" on the overflow and that's not what we expect
7455 ;; from truncate. Because true (non truncating) double division is
7456 ;; never generated, we can't create this insn anyway.
7459 ; [(set (match_operand:SI 0 "register_operand" "=a")
7461 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7463 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7464 ; (set (match_operand:SI 3 "register_operand" "=d")
7466 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7467 ; (clobber (reg:CC FLAGS_REG))]
7469 ; "div{l}\t{%2, %0|%0, %2}"
7470 ; [(set_attr "type" "idiv")])
7472 ;;- Logical AND instructions
7474 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7475 ;; Note that this excludes ah.
7477 (define_expand "testsi_ccno_1"
7478 [(set (reg:CCNO FLAGS_REG)
7480 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7481 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7484 (define_expand "testqi_ccz_1"
7485 [(set (reg:CCZ FLAGS_REG)
7486 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7487 (match_operand:QI 1 "nonmemory_operand"))
7490 (define_expand "testdi_ccno_1"
7491 [(set (reg:CCNO FLAGS_REG)
7493 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7494 (match_operand:DI 1 "x86_64_szext_general_operand"))
7496 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7498 (define_insn "*testdi_1"
7499 [(set (reg FLAGS_REG)
7502 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7503 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7505 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7506 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7508 test{l}\t{%k1, %k0|%k0, %k1}
7509 test{l}\t{%k1, %k0|%k0, %k1}
7510 test{q}\t{%1, %0|%0, %1}
7511 test{q}\t{%1, %0|%0, %1}
7512 test{q}\t{%1, %0|%0, %1}"
7513 [(set_attr "type" "test")
7514 (set_attr "modrm" "0,1,0,1,1")
7515 (set_attr "mode" "SI,SI,DI,DI,DI")])
7517 (define_insn "*testqi_1_maybe_si"
7518 [(set (reg FLAGS_REG)
7521 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7522 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7524 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7525 && ix86_match_ccmode (insn,
7526 CONST_INT_P (operands[1])
7527 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7529 if (which_alternative == 3)
7531 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7532 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7533 return "test{l}\t{%1, %k0|%k0, %1}";
7535 return "test{b}\t{%1, %0|%0, %1}";
7537 [(set_attr "type" "test")
7538 (set_attr "modrm" "0,1,1,1")
7539 (set_attr "mode" "QI,QI,QI,SI")
7540 (set_attr "pent_pair" "uv,np,uv,np")])
7542 (define_insn "*test<mode>_1"
7543 [(set (reg FLAGS_REG)
7546 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7547 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7549 "ix86_match_ccmode (insn, CCNOmode)
7550 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7551 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7552 [(set_attr "type" "test")
7553 (set_attr "modrm" "0,1,1")
7554 (set_attr "mode" "<MODE>")
7555 (set_attr "pent_pair" "uv,np,uv")])
7557 (define_expand "testqi_ext_ccno_0"
7558 [(set (reg:CCNO FLAGS_REG)
7562 (match_operand 0 "ext_register_operand")
7565 (match_operand 1 "const_int_operand"))
7568 (define_insn "*testqi_ext_0"
7569 [(set (reg FLAGS_REG)
7573 (match_operand 0 "ext_register_operand" "Q")
7576 (match_operand 1 "const_int_operand" "n"))
7578 "ix86_match_ccmode (insn, CCNOmode)"
7579 "test{b}\t{%1, %h0|%h0, %1}"
7580 [(set_attr "type" "test")
7581 (set_attr "mode" "QI")
7582 (set_attr "length_immediate" "1")
7583 (set_attr "modrm" "1")
7584 (set_attr "pent_pair" "np")])
7586 (define_insn "*testqi_ext_1_rex64"
7587 [(set (reg FLAGS_REG)
7591 (match_operand 0 "ext_register_operand" "Q")
7595 (match_operand:QI 1 "register_operand" "Q")))
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_1"
7603 [(set (reg FLAGS_REG)
7607 (match_operand 0 "ext_register_operand" "Q")
7611 (match_operand:QI 1 "general_operand" "Qm")))
7613 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7614 "test{b}\t{%1, %h0|%h0, %1}"
7615 [(set_attr "type" "test")
7616 (set_attr "mode" "QI")])
7618 (define_insn "*testqi_ext_2"
7619 [(set (reg FLAGS_REG)
7623 (match_operand 0 "ext_register_operand" "Q")
7627 (match_operand 1 "ext_register_operand" "Q")
7631 "ix86_match_ccmode (insn, CCNOmode)"
7632 "test{b}\t{%h1, %h0|%h0, %h1}"
7633 [(set_attr "type" "test")
7634 (set_attr "mode" "QI")])
7636 (define_insn "*testqi_ext_3_rex64"
7637 [(set (reg FLAGS_REG)
7638 (compare (zero_extract:DI
7639 (match_operand 0 "nonimmediate_operand" "rm")
7640 (match_operand:DI 1 "const_int_operand")
7641 (match_operand:DI 2 "const_int_operand"))
7644 && ix86_match_ccmode (insn, CCNOmode)
7645 && INTVAL (operands[1]) > 0
7646 && INTVAL (operands[2]) >= 0
7647 /* Ensure that resulting mask is zero or sign extended operand. */
7648 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7649 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7650 && INTVAL (operands[1]) > 32))
7651 && (GET_MODE (operands[0]) == SImode
7652 || GET_MODE (operands[0]) == DImode
7653 || GET_MODE (operands[0]) == HImode
7654 || GET_MODE (operands[0]) == QImode)"
7657 ;; Combine likes to form bit extractions for some tests. Humor it.
7658 (define_insn "*testqi_ext_3"
7659 [(set (reg FLAGS_REG)
7660 (compare (zero_extract:SI
7661 (match_operand 0 "nonimmediate_operand" "rm")
7662 (match_operand:SI 1 "const_int_operand")
7663 (match_operand:SI 2 "const_int_operand"))
7665 "ix86_match_ccmode (insn, CCNOmode)
7666 && INTVAL (operands[1]) > 0
7667 && INTVAL (operands[2]) >= 0
7668 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7669 && (GET_MODE (operands[0]) == SImode
7670 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7671 || GET_MODE (operands[0]) == HImode
7672 || GET_MODE (operands[0]) == QImode)"
7676 [(set (match_operand 0 "flags_reg_operand")
7677 (match_operator 1 "compare_operator"
7679 (match_operand 2 "nonimmediate_operand")
7680 (match_operand 3 "const_int_operand")
7681 (match_operand 4 "const_int_operand"))
7683 "ix86_match_ccmode (insn, CCNOmode)"
7684 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7686 rtx val = operands[2];
7687 HOST_WIDE_INT len = INTVAL (operands[3]);
7688 HOST_WIDE_INT pos = INTVAL (operands[4]);
7690 enum machine_mode mode, submode;
7692 mode = GET_MODE (val);
7695 /* ??? Combine likes to put non-volatile mem extractions in QImode
7696 no matter the size of the test. So find a mode that works. */
7697 if (! MEM_VOLATILE_P (val))
7699 mode = smallest_mode_for_size (pos + len, MODE_INT);
7700 val = adjust_address (val, mode, 0);
7703 else if (GET_CODE (val) == SUBREG
7704 && (submode = GET_MODE (SUBREG_REG (val)),
7705 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7706 && pos + len <= GET_MODE_BITSIZE (submode)
7707 && GET_MODE_CLASS (submode) == MODE_INT)
7709 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7711 val = SUBREG_REG (val);
7713 else if (mode == HImode && pos + len <= 8)
7715 /* Small HImode tests can be converted to QImode. */
7717 val = gen_lowpart (QImode, val);
7720 if (len == HOST_BITS_PER_WIDE_INT)
7723 mask = ((HOST_WIDE_INT)1 << len) - 1;
7726 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7729 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7730 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7731 ;; this is relatively important trick.
7732 ;; Do the conversion only post-reload to avoid limiting of the register class
7735 [(set (match_operand 0 "flags_reg_operand")
7736 (match_operator 1 "compare_operator"
7737 [(and (match_operand 2 "register_operand")
7738 (match_operand 3 "const_int_operand"))
7741 && QI_REG_P (operands[2])
7742 && GET_MODE (operands[2]) != QImode
7743 && ((ix86_match_ccmode (insn, CCZmode)
7744 && !(INTVAL (operands[3]) & ~(255 << 8)))
7745 || (ix86_match_ccmode (insn, CCNOmode)
7746 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7749 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7753 operands[2] = gen_lowpart (SImode, operands[2]);
7754 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7758 [(set (match_operand 0 "flags_reg_operand")
7759 (match_operator 1 "compare_operator"
7760 [(and (match_operand 2 "nonimmediate_operand")
7761 (match_operand 3 "const_int_operand"))
7764 && GET_MODE (operands[2]) != QImode
7765 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7766 && ((ix86_match_ccmode (insn, CCZmode)
7767 && !(INTVAL (operands[3]) & ~255))
7768 || (ix86_match_ccmode (insn, CCNOmode)
7769 && !(INTVAL (operands[3]) & ~127)))"
7771 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7774 operands[2] = gen_lowpart (QImode, operands[2]);
7775 operands[3] = gen_lowpart (QImode, operands[3]);
7778 ;; %%% This used to optimize known byte-wide and operations to memory,
7779 ;; and sometimes to QImode registers. If this is considered useful,
7780 ;; it should be done with splitters.
7782 (define_expand "and<mode>3"
7783 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7784 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7785 (match_operand:SWIM 2 "<general_szext_operand>")))]
7788 enum machine_mode mode = <MODE>mode;
7789 rtx (*insn) (rtx, rtx);
7791 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7793 HOST_WIDE_INT ival = INTVAL (operands[2]);
7795 if (ival == (HOST_WIDE_INT) 0xffffffff)
7797 else if (ival == 0xffff)
7799 else if (ival == 0xff)
7803 if (mode == <MODE>mode)
7805 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7809 if (<MODE>mode == DImode)
7810 insn = (mode == SImode)
7811 ? gen_zero_extendsidi2
7813 ? gen_zero_extendhidi2
7814 : gen_zero_extendqidi2;
7815 else if (<MODE>mode == SImode)
7816 insn = (mode == HImode)
7817 ? gen_zero_extendhisi2
7818 : gen_zero_extendqisi2;
7819 else if (<MODE>mode == HImode)
7820 insn = gen_zero_extendqihi2;
7824 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7828 (define_insn "*anddi_1"
7829 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7831 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7832 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7833 (clobber (reg:CC FLAGS_REG))]
7834 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7836 switch (get_attr_type (insn))
7842 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7843 if (get_attr_mode (insn) == MODE_SI)
7844 return "and{l}\t{%k2, %k0|%k0, %k2}";
7846 return "and{q}\t{%2, %0|%0, %2}";
7849 [(set_attr "type" "alu,alu,alu,imovx")
7850 (set_attr "length_immediate" "*,*,*,0")
7851 (set (attr "prefix_rex")
7853 (and (eq_attr "type" "imovx")
7854 (and (match_test "INTVAL (operands[2]) == 0xff")
7855 (match_operand 1 "ext_QIreg_operand")))
7857 (const_string "*")))
7858 (set_attr "mode" "SI,DI,DI,SI")])
7860 (define_insn "*andsi_1"
7861 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7862 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7863 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7864 (clobber (reg:CC FLAGS_REG))]
7865 "ix86_binary_operator_ok (AND, SImode, operands)"
7867 switch (get_attr_type (insn))
7873 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7874 return "and{l}\t{%2, %0|%0, %2}";
7877 [(set_attr "type" "alu,alu,imovx")
7878 (set (attr "prefix_rex")
7880 (and (eq_attr "type" "imovx")
7881 (and (match_test "INTVAL (operands[2]) == 0xff")
7882 (match_operand 1 "ext_QIreg_operand")))
7884 (const_string "*")))
7885 (set_attr "length_immediate" "*,*,0")
7886 (set_attr "mode" "SI")])
7888 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7889 (define_insn "*andsi_1_zext"
7890 [(set (match_operand:DI 0 "register_operand" "=r")
7892 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7893 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7894 (clobber (reg:CC FLAGS_REG))]
7895 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7896 "and{l}\t{%2, %k0|%k0, %2}"
7897 [(set_attr "type" "alu")
7898 (set_attr "mode" "SI")])
7900 (define_insn "*andhi_1"
7901 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7902 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7903 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7904 (clobber (reg:CC FLAGS_REG))]
7905 "ix86_binary_operator_ok (AND, HImode, operands)"
7907 switch (get_attr_type (insn))
7913 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7914 return "and{w}\t{%2, %0|%0, %2}";
7917 [(set_attr "type" "alu,alu,imovx")
7918 (set_attr "length_immediate" "*,*,0")
7919 (set (attr "prefix_rex")
7921 (and (eq_attr "type" "imovx")
7922 (match_operand 1 "ext_QIreg_operand"))
7924 (const_string "*")))
7925 (set_attr "mode" "HI,HI,SI")])
7927 ;; %%% Potential partial reg stall on alternative 2. What to do?
7928 (define_insn "*andqi_1"
7929 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7930 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7931 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7932 (clobber (reg:CC FLAGS_REG))]
7933 "ix86_binary_operator_ok (AND, QImode, operands)"
7935 and{b}\t{%2, %0|%0, %2}
7936 and{b}\t{%2, %0|%0, %2}
7937 and{l}\t{%k2, %k0|%k0, %k2}"
7938 [(set_attr "type" "alu")
7939 (set_attr "mode" "QI,QI,SI")])
7941 (define_insn "*andqi_1_slp"
7942 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7943 (and:QI (match_dup 0)
7944 (match_operand:QI 1 "general_operand" "qn,qmn")))
7945 (clobber (reg:CC FLAGS_REG))]
7946 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7947 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7948 "and{b}\t{%1, %0|%0, %1}"
7949 [(set_attr "type" "alu1")
7950 (set_attr "mode" "QI")])
7952 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7954 [(set (match_operand:DI 0 "register_operand")
7955 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7956 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7957 (clobber (reg:CC FLAGS_REG))]
7959 [(parallel [(set (match_dup 0)
7960 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7961 (clobber (reg:CC FLAGS_REG))])]
7962 "operands[2] = gen_lowpart (SImode, operands[2]);")
7965 [(set (match_operand:SWI248 0 "register_operand")
7966 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7967 (match_operand:SWI248 2 "const_int_operand")))
7968 (clobber (reg:CC FLAGS_REG))]
7970 && true_regnum (operands[0]) != true_regnum (operands[1])"
7973 HOST_WIDE_INT ival = INTVAL (operands[2]);
7974 enum machine_mode mode;
7975 rtx (*insn) (rtx, rtx);
7977 if (ival == (HOST_WIDE_INT) 0xffffffff)
7979 else if (ival == 0xffff)
7983 gcc_assert (ival == 0xff);
7987 if (<MODE>mode == DImode)
7988 insn = (mode == SImode)
7989 ? gen_zero_extendsidi2
7991 ? gen_zero_extendhidi2
7992 : gen_zero_extendqidi2;
7995 if (<MODE>mode != SImode)
7996 /* Zero extend to SImode to avoid partial register stalls. */
7997 operands[0] = gen_lowpart (SImode, operands[0]);
7999 insn = (mode == HImode)
8000 ? gen_zero_extendhisi2
8001 : gen_zero_extendqisi2;
8003 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8008 [(set (match_operand 0 "register_operand")
8010 (const_int -65536)))
8011 (clobber (reg:CC FLAGS_REG))]
8012 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8013 || optimize_function_for_size_p (cfun)"
8014 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8015 "operands[1] = gen_lowpart (HImode, operands[0]);")
8018 [(set (match_operand 0 "ext_register_operand")
8021 (clobber (reg:CC FLAGS_REG))]
8022 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8023 && reload_completed"
8024 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8025 "operands[1] = gen_lowpart (QImode, operands[0]);")
8028 [(set (match_operand 0 "ext_register_operand")
8030 (const_int -65281)))
8031 (clobber (reg:CC FLAGS_REG))]
8032 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8033 && reload_completed"
8034 [(parallel [(set (zero_extract:SI (match_dup 0)
8038 (zero_extract:SI (match_dup 0)
8041 (zero_extract:SI (match_dup 0)
8044 (clobber (reg:CC FLAGS_REG))])]
8045 "operands[0] = gen_lowpart (SImode, operands[0]);")
8047 (define_insn "*anddi_2"
8048 [(set (reg FLAGS_REG)
8051 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8052 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8054 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8055 (and:DI (match_dup 1) (match_dup 2)))]
8056 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8057 && ix86_binary_operator_ok (AND, DImode, operands)"
8059 and{l}\t{%k2, %k0|%k0, %k2}
8060 and{q}\t{%2, %0|%0, %2}
8061 and{q}\t{%2, %0|%0, %2}"
8062 [(set_attr "type" "alu")
8063 (set_attr "mode" "SI,DI,DI")])
8065 (define_insn "*andqi_2_maybe_si"
8066 [(set (reg FLAGS_REG)
8068 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8069 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8071 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8072 (and:QI (match_dup 1) (match_dup 2)))]
8073 "ix86_binary_operator_ok (AND, QImode, operands)
8074 && ix86_match_ccmode (insn,
8075 CONST_INT_P (operands[2])
8076 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8078 if (which_alternative == 2)
8080 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8081 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8082 return "and{l}\t{%2, %k0|%k0, %2}";
8084 return "and{b}\t{%2, %0|%0, %2}";
8086 [(set_attr "type" "alu")
8087 (set_attr "mode" "QI,QI,SI")])
8089 (define_insn "*and<mode>_2"
8090 [(set (reg FLAGS_REG)
8091 (compare (and:SWI124
8092 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8093 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8095 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8096 (and:SWI124 (match_dup 1) (match_dup 2)))]
8097 "ix86_match_ccmode (insn, CCNOmode)
8098 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8099 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8100 [(set_attr "type" "alu")
8101 (set_attr "mode" "<MODE>")])
8103 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8104 (define_insn "*andsi_2_zext"
8105 [(set (reg FLAGS_REG)
8107 (match_operand:SI 1 "nonimmediate_operand" "%0")
8108 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8110 (set (match_operand:DI 0 "register_operand" "=r")
8111 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8112 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8113 && ix86_binary_operator_ok (AND, SImode, operands)"
8114 "and{l}\t{%2, %k0|%k0, %2}"
8115 [(set_attr "type" "alu")
8116 (set_attr "mode" "SI")])
8118 (define_insn "*andqi_2_slp"
8119 [(set (reg FLAGS_REG)
8121 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8122 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8124 (set (strict_low_part (match_dup 0))
8125 (and:QI (match_dup 0) (match_dup 1)))]
8126 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8127 && ix86_match_ccmode (insn, CCNOmode)
8128 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8129 "and{b}\t{%1, %0|%0, %1}"
8130 [(set_attr "type" "alu1")
8131 (set_attr "mode" "QI")])
8133 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8134 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8135 ;; for a QImode operand, which of course failed.
8136 (define_insn "andqi_ext_0"
8137 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8142 (match_operand 1 "ext_register_operand" "0")
8145 (match_operand 2 "const_int_operand" "n")))
8146 (clobber (reg:CC FLAGS_REG))]
8148 "and{b}\t{%2, %h0|%h0, %2}"
8149 [(set_attr "type" "alu")
8150 (set_attr "length_immediate" "1")
8151 (set_attr "modrm" "1")
8152 (set_attr "mode" "QI")])
8154 ;; Generated by peephole translating test to and. This shows up
8155 ;; often in fp comparisons.
8156 (define_insn "*andqi_ext_0_cc"
8157 [(set (reg FLAGS_REG)
8161 (match_operand 1 "ext_register_operand" "0")
8164 (match_operand 2 "const_int_operand" "n"))
8166 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8175 "ix86_match_ccmode (insn, CCNOmode)"
8176 "and{b}\t{%2, %h0|%h0, %2}"
8177 [(set_attr "type" "alu")
8178 (set_attr "length_immediate" "1")
8179 (set_attr "modrm" "1")
8180 (set_attr "mode" "QI")])
8182 (define_insn "*andqi_ext_1_rex64"
8183 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8188 (match_operand 1 "ext_register_operand" "0")
8192 (match_operand 2 "ext_register_operand" "Q"))))
8193 (clobber (reg:CC FLAGS_REG))]
8195 "and{b}\t{%2, %h0|%h0, %2}"
8196 [(set_attr "type" "alu")
8197 (set_attr "length_immediate" "0")
8198 (set_attr "mode" "QI")])
8200 (define_insn "*andqi_ext_1"
8201 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8206 (match_operand 1 "ext_register_operand" "0")
8210 (match_operand:QI 2 "general_operand" "Qm"))))
8211 (clobber (reg:CC FLAGS_REG))]
8213 "and{b}\t{%2, %h0|%h0, %2}"
8214 [(set_attr "type" "alu")
8215 (set_attr "length_immediate" "0")
8216 (set_attr "mode" "QI")])
8218 (define_insn "*andqi_ext_2"
8219 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8224 (match_operand 1 "ext_register_operand" "%0")
8228 (match_operand 2 "ext_register_operand" "Q")
8231 (clobber (reg:CC FLAGS_REG))]
8233 "and{b}\t{%h2, %h0|%h0, %h2}"
8234 [(set_attr "type" "alu")
8235 (set_attr "length_immediate" "0")
8236 (set_attr "mode" "QI")])
8238 ;; Convert wide AND instructions with immediate operand to shorter QImode
8239 ;; equivalents when possible.
8240 ;; Don't do the splitting with memory operands, since it introduces risk
8241 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8242 ;; for size, but that can (should?) be handled by generic code instead.
8244 [(set (match_operand 0 "register_operand")
8245 (and (match_operand 1 "register_operand")
8246 (match_operand 2 "const_int_operand")))
8247 (clobber (reg:CC FLAGS_REG))]
8249 && QI_REG_P (operands[0])
8250 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8251 && !(~INTVAL (operands[2]) & ~(255 << 8))
8252 && GET_MODE (operands[0]) != QImode"
8253 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8254 (and:SI (zero_extract:SI (match_dup 1)
8255 (const_int 8) (const_int 8))
8257 (clobber (reg:CC FLAGS_REG))])]
8259 operands[0] = gen_lowpart (SImode, operands[0]);
8260 operands[1] = gen_lowpart (SImode, operands[1]);
8261 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8264 ;; Since AND can be encoded with sign extended immediate, this is only
8265 ;; profitable when 7th bit is not set.
8267 [(set (match_operand 0 "register_operand")
8268 (and (match_operand 1 "general_operand")
8269 (match_operand 2 "const_int_operand")))
8270 (clobber (reg:CC FLAGS_REG))]
8272 && ANY_QI_REG_P (operands[0])
8273 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8274 && !(~INTVAL (operands[2]) & ~255)
8275 && !(INTVAL (operands[2]) & 128)
8276 && GET_MODE (operands[0]) != QImode"
8277 [(parallel [(set (strict_low_part (match_dup 0))
8278 (and:QI (match_dup 1)
8280 (clobber (reg:CC FLAGS_REG))])]
8282 operands[0] = gen_lowpart (QImode, operands[0]);
8283 operands[1] = gen_lowpart (QImode, operands[1]);
8284 operands[2] = gen_lowpart (QImode, operands[2]);
8287 ;; Logical inclusive and exclusive OR instructions
8289 ;; %%% This used to optimize known byte-wide and operations to memory.
8290 ;; If this is considered useful, it should be done with splitters.
8292 (define_expand "<code><mode>3"
8293 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8294 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8295 (match_operand:SWIM 2 "<general_operand>")))]
8297 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8299 (define_insn "*<code><mode>_1"
8300 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8302 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8303 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8304 (clobber (reg:CC FLAGS_REG))]
8305 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8306 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8307 [(set_attr "type" "alu")
8308 (set_attr "mode" "<MODE>")])
8310 ;; %%% Potential partial reg stall on alternative 2. What to do?
8311 (define_insn "*<code>qi_1"
8312 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8313 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8314 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8315 (clobber (reg:CC FLAGS_REG))]
8316 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8318 <logic>{b}\t{%2, %0|%0, %2}
8319 <logic>{b}\t{%2, %0|%0, %2}
8320 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8321 [(set_attr "type" "alu")
8322 (set_attr "mode" "QI,QI,SI")])
8324 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8325 (define_insn "*<code>si_1_zext"
8326 [(set (match_operand:DI 0 "register_operand" "=r")
8328 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8329 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8330 (clobber (reg:CC FLAGS_REG))]
8331 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8332 "<logic>{l}\t{%2, %k0|%k0, %2}"
8333 [(set_attr "type" "alu")
8334 (set_attr "mode" "SI")])
8336 (define_insn "*<code>si_1_zext_imm"
8337 [(set (match_operand:DI 0 "register_operand" "=r")
8339 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8340 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8341 (clobber (reg:CC FLAGS_REG))]
8342 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8343 "<logic>{l}\t{%2, %k0|%k0, %2}"
8344 [(set_attr "type" "alu")
8345 (set_attr "mode" "SI")])
8347 (define_insn "*<code>qi_1_slp"
8348 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8349 (any_or:QI (match_dup 0)
8350 (match_operand:QI 1 "general_operand" "qmn,qn")))
8351 (clobber (reg:CC FLAGS_REG))]
8352 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8353 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8354 "<logic>{b}\t{%1, %0|%0, %1}"
8355 [(set_attr "type" "alu1")
8356 (set_attr "mode" "QI")])
8358 (define_insn "*<code><mode>_2"
8359 [(set (reg FLAGS_REG)
8360 (compare (any_or:SWI
8361 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8362 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8364 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8365 (any_or:SWI (match_dup 1) (match_dup 2)))]
8366 "ix86_match_ccmode (insn, CCNOmode)
8367 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8368 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8369 [(set_attr "type" "alu")
8370 (set_attr "mode" "<MODE>")])
8372 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8373 ;; ??? Special case for immediate operand is missing - it is tricky.
8374 (define_insn "*<code>si_2_zext"
8375 [(set (reg FLAGS_REG)
8376 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8377 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8379 (set (match_operand:DI 0 "register_operand" "=r")
8380 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8381 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8382 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8383 "<logic>{l}\t{%2, %k0|%k0, %2}"
8384 [(set_attr "type" "alu")
8385 (set_attr "mode" "SI")])
8387 (define_insn "*<code>si_2_zext_imm"
8388 [(set (reg FLAGS_REG)
8390 (match_operand:SI 1 "nonimmediate_operand" "%0")
8391 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8393 (set (match_operand:DI 0 "register_operand" "=r")
8394 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8395 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8396 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8397 "<logic>{l}\t{%2, %k0|%k0, %2}"
8398 [(set_attr "type" "alu")
8399 (set_attr "mode" "SI")])
8401 (define_insn "*<code>qi_2_slp"
8402 [(set (reg FLAGS_REG)
8403 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8404 (match_operand:QI 1 "general_operand" "qmn,qn"))
8406 (set (strict_low_part (match_dup 0))
8407 (any_or:QI (match_dup 0) (match_dup 1)))]
8408 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8409 && ix86_match_ccmode (insn, CCNOmode)
8410 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8411 "<logic>{b}\t{%1, %0|%0, %1}"
8412 [(set_attr "type" "alu1")
8413 (set_attr "mode" "QI")])
8415 (define_insn "*<code><mode>_3"
8416 [(set (reg FLAGS_REG)
8417 (compare (any_or:SWI
8418 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8419 (match_operand:SWI 2 "<general_operand>" "<g>"))
8421 (clobber (match_scratch:SWI 0 "=<r>"))]
8422 "ix86_match_ccmode (insn, CCNOmode)
8423 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8424 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8425 [(set_attr "type" "alu")
8426 (set_attr "mode" "<MODE>")])
8428 (define_insn "*<code>qi_ext_0"
8429 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8434 (match_operand 1 "ext_register_operand" "0")
8437 (match_operand 2 "const_int_operand" "n")))
8438 (clobber (reg:CC FLAGS_REG))]
8439 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8440 "<logic>{b}\t{%2, %h0|%h0, %2}"
8441 [(set_attr "type" "alu")
8442 (set_attr "length_immediate" "1")
8443 (set_attr "modrm" "1")
8444 (set_attr "mode" "QI")])
8446 (define_insn "*<code>qi_ext_1_rex64"
8447 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8452 (match_operand 1 "ext_register_operand" "0")
8456 (match_operand 2 "ext_register_operand" "Q"))))
8457 (clobber (reg:CC FLAGS_REG))]
8459 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8460 "<logic>{b}\t{%2, %h0|%h0, %2}"
8461 [(set_attr "type" "alu")
8462 (set_attr "length_immediate" "0")
8463 (set_attr "mode" "QI")])
8465 (define_insn "*<code>qi_ext_1"
8466 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8471 (match_operand 1 "ext_register_operand" "0")
8475 (match_operand:QI 2 "general_operand" "Qm"))))
8476 (clobber (reg:CC FLAGS_REG))]
8478 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8479 "<logic>{b}\t{%2, %h0|%h0, %2}"
8480 [(set_attr "type" "alu")
8481 (set_attr "length_immediate" "0")
8482 (set_attr "mode" "QI")])
8484 (define_insn "*<code>qi_ext_2"
8485 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8489 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8492 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8495 (clobber (reg:CC FLAGS_REG))]
8496 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8497 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8498 [(set_attr "type" "alu")
8499 (set_attr "length_immediate" "0")
8500 (set_attr "mode" "QI")])
8503 [(set (match_operand 0 "register_operand")
8504 (any_or (match_operand 1 "register_operand")
8505 (match_operand 2 "const_int_operand")))
8506 (clobber (reg:CC FLAGS_REG))]
8508 && QI_REG_P (operands[0])
8509 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8510 && !(INTVAL (operands[2]) & ~(255 << 8))
8511 && GET_MODE (operands[0]) != QImode"
8512 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8513 (any_or:SI (zero_extract:SI (match_dup 1)
8514 (const_int 8) (const_int 8))
8516 (clobber (reg:CC FLAGS_REG))])]
8518 operands[0] = gen_lowpart (SImode, operands[0]);
8519 operands[1] = gen_lowpart (SImode, operands[1]);
8520 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8523 ;; Since OR can be encoded with sign extended immediate, this is only
8524 ;; profitable when 7th bit is set.
8526 [(set (match_operand 0 "register_operand")
8527 (any_or (match_operand 1 "general_operand")
8528 (match_operand 2 "const_int_operand")))
8529 (clobber (reg:CC FLAGS_REG))]
8531 && ANY_QI_REG_P (operands[0])
8532 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8533 && !(INTVAL (operands[2]) & ~255)
8534 && (INTVAL (operands[2]) & 128)
8535 && GET_MODE (operands[0]) != QImode"
8536 [(parallel [(set (strict_low_part (match_dup 0))
8537 (any_or:QI (match_dup 1)
8539 (clobber (reg:CC FLAGS_REG))])]
8541 operands[0] = gen_lowpart (QImode, operands[0]);
8542 operands[1] = gen_lowpart (QImode, operands[1]);
8543 operands[2] = gen_lowpart (QImode, operands[2]);
8546 (define_expand "xorqi_cc_ext_1"
8548 (set (reg:CCNO FLAGS_REG)
8552 (match_operand 1 "ext_register_operand")
8555 (match_operand:QI 2 "general_operand"))
8557 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8567 (define_insn "*xorqi_cc_ext_1_rex64"
8568 [(set (reg FLAGS_REG)
8572 (match_operand 1 "ext_register_operand" "0")
8575 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8577 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8586 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8587 "xor{b}\t{%2, %h0|%h0, %2}"
8588 [(set_attr "type" "alu")
8589 (set_attr "modrm" "1")
8590 (set_attr "mode" "QI")])
8592 (define_insn "*xorqi_cc_ext_1"
8593 [(set (reg FLAGS_REG)
8597 (match_operand 1 "ext_register_operand" "0")
8600 (match_operand:QI 2 "general_operand" "qmn"))
8602 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8611 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8612 "xor{b}\t{%2, %h0|%h0, %2}"
8613 [(set_attr "type" "alu")
8614 (set_attr "modrm" "1")
8615 (set_attr "mode" "QI")])
8617 ;; Negation instructions
8619 (define_expand "neg<mode>2"
8620 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8621 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8623 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8625 (define_insn_and_split "*neg<dwi>2_doubleword"
8626 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8627 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8628 (clobber (reg:CC FLAGS_REG))]
8629 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8633 [(set (reg:CCZ FLAGS_REG)
8634 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8635 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8638 (plus:DWIH (match_dup 3)
8639 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8641 (clobber (reg:CC FLAGS_REG))])
8644 (neg:DWIH (match_dup 2)))
8645 (clobber (reg:CC FLAGS_REG))])]
8646 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8648 (define_insn "*neg<mode>2_1"
8649 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8650 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8651 (clobber (reg:CC FLAGS_REG))]
8652 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8653 "neg{<imodesuffix>}\t%0"
8654 [(set_attr "type" "negnot")
8655 (set_attr "mode" "<MODE>")])
8657 ;; Combine is quite creative about this pattern.
8658 (define_insn "*negsi2_1_zext"
8659 [(set (match_operand:DI 0 "register_operand" "=r")
8661 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8664 (clobber (reg:CC FLAGS_REG))]
8665 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8667 [(set_attr "type" "negnot")
8668 (set_attr "mode" "SI")])
8670 ;; The problem with neg is that it does not perform (compare x 0),
8671 ;; it really performs (compare 0 x), which leaves us with the zero
8672 ;; flag being the only useful item.
8674 (define_insn "*neg<mode>2_cmpz"
8675 [(set (reg:CCZ FLAGS_REG)
8677 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8679 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8680 (neg:SWI (match_dup 1)))]
8681 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8682 "neg{<imodesuffix>}\t%0"
8683 [(set_attr "type" "negnot")
8684 (set_attr "mode" "<MODE>")])
8686 (define_insn "*negsi2_cmpz_zext"
8687 [(set (reg:CCZ FLAGS_REG)
8691 (match_operand:DI 1 "register_operand" "0")
8695 (set (match_operand:DI 0 "register_operand" "=r")
8696 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8699 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8701 [(set_attr "type" "negnot")
8702 (set_attr "mode" "SI")])
8704 ;; Changing of sign for FP values is doable using integer unit too.
8706 (define_expand "<code><mode>2"
8707 [(set (match_operand:X87MODEF 0 "register_operand")
8708 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8709 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8710 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8712 (define_insn "*absneg<mode>2_mixed"
8713 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8714 (match_operator:MODEF 3 "absneg_operator"
8715 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8716 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8717 (clobber (reg:CC FLAGS_REG))]
8718 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8721 (define_insn "*absneg<mode>2_sse"
8722 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8723 (match_operator:MODEF 3 "absneg_operator"
8724 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8725 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8726 (clobber (reg:CC FLAGS_REG))]
8727 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8730 (define_insn "*absneg<mode>2_i387"
8731 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8732 (match_operator:X87MODEF 3 "absneg_operator"
8733 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8734 (use (match_operand 2))
8735 (clobber (reg:CC FLAGS_REG))]
8736 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8739 (define_expand "<code>tf2"
8740 [(set (match_operand:TF 0 "register_operand")
8741 (absneg:TF (match_operand:TF 1 "register_operand")))]
8743 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8745 (define_insn "*absnegtf2_sse"
8746 [(set (match_operand:TF 0 "register_operand" "=x,x")
8747 (match_operator:TF 3 "absneg_operator"
8748 [(match_operand:TF 1 "register_operand" "0,x")]))
8749 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8750 (clobber (reg:CC FLAGS_REG))]
8754 ;; Splitters for fp abs and neg.
8757 [(set (match_operand 0 "fp_register_operand")
8758 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8759 (use (match_operand 2))
8760 (clobber (reg:CC FLAGS_REG))]
8762 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8765 [(set (match_operand 0 "register_operand")
8766 (match_operator 3 "absneg_operator"
8767 [(match_operand 1 "register_operand")]))
8768 (use (match_operand 2 "nonimmediate_operand"))
8769 (clobber (reg:CC FLAGS_REG))]
8770 "reload_completed && SSE_REG_P (operands[0])"
8771 [(set (match_dup 0) (match_dup 3))]
8773 enum machine_mode mode = GET_MODE (operands[0]);
8774 enum machine_mode vmode = GET_MODE (operands[2]);
8777 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8778 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8779 if (operands_match_p (operands[0], operands[2]))
8782 operands[1] = operands[2];
8785 if (GET_CODE (operands[3]) == ABS)
8786 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8788 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8793 [(set (match_operand:SF 0 "register_operand")
8794 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8795 (use (match_operand:V4SF 2))
8796 (clobber (reg:CC FLAGS_REG))]
8798 [(parallel [(set (match_dup 0) (match_dup 1))
8799 (clobber (reg:CC FLAGS_REG))])]
8802 operands[0] = gen_lowpart (SImode, operands[0]);
8803 if (GET_CODE (operands[1]) == ABS)
8805 tmp = gen_int_mode (0x7fffffff, SImode);
8806 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8810 tmp = gen_int_mode (0x80000000, SImode);
8811 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8817 [(set (match_operand:DF 0 "register_operand")
8818 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8819 (use (match_operand 2))
8820 (clobber (reg:CC FLAGS_REG))]
8822 [(parallel [(set (match_dup 0) (match_dup 1))
8823 (clobber (reg:CC FLAGS_REG))])]
8828 tmp = gen_lowpart (DImode, operands[0]);
8829 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8832 if (GET_CODE (operands[1]) == ABS)
8835 tmp = gen_rtx_NOT (DImode, tmp);
8839 operands[0] = gen_highpart (SImode, operands[0]);
8840 if (GET_CODE (operands[1]) == ABS)
8842 tmp = gen_int_mode (0x7fffffff, SImode);
8843 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8847 tmp = gen_int_mode (0x80000000, SImode);
8848 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8855 [(set (match_operand:XF 0 "register_operand")
8856 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8857 (use (match_operand 2))
8858 (clobber (reg:CC FLAGS_REG))]
8860 [(parallel [(set (match_dup 0) (match_dup 1))
8861 (clobber (reg:CC FLAGS_REG))])]
8864 operands[0] = gen_rtx_REG (SImode,
8865 true_regnum (operands[0])
8866 + (TARGET_64BIT ? 1 : 2));
8867 if (GET_CODE (operands[1]) == ABS)
8869 tmp = GEN_INT (0x7fff);
8870 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8874 tmp = GEN_INT (0x8000);
8875 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8880 ;; Conditionalize these after reload. If they match before reload, we
8881 ;; lose the clobber and ability to use integer instructions.
8883 (define_insn "*<code><mode>2_1"
8884 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8885 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8887 && (reload_completed
8888 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8889 "f<absneg_mnemonic>"
8890 [(set_attr "type" "fsgn")
8891 (set_attr "mode" "<MODE>")])
8893 (define_insn "*<code>extendsfdf2"
8894 [(set (match_operand:DF 0 "register_operand" "=f")
8895 (absneg:DF (float_extend:DF
8896 (match_operand:SF 1 "register_operand" "0"))))]
8897 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8898 "f<absneg_mnemonic>"
8899 [(set_attr "type" "fsgn")
8900 (set_attr "mode" "DF")])
8902 (define_insn "*<code>extendsfxf2"
8903 [(set (match_operand:XF 0 "register_operand" "=f")
8904 (absneg:XF (float_extend:XF
8905 (match_operand:SF 1 "register_operand" "0"))))]
8907 "f<absneg_mnemonic>"
8908 [(set_attr "type" "fsgn")
8909 (set_attr "mode" "XF")])
8911 (define_insn "*<code>extenddfxf2"
8912 [(set (match_operand:XF 0 "register_operand" "=f")
8913 (absneg:XF (float_extend:XF
8914 (match_operand:DF 1 "register_operand" "0"))))]
8916 "f<absneg_mnemonic>"
8917 [(set_attr "type" "fsgn")
8918 (set_attr "mode" "XF")])
8920 ;; Copysign instructions
8922 (define_mode_iterator CSGNMODE [SF DF TF])
8923 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8925 (define_expand "copysign<mode>3"
8926 [(match_operand:CSGNMODE 0 "register_operand")
8927 (match_operand:CSGNMODE 1 "nonmemory_operand")
8928 (match_operand:CSGNMODE 2 "register_operand")]
8929 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8930 || (TARGET_SSE && (<MODE>mode == TFmode))"
8931 "ix86_expand_copysign (operands); DONE;")
8933 (define_insn_and_split "copysign<mode>3_const"
8934 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8936 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8937 (match_operand:CSGNMODE 2 "register_operand" "0")
8938 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8940 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8941 || (TARGET_SSE && (<MODE>mode == TFmode))"
8943 "&& reload_completed"
8945 "ix86_split_copysign_const (operands); DONE;")
8947 (define_insn "copysign<mode>3_var"
8948 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8950 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8951 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8952 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8953 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8955 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8956 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8957 || (TARGET_SSE && (<MODE>mode == TFmode))"
8961 [(set (match_operand:CSGNMODE 0 "register_operand")
8963 [(match_operand:CSGNMODE 2 "register_operand")
8964 (match_operand:CSGNMODE 3 "register_operand")
8965 (match_operand:<CSGNVMODE> 4)
8966 (match_operand:<CSGNVMODE> 5)]
8968 (clobber (match_scratch:<CSGNVMODE> 1))]
8969 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8970 || (TARGET_SSE && (<MODE>mode == TFmode)))
8971 && reload_completed"
8973 "ix86_split_copysign_var (operands); DONE;")
8975 ;; One complement instructions
8977 (define_expand "one_cmpl<mode>2"
8978 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8979 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8981 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8983 (define_insn "*one_cmpl<mode>2_1"
8984 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8985 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8986 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8987 "not{<imodesuffix>}\t%0"
8988 [(set_attr "type" "negnot")
8989 (set_attr "mode" "<MODE>")])
8991 ;; %%% Potential partial reg stall on alternative 1. What to do?
8992 (define_insn "*one_cmplqi2_1"
8993 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8994 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8995 "ix86_unary_operator_ok (NOT, QImode, operands)"
8999 [(set_attr "type" "negnot")
9000 (set_attr "mode" "QI,SI")])
9002 ;; ??? Currently never generated - xor is used instead.
9003 (define_insn "*one_cmplsi2_1_zext"
9004 [(set (match_operand:DI 0 "register_operand" "=r")
9006 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9007 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9009 [(set_attr "type" "negnot")
9010 (set_attr "mode" "SI")])
9012 (define_insn "*one_cmpl<mode>2_2"
9013 [(set (reg FLAGS_REG)
9014 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9016 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9017 (not:SWI (match_dup 1)))]
9018 "ix86_match_ccmode (insn, CCNOmode)
9019 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9021 [(set_attr "type" "alu1")
9022 (set_attr "mode" "<MODE>")])
9025 [(set (match_operand 0 "flags_reg_operand")
9026 (match_operator 2 "compare_operator"
9027 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9029 (set (match_operand:SWI 1 "nonimmediate_operand")
9030 (not:SWI (match_dup 3)))]
9031 "ix86_match_ccmode (insn, CCNOmode)"
9032 [(parallel [(set (match_dup 0)
9033 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9036 (xor:SWI (match_dup 3) (const_int -1)))])])
9038 ;; ??? Currently never generated - xor is used instead.
9039 (define_insn "*one_cmplsi2_2_zext"
9040 [(set (reg FLAGS_REG)
9041 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9043 (set (match_operand:DI 0 "register_operand" "=r")
9044 (zero_extend:DI (not:SI (match_dup 1))))]
9045 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9046 && ix86_unary_operator_ok (NOT, SImode, operands)"
9048 [(set_attr "type" "alu1")
9049 (set_attr "mode" "SI")])
9052 [(set (match_operand 0 "flags_reg_operand")
9053 (match_operator 2 "compare_operator"
9054 [(not:SI (match_operand:SI 3 "register_operand"))
9056 (set (match_operand:DI 1 "register_operand")
9057 (zero_extend:DI (not:SI (match_dup 3))))]
9058 "ix86_match_ccmode (insn, CCNOmode)"
9059 [(parallel [(set (match_dup 0)
9060 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9063 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9065 ;; Shift instructions
9067 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9068 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9069 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9070 ;; from the assembler input.
9072 ;; This instruction shifts the target reg/mem as usual, but instead of
9073 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9074 ;; is a left shift double, bits are taken from the high order bits of
9075 ;; reg, else if the insn is a shift right double, bits are taken from the
9076 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9077 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9079 ;; Since sh[lr]d does not change the `reg' operand, that is done
9080 ;; separately, making all shifts emit pairs of shift double and normal
9081 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9082 ;; support a 63 bit shift, each shift where the count is in a reg expands
9083 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9085 ;; If the shift count is a constant, we need never emit more than one
9086 ;; shift pair, instead using moves and sign extension for counts greater
9089 (define_expand "ashl<mode>3"
9090 [(set (match_operand:SDWIM 0 "<shift_operand>")
9091 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9092 (match_operand:QI 2 "nonmemory_operand")))]
9094 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9096 (define_insn "*ashl<mode>3_doubleword"
9097 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9098 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9099 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9100 (clobber (reg:CC FLAGS_REG))]
9103 [(set_attr "type" "multi")])
9106 [(set (match_operand:DWI 0 "register_operand")
9107 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9108 (match_operand:QI 2 "nonmemory_operand")))
9109 (clobber (reg:CC FLAGS_REG))]
9110 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9112 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9114 ;; By default we don't ask for a scratch register, because when DWImode
9115 ;; values are manipulated, registers are already at a premium. But if
9116 ;; we have one handy, we won't turn it away.
9119 [(match_scratch:DWIH 3 "r")
9120 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9122 (match_operand:<DWI> 1 "nonmemory_operand")
9123 (match_operand:QI 2 "nonmemory_operand")))
9124 (clobber (reg:CC FLAGS_REG))])
9128 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9130 (define_insn "x86_64_shld"
9131 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9132 (ior:DI (ashift:DI (match_dup 0)
9133 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9134 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9135 (minus:QI (const_int 64) (match_dup 2)))))
9136 (clobber (reg:CC FLAGS_REG))]
9138 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9139 [(set_attr "type" "ishift")
9140 (set_attr "prefix_0f" "1")
9141 (set_attr "mode" "DI")
9142 (set_attr "athlon_decode" "vector")
9143 (set_attr "amdfam10_decode" "vector")
9144 (set_attr "bdver1_decode" "vector")])
9146 (define_insn "x86_shld"
9147 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9148 (ior:SI (ashift:SI (match_dup 0)
9149 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9150 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9151 (minus:QI (const_int 32) (match_dup 2)))))
9152 (clobber (reg:CC FLAGS_REG))]
9154 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9155 [(set_attr "type" "ishift")
9156 (set_attr "prefix_0f" "1")
9157 (set_attr "mode" "SI")
9158 (set_attr "pent_pair" "np")
9159 (set_attr "athlon_decode" "vector")
9160 (set_attr "amdfam10_decode" "vector")
9161 (set_attr "bdver1_decode" "vector")])
9163 (define_expand "x86_shift<mode>_adj_1"
9164 [(set (reg:CCZ FLAGS_REG)
9165 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9168 (set (match_operand:SWI48 0 "register_operand")
9169 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9170 (match_operand:SWI48 1 "register_operand")
9173 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9174 (match_operand:SWI48 3 "register_operand")
9177 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9179 (define_expand "x86_shift<mode>_adj_2"
9180 [(use (match_operand:SWI48 0 "register_operand"))
9181 (use (match_operand:SWI48 1 "register_operand"))
9182 (use (match_operand:QI 2 "register_operand"))]
9185 rtx label = gen_label_rtx ();
9188 emit_insn (gen_testqi_ccz_1 (operands[2],
9189 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9191 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9192 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9193 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9194 gen_rtx_LABEL_REF (VOIDmode, label),
9196 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9197 JUMP_LABEL (tmp) = label;
9199 emit_move_insn (operands[0], operands[1]);
9200 ix86_expand_clear (operands[1]);
9203 LABEL_NUSES (label) = 1;
9208 ;; Avoid useless masking of count operand.
9209 (define_insn_and_split "*ashl<mode>3_mask"
9210 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9212 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9215 (match_operand:SI 2 "nonimmediate_operand" "c")
9216 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9217 (clobber (reg:CC FLAGS_REG))]
9218 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9219 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9220 == GET_MODE_BITSIZE (<MODE>mode)-1"
9223 [(parallel [(set (match_dup 0)
9224 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9225 (clobber (reg:CC FLAGS_REG))])]
9227 if (can_create_pseudo_p ())
9228 operands [2] = force_reg (SImode, operands[2]);
9230 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9232 [(set_attr "type" "ishift")
9233 (set_attr "mode" "<MODE>")])
9235 (define_insn "*bmi2_ashl<mode>3_1"
9236 [(set (match_operand:SWI48 0 "register_operand" "=r")
9237 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9238 (match_operand:SWI48 2 "register_operand" "r")))]
9240 "shlx\t{%2, %1, %0|%0, %1, %2}"
9241 [(set_attr "type" "ishiftx")
9242 (set_attr "mode" "<MODE>")])
9244 (define_insn "*ashl<mode>3_1"
9245 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9246 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9247 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9248 (clobber (reg:CC FLAGS_REG))]
9249 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9251 switch (get_attr_type (insn))
9258 gcc_assert (operands[2] == const1_rtx);
9259 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9260 return "add{<imodesuffix>}\t%0, %0";
9263 if (operands[2] == const1_rtx
9264 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9265 return "sal{<imodesuffix>}\t%0";
9267 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9270 [(set_attr "isa" "*,*,bmi2")
9272 (cond [(eq_attr "alternative" "1")
9273 (const_string "lea")
9274 (eq_attr "alternative" "2")
9275 (const_string "ishiftx")
9276 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9277 (match_operand 0 "register_operand"))
9278 (match_operand 2 "const1_operand"))
9279 (const_string "alu")
9281 (const_string "ishift")))
9282 (set (attr "length_immediate")
9284 (ior (eq_attr "type" "alu")
9285 (and (eq_attr "type" "ishift")
9286 (and (match_operand 2 "const1_operand")
9287 (ior (match_test "TARGET_SHIFT1")
9288 (match_test "optimize_function_for_size_p (cfun)")))))
9290 (const_string "*")))
9291 (set_attr "mode" "<MODE>")])
9293 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9295 [(set (match_operand:SWI48 0 "register_operand")
9296 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9297 (match_operand:QI 2 "register_operand")))
9298 (clobber (reg:CC FLAGS_REG))]
9299 "TARGET_BMI2 && reload_completed"
9301 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9302 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9304 (define_insn "*bmi2_ashlsi3_1_zext"
9305 [(set (match_operand:DI 0 "register_operand" "=r")
9307 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9308 (match_operand:SI 2 "register_operand" "r"))))]
9309 "TARGET_64BIT && TARGET_BMI2"
9310 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9311 [(set_attr "type" "ishiftx")
9312 (set_attr "mode" "SI")])
9314 (define_insn "*ashlsi3_1_zext"
9315 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9317 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9318 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9319 (clobber (reg:CC FLAGS_REG))]
9320 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9322 switch (get_attr_type (insn))
9329 gcc_assert (operands[2] == const1_rtx);
9330 return "add{l}\t%k0, %k0";
9333 if (operands[2] == const1_rtx
9334 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9335 return "sal{l}\t%k0";
9337 return "sal{l}\t{%2, %k0|%k0, %2}";
9340 [(set_attr "isa" "*,*,bmi2")
9342 (cond [(eq_attr "alternative" "1")
9343 (const_string "lea")
9344 (eq_attr "alternative" "2")
9345 (const_string "ishiftx")
9346 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9347 (match_operand 2 "const1_operand"))
9348 (const_string "alu")
9350 (const_string "ishift")))
9351 (set (attr "length_immediate")
9353 (ior (eq_attr "type" "alu")
9354 (and (eq_attr "type" "ishift")
9355 (and (match_operand 2 "const1_operand")
9356 (ior (match_test "TARGET_SHIFT1")
9357 (match_test "optimize_function_for_size_p (cfun)")))))
9359 (const_string "*")))
9360 (set_attr "mode" "SI")])
9362 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9364 [(set (match_operand:DI 0 "register_operand")
9366 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9367 (match_operand:QI 2 "register_operand"))))
9368 (clobber (reg:CC FLAGS_REG))]
9369 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9371 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9372 "operands[2] = gen_lowpart (SImode, operands[2]);")
9374 (define_insn "*ashlhi3_1"
9375 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9376 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9377 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9378 (clobber (reg:CC FLAGS_REG))]
9379 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9381 switch (get_attr_type (insn))
9387 gcc_assert (operands[2] == const1_rtx);
9388 return "add{w}\t%0, %0";
9391 if (operands[2] == const1_rtx
9392 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9393 return "sal{w}\t%0";
9395 return "sal{w}\t{%2, %0|%0, %2}";
9399 (cond [(eq_attr "alternative" "1")
9400 (const_string "lea")
9401 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9402 (match_operand 0 "register_operand"))
9403 (match_operand 2 "const1_operand"))
9404 (const_string "alu")
9406 (const_string "ishift")))
9407 (set (attr "length_immediate")
9409 (ior (eq_attr "type" "alu")
9410 (and (eq_attr "type" "ishift")
9411 (and (match_operand 2 "const1_operand")
9412 (ior (match_test "TARGET_SHIFT1")
9413 (match_test "optimize_function_for_size_p (cfun)")))))
9415 (const_string "*")))
9416 (set_attr "mode" "HI,SI")])
9418 ;; %%% Potential partial reg stall on alternative 1. What to do?
9419 (define_insn "*ashlqi3_1"
9420 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9421 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9422 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9423 (clobber (reg:CC FLAGS_REG))]
9424 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9426 switch (get_attr_type (insn))
9432 gcc_assert (operands[2] == const1_rtx);
9433 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9434 return "add{l}\t%k0, %k0";
9436 return "add{b}\t%0, %0";
9439 if (operands[2] == const1_rtx
9440 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9442 if (get_attr_mode (insn) == MODE_SI)
9443 return "sal{l}\t%k0";
9445 return "sal{b}\t%0";
9449 if (get_attr_mode (insn) == MODE_SI)
9450 return "sal{l}\t{%2, %k0|%k0, %2}";
9452 return "sal{b}\t{%2, %0|%0, %2}";
9457 (cond [(eq_attr "alternative" "2")
9458 (const_string "lea")
9459 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9460 (match_operand 0 "register_operand"))
9461 (match_operand 2 "const1_operand"))
9462 (const_string "alu")
9464 (const_string "ishift")))
9465 (set (attr "length_immediate")
9467 (ior (eq_attr "type" "alu")
9468 (and (eq_attr "type" "ishift")
9469 (and (match_operand 2 "const1_operand")
9470 (ior (match_test "TARGET_SHIFT1")
9471 (match_test "optimize_function_for_size_p (cfun)")))))
9473 (const_string "*")))
9474 (set_attr "mode" "QI,SI,SI")])
9476 (define_insn "*ashlqi3_1_slp"
9477 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9478 (ashift:QI (match_dup 0)
9479 (match_operand:QI 1 "nonmemory_operand" "cI")))
9480 (clobber (reg:CC FLAGS_REG))]
9481 "(optimize_function_for_size_p (cfun)
9482 || !TARGET_PARTIAL_FLAG_REG_STALL
9483 || (operands[1] == const1_rtx
9485 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9487 switch (get_attr_type (insn))
9490 gcc_assert (operands[1] == const1_rtx);
9491 return "add{b}\t%0, %0";
9494 if (operands[1] == const1_rtx
9495 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9496 return "sal{b}\t%0";
9498 return "sal{b}\t{%1, %0|%0, %1}";
9502 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9503 (match_operand 0 "register_operand"))
9504 (match_operand 1 "const1_operand"))
9505 (const_string "alu")
9507 (const_string "ishift1")))
9508 (set (attr "length_immediate")
9510 (ior (eq_attr "type" "alu")
9511 (and (eq_attr "type" "ishift1")
9512 (and (match_operand 1 "const1_operand")
9513 (ior (match_test "TARGET_SHIFT1")
9514 (match_test "optimize_function_for_size_p (cfun)")))))
9516 (const_string "*")))
9517 (set_attr "mode" "QI")])
9519 ;; Convert ashift to the lea pattern to avoid flags dependency.
9521 [(set (match_operand 0 "register_operand")
9522 (ashift (match_operand 1 "index_register_operand")
9523 (match_operand:QI 2 "const_int_operand")))
9524 (clobber (reg:CC FLAGS_REG))]
9525 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9527 && true_regnum (operands[0]) != true_regnum (operands[1])"
9530 enum machine_mode mode = GET_MODE (operands[0]);
9533 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9536 operands[0] = gen_lowpart (mode, operands[0]);
9537 operands[1] = gen_lowpart (mode, operands[1]);
9540 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9542 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9544 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9548 ;; Convert ashift to the lea pattern to avoid flags dependency.
9550 [(set (match_operand:DI 0 "register_operand")
9552 (ashift:SI (match_operand:SI 1 "index_register_operand")
9553 (match_operand:QI 2 "const_int_operand"))))
9554 (clobber (reg:CC FLAGS_REG))]
9555 "TARGET_64BIT && reload_completed
9556 && true_regnum (operands[0]) != true_regnum (operands[1])"
9558 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9560 operands[1] = gen_lowpart (DImode, operands[1]);
9561 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9564 ;; This pattern can't accept a variable shift count, since shifts by
9565 ;; zero don't affect the flags. We assume that shifts by constant
9566 ;; zero are optimized away.
9567 (define_insn "*ashl<mode>3_cmp"
9568 [(set (reg FLAGS_REG)
9570 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9571 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9573 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9574 (ashift:SWI (match_dup 1) (match_dup 2)))]
9575 "(optimize_function_for_size_p (cfun)
9576 || !TARGET_PARTIAL_FLAG_REG_STALL
9577 || (operands[2] == const1_rtx
9579 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9580 && ix86_match_ccmode (insn, CCGOCmode)
9581 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9583 switch (get_attr_type (insn))
9586 gcc_assert (operands[2] == const1_rtx);
9587 return "add{<imodesuffix>}\t%0, %0";
9590 if (operands[2] == const1_rtx
9591 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9592 return "sal{<imodesuffix>}\t%0";
9594 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9598 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9599 (match_operand 0 "register_operand"))
9600 (match_operand 2 "const1_operand"))
9601 (const_string "alu")
9603 (const_string "ishift")))
9604 (set (attr "length_immediate")
9606 (ior (eq_attr "type" "alu")
9607 (and (eq_attr "type" "ishift")
9608 (and (match_operand 2 "const1_operand")
9609 (ior (match_test "TARGET_SHIFT1")
9610 (match_test "optimize_function_for_size_p (cfun)")))))
9612 (const_string "*")))
9613 (set_attr "mode" "<MODE>")])
9615 (define_insn "*ashlsi3_cmp_zext"
9616 [(set (reg FLAGS_REG)
9618 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9619 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9621 (set (match_operand:DI 0 "register_operand" "=r")
9622 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9624 && (optimize_function_for_size_p (cfun)
9625 || !TARGET_PARTIAL_FLAG_REG_STALL
9626 || (operands[2] == const1_rtx
9628 || TARGET_DOUBLE_WITH_ADD)))
9629 && ix86_match_ccmode (insn, CCGOCmode)
9630 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9632 switch (get_attr_type (insn))
9635 gcc_assert (operands[2] == const1_rtx);
9636 return "add{l}\t%k0, %k0";
9639 if (operands[2] == const1_rtx
9640 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9641 return "sal{l}\t%k0";
9643 return "sal{l}\t{%2, %k0|%k0, %2}";
9647 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9648 (match_operand 2 "const1_operand"))
9649 (const_string "alu")
9651 (const_string "ishift")))
9652 (set (attr "length_immediate")
9654 (ior (eq_attr "type" "alu")
9655 (and (eq_attr "type" "ishift")
9656 (and (match_operand 2 "const1_operand")
9657 (ior (match_test "TARGET_SHIFT1")
9658 (match_test "optimize_function_for_size_p (cfun)")))))
9660 (const_string "*")))
9661 (set_attr "mode" "SI")])
9663 (define_insn "*ashl<mode>3_cconly"
9664 [(set (reg FLAGS_REG)
9666 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9667 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9669 (clobber (match_scratch:SWI 0 "=<r>"))]
9670 "(optimize_function_for_size_p (cfun)
9671 || !TARGET_PARTIAL_FLAG_REG_STALL
9672 || (operands[2] == const1_rtx
9674 || TARGET_DOUBLE_WITH_ADD)))
9675 && ix86_match_ccmode (insn, CCGOCmode)"
9677 switch (get_attr_type (insn))
9680 gcc_assert (operands[2] == const1_rtx);
9681 return "add{<imodesuffix>}\t%0, %0";
9684 if (operands[2] == const1_rtx
9685 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9686 return "sal{<imodesuffix>}\t%0";
9688 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9692 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9693 (match_operand 0 "register_operand"))
9694 (match_operand 2 "const1_operand"))
9695 (const_string "alu")
9697 (const_string "ishift")))
9698 (set (attr "length_immediate")
9700 (ior (eq_attr "type" "alu")
9701 (and (eq_attr "type" "ishift")
9702 (and (match_operand 2 "const1_operand")
9703 (ior (match_test "TARGET_SHIFT1")
9704 (match_test "optimize_function_for_size_p (cfun)")))))
9706 (const_string "*")))
9707 (set_attr "mode" "<MODE>")])
9709 ;; See comment above `ashl<mode>3' about how this works.
9711 (define_expand "<shift_insn><mode>3"
9712 [(set (match_operand:SDWIM 0 "<shift_operand>")
9713 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9714 (match_operand:QI 2 "nonmemory_operand")))]
9716 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9718 ;; Avoid useless masking of count operand.
9719 (define_insn_and_split "*<shift_insn><mode>3_mask"
9720 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9722 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9725 (match_operand:SI 2 "nonimmediate_operand" "c")
9726 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9727 (clobber (reg:CC FLAGS_REG))]
9728 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9729 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9730 == GET_MODE_BITSIZE (<MODE>mode)-1"
9733 [(parallel [(set (match_dup 0)
9734 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9735 (clobber (reg:CC FLAGS_REG))])]
9737 if (can_create_pseudo_p ())
9738 operands [2] = force_reg (SImode, operands[2]);
9740 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9742 [(set_attr "type" "ishift")
9743 (set_attr "mode" "<MODE>")])
9745 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9746 [(set (match_operand:DWI 0 "register_operand" "=r")
9747 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9748 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9749 (clobber (reg:CC FLAGS_REG))]
9752 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9754 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9755 [(set_attr "type" "multi")])
9757 ;; By default we don't ask for a scratch register, because when DWImode
9758 ;; values are manipulated, registers are already at a premium. But if
9759 ;; we have one handy, we won't turn it away.
9762 [(match_scratch:DWIH 3 "r")
9763 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9765 (match_operand:<DWI> 1 "register_operand")
9766 (match_operand:QI 2 "nonmemory_operand")))
9767 (clobber (reg:CC FLAGS_REG))])
9771 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9773 (define_insn "x86_64_shrd"
9774 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9775 (ior:DI (ashiftrt:DI (match_dup 0)
9776 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9777 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9778 (minus:QI (const_int 64) (match_dup 2)))))
9779 (clobber (reg:CC FLAGS_REG))]
9781 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9782 [(set_attr "type" "ishift")
9783 (set_attr "prefix_0f" "1")
9784 (set_attr "mode" "DI")
9785 (set_attr "athlon_decode" "vector")
9786 (set_attr "amdfam10_decode" "vector")
9787 (set_attr "bdver1_decode" "vector")])
9789 (define_insn "x86_shrd"
9790 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9791 (ior:SI (ashiftrt:SI (match_dup 0)
9792 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9793 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9794 (minus:QI (const_int 32) (match_dup 2)))))
9795 (clobber (reg:CC FLAGS_REG))]
9797 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9798 [(set_attr "type" "ishift")
9799 (set_attr "prefix_0f" "1")
9800 (set_attr "mode" "SI")
9801 (set_attr "pent_pair" "np")
9802 (set_attr "athlon_decode" "vector")
9803 (set_attr "amdfam10_decode" "vector")
9804 (set_attr "bdver1_decode" "vector")])
9806 (define_insn "ashrdi3_cvt"
9807 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9808 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9809 (match_operand:QI 2 "const_int_operand")))
9810 (clobber (reg:CC FLAGS_REG))]
9811 "TARGET_64BIT && INTVAL (operands[2]) == 63
9812 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9813 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9816 sar{q}\t{%2, %0|%0, %2}"
9817 [(set_attr "type" "imovx,ishift")
9818 (set_attr "prefix_0f" "0,*")
9819 (set_attr "length_immediate" "0,*")
9820 (set_attr "modrm" "0,1")
9821 (set_attr "mode" "DI")])
9823 (define_insn "ashrsi3_cvt"
9824 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9825 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9826 (match_operand:QI 2 "const_int_operand")))
9827 (clobber (reg:CC FLAGS_REG))]
9828 "INTVAL (operands[2]) == 31
9829 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9830 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9833 sar{l}\t{%2, %0|%0, %2}"
9834 [(set_attr "type" "imovx,ishift")
9835 (set_attr "prefix_0f" "0,*")
9836 (set_attr "length_immediate" "0,*")
9837 (set_attr "modrm" "0,1")
9838 (set_attr "mode" "SI")])
9840 (define_insn "*ashrsi3_cvt_zext"
9841 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9843 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9844 (match_operand:QI 2 "const_int_operand"))))
9845 (clobber (reg:CC FLAGS_REG))]
9846 "TARGET_64BIT && INTVAL (operands[2]) == 31
9847 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9848 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9851 sar{l}\t{%2, %k0|%k0, %2}"
9852 [(set_attr "type" "imovx,ishift")
9853 (set_attr "prefix_0f" "0,*")
9854 (set_attr "length_immediate" "0,*")
9855 (set_attr "modrm" "0,1")
9856 (set_attr "mode" "SI")])
9858 (define_expand "x86_shift<mode>_adj_3"
9859 [(use (match_operand:SWI48 0 "register_operand"))
9860 (use (match_operand:SWI48 1 "register_operand"))
9861 (use (match_operand:QI 2 "register_operand"))]
9864 rtx label = gen_label_rtx ();
9867 emit_insn (gen_testqi_ccz_1 (operands[2],
9868 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9870 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9871 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9872 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9873 gen_rtx_LABEL_REF (VOIDmode, label),
9875 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9876 JUMP_LABEL (tmp) = label;
9878 emit_move_insn (operands[0], operands[1]);
9879 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9880 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9882 LABEL_NUSES (label) = 1;
9887 (define_insn "*bmi2_<shift_insn><mode>3_1"
9888 [(set (match_operand:SWI48 0 "register_operand" "=r")
9889 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9890 (match_operand:SWI48 2 "register_operand" "r")))]
9892 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9893 [(set_attr "type" "ishiftx")
9894 (set_attr "mode" "<MODE>")])
9896 (define_insn "*<shift_insn><mode>3_1"
9897 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9899 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9900 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9901 (clobber (reg:CC FLAGS_REG))]
9902 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9904 switch (get_attr_type (insn))
9910 if (operands[2] == const1_rtx
9911 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9912 return "<shift>{<imodesuffix>}\t%0";
9914 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9917 [(set_attr "isa" "*,bmi2")
9918 (set_attr "type" "ishift,ishiftx")
9919 (set (attr "length_immediate")
9921 (and (match_operand 2 "const1_operand")
9922 (ior (match_test "TARGET_SHIFT1")
9923 (match_test "optimize_function_for_size_p (cfun)")))
9925 (const_string "*")))
9926 (set_attr "mode" "<MODE>")])
9928 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9930 [(set (match_operand:SWI48 0 "register_operand")
9931 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9932 (match_operand:QI 2 "register_operand")))
9933 (clobber (reg:CC FLAGS_REG))]
9934 "TARGET_BMI2 && reload_completed"
9936 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9937 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9939 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9940 [(set (match_operand:DI 0 "register_operand" "=r")
9942 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9943 (match_operand:SI 2 "register_operand" "r"))))]
9944 "TARGET_64BIT && TARGET_BMI2"
9945 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9946 [(set_attr "type" "ishiftx")
9947 (set_attr "mode" "SI")])
9949 (define_insn "*<shift_insn>si3_1_zext"
9950 [(set (match_operand:DI 0 "register_operand" "=r,r")
9952 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9953 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9954 (clobber (reg:CC FLAGS_REG))]
9955 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9957 switch (get_attr_type (insn))
9963 if (operands[2] == const1_rtx
9964 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9965 return "<shift>{l}\t%k0";
9967 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9970 [(set_attr "isa" "*,bmi2")
9971 (set_attr "type" "ishift,ishiftx")
9972 (set (attr "length_immediate")
9974 (and (match_operand 2 "const1_operand")
9975 (ior (match_test "TARGET_SHIFT1")
9976 (match_test "optimize_function_for_size_p (cfun)")))
9978 (const_string "*")))
9979 (set_attr "mode" "SI")])
9981 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9983 [(set (match_operand:DI 0 "register_operand")
9985 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9986 (match_operand:QI 2 "register_operand"))))
9987 (clobber (reg:CC FLAGS_REG))]
9988 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9990 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9991 "operands[2] = gen_lowpart (SImode, operands[2]);")
9993 (define_insn "*<shift_insn><mode>3_1"
9994 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9996 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9997 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9998 (clobber (reg:CC FLAGS_REG))]
9999 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10001 if (operands[2] == const1_rtx
10002 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10003 return "<shift>{<imodesuffix>}\t%0";
10005 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10007 [(set_attr "type" "ishift")
10008 (set (attr "length_immediate")
10010 (and (match_operand 2 "const1_operand")
10011 (ior (match_test "TARGET_SHIFT1")
10012 (match_test "optimize_function_for_size_p (cfun)")))
10014 (const_string "*")))
10015 (set_attr "mode" "<MODE>")])
10017 (define_insn "*<shift_insn>qi3_1_slp"
10018 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10019 (any_shiftrt:QI (match_dup 0)
10020 (match_operand:QI 1 "nonmemory_operand" "cI")))
10021 (clobber (reg:CC FLAGS_REG))]
10022 "(optimize_function_for_size_p (cfun)
10023 || !TARGET_PARTIAL_REG_STALL
10024 || (operands[1] == const1_rtx
10025 && TARGET_SHIFT1))"
10027 if (operands[1] == const1_rtx
10028 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10029 return "<shift>{b}\t%0";
10031 return "<shift>{b}\t{%1, %0|%0, %1}";
10033 [(set_attr "type" "ishift1")
10034 (set (attr "length_immediate")
10036 (and (match_operand 1 "const1_operand")
10037 (ior (match_test "TARGET_SHIFT1")
10038 (match_test "optimize_function_for_size_p (cfun)")))
10040 (const_string "*")))
10041 (set_attr "mode" "QI")])
10043 ;; This pattern can't accept a variable shift count, since shifts by
10044 ;; zero don't affect the flags. We assume that shifts by constant
10045 ;; zero are optimized away.
10046 (define_insn "*<shift_insn><mode>3_cmp"
10047 [(set (reg FLAGS_REG)
10050 (match_operand:SWI 1 "nonimmediate_operand" "0")
10051 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10053 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10054 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10055 "(optimize_function_for_size_p (cfun)
10056 || !TARGET_PARTIAL_FLAG_REG_STALL
10057 || (operands[2] == const1_rtx
10059 && ix86_match_ccmode (insn, CCGOCmode)
10060 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10062 if (operands[2] == const1_rtx
10063 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10064 return "<shift>{<imodesuffix>}\t%0";
10066 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10068 [(set_attr "type" "ishift")
10069 (set (attr "length_immediate")
10071 (and (match_operand 2 "const1_operand")
10072 (ior (match_test "TARGET_SHIFT1")
10073 (match_test "optimize_function_for_size_p (cfun)")))
10075 (const_string "*")))
10076 (set_attr "mode" "<MODE>")])
10078 (define_insn "*<shift_insn>si3_cmp_zext"
10079 [(set (reg FLAGS_REG)
10081 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10082 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10084 (set (match_operand:DI 0 "register_operand" "=r")
10085 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10087 && (optimize_function_for_size_p (cfun)
10088 || !TARGET_PARTIAL_FLAG_REG_STALL
10089 || (operands[2] == const1_rtx
10091 && ix86_match_ccmode (insn, CCGOCmode)
10092 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10094 if (operands[2] == const1_rtx
10095 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10096 return "<shift>{l}\t%k0";
10098 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10100 [(set_attr "type" "ishift")
10101 (set (attr "length_immediate")
10103 (and (match_operand 2 "const1_operand")
10104 (ior (match_test "TARGET_SHIFT1")
10105 (match_test "optimize_function_for_size_p (cfun)")))
10107 (const_string "*")))
10108 (set_attr "mode" "SI")])
10110 (define_insn "*<shift_insn><mode>3_cconly"
10111 [(set (reg FLAGS_REG)
10114 (match_operand:SWI 1 "register_operand" "0")
10115 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10117 (clobber (match_scratch:SWI 0 "=<r>"))]
10118 "(optimize_function_for_size_p (cfun)
10119 || !TARGET_PARTIAL_FLAG_REG_STALL
10120 || (operands[2] == const1_rtx
10122 && ix86_match_ccmode (insn, CCGOCmode)"
10124 if (operands[2] == const1_rtx
10125 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10126 return "<shift>{<imodesuffix>}\t%0";
10128 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10130 [(set_attr "type" "ishift")
10131 (set (attr "length_immediate")
10133 (and (match_operand 2 "const1_operand")
10134 (ior (match_test "TARGET_SHIFT1")
10135 (match_test "optimize_function_for_size_p (cfun)")))
10137 (const_string "*")))
10138 (set_attr "mode" "<MODE>")])
10140 ;; Rotate instructions
10142 (define_expand "<rotate_insn>ti3"
10143 [(set (match_operand:TI 0 "register_operand")
10144 (any_rotate:TI (match_operand:TI 1 "register_operand")
10145 (match_operand:QI 2 "nonmemory_operand")))]
10148 if (const_1_to_63_operand (operands[2], VOIDmode))
10149 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10150 (operands[0], operands[1], operands[2]));
10157 (define_expand "<rotate_insn>di3"
10158 [(set (match_operand:DI 0 "shiftdi_operand")
10159 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10160 (match_operand:QI 2 "nonmemory_operand")))]
10164 ix86_expand_binary_operator (<CODE>, DImode, operands);
10165 else if (const_1_to_31_operand (operands[2], VOIDmode))
10166 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10167 (operands[0], operands[1], operands[2]));
10174 (define_expand "<rotate_insn><mode>3"
10175 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10176 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10177 (match_operand:QI 2 "nonmemory_operand")))]
10179 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10181 ;; Avoid useless masking of count operand.
10182 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10183 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10185 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10188 (match_operand:SI 2 "nonimmediate_operand" "c")
10189 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10190 (clobber (reg:CC FLAGS_REG))]
10191 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10192 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10193 == GET_MODE_BITSIZE (<MODE>mode)-1"
10196 [(parallel [(set (match_dup 0)
10197 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10198 (clobber (reg:CC FLAGS_REG))])]
10200 if (can_create_pseudo_p ())
10201 operands [2] = force_reg (SImode, operands[2]);
10203 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10205 [(set_attr "type" "rotate")
10206 (set_attr "mode" "<MODE>")])
10208 ;; Implement rotation using two double-precision
10209 ;; shift instructions and a scratch register.
10211 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10212 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10213 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10214 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10215 (clobber (reg:CC FLAGS_REG))
10216 (clobber (match_scratch:DWIH 3 "=&r"))]
10220 [(set (match_dup 3) (match_dup 4))
10222 [(set (match_dup 4)
10223 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10224 (lshiftrt:DWIH (match_dup 5)
10225 (minus:QI (match_dup 6) (match_dup 2)))))
10226 (clobber (reg:CC FLAGS_REG))])
10228 [(set (match_dup 5)
10229 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10230 (lshiftrt:DWIH (match_dup 3)
10231 (minus:QI (match_dup 6) (match_dup 2)))))
10232 (clobber (reg:CC FLAGS_REG))])]
10234 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10236 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10239 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10240 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10241 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10242 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10243 (clobber (reg:CC FLAGS_REG))
10244 (clobber (match_scratch:DWIH 3 "=&r"))]
10248 [(set (match_dup 3) (match_dup 4))
10250 [(set (match_dup 4)
10251 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10252 (ashift:DWIH (match_dup 5)
10253 (minus:QI (match_dup 6) (match_dup 2)))))
10254 (clobber (reg:CC FLAGS_REG))])
10256 [(set (match_dup 5)
10257 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10258 (ashift:DWIH (match_dup 3)
10259 (minus:QI (match_dup 6) (match_dup 2)))))
10260 (clobber (reg:CC FLAGS_REG))])]
10262 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10264 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10267 (define_insn "*bmi2_rorx<mode>3_1"
10268 [(set (match_operand:SWI48 0 "register_operand" "=r")
10269 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10270 (match_operand:QI 2 "immediate_operand" "<S>")))]
10272 "rorx\t{%2, %1, %0|%0, %1, %2}"
10273 [(set_attr "type" "rotatex")
10274 (set_attr "mode" "<MODE>")])
10276 (define_insn "*<rotate_insn><mode>3_1"
10277 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10279 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10280 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10281 (clobber (reg:CC FLAGS_REG))]
10282 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10284 switch (get_attr_type (insn))
10290 if (operands[2] == const1_rtx
10291 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10292 return "<rotate>{<imodesuffix>}\t%0";
10294 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10297 [(set_attr "isa" "*,bmi2")
10298 (set_attr "type" "rotate,rotatex")
10299 (set (attr "length_immediate")
10301 (and (eq_attr "type" "rotate")
10302 (and (match_operand 2 "const1_operand")
10303 (ior (match_test "TARGET_SHIFT1")
10304 (match_test "optimize_function_for_size_p (cfun)"))))
10306 (const_string "*")))
10307 (set_attr "mode" "<MODE>")])
10309 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10311 [(set (match_operand:SWI48 0 "register_operand")
10312 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10313 (match_operand:QI 2 "immediate_operand")))
10314 (clobber (reg:CC FLAGS_REG))]
10315 "TARGET_BMI2 && reload_completed"
10316 [(set (match_dup 0)
10317 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10320 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10324 [(set (match_operand:SWI48 0 "register_operand")
10325 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10326 (match_operand:QI 2 "immediate_operand")))
10327 (clobber (reg:CC FLAGS_REG))]
10328 "TARGET_BMI2 && reload_completed"
10329 [(set (match_dup 0)
10330 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10332 (define_insn "*bmi2_rorxsi3_1_zext"
10333 [(set (match_operand:DI 0 "register_operand" "=r")
10335 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10336 (match_operand:QI 2 "immediate_operand" "I"))))]
10337 "TARGET_64BIT && TARGET_BMI2"
10338 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10339 [(set_attr "type" "rotatex")
10340 (set_attr "mode" "SI")])
10342 (define_insn "*<rotate_insn>si3_1_zext"
10343 [(set (match_operand:DI 0 "register_operand" "=r,r")
10345 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10346 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10347 (clobber (reg:CC FLAGS_REG))]
10348 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10350 switch (get_attr_type (insn))
10356 if (operands[2] == const1_rtx
10357 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10358 return "<rotate>{l}\t%k0";
10360 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10363 [(set_attr "isa" "*,bmi2")
10364 (set_attr "type" "rotate,rotatex")
10365 (set (attr "length_immediate")
10367 (and (eq_attr "type" "rotate")
10368 (and (match_operand 2 "const1_operand")
10369 (ior (match_test "TARGET_SHIFT1")
10370 (match_test "optimize_function_for_size_p (cfun)"))))
10372 (const_string "*")))
10373 (set_attr "mode" "SI")])
10375 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10377 [(set (match_operand:DI 0 "register_operand")
10379 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10380 (match_operand:QI 2 "immediate_operand"))))
10381 (clobber (reg:CC FLAGS_REG))]
10382 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10383 [(set (match_dup 0)
10384 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10387 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10391 [(set (match_operand:DI 0 "register_operand")
10393 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10394 (match_operand:QI 2 "immediate_operand"))))
10395 (clobber (reg:CC FLAGS_REG))]
10396 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10397 [(set (match_dup 0)
10398 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10400 (define_insn "*<rotate_insn><mode>3_1"
10401 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10402 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10403 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10404 (clobber (reg:CC FLAGS_REG))]
10405 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10407 if (operands[2] == const1_rtx
10408 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10409 return "<rotate>{<imodesuffix>}\t%0";
10411 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10413 [(set_attr "type" "rotate")
10414 (set (attr "length_immediate")
10416 (and (match_operand 2 "const1_operand")
10417 (ior (match_test "TARGET_SHIFT1")
10418 (match_test "optimize_function_for_size_p (cfun)")))
10420 (const_string "*")))
10421 (set_attr "mode" "<MODE>")])
10423 (define_insn "*<rotate_insn>qi3_1_slp"
10424 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10425 (any_rotate:QI (match_dup 0)
10426 (match_operand:QI 1 "nonmemory_operand" "cI")))
10427 (clobber (reg:CC FLAGS_REG))]
10428 "(optimize_function_for_size_p (cfun)
10429 || !TARGET_PARTIAL_REG_STALL
10430 || (operands[1] == const1_rtx
10431 && TARGET_SHIFT1))"
10433 if (operands[1] == const1_rtx
10434 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10435 return "<rotate>{b}\t%0";
10437 return "<rotate>{b}\t{%1, %0|%0, %1}";
10439 [(set_attr "type" "rotate1")
10440 (set (attr "length_immediate")
10442 (and (match_operand 1 "const1_operand")
10443 (ior (match_test "TARGET_SHIFT1")
10444 (match_test "optimize_function_for_size_p (cfun)")))
10446 (const_string "*")))
10447 (set_attr "mode" "QI")])
10450 [(set (match_operand:HI 0 "register_operand")
10451 (any_rotate:HI (match_dup 0) (const_int 8)))
10452 (clobber (reg:CC FLAGS_REG))]
10454 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10455 [(parallel [(set (strict_low_part (match_dup 0))
10456 (bswap:HI (match_dup 0)))
10457 (clobber (reg:CC FLAGS_REG))])])
10459 ;; Bit set / bit test instructions
10461 (define_expand "extv"
10462 [(set (match_operand:SI 0 "register_operand")
10463 (sign_extract:SI (match_operand:SI 1 "register_operand")
10464 (match_operand:SI 2 "const8_operand")
10465 (match_operand:SI 3 "const8_operand")))]
10468 /* Handle extractions from %ah et al. */
10469 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10472 /* From mips.md: extract_bit_field doesn't verify that our source
10473 matches the predicate, so check it again here. */
10474 if (! ext_register_operand (operands[1], VOIDmode))
10478 (define_expand "extzv"
10479 [(set (match_operand:SI 0 "register_operand")
10480 (zero_extract:SI (match_operand 1 "ext_register_operand")
10481 (match_operand:SI 2 "const8_operand")
10482 (match_operand:SI 3 "const8_operand")))]
10485 /* Handle extractions from %ah et al. */
10486 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10489 /* From mips.md: extract_bit_field doesn't verify that our source
10490 matches the predicate, so check it again here. */
10491 if (! ext_register_operand (operands[1], VOIDmode))
10495 (define_expand "insv"
10496 [(set (zero_extract (match_operand 0 "register_operand")
10497 (match_operand 1 "const_int_operand")
10498 (match_operand 2 "const_int_operand"))
10499 (match_operand 3 "register_operand"))]
10502 rtx (*gen_mov_insv_1) (rtx, rtx);
10504 if (ix86_expand_pinsr (operands))
10507 /* Handle insertions to %ah et al. */
10508 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10511 /* From mips.md: insert_bit_field doesn't verify that our source
10512 matches the predicate, so check it again here. */
10513 if (! ext_register_operand (operands[0], VOIDmode))
10516 gen_mov_insv_1 = (TARGET_64BIT
10517 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10519 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10523 ;; %%% bts, btr, btc, bt.
10524 ;; In general these instructions are *slow* when applied to memory,
10525 ;; since they enforce atomic operation. When applied to registers,
10526 ;; it depends on the cpu implementation. They're never faster than
10527 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10528 ;; no point. But in 64-bit, we can't hold the relevant immediates
10529 ;; within the instruction itself, so operating on bits in the high
10530 ;; 32-bits of a register becomes easier.
10532 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10533 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10534 ;; negdf respectively, so they can never be disabled entirely.
10536 (define_insn "*btsq"
10537 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10539 (match_operand:DI 1 "const_0_to_63_operand"))
10541 (clobber (reg:CC FLAGS_REG))]
10542 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10543 "bts{q}\t{%1, %0|%0, %1}"
10544 [(set_attr "type" "alu1")
10545 (set_attr "prefix_0f" "1")
10546 (set_attr "mode" "DI")])
10548 (define_insn "*btrq"
10549 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10551 (match_operand:DI 1 "const_0_to_63_operand"))
10553 (clobber (reg:CC FLAGS_REG))]
10554 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10555 "btr{q}\t{%1, %0|%0, %1}"
10556 [(set_attr "type" "alu1")
10557 (set_attr "prefix_0f" "1")
10558 (set_attr "mode" "DI")])
10560 (define_insn "*btcq"
10561 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10563 (match_operand:DI 1 "const_0_to_63_operand"))
10564 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10565 (clobber (reg:CC FLAGS_REG))]
10566 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10567 "btc{q}\t{%1, %0|%0, %1}"
10568 [(set_attr "type" "alu1")
10569 (set_attr "prefix_0f" "1")
10570 (set_attr "mode" "DI")])
10572 ;; Allow Nocona to avoid these instructions if a register is available.
10575 [(match_scratch:DI 2 "r")
10576 (parallel [(set (zero_extract:DI
10577 (match_operand:DI 0 "register_operand")
10579 (match_operand:DI 1 "const_0_to_63_operand"))
10581 (clobber (reg:CC FLAGS_REG))])]
10582 "TARGET_64BIT && !TARGET_USE_BT"
10585 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10588 if (HOST_BITS_PER_WIDE_INT >= 64)
10589 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10590 else if (i < HOST_BITS_PER_WIDE_INT)
10591 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10593 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10595 op1 = immed_double_const (lo, hi, DImode);
10598 emit_move_insn (operands[2], op1);
10602 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10607 [(match_scratch:DI 2 "r")
10608 (parallel [(set (zero_extract:DI
10609 (match_operand:DI 0 "register_operand")
10611 (match_operand:DI 1 "const_0_to_63_operand"))
10613 (clobber (reg:CC FLAGS_REG))])]
10614 "TARGET_64BIT && !TARGET_USE_BT"
10617 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10620 if (HOST_BITS_PER_WIDE_INT >= 64)
10621 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10622 else if (i < HOST_BITS_PER_WIDE_INT)
10623 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10625 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10627 op1 = immed_double_const (~lo, ~hi, DImode);
10630 emit_move_insn (operands[2], op1);
10634 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10639 [(match_scratch:DI 2 "r")
10640 (parallel [(set (zero_extract:DI
10641 (match_operand:DI 0 "register_operand")
10643 (match_operand:DI 1 "const_0_to_63_operand"))
10644 (not:DI (zero_extract:DI
10645 (match_dup 0) (const_int 1) (match_dup 1))))
10646 (clobber (reg:CC FLAGS_REG))])]
10647 "TARGET_64BIT && !TARGET_USE_BT"
10650 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10653 if (HOST_BITS_PER_WIDE_INT >= 64)
10654 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10655 else if (i < HOST_BITS_PER_WIDE_INT)
10656 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10658 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10660 op1 = immed_double_const (lo, hi, DImode);
10663 emit_move_insn (operands[2], op1);
10667 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10671 (define_insn "*bt<mode>"
10672 [(set (reg:CCC FLAGS_REG)
10674 (zero_extract:SWI48
10675 (match_operand:SWI48 0 "register_operand" "r")
10677 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10679 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10680 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10681 [(set_attr "type" "alu1")
10682 (set_attr "prefix_0f" "1")
10683 (set_attr "mode" "<MODE>")])
10685 ;; Store-flag instructions.
10687 ;; For all sCOND expanders, also expand the compare or test insn that
10688 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10690 (define_insn_and_split "*setcc_di_1"
10691 [(set (match_operand:DI 0 "register_operand" "=q")
10692 (match_operator:DI 1 "ix86_comparison_operator"
10693 [(reg FLAGS_REG) (const_int 0)]))]
10694 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10696 "&& reload_completed"
10697 [(set (match_dup 2) (match_dup 1))
10698 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10700 PUT_MODE (operands[1], QImode);
10701 operands[2] = gen_lowpart (QImode, operands[0]);
10704 (define_insn_and_split "*setcc_si_1_and"
10705 [(set (match_operand:SI 0 "register_operand" "=q")
10706 (match_operator:SI 1 "ix86_comparison_operator"
10707 [(reg FLAGS_REG) (const_int 0)]))
10708 (clobber (reg:CC FLAGS_REG))]
10709 "!TARGET_PARTIAL_REG_STALL
10710 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10712 "&& reload_completed"
10713 [(set (match_dup 2) (match_dup 1))
10714 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10715 (clobber (reg:CC FLAGS_REG))])]
10717 PUT_MODE (operands[1], QImode);
10718 operands[2] = gen_lowpart (QImode, operands[0]);
10721 (define_insn_and_split "*setcc_si_1_movzbl"
10722 [(set (match_operand:SI 0 "register_operand" "=q")
10723 (match_operator:SI 1 "ix86_comparison_operator"
10724 [(reg FLAGS_REG) (const_int 0)]))]
10725 "!TARGET_PARTIAL_REG_STALL
10726 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10728 "&& reload_completed"
10729 [(set (match_dup 2) (match_dup 1))
10730 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10732 PUT_MODE (operands[1], QImode);
10733 operands[2] = gen_lowpart (QImode, operands[0]);
10736 (define_insn "*setcc_qi"
10737 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10738 (match_operator:QI 1 "ix86_comparison_operator"
10739 [(reg FLAGS_REG) (const_int 0)]))]
10742 [(set_attr "type" "setcc")
10743 (set_attr "mode" "QI")])
10745 (define_insn "*setcc_qi_slp"
10746 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10747 (match_operator:QI 1 "ix86_comparison_operator"
10748 [(reg FLAGS_REG) (const_int 0)]))]
10751 [(set_attr "type" "setcc")
10752 (set_attr "mode" "QI")])
10754 ;; In general it is not safe to assume too much about CCmode registers,
10755 ;; so simplify-rtx stops when it sees a second one. Under certain
10756 ;; conditions this is safe on x86, so help combine not create
10763 [(set (match_operand:QI 0 "nonimmediate_operand")
10764 (ne:QI (match_operator 1 "ix86_comparison_operator"
10765 [(reg FLAGS_REG) (const_int 0)])
10768 [(set (match_dup 0) (match_dup 1))]
10769 "PUT_MODE (operands[1], QImode);")
10772 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10773 (ne:QI (match_operator 1 "ix86_comparison_operator"
10774 [(reg FLAGS_REG) (const_int 0)])
10777 [(set (match_dup 0) (match_dup 1))]
10778 "PUT_MODE (operands[1], QImode);")
10781 [(set (match_operand:QI 0 "nonimmediate_operand")
10782 (eq:QI (match_operator 1 "ix86_comparison_operator"
10783 [(reg FLAGS_REG) (const_int 0)])
10786 [(set (match_dup 0) (match_dup 1))]
10788 rtx new_op1 = copy_rtx (operands[1]);
10789 operands[1] = new_op1;
10790 PUT_MODE (new_op1, QImode);
10791 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10792 GET_MODE (XEXP (new_op1, 0))));
10794 /* Make sure that (a) the CCmode we have for the flags is strong
10795 enough for the reversed compare or (b) we have a valid FP compare. */
10796 if (! ix86_comparison_operator (new_op1, VOIDmode))
10801 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10802 (eq:QI (match_operator 1 "ix86_comparison_operator"
10803 [(reg FLAGS_REG) (const_int 0)])
10806 [(set (match_dup 0) (match_dup 1))]
10808 rtx new_op1 = copy_rtx (operands[1]);
10809 operands[1] = new_op1;
10810 PUT_MODE (new_op1, QImode);
10811 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10812 GET_MODE (XEXP (new_op1, 0))));
10814 /* Make sure that (a) the CCmode we have for the flags is strong
10815 enough for the reversed compare or (b) we have a valid FP compare. */
10816 if (! ix86_comparison_operator (new_op1, VOIDmode))
10820 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10821 ;; subsequent logical operations are used to imitate conditional moves.
10822 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10825 (define_insn "setcc_<mode>_sse"
10826 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10827 (match_operator:MODEF 3 "sse_comparison_operator"
10828 [(match_operand:MODEF 1 "register_operand" "0,x")
10829 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10830 "SSE_FLOAT_MODE_P (<MODE>mode)"
10832 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10833 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10834 [(set_attr "isa" "noavx,avx")
10835 (set_attr "type" "ssecmp")
10836 (set_attr "length_immediate" "1")
10837 (set_attr "prefix" "orig,vex")
10838 (set_attr "mode" "<MODE>")])
10840 ;; Basic conditional jump instructions.
10841 ;; We ignore the overflow flag for signed branch instructions.
10843 (define_insn "*jcc_1"
10845 (if_then_else (match_operator 1 "ix86_comparison_operator"
10846 [(reg FLAGS_REG) (const_int 0)])
10847 (label_ref (match_operand 0))
10851 [(set_attr "type" "ibr")
10852 (set_attr "modrm" "0")
10853 (set (attr "length")
10854 (if_then_else (and (ge (minus (match_dup 0) (pc))
10856 (lt (minus (match_dup 0) (pc))
10861 (define_insn "*jcc_2"
10863 (if_then_else (match_operator 1 "ix86_comparison_operator"
10864 [(reg FLAGS_REG) (const_int 0)])
10866 (label_ref (match_operand 0))))]
10869 [(set_attr "type" "ibr")
10870 (set_attr "modrm" "0")
10871 (set (attr "length")
10872 (if_then_else (and (ge (minus (match_dup 0) (pc))
10874 (lt (minus (match_dup 0) (pc))
10879 ;; In general it is not safe to assume too much about CCmode registers,
10880 ;; so simplify-rtx stops when it sees a second one. Under certain
10881 ;; conditions this is safe on x86, so help combine not create
10889 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10890 [(reg FLAGS_REG) (const_int 0)])
10892 (label_ref (match_operand 1))
10896 (if_then_else (match_dup 0)
10897 (label_ref (match_dup 1))
10899 "PUT_MODE (operands[0], VOIDmode);")
10903 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10904 [(reg FLAGS_REG) (const_int 0)])
10906 (label_ref (match_operand 1))
10910 (if_then_else (match_dup 0)
10911 (label_ref (match_dup 1))
10914 rtx new_op0 = copy_rtx (operands[0]);
10915 operands[0] = new_op0;
10916 PUT_MODE (new_op0, VOIDmode);
10917 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10918 GET_MODE (XEXP (new_op0, 0))));
10920 /* Make sure that (a) the CCmode we have for the flags is strong
10921 enough for the reversed compare or (b) we have a valid FP compare. */
10922 if (! ix86_comparison_operator (new_op0, VOIDmode))
10926 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10927 ;; pass generates from shift insn with QImode operand. Actually, the mode
10928 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10929 ;; appropriate modulo of the bit offset value.
10931 (define_insn_and_split "*jcc_bt<mode>"
10933 (if_then_else (match_operator 0 "bt_comparison_operator"
10934 [(zero_extract:SWI48
10935 (match_operand:SWI48 1 "register_operand" "r")
10938 (match_operand:QI 2 "register_operand" "r")))
10940 (label_ref (match_operand 3))
10942 (clobber (reg:CC FLAGS_REG))]
10943 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10946 [(set (reg:CCC FLAGS_REG)
10948 (zero_extract:SWI48
10954 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10955 (label_ref (match_dup 3))
10958 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10960 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10963 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10964 ;; also for DImode, this is what combine produces.
10965 (define_insn_and_split "*jcc_bt<mode>_mask"
10967 (if_then_else (match_operator 0 "bt_comparison_operator"
10968 [(zero_extract:SWI48
10969 (match_operand:SWI48 1 "register_operand" "r")
10972 (match_operand:SI 2 "register_operand" "r")
10973 (match_operand:SI 3 "const_int_operand" "n")))])
10974 (label_ref (match_operand 4))
10976 (clobber (reg:CC FLAGS_REG))]
10977 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10978 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10979 == GET_MODE_BITSIZE (<MODE>mode)-1"
10982 [(set (reg:CCC FLAGS_REG)
10984 (zero_extract:SWI48
10990 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10991 (label_ref (match_dup 4))
10994 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10996 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10999 (define_insn_and_split "*jcc_btsi_1"
11001 (if_then_else (match_operator 0 "bt_comparison_operator"
11004 (match_operand:SI 1 "register_operand" "r")
11005 (match_operand:QI 2 "register_operand" "r"))
11008 (label_ref (match_operand 3))
11010 (clobber (reg:CC FLAGS_REG))]
11011 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11014 [(set (reg:CCC FLAGS_REG)
11022 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11023 (label_ref (match_dup 3))
11026 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11028 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11031 ;; avoid useless masking of bit offset operand
11032 (define_insn_and_split "*jcc_btsi_mask_1"
11035 (match_operator 0 "bt_comparison_operator"
11038 (match_operand:SI 1 "register_operand" "r")
11041 (match_operand:SI 2 "register_operand" "r")
11042 (match_operand:SI 3 "const_int_operand" "n")) 0))
11045 (label_ref (match_operand 4))
11047 (clobber (reg:CC FLAGS_REG))]
11048 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11049 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11052 [(set (reg:CCC FLAGS_REG)
11060 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11061 (label_ref (match_dup 4))
11063 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11065 ;; Define combination compare-and-branch fp compare instructions to help
11068 (define_insn "*fp_jcc_1_387"
11070 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11071 [(match_operand 1 "register_operand" "f")
11072 (match_operand 2 "nonimmediate_operand" "fm")])
11073 (label_ref (match_operand 3))
11075 (clobber (reg:CCFP FPSR_REG))
11076 (clobber (reg:CCFP FLAGS_REG))
11077 (clobber (match_scratch:HI 4 "=a"))]
11079 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11080 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11081 && SELECT_CC_MODE (GET_CODE (operands[0]),
11082 operands[1], operands[2]) == CCFPmode
11086 (define_insn "*fp_jcc_1r_387"
11088 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11089 [(match_operand 1 "register_operand" "f")
11090 (match_operand 2 "nonimmediate_operand" "fm")])
11092 (label_ref (match_operand 3))))
11093 (clobber (reg:CCFP FPSR_REG))
11094 (clobber (reg:CCFP FLAGS_REG))
11095 (clobber (match_scratch:HI 4 "=a"))]
11097 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11098 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11099 && SELECT_CC_MODE (GET_CODE (operands[0]),
11100 operands[1], operands[2]) == CCFPmode
11104 (define_insn "*fp_jcc_2_387"
11106 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11107 [(match_operand 1 "register_operand" "f")
11108 (match_operand 2 "register_operand" "f")])
11109 (label_ref (match_operand 3))
11111 (clobber (reg:CCFP FPSR_REG))
11112 (clobber (reg:CCFP FLAGS_REG))
11113 (clobber (match_scratch:HI 4 "=a"))]
11114 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11115 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11119 (define_insn "*fp_jcc_2r_387"
11121 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11122 [(match_operand 1 "register_operand" "f")
11123 (match_operand 2 "register_operand" "f")])
11125 (label_ref (match_operand 3))))
11126 (clobber (reg:CCFP FPSR_REG))
11127 (clobber (reg:CCFP FLAGS_REG))
11128 (clobber (match_scratch:HI 4 "=a"))]
11129 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11130 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11134 (define_insn "*fp_jcc_3_387"
11136 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11137 [(match_operand 1 "register_operand" "f")
11138 (match_operand 2 "const0_operand")])
11139 (label_ref (match_operand 3))
11141 (clobber (reg:CCFP FPSR_REG))
11142 (clobber (reg:CCFP FLAGS_REG))
11143 (clobber (match_scratch:HI 4 "=a"))]
11144 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11145 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11146 && SELECT_CC_MODE (GET_CODE (operands[0]),
11147 operands[1], operands[2]) == CCFPmode
11153 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11154 [(match_operand 1 "register_operand")
11155 (match_operand 2 "nonimmediate_operand")])
11157 (match_operand 4)))
11158 (clobber (reg:CCFP FPSR_REG))
11159 (clobber (reg:CCFP FLAGS_REG))]
11163 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11164 operands[3], operands[4], NULL_RTX, NULL_RTX);
11170 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11171 [(match_operand 1 "register_operand")
11172 (match_operand 2 "general_operand")])
11174 (match_operand 4)))
11175 (clobber (reg:CCFP FPSR_REG))
11176 (clobber (reg:CCFP FLAGS_REG))
11177 (clobber (match_scratch:HI 5 "=a"))]
11181 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11182 operands[3], operands[4], operands[5], NULL_RTX);
11186 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11187 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11188 ;; with a precedence over other operators and is always put in the first
11189 ;; place. Swap condition and operands to match ficom instruction.
11191 (define_insn "*fp_jcc_4_<mode>_387"
11194 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11195 [(match_operator 1 "float_operator"
11196 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11197 (match_operand 3 "register_operand" "f,f")])
11198 (label_ref (match_operand 4))
11200 (clobber (reg:CCFP FPSR_REG))
11201 (clobber (reg:CCFP FLAGS_REG))
11202 (clobber (match_scratch:HI 5 "=a,a"))]
11203 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11204 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11205 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11206 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11213 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11214 [(match_operator 1 "float_operator"
11215 [(match_operand:SWI24 2 "memory_operand")])
11216 (match_operand 3 "register_operand")])
11218 (match_operand 5)))
11219 (clobber (reg:CCFP FPSR_REG))
11220 (clobber (reg:CCFP FLAGS_REG))
11221 (clobber (match_scratch:HI 6 "=a"))]
11225 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11227 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11228 operands[3], operands[7],
11229 operands[4], operands[5], operands[6], NULL_RTX);
11233 ;; %%% Kill this when reload knows how to do it.
11237 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11238 [(match_operator 1 "float_operator"
11239 [(match_operand:SWI24 2 "register_operand")])
11240 (match_operand 3 "register_operand")])
11242 (match_operand 5)))
11243 (clobber (reg:CCFP FPSR_REG))
11244 (clobber (reg:CCFP FLAGS_REG))
11245 (clobber (match_scratch:HI 6 "=a"))]
11249 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11250 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11252 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11253 operands[3], operands[7],
11254 operands[4], operands[5], operands[6], operands[2]);
11258 ;; Unconditional and other jump instructions
11260 (define_insn "jump"
11262 (label_ref (match_operand 0)))]
11265 [(set_attr "type" "ibr")
11266 (set (attr "length")
11267 (if_then_else (and (ge (minus (match_dup 0) (pc))
11269 (lt (minus (match_dup 0) (pc))
11273 (set_attr "modrm" "0")])
11275 (define_expand "indirect_jump"
11276 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11280 operands[0] = convert_memory_address (word_mode, operands[0]);
11283 (define_insn "*indirect_jump"
11284 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11287 [(set_attr "type" "ibr")
11288 (set_attr "length_immediate" "0")])
11290 (define_expand "tablejump"
11291 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11292 (use (label_ref (match_operand 1)))])]
11295 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11296 relative. Convert the relative address to an absolute address. */
11300 enum rtx_code code;
11302 /* We can't use @GOTOFF for text labels on VxWorks;
11303 see gotoff_operand. */
11304 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11308 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11310 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11314 op1 = pic_offset_table_rtx;
11319 op0 = pic_offset_table_rtx;
11323 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11328 operands[0] = convert_memory_address (word_mode, operands[0]);
11331 (define_insn "*tablejump_1"
11332 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11333 (use (label_ref (match_operand 1)))]
11336 [(set_attr "type" "ibr")
11337 (set_attr "length_immediate" "0")])
11339 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11342 [(set (reg FLAGS_REG) (match_operand 0))
11343 (set (match_operand:QI 1 "register_operand")
11344 (match_operator:QI 2 "ix86_comparison_operator"
11345 [(reg FLAGS_REG) (const_int 0)]))
11346 (set (match_operand 3 "q_regs_operand")
11347 (zero_extend (match_dup 1)))]
11348 "(peep2_reg_dead_p (3, operands[1])
11349 || operands_match_p (operands[1], operands[3]))
11350 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11351 [(set (match_dup 4) (match_dup 0))
11352 (set (strict_low_part (match_dup 5))
11355 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11356 operands[5] = gen_lowpart (QImode, operands[3]);
11357 ix86_expand_clear (operands[3]);
11361 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11362 (match_operand 4)])
11363 (set (match_operand:QI 1 "register_operand")
11364 (match_operator:QI 2 "ix86_comparison_operator"
11365 [(reg FLAGS_REG) (const_int 0)]))
11366 (set (match_operand 3 "q_regs_operand")
11367 (zero_extend (match_dup 1)))]
11368 "(peep2_reg_dead_p (3, operands[1])
11369 || operands_match_p (operands[1], operands[3]))
11370 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11371 [(parallel [(set (match_dup 5) (match_dup 0))
11373 (set (strict_low_part (match_dup 6))
11376 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11377 operands[6] = gen_lowpart (QImode, operands[3]);
11378 ix86_expand_clear (operands[3]);
11381 ;; Similar, but match zero extend with andsi3.
11384 [(set (reg FLAGS_REG) (match_operand 0))
11385 (set (match_operand:QI 1 "register_operand")
11386 (match_operator:QI 2 "ix86_comparison_operator"
11387 [(reg FLAGS_REG) (const_int 0)]))
11388 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11389 (and:SI (match_dup 3) (const_int 255)))
11390 (clobber (reg:CC FLAGS_REG))])]
11391 "REGNO (operands[1]) == REGNO (operands[3])
11392 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11393 [(set (match_dup 4) (match_dup 0))
11394 (set (strict_low_part (match_dup 5))
11397 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11398 operands[5] = gen_lowpart (QImode, operands[3]);
11399 ix86_expand_clear (operands[3]);
11403 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11404 (match_operand 4)])
11405 (set (match_operand:QI 1 "register_operand")
11406 (match_operator:QI 2 "ix86_comparison_operator"
11407 [(reg FLAGS_REG) (const_int 0)]))
11408 (parallel [(set (match_operand 3 "q_regs_operand")
11409 (zero_extend (match_dup 1)))
11410 (clobber (reg:CC FLAGS_REG))])]
11411 "(peep2_reg_dead_p (3, operands[1])
11412 || operands_match_p (operands[1], operands[3]))
11413 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11414 [(parallel [(set (match_dup 5) (match_dup 0))
11416 (set (strict_low_part (match_dup 6))
11419 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11420 operands[6] = gen_lowpart (QImode, operands[3]);
11421 ix86_expand_clear (operands[3]);
11424 ;; Call instructions.
11426 ;; The predicates normally associated with named expanders are not properly
11427 ;; checked for calls. This is a bug in the generic code, but it isn't that
11428 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11430 ;; P6 processors will jump to the address after the decrement when %esp
11431 ;; is used as a call operand, so they will execute return address as a code.
11432 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11434 ;; Register constraint for call instruction.
11435 (define_mode_attr c [(SI "l") (DI "r")])
11437 ;; Call subroutine returning no value.
11439 (define_expand "call"
11440 [(call (match_operand:QI 0)
11442 (use (match_operand 2))]
11445 ix86_expand_call (NULL, operands[0], operands[1],
11446 operands[2], NULL, false);
11450 (define_expand "sibcall"
11451 [(call (match_operand:QI 0)
11453 (use (match_operand 2))]
11456 ix86_expand_call (NULL, operands[0], operands[1],
11457 operands[2], NULL, true);
11461 (define_insn_and_split "*call_vzeroupper"
11462 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11464 (unspec [(match_operand 2 "const_int_operand")]
11465 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11466 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11468 "&& reload_completed"
11470 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11471 [(set_attr "type" "call")])
11473 (define_insn "*call"
11474 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11475 (match_operand 1))]
11476 "!SIBLING_CALL_P (insn)"
11477 "* return ix86_output_call_insn (insn, operands[0]);"
11478 [(set_attr "type" "call")])
11480 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11481 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11483 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11484 (clobber (reg:TI XMM6_REG))
11485 (clobber (reg:TI XMM7_REG))
11486 (clobber (reg:TI XMM8_REG))
11487 (clobber (reg:TI XMM9_REG))
11488 (clobber (reg:TI XMM10_REG))
11489 (clobber (reg:TI XMM11_REG))
11490 (clobber (reg:TI XMM12_REG))
11491 (clobber (reg:TI XMM13_REG))
11492 (clobber (reg:TI XMM14_REG))
11493 (clobber (reg:TI XMM15_REG))
11494 (clobber (reg:DI SI_REG))
11495 (clobber (reg:DI DI_REG))
11496 (unspec [(match_operand 2 "const_int_operand")]
11497 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11498 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11500 "&& reload_completed"
11502 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11503 [(set_attr "type" "call")])
11505 (define_insn "*call_rex64_ms_sysv"
11506 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11508 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11509 (clobber (reg:TI XMM6_REG))
11510 (clobber (reg:TI XMM7_REG))
11511 (clobber (reg:TI XMM8_REG))
11512 (clobber (reg:TI XMM9_REG))
11513 (clobber (reg:TI XMM10_REG))
11514 (clobber (reg:TI XMM11_REG))
11515 (clobber (reg:TI XMM12_REG))
11516 (clobber (reg:TI XMM13_REG))
11517 (clobber (reg:TI XMM14_REG))
11518 (clobber (reg:TI XMM15_REG))
11519 (clobber (reg:DI SI_REG))
11520 (clobber (reg:DI DI_REG))]
11521 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11522 "* return ix86_output_call_insn (insn, operands[0]);"
11523 [(set_attr "type" "call")])
11525 (define_insn_and_split "*sibcall_vzeroupper"
11526 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11528 (unspec [(match_operand 2 "const_int_operand")]
11529 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11530 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11532 "&& reload_completed"
11534 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11535 [(set_attr "type" "call")])
11537 (define_insn "*sibcall"
11538 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11539 (match_operand 1))]
11540 "SIBLING_CALL_P (insn)"
11541 "* return ix86_output_call_insn (insn, operands[0]);"
11542 [(set_attr "type" "call")])
11544 (define_expand "call_pop"
11545 [(parallel [(call (match_operand:QI 0)
11546 (match_operand:SI 1))
11547 (set (reg:SI SP_REG)
11548 (plus:SI (reg:SI SP_REG)
11549 (match_operand:SI 3)))])]
11552 ix86_expand_call (NULL, operands[0], operands[1],
11553 operands[2], operands[3], false);
11557 (define_insn_and_split "*call_pop_vzeroupper"
11558 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11560 (set (reg:SI SP_REG)
11561 (plus:SI (reg:SI SP_REG)
11562 (match_operand:SI 2 "immediate_operand" "i")))
11563 (unspec [(match_operand 3 "const_int_operand")]
11564 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11565 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11567 "&& reload_completed"
11569 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11570 [(set_attr "type" "call")])
11572 (define_insn "*call_pop"
11573 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11575 (set (reg:SI SP_REG)
11576 (plus:SI (reg:SI SP_REG)
11577 (match_operand:SI 2 "immediate_operand" "i")))]
11578 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11579 "* return ix86_output_call_insn (insn, operands[0]);"
11580 [(set_attr "type" "call")])
11582 (define_insn_and_split "*sibcall_pop_vzeroupper"
11583 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11585 (set (reg:SI SP_REG)
11586 (plus:SI (reg:SI SP_REG)
11587 (match_operand:SI 2 "immediate_operand" "i")))
11588 (unspec [(match_operand 3 "const_int_operand")]
11589 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11590 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11592 "&& reload_completed"
11594 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11595 [(set_attr "type" "call")])
11597 (define_insn "*sibcall_pop"
11598 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11600 (set (reg:SI SP_REG)
11601 (plus:SI (reg:SI SP_REG)
11602 (match_operand:SI 2 "immediate_operand" "i")))]
11603 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11604 "* return ix86_output_call_insn (insn, operands[0]);"
11605 [(set_attr "type" "call")])
11607 ;; Call subroutine, returning value in operand 0
11609 (define_expand "call_value"
11610 [(set (match_operand 0)
11611 (call (match_operand:QI 1)
11612 (match_operand 2)))
11613 (use (match_operand 3))]
11616 ix86_expand_call (operands[0], operands[1], operands[2],
11617 operands[3], NULL, false);
11621 (define_expand "sibcall_value"
11622 [(set (match_operand 0)
11623 (call (match_operand:QI 1)
11624 (match_operand 2)))
11625 (use (match_operand 3))]
11628 ix86_expand_call (operands[0], operands[1], operands[2],
11629 operands[3], NULL, true);
11633 (define_insn_and_split "*call_value_vzeroupper"
11634 [(set (match_operand 0)
11635 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11636 (match_operand 2)))
11637 (unspec [(match_operand 3 "const_int_operand")]
11638 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11639 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11641 "&& reload_completed"
11643 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11644 [(set_attr "type" "callv")])
11646 (define_insn "*call_value"
11647 [(set (match_operand 0)
11648 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11649 (match_operand 2)))]
11650 "!SIBLING_CALL_P (insn)"
11651 "* return ix86_output_call_insn (insn, operands[1]);"
11652 [(set_attr "type" "callv")])
11654 (define_insn_and_split "*sibcall_value_vzeroupper"
11655 [(set (match_operand 0)
11656 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11657 (match_operand 2)))
11658 (unspec [(match_operand 3 "const_int_operand")]
11659 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11660 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11662 "&& reload_completed"
11664 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11665 [(set_attr "type" "callv")])
11667 (define_insn "*sibcall_value"
11668 [(set (match_operand 0)
11669 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11670 (match_operand 2)))]
11671 "SIBLING_CALL_P (insn)"
11672 "* return ix86_output_call_insn (insn, operands[1]);"
11673 [(set_attr "type" "callv")])
11675 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11676 [(set (match_operand 0)
11677 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11678 (match_operand 2)))
11679 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11680 (clobber (reg:TI XMM6_REG))
11681 (clobber (reg:TI XMM7_REG))
11682 (clobber (reg:TI XMM8_REG))
11683 (clobber (reg:TI XMM9_REG))
11684 (clobber (reg:TI XMM10_REG))
11685 (clobber (reg:TI XMM11_REG))
11686 (clobber (reg:TI XMM12_REG))
11687 (clobber (reg:TI XMM13_REG))
11688 (clobber (reg:TI XMM14_REG))
11689 (clobber (reg:TI XMM15_REG))
11690 (clobber (reg:DI SI_REG))
11691 (clobber (reg:DI DI_REG))
11692 (unspec [(match_operand 3 "const_int_operand")]
11693 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11694 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11696 "&& reload_completed"
11698 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11699 [(set_attr "type" "callv")])
11701 (define_insn "*call_value_rex64_ms_sysv"
11702 [(set (match_operand 0)
11703 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11704 (match_operand 2)))
11705 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11706 (clobber (reg:TI XMM6_REG))
11707 (clobber (reg:TI XMM7_REG))
11708 (clobber (reg:TI XMM8_REG))
11709 (clobber (reg:TI XMM9_REG))
11710 (clobber (reg:TI XMM10_REG))
11711 (clobber (reg:TI XMM11_REG))
11712 (clobber (reg:TI XMM12_REG))
11713 (clobber (reg:TI XMM13_REG))
11714 (clobber (reg:TI XMM14_REG))
11715 (clobber (reg:TI XMM15_REG))
11716 (clobber (reg:DI SI_REG))
11717 (clobber (reg:DI DI_REG))]
11718 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11719 "* return ix86_output_call_insn (insn, operands[1]);"
11720 [(set_attr "type" "callv")])
11722 (define_expand "call_value_pop"
11723 [(parallel [(set (match_operand 0)
11724 (call (match_operand:QI 1)
11725 (match_operand:SI 2)))
11726 (set (reg:SI SP_REG)
11727 (plus:SI (reg:SI SP_REG)
11728 (match_operand:SI 4)))])]
11731 ix86_expand_call (operands[0], operands[1], operands[2],
11732 operands[3], operands[4], false);
11736 (define_insn_and_split "*call_value_pop_vzeroupper"
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 (unspec [(match_operand 4 "const_int_operand")]
11744 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11745 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11747 "&& reload_completed"
11749 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11750 [(set_attr "type" "callv")])
11752 (define_insn "*call_value_pop"
11753 [(set (match_operand 0)
11754 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11755 (match_operand 2)))
11756 (set (reg:SI SP_REG)
11757 (plus:SI (reg:SI SP_REG)
11758 (match_operand:SI 3 "immediate_operand" "i")))]
11759 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11760 "* return ix86_output_call_insn (insn, operands[1]);"
11761 [(set_attr "type" "callv")])
11763 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
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 (unspec [(match_operand 4 "const_int_operand")]
11771 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11772 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11774 "&& reload_completed"
11776 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11777 [(set_attr "type" "callv")])
11779 (define_insn "*sibcall_value_pop"
11780 [(set (match_operand 0)
11781 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11782 (match_operand 2)))
11783 (set (reg:SI SP_REG)
11784 (plus:SI (reg:SI SP_REG)
11785 (match_operand:SI 3 "immediate_operand" "i")))]
11786 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11787 "* return ix86_output_call_insn (insn, operands[1]);"
11788 [(set_attr "type" "callv")])
11790 ;; Call subroutine returning any type.
11792 (define_expand "untyped_call"
11793 [(parallel [(call (match_operand 0)
11796 (match_operand 2)])]
11801 /* In order to give reg-stack an easier job in validating two
11802 coprocessor registers as containing a possible return value,
11803 simply pretend the untyped call returns a complex long double
11806 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11807 and should have the default ABI. */
11809 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11810 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11811 operands[0], const0_rtx,
11812 GEN_INT ((TARGET_64BIT
11813 ? (ix86_abi == SYSV_ABI
11814 ? X86_64_SSE_REGPARM_MAX
11815 : X86_64_MS_SSE_REGPARM_MAX)
11816 : X86_32_SSE_REGPARM_MAX)
11820 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11822 rtx set = XVECEXP (operands[2], 0, i);
11823 emit_move_insn (SET_DEST (set), SET_SRC (set));
11826 /* The optimizer does not know that the call sets the function value
11827 registers we stored in the result block. We avoid problems by
11828 claiming that all hard registers are used and clobbered at this
11830 emit_insn (gen_blockage ());
11835 ;; Prologue and epilogue instructions
11837 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11838 ;; all of memory. This blocks insns from being moved across this point.
11840 (define_insn "blockage"
11841 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11844 [(set_attr "length" "0")])
11846 ;; Do not schedule instructions accessing memory across this point.
11848 (define_expand "memory_blockage"
11849 [(set (match_dup 0)
11850 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11853 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11854 MEM_VOLATILE_P (operands[0]) = 1;
11857 (define_insn "*memory_blockage"
11858 [(set (match_operand:BLK 0)
11859 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11862 [(set_attr "length" "0")])
11864 ;; As USE insns aren't meaningful after reload, this is used instead
11865 ;; to prevent deleting instructions setting registers for PIC code
11866 (define_insn "prologue_use"
11867 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11870 [(set_attr "length" "0")])
11872 ;; Insn emitted into the body of a function to return from a function.
11873 ;; This is only done if the function's epilogue is known to be simple.
11874 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11876 (define_expand "return"
11878 "ix86_can_use_return_insn_p ()"
11880 ix86_maybe_emit_epilogue_vzeroupper ();
11881 if (crtl->args.pops_args)
11883 rtx popc = GEN_INT (crtl->args.pops_args);
11884 emit_jump_insn (gen_simple_return_pop_internal (popc));
11889 ;; We need to disable this for TARGET_SEH, as otherwise
11890 ;; shrink-wrapped prologue gets enabled too. This might exceed
11891 ;; the maximum size of prologue in unwind information.
11893 (define_expand "simple_return"
11897 ix86_maybe_emit_epilogue_vzeroupper ();
11898 if (crtl->args.pops_args)
11900 rtx popc = GEN_INT (crtl->args.pops_args);
11901 emit_jump_insn (gen_simple_return_pop_internal (popc));
11906 (define_insn "simple_return_internal"
11910 [(set_attr "length" "1")
11911 (set_attr "atom_unit" "jeu")
11912 (set_attr "length_immediate" "0")
11913 (set_attr "modrm" "0")])
11915 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11916 ;; instruction Athlon and K8 have.
11918 (define_insn "simple_return_internal_long"
11920 (unspec [(const_int 0)] UNSPEC_REP)]
11923 [(set_attr "length" "2")
11924 (set_attr "atom_unit" "jeu")
11925 (set_attr "length_immediate" "0")
11926 (set_attr "prefix_rep" "1")
11927 (set_attr "modrm" "0")])
11929 (define_insn "simple_return_pop_internal"
11931 (use (match_operand:SI 0 "const_int_operand"))]
11934 [(set_attr "length" "3")
11935 (set_attr "atom_unit" "jeu")
11936 (set_attr "length_immediate" "2")
11937 (set_attr "modrm" "0")])
11939 (define_insn "simple_return_indirect_internal"
11941 (use (match_operand:SI 0 "register_operand" "r"))]
11944 [(set_attr "type" "ibr")
11945 (set_attr "length_immediate" "0")])
11951 [(set_attr "length" "1")
11952 (set_attr "length_immediate" "0")
11953 (set_attr "modrm" "0")])
11955 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11956 (define_insn "nops"
11957 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11961 int num = INTVAL (operands[0]);
11963 gcc_assert (IN_RANGE (num, 1, 8));
11966 fputs ("\tnop\n", asm_out_file);
11970 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11971 (set_attr "length_immediate" "0")
11972 (set_attr "modrm" "0")])
11974 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11975 ;; branch prediction penalty for the third jump in a 16-byte
11979 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11982 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11983 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11985 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11986 The align insn is used to avoid 3 jump instructions in the row to improve
11987 branch prediction and the benefits hardly outweigh the cost of extra 8
11988 nops on the average inserted by full alignment pseudo operation. */
11992 [(set_attr "length" "16")])
11994 (define_expand "prologue"
11997 "ix86_expand_prologue (); DONE;")
11999 (define_insn "set_got"
12000 [(set (match_operand:SI 0 "register_operand" "=r")
12001 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12002 (clobber (reg:CC FLAGS_REG))]
12004 "* return output_set_got (operands[0], NULL_RTX);"
12005 [(set_attr "type" "multi")
12006 (set_attr "length" "12")])
12008 (define_insn "set_got_labelled"
12009 [(set (match_operand:SI 0 "register_operand" "=r")
12010 (unspec:SI [(label_ref (match_operand 1))]
12012 (clobber (reg:CC FLAGS_REG))]
12014 "* return output_set_got (operands[0], operands[1]);"
12015 [(set_attr "type" "multi")
12016 (set_attr "length" "12")])
12018 (define_insn "set_got_rex64"
12019 [(set (match_operand:DI 0 "register_operand" "=r")
12020 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12022 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12023 [(set_attr "type" "lea")
12024 (set_attr "length_address" "4")
12025 (set_attr "mode" "DI")])
12027 (define_insn "set_rip_rex64"
12028 [(set (match_operand:DI 0 "register_operand" "=r")
12029 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12031 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12032 [(set_attr "type" "lea")
12033 (set_attr "length_address" "4")
12034 (set_attr "mode" "DI")])
12036 (define_insn "set_got_offset_rex64"
12037 [(set (match_operand:DI 0 "register_operand" "=r")
12039 [(label_ref (match_operand 1))]
12040 UNSPEC_SET_GOT_OFFSET))]
12042 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12043 [(set_attr "type" "imov")
12044 (set_attr "length_immediate" "0")
12045 (set_attr "length_address" "8")
12046 (set_attr "mode" "DI")])
12048 (define_expand "epilogue"
12051 "ix86_expand_epilogue (1); DONE;")
12053 (define_expand "sibcall_epilogue"
12056 "ix86_expand_epilogue (0); DONE;")
12058 (define_expand "eh_return"
12059 [(use (match_operand 0 "register_operand"))]
12062 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12064 /* Tricky bit: we write the address of the handler to which we will
12065 be returning into someone else's stack frame, one word below the
12066 stack address we wish to restore. */
12067 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12068 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12069 tmp = gen_rtx_MEM (Pmode, tmp);
12070 emit_move_insn (tmp, ra);
12072 emit_jump_insn (gen_eh_return_internal ());
12077 (define_insn_and_split "eh_return_internal"
12081 "epilogue_completed"
12083 "ix86_expand_epilogue (2); DONE;")
12085 (define_insn "leave"
12086 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12087 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12088 (clobber (mem:BLK (scratch)))]
12091 [(set_attr "type" "leave")])
12093 (define_insn "leave_rex64"
12094 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12095 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12096 (clobber (mem:BLK (scratch)))]
12099 [(set_attr "type" "leave")])
12101 ;; Handle -fsplit-stack.
12103 (define_expand "split_stack_prologue"
12107 ix86_expand_split_stack_prologue ();
12111 ;; In order to support the call/return predictor, we use a return
12112 ;; instruction which the middle-end doesn't see.
12113 (define_insn "split_stack_return"
12114 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12115 UNSPECV_SPLIT_STACK_RETURN)]
12118 if (operands[0] == const0_rtx)
12123 [(set_attr "atom_unit" "jeu")
12124 (set_attr "modrm" "0")
12125 (set (attr "length")
12126 (if_then_else (match_operand:SI 0 "const0_operand")
12129 (set (attr "length_immediate")
12130 (if_then_else (match_operand:SI 0 "const0_operand")
12134 ;; If there are operand 0 bytes available on the stack, jump to
12137 (define_expand "split_stack_space_check"
12138 [(set (pc) (if_then_else
12139 (ltu (minus (reg SP_REG)
12140 (match_operand 0 "register_operand"))
12141 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12142 (label_ref (match_operand 1))
12146 rtx reg, size, limit;
12148 reg = gen_reg_rtx (Pmode);
12149 size = force_reg (Pmode, operands[0]);
12150 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12151 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12152 UNSPEC_STACK_CHECK);
12153 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12154 ix86_expand_branch (GEU, reg, limit, operands[1]);
12159 ;; Bit manipulation instructions.
12161 (define_expand "ffs<mode>2"
12162 [(set (match_dup 2) (const_int -1))
12163 (parallel [(set (match_dup 3) (match_dup 4))
12164 (set (match_operand:SWI48 0 "register_operand")
12166 (match_operand:SWI48 1 "nonimmediate_operand")))])
12167 (set (match_dup 0) (if_then_else:SWI48
12168 (eq (match_dup 3) (const_int 0))
12171 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12172 (clobber (reg:CC FLAGS_REG))])]
12175 enum machine_mode flags_mode;
12177 if (<MODE>mode == SImode && !TARGET_CMOVE)
12179 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12183 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12185 operands[2] = gen_reg_rtx (<MODE>mode);
12186 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12187 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12190 (define_insn_and_split "ffssi2_no_cmove"
12191 [(set (match_operand:SI 0 "register_operand" "=r")
12192 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12193 (clobber (match_scratch:SI 2 "=&q"))
12194 (clobber (reg:CC FLAGS_REG))]
12197 "&& reload_completed"
12198 [(parallel [(set (match_dup 4) (match_dup 5))
12199 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12200 (set (strict_low_part (match_dup 3))
12201 (eq:QI (match_dup 4) (const_int 0)))
12202 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12203 (clobber (reg:CC FLAGS_REG))])
12204 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12205 (clobber (reg:CC FLAGS_REG))])
12206 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12207 (clobber (reg:CC FLAGS_REG))])]
12209 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12211 operands[3] = gen_lowpart (QImode, operands[2]);
12212 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12213 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12215 ix86_expand_clear (operands[2]);
12218 (define_insn "*tzcnt<mode>_1"
12219 [(set (reg:CCC FLAGS_REG)
12220 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12222 (set (match_operand:SWI48 0 "register_operand" "=r")
12223 (ctz:SWI48 (match_dup 1)))]
12225 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12226 [(set_attr "type" "alu1")
12227 (set_attr "prefix_0f" "1")
12228 (set_attr "prefix_rep" "1")
12229 (set_attr "mode" "<MODE>")])
12231 (define_insn "*bsf<mode>_1"
12232 [(set (reg:CCZ FLAGS_REG)
12233 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12235 (set (match_operand:SWI48 0 "register_operand" "=r")
12236 (ctz:SWI48 (match_dup 1)))]
12238 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12239 [(set_attr "type" "alu1")
12240 (set_attr "prefix_0f" "1")
12241 (set_attr "mode" "<MODE>")])
12243 (define_insn "ctz<mode>2"
12244 [(set (match_operand:SWI248 0 "register_operand" "=r")
12245 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12246 (clobber (reg:CC FLAGS_REG))]
12250 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12251 else if (optimize_function_for_size_p (cfun))
12253 else if (TARGET_GENERIC)
12254 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12255 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12257 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12259 [(set_attr "type" "alu1")
12260 (set_attr "prefix_0f" "1")
12261 (set (attr "prefix_rep")
12263 (ior (match_test "TARGET_BMI")
12264 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12265 (match_test "TARGET_GENERIC")))
12267 (const_string "0")))
12268 (set_attr "mode" "<MODE>")])
12270 (define_expand "clz<mode>2"
12272 [(set (match_operand:SWI248 0 "register_operand")
12275 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12276 (clobber (reg:CC FLAGS_REG))])
12278 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12279 (clobber (reg:CC FLAGS_REG))])]
12284 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12287 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12290 (define_insn "clz<mode>2_lzcnt"
12291 [(set (match_operand:SWI248 0 "register_operand" "=r")
12292 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12293 (clobber (reg:CC FLAGS_REG))]
12295 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12296 [(set_attr "prefix_rep" "1")
12297 (set_attr "type" "bitmanip")
12298 (set_attr "mode" "<MODE>")])
12300 ;; BMI instructions.
12301 (define_insn "*bmi_andn_<mode>"
12302 [(set (match_operand:SWI48 0 "register_operand" "=r")
12305 (match_operand:SWI48 1 "register_operand" "r"))
12306 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12307 (clobber (reg:CC FLAGS_REG))]
12309 "andn\t{%2, %1, %0|%0, %1, %2}"
12310 [(set_attr "type" "bitmanip")
12311 (set_attr "mode" "<MODE>")])
12313 (define_insn "bmi_bextr_<mode>"
12314 [(set (match_operand:SWI48 0 "register_operand" "=r")
12315 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12316 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12318 (clobber (reg:CC FLAGS_REG))]
12320 "bextr\t{%2, %1, %0|%0, %1, %2}"
12321 [(set_attr "type" "bitmanip")
12322 (set_attr "mode" "<MODE>")])
12324 (define_insn "*bmi_blsi_<mode>"
12325 [(set (match_operand:SWI48 0 "register_operand" "=r")
12328 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12330 (clobber (reg:CC FLAGS_REG))]
12332 "blsi\t{%1, %0|%0, %1}"
12333 [(set_attr "type" "bitmanip")
12334 (set_attr "mode" "<MODE>")])
12336 (define_insn "*bmi_blsmsk_<mode>"
12337 [(set (match_operand:SWI48 0 "register_operand" "=r")
12340 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12343 (clobber (reg:CC FLAGS_REG))]
12345 "blsmsk\t{%1, %0|%0, %1}"
12346 [(set_attr "type" "bitmanip")
12347 (set_attr "mode" "<MODE>")])
12349 (define_insn "*bmi_blsr_<mode>"
12350 [(set (match_operand:SWI48 0 "register_operand" "=r")
12353 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12356 (clobber (reg:CC FLAGS_REG))]
12358 "blsr\t{%1, %0|%0, %1}"
12359 [(set_attr "type" "bitmanip")
12360 (set_attr "mode" "<MODE>")])
12362 ;; BMI2 instructions.
12363 (define_insn "bmi2_bzhi_<mode>3"
12364 [(set (match_operand:SWI48 0 "register_operand" "=r")
12365 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12366 (lshiftrt:SWI48 (const_int -1)
12367 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12368 (clobber (reg:CC FLAGS_REG))]
12370 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12371 [(set_attr "type" "bitmanip")
12372 (set_attr "prefix" "vex")
12373 (set_attr "mode" "<MODE>")])
12375 (define_insn "bmi2_pdep_<mode>3"
12376 [(set (match_operand:SWI48 0 "register_operand" "=r")
12377 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12378 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12381 "pdep\t{%2, %1, %0|%0, %1, %2}"
12382 [(set_attr "type" "bitmanip")
12383 (set_attr "prefix" "vex")
12384 (set_attr "mode" "<MODE>")])
12386 (define_insn "bmi2_pext_<mode>3"
12387 [(set (match_operand:SWI48 0 "register_operand" "=r")
12388 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12389 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12392 "pext\t{%2, %1, %0|%0, %1, %2}"
12393 [(set_attr "type" "bitmanip")
12394 (set_attr "prefix" "vex")
12395 (set_attr "mode" "<MODE>")])
12397 ;; TBM instructions.
12398 (define_insn "tbm_bextri_<mode>"
12399 [(set (match_operand:SWI48 0 "register_operand" "=r")
12400 (zero_extract:SWI48
12401 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12402 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12403 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12404 (clobber (reg:CC FLAGS_REG))]
12407 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12408 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12410 [(set_attr "type" "bitmanip")
12411 (set_attr "mode" "<MODE>")])
12413 (define_insn "*tbm_blcfill_<mode>"
12414 [(set (match_operand:SWI48 0 "register_operand" "=r")
12417 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12420 (clobber (reg:CC FLAGS_REG))]
12422 "blcfill\t{%1, %0|%0, %1}"
12423 [(set_attr "type" "bitmanip")
12424 (set_attr "mode" "<MODE>")])
12426 (define_insn "*tbm_blci_<mode>"
12427 [(set (match_operand:SWI48 0 "register_operand" "=r")
12431 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12434 (clobber (reg:CC FLAGS_REG))]
12436 "blci\t{%1, %0|%0, %1}"
12437 [(set_attr "type" "bitmanip")
12438 (set_attr "mode" "<MODE>")])
12440 (define_insn "*tbm_blcic_<mode>"
12441 [(set (match_operand:SWI48 0 "register_operand" "=r")
12444 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12448 (clobber (reg:CC FLAGS_REG))]
12450 "blcic\t{%1, %0|%0, %1}"
12451 [(set_attr "type" "bitmanip")
12452 (set_attr "mode" "<MODE>")])
12454 (define_insn "*tbm_blcmsk_<mode>"
12455 [(set (match_operand:SWI48 0 "register_operand" "=r")
12458 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12461 (clobber (reg:CC FLAGS_REG))]
12463 "blcmsk\t{%1, %0|%0, %1}"
12464 [(set_attr "type" "bitmanip")
12465 (set_attr "mode" "<MODE>")])
12467 (define_insn "*tbm_blcs_<mode>"
12468 [(set (match_operand:SWI48 0 "register_operand" "=r")
12471 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12474 (clobber (reg:CC FLAGS_REG))]
12476 "blcs\t{%1, %0|%0, %1}"
12477 [(set_attr "type" "bitmanip")
12478 (set_attr "mode" "<MODE>")])
12480 (define_insn "*tbm_blsfill_<mode>"
12481 [(set (match_operand:SWI48 0 "register_operand" "=r")
12484 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12487 (clobber (reg:CC FLAGS_REG))]
12489 "blsfill\t{%1, %0|%0, %1}"
12490 [(set_attr "type" "bitmanip")
12491 (set_attr "mode" "<MODE>")])
12493 (define_insn "*tbm_blsic_<mode>"
12494 [(set (match_operand:SWI48 0 "register_operand" "=r")
12497 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12501 (clobber (reg:CC FLAGS_REG))]
12503 "blsic\t{%1, %0|%0, %1}"
12504 [(set_attr "type" "bitmanip")
12505 (set_attr "mode" "<MODE>")])
12507 (define_insn "*tbm_t1mskc_<mode>"
12508 [(set (match_operand:SWI48 0 "register_operand" "=r")
12511 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12515 (clobber (reg:CC FLAGS_REG))]
12517 "t1mskc\t{%1, %0|%0, %1}"
12518 [(set_attr "type" "bitmanip")
12519 (set_attr "mode" "<MODE>")])
12521 (define_insn "*tbm_tzmsk_<mode>"
12522 [(set (match_operand:SWI48 0 "register_operand" "=r")
12525 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12529 (clobber (reg:CC FLAGS_REG))]
12531 "tzmsk\t{%1, %0|%0, %1}"
12532 [(set_attr "type" "bitmanip")
12533 (set_attr "mode" "<MODE>")])
12535 (define_insn "bsr_rex64"
12536 [(set (match_operand:DI 0 "register_operand" "=r")
12537 (minus:DI (const_int 63)
12538 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12539 (clobber (reg:CC FLAGS_REG))]
12541 "bsr{q}\t{%1, %0|%0, %1}"
12542 [(set_attr "type" "alu1")
12543 (set_attr "prefix_0f" "1")
12544 (set_attr "mode" "DI")])
12547 [(set (match_operand:SI 0 "register_operand" "=r")
12548 (minus:SI (const_int 31)
12549 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12550 (clobber (reg:CC FLAGS_REG))]
12552 "bsr{l}\t{%1, %0|%0, %1}"
12553 [(set_attr "type" "alu1")
12554 (set_attr "prefix_0f" "1")
12555 (set_attr "mode" "SI")])
12557 (define_insn "*bsrhi"
12558 [(set (match_operand:HI 0 "register_operand" "=r")
12559 (minus:HI (const_int 15)
12560 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12561 (clobber (reg:CC FLAGS_REG))]
12563 "bsr{w}\t{%1, %0|%0, %1}"
12564 [(set_attr "type" "alu1")
12565 (set_attr "prefix_0f" "1")
12566 (set_attr "mode" "HI")])
12568 (define_insn "popcount<mode>2"
12569 [(set (match_operand:SWI248 0 "register_operand" "=r")
12571 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12572 (clobber (reg:CC FLAGS_REG))]
12576 return "popcnt\t{%1, %0|%0, %1}";
12578 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12581 [(set_attr "prefix_rep" "1")
12582 (set_attr "type" "bitmanip")
12583 (set_attr "mode" "<MODE>")])
12585 (define_insn "*popcount<mode>2_cmp"
12586 [(set (reg FLAGS_REG)
12589 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12591 (set (match_operand:SWI248 0 "register_operand" "=r")
12592 (popcount:SWI248 (match_dup 1)))]
12593 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12596 return "popcnt\t{%1, %0|%0, %1}";
12598 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12601 [(set_attr "prefix_rep" "1")
12602 (set_attr "type" "bitmanip")
12603 (set_attr "mode" "<MODE>")])
12605 (define_insn "*popcountsi2_cmp_zext"
12606 [(set (reg FLAGS_REG)
12608 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12610 (set (match_operand:DI 0 "register_operand" "=r")
12611 (zero_extend:DI(popcount:SI (match_dup 1))))]
12612 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12615 return "popcnt\t{%1, %0|%0, %1}";
12617 return "popcnt{l}\t{%1, %0|%0, %1}";
12620 [(set_attr "prefix_rep" "1")
12621 (set_attr "type" "bitmanip")
12622 (set_attr "mode" "SI")])
12624 (define_expand "bswapdi2"
12625 [(set (match_operand:DI 0 "register_operand")
12626 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12629 if (TARGET_64BIT && !TARGET_MOVBE)
12630 operands[1] = force_reg (DImode, operands[1]);
12633 (define_insn_and_split "*bswapdi2_doubleword"
12634 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12636 (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12638 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12640 "&& reload_completed"
12641 [(set (match_dup 2)
12642 (bswap:SI (match_dup 1)))
12644 (bswap:SI (match_dup 3)))]
12646 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
12648 if (REG_P (operands[0]) && REG_P (operands[1]))
12650 emit_insn (gen_swapsi (operands[0], operands[2]));
12651 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12652 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12658 if (MEM_P (operands[0]))
12660 emit_insn (gen_bswapsi2 (operands[3], operands[3]));
12661 emit_insn (gen_bswapsi2 (operands[1], operands[1]));
12663 emit_move_insn (operands[0], operands[3]);
12664 emit_move_insn (operands[2], operands[1]);
12666 if (MEM_P (operands[1]))
12668 emit_move_insn (operands[2], operands[1]);
12669 emit_move_insn (operands[0], operands[3]);
12671 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12672 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12678 (define_expand "bswapsi2"
12679 [(set (match_operand:SI 0 "register_operand")
12680 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12685 else if (TARGET_BSWAP)
12686 operands[1] = force_reg (SImode, operands[1]);
12689 rtx x = operands[0];
12691 emit_move_insn (x, operands[1]);
12692 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12693 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12694 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12699 (define_insn "*bswap<mode>2_movbe"
12700 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12701 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12703 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12706 movbe\t{%1, %0|%0, %1}
12707 movbe\t{%1, %0|%0, %1}"
12708 [(set_attr "type" "bitmanip,imov,imov")
12709 (set_attr "modrm" "0,1,1")
12710 (set_attr "prefix_0f" "*,1,1")
12711 (set_attr "prefix_extra" "*,1,1")
12712 (set_attr "mode" "<MODE>")])
12714 (define_insn "*bswap<mode>2"
12715 [(set (match_operand:SWI48 0 "register_operand" "=r")
12716 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12719 [(set_attr "type" "bitmanip")
12720 (set_attr "modrm" "0")
12721 (set_attr "mode" "<MODE>")])
12723 (define_insn "*bswaphi_lowpart_1"
12724 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12725 (bswap:HI (match_dup 0)))
12726 (clobber (reg:CC FLAGS_REG))]
12727 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12729 xchg{b}\t{%h0, %b0|%b0, %h0}
12730 rol{w}\t{$8, %0|%0, 8}"
12731 [(set_attr "length" "2,4")
12732 (set_attr "mode" "QI,HI")])
12734 (define_insn "bswaphi_lowpart"
12735 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12736 (bswap:HI (match_dup 0)))
12737 (clobber (reg:CC FLAGS_REG))]
12739 "rol{w}\t{$8, %0|%0, 8}"
12740 [(set_attr "length" "4")
12741 (set_attr "mode" "HI")])
12743 (define_expand "paritydi2"
12744 [(set (match_operand:DI 0 "register_operand")
12745 (parity:DI (match_operand:DI 1 "register_operand")))]
12748 rtx scratch = gen_reg_rtx (QImode);
12751 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12752 NULL_RTX, operands[1]));
12754 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12755 gen_rtx_REG (CCmode, FLAGS_REG),
12757 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12760 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12763 rtx tmp = gen_reg_rtx (SImode);
12765 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12766 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12771 (define_expand "paritysi2"
12772 [(set (match_operand:SI 0 "register_operand")
12773 (parity:SI (match_operand:SI 1 "register_operand")))]
12776 rtx scratch = gen_reg_rtx (QImode);
12779 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12781 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12782 gen_rtx_REG (CCmode, FLAGS_REG),
12784 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12786 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12790 (define_insn_and_split "paritydi2_cmp"
12791 [(set (reg:CC FLAGS_REG)
12792 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12794 (clobber (match_scratch:DI 0 "=r"))
12795 (clobber (match_scratch:SI 1 "=&r"))
12796 (clobber (match_scratch:HI 2 "=Q"))]
12799 "&& reload_completed"
12801 [(set (match_dup 1)
12802 (xor:SI (match_dup 1) (match_dup 4)))
12803 (clobber (reg:CC FLAGS_REG))])
12805 [(set (reg:CC FLAGS_REG)
12806 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12807 (clobber (match_dup 1))
12808 (clobber (match_dup 2))])]
12810 operands[4] = gen_lowpart (SImode, operands[3]);
12814 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12815 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12818 operands[1] = gen_highpart (SImode, operands[3]);
12821 (define_insn_and_split "paritysi2_cmp"
12822 [(set (reg:CC FLAGS_REG)
12823 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12825 (clobber (match_scratch:SI 0 "=r"))
12826 (clobber (match_scratch:HI 1 "=&Q"))]
12829 "&& reload_completed"
12831 [(set (match_dup 1)
12832 (xor:HI (match_dup 1) (match_dup 3)))
12833 (clobber (reg:CC FLAGS_REG))])
12835 [(set (reg:CC FLAGS_REG)
12836 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12837 (clobber (match_dup 1))])]
12839 operands[3] = gen_lowpart (HImode, operands[2]);
12841 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12842 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12845 (define_insn "*parityhi2_cmp"
12846 [(set (reg:CC FLAGS_REG)
12847 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12849 (clobber (match_scratch:HI 0 "=Q"))]
12851 "xor{b}\t{%h0, %b0|%b0, %h0}"
12852 [(set_attr "length" "2")
12853 (set_attr "mode" "HI")])
12856 ;; Thread-local storage patterns for ELF.
12858 ;; Note that these code sequences must appear exactly as shown
12859 ;; in order to allow linker relaxation.
12861 (define_insn "*tls_global_dynamic_32_gnu"
12862 [(set (match_operand:SI 0 "register_operand" "=a")
12864 [(match_operand:SI 1 "register_operand" "b")
12865 (match_operand 2 "tls_symbolic_operand")
12866 (match_operand 3 "constant_call_address_operand" "z")]
12868 (clobber (match_scratch:SI 4 "=d"))
12869 (clobber (match_scratch:SI 5 "=c"))
12870 (clobber (reg:CC FLAGS_REG))]
12871 "!TARGET_64BIT && TARGET_GNU_TLS"
12874 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12875 if (TARGET_SUN_TLS)
12876 #ifdef HAVE_AS_IX86_TLSGDPLT
12877 return "call\t%a2@tlsgdplt";
12879 return "call\t%p3@plt";
12881 return "call\t%P3";
12883 [(set_attr "type" "multi")
12884 (set_attr "length" "12")])
12886 (define_expand "tls_global_dynamic_32"
12888 [(set (match_operand:SI 0 "register_operand")
12889 (unspec:SI [(match_operand:SI 2 "register_operand")
12890 (match_operand 1 "tls_symbolic_operand")
12891 (match_operand 3 "constant_call_address_operand")]
12893 (clobber (match_scratch:SI 4))
12894 (clobber (match_scratch:SI 5))
12895 (clobber (reg:CC FLAGS_REG))])])
12897 (define_insn "*tls_global_dynamic_64_<mode>"
12898 [(set (match_operand:P 0 "register_operand" "=a")
12900 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12901 (match_operand 3)))
12902 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12907 fputs (ASM_BYTE "0x66\n", asm_out_file);
12909 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12910 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12911 fputs ("\trex64\n", asm_out_file);
12912 if (TARGET_SUN_TLS)
12913 return "call\t%p2@plt";
12914 return "call\t%P2";
12916 [(set_attr "type" "multi")
12917 (set (attr "length")
12918 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12920 (define_expand "tls_global_dynamic_64_<mode>"
12922 [(set (match_operand:P 0 "register_operand")
12924 (mem:QI (match_operand 2 "constant_call_address_operand"))
12926 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12930 (define_insn "*tls_local_dynamic_base_32_gnu"
12931 [(set (match_operand:SI 0 "register_operand" "=a")
12933 [(match_operand:SI 1 "register_operand" "b")
12934 (match_operand 2 "constant_call_address_operand" "z")]
12935 UNSPEC_TLS_LD_BASE))
12936 (clobber (match_scratch:SI 3 "=d"))
12937 (clobber (match_scratch:SI 4 "=c"))
12938 (clobber (reg:CC FLAGS_REG))]
12939 "!TARGET_64BIT && TARGET_GNU_TLS"
12942 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12943 if (TARGET_SUN_TLS)
12944 #ifdef HAVE_AS_IX86_TLSLDMPLT
12945 return "call\t%&@tlsldmplt";
12947 return "call\t%p2@plt";
12949 return "call\t%P2";
12951 [(set_attr "type" "multi")
12952 (set_attr "length" "11")])
12954 (define_expand "tls_local_dynamic_base_32"
12956 [(set (match_operand:SI 0 "register_operand")
12958 [(match_operand:SI 1 "register_operand")
12959 (match_operand 2 "constant_call_address_operand")]
12960 UNSPEC_TLS_LD_BASE))
12961 (clobber (match_scratch:SI 3))
12962 (clobber (match_scratch:SI 4))
12963 (clobber (reg:CC FLAGS_REG))])])
12965 (define_insn "*tls_local_dynamic_base_64_<mode>"
12966 [(set (match_operand:P 0 "register_operand" "=a")
12968 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12969 (match_operand 2)))
12970 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12974 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12975 if (TARGET_SUN_TLS)
12976 return "call\t%p1@plt";
12977 return "call\t%P1";
12979 [(set_attr "type" "multi")
12980 (set_attr "length" "12")])
12982 (define_expand "tls_local_dynamic_base_64_<mode>"
12984 [(set (match_operand:P 0 "register_operand")
12986 (mem:QI (match_operand 1 "constant_call_address_operand"))
12988 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12991 ;; Local dynamic of a single variable is a lose. Show combine how
12992 ;; to convert that back to global dynamic.
12994 (define_insn_and_split "*tls_local_dynamic_32_once"
12995 [(set (match_operand:SI 0 "register_operand" "=a")
12997 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12998 (match_operand 2 "constant_call_address_operand" "z")]
12999 UNSPEC_TLS_LD_BASE)
13000 (const:SI (unspec:SI
13001 [(match_operand 3 "tls_symbolic_operand")]
13003 (clobber (match_scratch:SI 4 "=d"))
13004 (clobber (match_scratch:SI 5 "=c"))
13005 (clobber (reg:CC FLAGS_REG))]
13010 [(set (match_dup 0)
13011 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13013 (clobber (match_dup 4))
13014 (clobber (match_dup 5))
13015 (clobber (reg:CC FLAGS_REG))])])
13017 ;; Segment register for the thread base ptr load
13018 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13020 ;; Load and add the thread base pointer from %<tp_seg>:0.
13021 (define_insn "*load_tp_x32"
13022 [(set (match_operand:SI 0 "register_operand" "=r")
13023 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13025 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13026 [(set_attr "type" "imov")
13027 (set_attr "modrm" "0")
13028 (set_attr "length" "7")
13029 (set_attr "memory" "load")
13030 (set_attr "imm_disp" "false")])
13032 (define_insn "*load_tp_x32_zext"
13033 [(set (match_operand:DI 0 "register_operand" "=r")
13034 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13036 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13037 [(set_attr "type" "imov")
13038 (set_attr "modrm" "0")
13039 (set_attr "length" "7")
13040 (set_attr "memory" "load")
13041 (set_attr "imm_disp" "false")])
13043 (define_insn "*load_tp_<mode>"
13044 [(set (match_operand:P 0 "register_operand" "=r")
13045 (unspec:P [(const_int 0)] UNSPEC_TP))]
13047 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13048 [(set_attr "type" "imov")
13049 (set_attr "modrm" "0")
13050 (set_attr "length" "7")
13051 (set_attr "memory" "load")
13052 (set_attr "imm_disp" "false")])
13054 (define_insn "*add_tp_x32"
13055 [(set (match_operand:SI 0 "register_operand" "=r")
13056 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13057 (match_operand:SI 1 "register_operand" "0")))
13058 (clobber (reg:CC FLAGS_REG))]
13060 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13061 [(set_attr "type" "alu")
13062 (set_attr "modrm" "0")
13063 (set_attr "length" "7")
13064 (set_attr "memory" "load")
13065 (set_attr "imm_disp" "false")])
13067 (define_insn "*add_tp_x32_zext"
13068 [(set (match_operand:DI 0 "register_operand" "=r")
13070 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13071 (match_operand:SI 1 "register_operand" "0"))))
13072 (clobber (reg:CC FLAGS_REG))]
13074 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13075 [(set_attr "type" "alu")
13076 (set_attr "modrm" "0")
13077 (set_attr "length" "7")
13078 (set_attr "memory" "load")
13079 (set_attr "imm_disp" "false")])
13081 (define_insn "*add_tp_<mode>"
13082 [(set (match_operand:P 0 "register_operand" "=r")
13083 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13084 (match_operand:P 1 "register_operand" "0")))
13085 (clobber (reg:CC FLAGS_REG))]
13087 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13088 [(set_attr "type" "alu")
13089 (set_attr "modrm" "0")
13090 (set_attr "length" "7")
13091 (set_attr "memory" "load")
13092 (set_attr "imm_disp" "false")])
13094 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13095 ;; %rax as destination of the initial executable code sequence.
13096 (define_insn "tls_initial_exec_64_sun"
13097 [(set (match_operand:DI 0 "register_operand" "=a")
13099 [(match_operand 1 "tls_symbolic_operand")]
13100 UNSPEC_TLS_IE_SUN))
13101 (clobber (reg:CC FLAGS_REG))]
13102 "TARGET_64BIT && TARGET_SUN_TLS"
13105 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13106 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13108 [(set_attr "type" "multi")])
13110 ;; GNU2 TLS patterns can be split.
13112 (define_expand "tls_dynamic_gnu2_32"
13113 [(set (match_dup 3)
13114 (plus:SI (match_operand:SI 2 "register_operand")
13116 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13119 [(set (match_operand:SI 0 "register_operand")
13120 (unspec:SI [(match_dup 1) (match_dup 3)
13121 (match_dup 2) (reg:SI SP_REG)]
13123 (clobber (reg:CC FLAGS_REG))])]
13124 "!TARGET_64BIT && TARGET_GNU2_TLS"
13126 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13127 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13130 (define_insn "*tls_dynamic_gnu2_lea_32"
13131 [(set (match_operand:SI 0 "register_operand" "=r")
13132 (plus:SI (match_operand:SI 1 "register_operand" "b")
13134 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13135 UNSPEC_TLSDESC))))]
13136 "!TARGET_64BIT && TARGET_GNU2_TLS"
13137 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13138 [(set_attr "type" "lea")
13139 (set_attr "mode" "SI")
13140 (set_attr "length" "6")
13141 (set_attr "length_address" "4")])
13143 (define_insn "*tls_dynamic_gnu2_call_32"
13144 [(set (match_operand:SI 0 "register_operand" "=a")
13145 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13146 (match_operand:SI 2 "register_operand" "0")
13147 ;; we have to make sure %ebx still points to the GOT
13148 (match_operand:SI 3 "register_operand" "b")
13151 (clobber (reg:CC FLAGS_REG))]
13152 "!TARGET_64BIT && TARGET_GNU2_TLS"
13153 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13154 [(set_attr "type" "call")
13155 (set_attr "length" "2")
13156 (set_attr "length_address" "0")])
13158 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13159 [(set (match_operand:SI 0 "register_operand" "=&a")
13161 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13162 (match_operand:SI 4)
13163 (match_operand:SI 2 "register_operand" "b")
13166 (const:SI (unspec:SI
13167 [(match_operand 1 "tls_symbolic_operand")]
13169 (clobber (reg:CC FLAGS_REG))]
13170 "!TARGET_64BIT && TARGET_GNU2_TLS"
13173 [(set (match_dup 0) (match_dup 5))]
13175 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13176 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13179 (define_expand "tls_dynamic_gnu2_64"
13180 [(set (match_dup 2)
13181 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13184 [(set (match_operand:DI 0 "register_operand")
13185 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13187 (clobber (reg:CC FLAGS_REG))])]
13188 "TARGET_64BIT && TARGET_GNU2_TLS"
13190 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13191 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13194 (define_insn "*tls_dynamic_gnu2_lea_64"
13195 [(set (match_operand:DI 0 "register_operand" "=r")
13196 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13198 "TARGET_64BIT && TARGET_GNU2_TLS"
13199 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13200 [(set_attr "type" "lea")
13201 (set_attr "mode" "DI")
13202 (set_attr "length" "7")
13203 (set_attr "length_address" "4")])
13205 (define_insn "*tls_dynamic_gnu2_call_64"
13206 [(set (match_operand:DI 0 "register_operand" "=a")
13207 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13208 (match_operand:DI 2 "register_operand" "0")
13211 (clobber (reg:CC FLAGS_REG))]
13212 "TARGET_64BIT && TARGET_GNU2_TLS"
13213 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13214 [(set_attr "type" "call")
13215 (set_attr "length" "2")
13216 (set_attr "length_address" "0")])
13218 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13219 [(set (match_operand:DI 0 "register_operand" "=&a")
13221 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13222 (match_operand:DI 3)
13225 (const:DI (unspec:DI
13226 [(match_operand 1 "tls_symbolic_operand")]
13228 (clobber (reg:CC FLAGS_REG))]
13229 "TARGET_64BIT && TARGET_GNU2_TLS"
13232 [(set (match_dup 0) (match_dup 4))]
13234 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13235 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13238 ;; These patterns match the binary 387 instructions for addM3, subM3,
13239 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13240 ;; SFmode. The first is the normal insn, the second the same insn but
13241 ;; with one operand a conversion, and the third the same insn but with
13242 ;; the other operand a conversion. The conversion may be SFmode or
13243 ;; SImode if the target mode DFmode, but only SImode if the target mode
13246 ;; Gcc is slightly more smart about handling normal two address instructions
13247 ;; so use special patterns for add and mull.
13249 (define_insn "*fop_<mode>_comm_mixed"
13250 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13251 (match_operator:MODEF 3 "binary_fp_operator"
13252 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13253 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13254 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13255 && COMMUTATIVE_ARITH_P (operands[3])
13256 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13257 "* return output_387_binary_op (insn, operands);"
13258 [(set (attr "type")
13259 (if_then_else (eq_attr "alternative" "1,2")
13260 (if_then_else (match_operand:MODEF 3 "mult_operator")
13261 (const_string "ssemul")
13262 (const_string "sseadd"))
13263 (if_then_else (match_operand:MODEF 3 "mult_operator")
13264 (const_string "fmul")
13265 (const_string "fop"))))
13266 (set_attr "isa" "*,noavx,avx")
13267 (set_attr "prefix" "orig,orig,vex")
13268 (set_attr "mode" "<MODE>")])
13270 (define_insn "*fop_<mode>_comm_sse"
13271 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13272 (match_operator:MODEF 3 "binary_fp_operator"
13273 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13274 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13275 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13276 && COMMUTATIVE_ARITH_P (operands[3])
13277 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13278 "* return output_387_binary_op (insn, operands);"
13279 [(set (attr "type")
13280 (if_then_else (match_operand:MODEF 3 "mult_operator")
13281 (const_string "ssemul")
13282 (const_string "sseadd")))
13283 (set_attr "isa" "noavx,avx")
13284 (set_attr "prefix" "orig,vex")
13285 (set_attr "mode" "<MODE>")])
13287 (define_insn "*fop_<mode>_comm_i387"
13288 [(set (match_operand:MODEF 0 "register_operand" "=f")
13289 (match_operator:MODEF 3 "binary_fp_operator"
13290 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13291 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13292 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13293 && COMMUTATIVE_ARITH_P (operands[3])
13294 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13295 "* return output_387_binary_op (insn, operands);"
13296 [(set (attr "type")
13297 (if_then_else (match_operand:MODEF 3 "mult_operator")
13298 (const_string "fmul")
13299 (const_string "fop")))
13300 (set_attr "mode" "<MODE>")])
13302 (define_insn "*fop_<mode>_1_mixed"
13303 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13304 (match_operator:MODEF 3 "binary_fp_operator"
13305 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13306 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13307 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13308 && !COMMUTATIVE_ARITH_P (operands[3])
13309 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13310 "* return output_387_binary_op (insn, operands);"
13311 [(set (attr "type")
13312 (cond [(and (eq_attr "alternative" "2,3")
13313 (match_operand:MODEF 3 "mult_operator"))
13314 (const_string "ssemul")
13315 (and (eq_attr "alternative" "2,3")
13316 (match_operand:MODEF 3 "div_operator"))
13317 (const_string "ssediv")
13318 (eq_attr "alternative" "2,3")
13319 (const_string "sseadd")
13320 (match_operand:MODEF 3 "mult_operator")
13321 (const_string "fmul")
13322 (match_operand:MODEF 3 "div_operator")
13323 (const_string "fdiv")
13325 (const_string "fop")))
13326 (set_attr "isa" "*,*,noavx,avx")
13327 (set_attr "prefix" "orig,orig,orig,vex")
13328 (set_attr "mode" "<MODE>")])
13330 (define_insn "*rcpsf2_sse"
13331 [(set (match_operand:SF 0 "register_operand" "=x")
13332 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13335 "%vrcpss\t{%1, %d0|%d0, %1}"
13336 [(set_attr "type" "sse")
13337 (set_attr "atom_sse_attr" "rcp")
13338 (set_attr "prefix" "maybe_vex")
13339 (set_attr "mode" "SF")])
13341 (define_insn "*fop_<mode>_1_sse"
13342 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13343 (match_operator:MODEF 3 "binary_fp_operator"
13344 [(match_operand:MODEF 1 "register_operand" "0,x")
13345 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13346 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13347 && !COMMUTATIVE_ARITH_P (operands[3])"
13348 "* return output_387_binary_op (insn, operands);"
13349 [(set (attr "type")
13350 (cond [(match_operand:MODEF 3 "mult_operator")
13351 (const_string "ssemul")
13352 (match_operand:MODEF 3 "div_operator")
13353 (const_string "ssediv")
13355 (const_string "sseadd")))
13356 (set_attr "isa" "noavx,avx")
13357 (set_attr "prefix" "orig,vex")
13358 (set_attr "mode" "<MODE>")])
13360 ;; This pattern is not fully shadowed by the pattern above.
13361 (define_insn "*fop_<mode>_1_i387"
13362 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13363 (match_operator:MODEF 3 "binary_fp_operator"
13364 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13365 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13366 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13367 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13368 && !COMMUTATIVE_ARITH_P (operands[3])
13369 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13370 "* return output_387_binary_op (insn, operands);"
13371 [(set (attr "type")
13372 (cond [(match_operand:MODEF 3 "mult_operator")
13373 (const_string "fmul")
13374 (match_operand:MODEF 3 "div_operator")
13375 (const_string "fdiv")
13377 (const_string "fop")))
13378 (set_attr "mode" "<MODE>")])
13380 ;; ??? Add SSE splitters for these!
13381 (define_insn "*fop_<MODEF:mode>_2_i387"
13382 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13383 (match_operator:MODEF 3 "binary_fp_operator"
13385 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13386 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13387 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13388 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13389 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13390 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13391 [(set (attr "type")
13392 (cond [(match_operand:MODEF 3 "mult_operator")
13393 (const_string "fmul")
13394 (match_operand:MODEF 3 "div_operator")
13395 (const_string "fdiv")
13397 (const_string "fop")))
13398 (set_attr "fp_int_src" "true")
13399 (set_attr "mode" "<SWI24:MODE>")])
13401 (define_insn "*fop_<MODEF:mode>_3_i387"
13402 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13403 (match_operator:MODEF 3 "binary_fp_operator"
13404 [(match_operand:MODEF 1 "register_operand" "0,0")
13406 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13407 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13408 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13409 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13410 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13411 [(set (attr "type")
13412 (cond [(match_operand:MODEF 3 "mult_operator")
13413 (const_string "fmul")
13414 (match_operand:MODEF 3 "div_operator")
13415 (const_string "fdiv")
13417 (const_string "fop")))
13418 (set_attr "fp_int_src" "true")
13419 (set_attr "mode" "<MODE>")])
13421 (define_insn "*fop_df_4_i387"
13422 [(set (match_operand:DF 0 "register_operand" "=f,f")
13423 (match_operator:DF 3 "binary_fp_operator"
13425 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13426 (match_operand:DF 2 "register_operand" "0,f")]))]
13427 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13428 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13429 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13430 "* return output_387_binary_op (insn, operands);"
13431 [(set (attr "type")
13432 (cond [(match_operand:DF 3 "mult_operator")
13433 (const_string "fmul")
13434 (match_operand:DF 3 "div_operator")
13435 (const_string "fdiv")
13437 (const_string "fop")))
13438 (set_attr "mode" "SF")])
13440 (define_insn "*fop_df_5_i387"
13441 [(set (match_operand:DF 0 "register_operand" "=f,f")
13442 (match_operator:DF 3 "binary_fp_operator"
13443 [(match_operand:DF 1 "register_operand" "0,f")
13445 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13446 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13447 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13448 "* return output_387_binary_op (insn, operands);"
13449 [(set (attr "type")
13450 (cond [(match_operand:DF 3 "mult_operator")
13451 (const_string "fmul")
13452 (match_operand:DF 3 "div_operator")
13453 (const_string "fdiv")
13455 (const_string "fop")))
13456 (set_attr "mode" "SF")])
13458 (define_insn "*fop_df_6_i387"
13459 [(set (match_operand:DF 0 "register_operand" "=f,f")
13460 (match_operator:DF 3 "binary_fp_operator"
13462 (match_operand:SF 1 "register_operand" "0,f"))
13464 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13465 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13466 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13467 "* return output_387_binary_op (insn, operands);"
13468 [(set (attr "type")
13469 (cond [(match_operand:DF 3 "mult_operator")
13470 (const_string "fmul")
13471 (match_operand:DF 3 "div_operator")
13472 (const_string "fdiv")
13474 (const_string "fop")))
13475 (set_attr "mode" "SF")])
13477 (define_insn "*fop_xf_comm_i387"
13478 [(set (match_operand:XF 0 "register_operand" "=f")
13479 (match_operator:XF 3 "binary_fp_operator"
13480 [(match_operand:XF 1 "register_operand" "%0")
13481 (match_operand:XF 2 "register_operand" "f")]))]
13483 && COMMUTATIVE_ARITH_P (operands[3])"
13484 "* return output_387_binary_op (insn, operands);"
13485 [(set (attr "type")
13486 (if_then_else (match_operand:XF 3 "mult_operator")
13487 (const_string "fmul")
13488 (const_string "fop")))
13489 (set_attr "mode" "XF")])
13491 (define_insn "*fop_xf_1_i387"
13492 [(set (match_operand:XF 0 "register_operand" "=f,f")
13493 (match_operator:XF 3 "binary_fp_operator"
13494 [(match_operand:XF 1 "register_operand" "0,f")
13495 (match_operand:XF 2 "register_operand" "f,0")]))]
13497 && !COMMUTATIVE_ARITH_P (operands[3])"
13498 "* return output_387_binary_op (insn, operands);"
13499 [(set (attr "type")
13500 (cond [(match_operand:XF 3 "mult_operator")
13501 (const_string "fmul")
13502 (match_operand:XF 3 "div_operator")
13503 (const_string "fdiv")
13505 (const_string "fop")))
13506 (set_attr "mode" "XF")])
13508 (define_insn "*fop_xf_2_i387"
13509 [(set (match_operand:XF 0 "register_operand" "=f,f")
13510 (match_operator:XF 3 "binary_fp_operator"
13512 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13513 (match_operand:XF 2 "register_operand" "0,0")]))]
13514 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13515 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13516 [(set (attr "type")
13517 (cond [(match_operand:XF 3 "mult_operator")
13518 (const_string "fmul")
13519 (match_operand:XF 3 "div_operator")
13520 (const_string "fdiv")
13522 (const_string "fop")))
13523 (set_attr "fp_int_src" "true")
13524 (set_attr "mode" "<MODE>")])
13526 (define_insn "*fop_xf_3_i387"
13527 [(set (match_operand:XF 0 "register_operand" "=f,f")
13528 (match_operator:XF 3 "binary_fp_operator"
13529 [(match_operand:XF 1 "register_operand" "0,0")
13531 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13532 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13533 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13534 [(set (attr "type")
13535 (cond [(match_operand:XF 3 "mult_operator")
13536 (const_string "fmul")
13537 (match_operand:XF 3 "div_operator")
13538 (const_string "fdiv")
13540 (const_string "fop")))
13541 (set_attr "fp_int_src" "true")
13542 (set_attr "mode" "<MODE>")])
13544 (define_insn "*fop_xf_4_i387"
13545 [(set (match_operand:XF 0 "register_operand" "=f,f")
13546 (match_operator:XF 3 "binary_fp_operator"
13548 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13549 (match_operand:XF 2 "register_operand" "0,f")]))]
13551 "* return output_387_binary_op (insn, operands);"
13552 [(set (attr "type")
13553 (cond [(match_operand:XF 3 "mult_operator")
13554 (const_string "fmul")
13555 (match_operand:XF 3 "div_operator")
13556 (const_string "fdiv")
13558 (const_string "fop")))
13559 (set_attr "mode" "<MODE>")])
13561 (define_insn "*fop_xf_5_i387"
13562 [(set (match_operand:XF 0 "register_operand" "=f,f")
13563 (match_operator:XF 3 "binary_fp_operator"
13564 [(match_operand:XF 1 "register_operand" "0,f")
13566 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13568 "* return output_387_binary_op (insn, operands);"
13569 [(set (attr "type")
13570 (cond [(match_operand:XF 3 "mult_operator")
13571 (const_string "fmul")
13572 (match_operand:XF 3 "div_operator")
13573 (const_string "fdiv")
13575 (const_string "fop")))
13576 (set_attr "mode" "<MODE>")])
13578 (define_insn "*fop_xf_6_i387"
13579 [(set (match_operand:XF 0 "register_operand" "=f,f")
13580 (match_operator:XF 3 "binary_fp_operator"
13582 (match_operand:MODEF 1 "register_operand" "0,f"))
13584 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13586 "* return output_387_binary_op (insn, operands);"
13587 [(set (attr "type")
13588 (cond [(match_operand:XF 3 "mult_operator")
13589 (const_string "fmul")
13590 (match_operand:XF 3 "div_operator")
13591 (const_string "fdiv")
13593 (const_string "fop")))
13594 (set_attr "mode" "<MODE>")])
13597 [(set (match_operand 0 "register_operand")
13598 (match_operator 3 "binary_fp_operator"
13599 [(float (match_operand:SWI24 1 "register_operand"))
13600 (match_operand 2 "register_operand")]))]
13602 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13603 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13606 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13607 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13608 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13609 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13610 GET_MODE (operands[3]),
13613 ix86_free_from_memory (GET_MODE (operands[1]));
13618 [(set (match_operand 0 "register_operand")
13619 (match_operator 3 "binary_fp_operator"
13620 [(match_operand 1 "register_operand")
13621 (float (match_operand:SWI24 2 "register_operand"))]))]
13623 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13624 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13627 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13628 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13629 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13630 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13631 GET_MODE (operands[3]),
13634 ix86_free_from_memory (GET_MODE (operands[2]));
13638 ;; FPU special functions.
13640 ;; This pattern implements a no-op XFmode truncation for
13641 ;; all fancy i386 XFmode math functions.
13643 (define_insn "truncxf<mode>2_i387_noop_unspec"
13644 [(set (match_operand:MODEF 0 "register_operand" "=f")
13645 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13646 UNSPEC_TRUNC_NOOP))]
13647 "TARGET_USE_FANCY_MATH_387"
13648 "* return output_387_reg_move (insn, operands);"
13649 [(set_attr "type" "fmov")
13650 (set_attr "mode" "<MODE>")])
13652 (define_insn "sqrtxf2"
13653 [(set (match_operand:XF 0 "register_operand" "=f")
13654 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13655 "TARGET_USE_FANCY_MATH_387"
13657 [(set_attr "type" "fpspc")
13658 (set_attr "mode" "XF")
13659 (set_attr "athlon_decode" "direct")
13660 (set_attr "amdfam10_decode" "direct")
13661 (set_attr "bdver1_decode" "direct")])
13663 (define_insn "sqrt_extend<mode>xf2_i387"
13664 [(set (match_operand:XF 0 "register_operand" "=f")
13667 (match_operand:MODEF 1 "register_operand" "0"))))]
13668 "TARGET_USE_FANCY_MATH_387"
13670 [(set_attr "type" "fpspc")
13671 (set_attr "mode" "XF")
13672 (set_attr "athlon_decode" "direct")
13673 (set_attr "amdfam10_decode" "direct")
13674 (set_attr "bdver1_decode" "direct")])
13676 (define_insn "*rsqrtsf2_sse"
13677 [(set (match_operand:SF 0 "register_operand" "=x")
13678 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13681 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13682 [(set_attr "type" "sse")
13683 (set_attr "atom_sse_attr" "rcp")
13684 (set_attr "prefix" "maybe_vex")
13685 (set_attr "mode" "SF")])
13687 (define_expand "rsqrtsf2"
13688 [(set (match_operand:SF 0 "register_operand")
13689 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13693 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13697 (define_insn "*sqrt<mode>2_sse"
13698 [(set (match_operand:MODEF 0 "register_operand" "=x")
13700 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13701 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13702 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13703 [(set_attr "type" "sse")
13704 (set_attr "atom_sse_attr" "sqrt")
13705 (set_attr "prefix" "maybe_vex")
13706 (set_attr "mode" "<MODE>")
13707 (set_attr "athlon_decode" "*")
13708 (set_attr "amdfam10_decode" "*")
13709 (set_attr "bdver1_decode" "*")])
13711 (define_expand "sqrt<mode>2"
13712 [(set (match_operand:MODEF 0 "register_operand")
13714 (match_operand:MODEF 1 "nonimmediate_operand")))]
13715 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13716 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13718 if (<MODE>mode == SFmode
13720 && TARGET_RECIP_SQRT
13721 && !optimize_function_for_size_p (cfun)
13722 && flag_finite_math_only && !flag_trapping_math
13723 && flag_unsafe_math_optimizations)
13725 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13729 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13731 rtx op0 = gen_reg_rtx (XFmode);
13732 rtx op1 = force_reg (<MODE>mode, operands[1]);
13734 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13735 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13740 (define_insn "fpremxf4_i387"
13741 [(set (match_operand:XF 0 "register_operand" "=f")
13742 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13743 (match_operand:XF 3 "register_operand" "1")]
13745 (set (match_operand:XF 1 "register_operand" "=u")
13746 (unspec:XF [(match_dup 2) (match_dup 3)]
13748 (set (reg:CCFP FPSR_REG)
13749 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13751 "TARGET_USE_FANCY_MATH_387"
13753 [(set_attr "type" "fpspc")
13754 (set_attr "mode" "XF")])
13756 (define_expand "fmodxf3"
13757 [(use (match_operand:XF 0 "register_operand"))
13758 (use (match_operand:XF 1 "general_operand"))
13759 (use (match_operand:XF 2 "general_operand"))]
13760 "TARGET_USE_FANCY_MATH_387"
13762 rtx label = gen_label_rtx ();
13764 rtx op1 = gen_reg_rtx (XFmode);
13765 rtx op2 = gen_reg_rtx (XFmode);
13767 emit_move_insn (op2, operands[2]);
13768 emit_move_insn (op1, operands[1]);
13770 emit_label (label);
13771 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13772 ix86_emit_fp_unordered_jump (label);
13773 LABEL_NUSES (label) = 1;
13775 emit_move_insn (operands[0], op1);
13779 (define_expand "fmod<mode>3"
13780 [(use (match_operand:MODEF 0 "register_operand"))
13781 (use (match_operand:MODEF 1 "general_operand"))
13782 (use (match_operand:MODEF 2 "general_operand"))]
13783 "TARGET_USE_FANCY_MATH_387"
13785 rtx (*gen_truncxf) (rtx, rtx);
13787 rtx label = gen_label_rtx ();
13789 rtx op1 = gen_reg_rtx (XFmode);
13790 rtx op2 = gen_reg_rtx (XFmode);
13792 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13793 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13795 emit_label (label);
13796 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13797 ix86_emit_fp_unordered_jump (label);
13798 LABEL_NUSES (label) = 1;
13800 /* Truncate the result properly for strict SSE math. */
13801 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13802 && !TARGET_MIX_SSE_I387)
13803 gen_truncxf = gen_truncxf<mode>2;
13805 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13807 emit_insn (gen_truncxf (operands[0], op1));
13811 (define_insn "fprem1xf4_i387"
13812 [(set (match_operand:XF 0 "register_operand" "=f")
13813 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13814 (match_operand:XF 3 "register_operand" "1")]
13816 (set (match_operand:XF 1 "register_operand" "=u")
13817 (unspec:XF [(match_dup 2) (match_dup 3)]
13819 (set (reg:CCFP FPSR_REG)
13820 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13822 "TARGET_USE_FANCY_MATH_387"
13824 [(set_attr "type" "fpspc")
13825 (set_attr "mode" "XF")])
13827 (define_expand "remainderxf3"
13828 [(use (match_operand:XF 0 "register_operand"))
13829 (use (match_operand:XF 1 "general_operand"))
13830 (use (match_operand:XF 2 "general_operand"))]
13831 "TARGET_USE_FANCY_MATH_387"
13833 rtx label = gen_label_rtx ();
13835 rtx op1 = gen_reg_rtx (XFmode);
13836 rtx op2 = gen_reg_rtx (XFmode);
13838 emit_move_insn (op2, operands[2]);
13839 emit_move_insn (op1, operands[1]);
13841 emit_label (label);
13842 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13843 ix86_emit_fp_unordered_jump (label);
13844 LABEL_NUSES (label) = 1;
13846 emit_move_insn (operands[0], op1);
13850 (define_expand "remainder<mode>3"
13851 [(use (match_operand:MODEF 0 "register_operand"))
13852 (use (match_operand:MODEF 1 "general_operand"))
13853 (use (match_operand:MODEF 2 "general_operand"))]
13854 "TARGET_USE_FANCY_MATH_387"
13856 rtx (*gen_truncxf) (rtx, rtx);
13858 rtx label = gen_label_rtx ();
13860 rtx op1 = gen_reg_rtx (XFmode);
13861 rtx op2 = gen_reg_rtx (XFmode);
13863 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13864 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13866 emit_label (label);
13868 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13869 ix86_emit_fp_unordered_jump (label);
13870 LABEL_NUSES (label) = 1;
13872 /* Truncate the result properly for strict SSE math. */
13873 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13874 && !TARGET_MIX_SSE_I387)
13875 gen_truncxf = gen_truncxf<mode>2;
13877 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13879 emit_insn (gen_truncxf (operands[0], op1));
13883 (define_int_iterator SINCOS
13887 (define_int_attr sincos
13888 [(UNSPEC_SIN "sin")
13889 (UNSPEC_COS "cos")])
13891 (define_insn "*<sincos>xf2_i387"
13892 [(set (match_operand:XF 0 "register_operand" "=f")
13893 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13895 "TARGET_USE_FANCY_MATH_387
13896 && flag_unsafe_math_optimizations"
13898 [(set_attr "type" "fpspc")
13899 (set_attr "mode" "XF")])
13901 (define_insn "*<sincos>_extend<mode>xf2_i387"
13902 [(set (match_operand:XF 0 "register_operand" "=f")
13903 (unspec:XF [(float_extend:XF
13904 (match_operand:MODEF 1 "register_operand" "0"))]
13906 "TARGET_USE_FANCY_MATH_387
13907 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13908 || TARGET_MIX_SSE_I387)
13909 && flag_unsafe_math_optimizations"
13911 [(set_attr "type" "fpspc")
13912 (set_attr "mode" "XF")])
13914 ;; When sincos pattern is defined, sin and cos builtin functions will be
13915 ;; expanded to sincos pattern with one of its outputs left unused.
13916 ;; CSE pass will figure out if two sincos patterns can be combined,
13917 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13918 ;; depending on the unused output.
13920 (define_insn "sincosxf3"
13921 [(set (match_operand:XF 0 "register_operand" "=f")
13922 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13923 UNSPEC_SINCOS_COS))
13924 (set (match_operand:XF 1 "register_operand" "=u")
13925 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13926 "TARGET_USE_FANCY_MATH_387
13927 && flag_unsafe_math_optimizations"
13929 [(set_attr "type" "fpspc")
13930 (set_attr "mode" "XF")])
13933 [(set (match_operand:XF 0 "register_operand")
13934 (unspec:XF [(match_operand:XF 2 "register_operand")]
13935 UNSPEC_SINCOS_COS))
13936 (set (match_operand:XF 1 "register_operand")
13937 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13938 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13939 && can_create_pseudo_p ()"
13940 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13943 [(set (match_operand:XF 0 "register_operand")
13944 (unspec:XF [(match_operand:XF 2 "register_operand")]
13945 UNSPEC_SINCOS_COS))
13946 (set (match_operand:XF 1 "register_operand")
13947 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13948 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13949 && can_create_pseudo_p ()"
13950 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13952 (define_insn "sincos_extend<mode>xf3_i387"
13953 [(set (match_operand:XF 0 "register_operand" "=f")
13954 (unspec:XF [(float_extend:XF
13955 (match_operand:MODEF 2 "register_operand" "0"))]
13956 UNSPEC_SINCOS_COS))
13957 (set (match_operand:XF 1 "register_operand" "=u")
13958 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13959 "TARGET_USE_FANCY_MATH_387
13960 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13961 || TARGET_MIX_SSE_I387)
13962 && flag_unsafe_math_optimizations"
13964 [(set_attr "type" "fpspc")
13965 (set_attr "mode" "XF")])
13968 [(set (match_operand:XF 0 "register_operand")
13969 (unspec:XF [(float_extend:XF
13970 (match_operand:MODEF 2 "register_operand"))]
13971 UNSPEC_SINCOS_COS))
13972 (set (match_operand:XF 1 "register_operand")
13973 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13974 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13975 && can_create_pseudo_p ()"
13976 [(set (match_dup 1)
13977 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13980 [(set (match_operand:XF 0 "register_operand")
13981 (unspec:XF [(float_extend:XF
13982 (match_operand:MODEF 2 "register_operand"))]
13983 UNSPEC_SINCOS_COS))
13984 (set (match_operand:XF 1 "register_operand")
13985 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13986 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13987 && can_create_pseudo_p ()"
13988 [(set (match_dup 0)
13989 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13991 (define_expand "sincos<mode>3"
13992 [(use (match_operand:MODEF 0 "register_operand"))
13993 (use (match_operand:MODEF 1 "register_operand"))
13994 (use (match_operand:MODEF 2 "register_operand"))]
13995 "TARGET_USE_FANCY_MATH_387
13996 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13997 || TARGET_MIX_SSE_I387)
13998 && flag_unsafe_math_optimizations"
14000 rtx op0 = gen_reg_rtx (XFmode);
14001 rtx op1 = gen_reg_rtx (XFmode);
14003 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14004 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14005 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14009 (define_insn "fptanxf4_i387"
14010 [(set (match_operand:XF 0 "register_operand" "=f")
14011 (match_operand:XF 3 "const_double_operand" "F"))
14012 (set (match_operand:XF 1 "register_operand" "=u")
14013 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14015 "TARGET_USE_FANCY_MATH_387
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_insn "fptan_extend<mode>xf4_i387"
14023 [(set (match_operand:MODEF 0 "register_operand" "=f")
14024 (match_operand:MODEF 3 "const_double_operand" "F"))
14025 (set (match_operand:XF 1 "register_operand" "=u")
14026 (unspec:XF [(float_extend:XF
14027 (match_operand:MODEF 2 "register_operand" "0"))]
14029 "TARGET_USE_FANCY_MATH_387
14030 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14031 || TARGET_MIX_SSE_I387)
14032 && flag_unsafe_math_optimizations
14033 && standard_80387_constant_p (operands[3]) == 2"
14035 [(set_attr "type" "fpspc")
14036 (set_attr "mode" "XF")])
14038 (define_expand "tanxf2"
14039 [(use (match_operand:XF 0 "register_operand"))
14040 (use (match_operand:XF 1 "register_operand"))]
14041 "TARGET_USE_FANCY_MATH_387
14042 && flag_unsafe_math_optimizations"
14044 rtx one = gen_reg_rtx (XFmode);
14045 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14047 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14051 (define_expand "tan<mode>2"
14052 [(use (match_operand:MODEF 0 "register_operand"))
14053 (use (match_operand:MODEF 1 "register_operand"))]
14054 "TARGET_USE_FANCY_MATH_387
14055 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14056 || TARGET_MIX_SSE_I387)
14057 && flag_unsafe_math_optimizations"
14059 rtx op0 = gen_reg_rtx (XFmode);
14061 rtx one = gen_reg_rtx (<MODE>mode);
14062 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14064 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14065 operands[1], op2));
14066 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14070 (define_insn "*fpatanxf3_i387"
14071 [(set (match_operand:XF 0 "register_operand" "=f")
14072 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14073 (match_operand:XF 2 "register_operand" "u")]
14075 (clobber (match_scratch:XF 3 "=2"))]
14076 "TARGET_USE_FANCY_MATH_387
14077 && flag_unsafe_math_optimizations"
14079 [(set_attr "type" "fpspc")
14080 (set_attr "mode" "XF")])
14082 (define_insn "fpatan_extend<mode>xf3_i387"
14083 [(set (match_operand:XF 0 "register_operand" "=f")
14084 (unspec:XF [(float_extend:XF
14085 (match_operand:MODEF 1 "register_operand" "0"))
14087 (match_operand:MODEF 2 "register_operand" "u"))]
14089 (clobber (match_scratch:XF 3 "=2"))]
14090 "TARGET_USE_FANCY_MATH_387
14091 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14092 || TARGET_MIX_SSE_I387)
14093 && flag_unsafe_math_optimizations"
14095 [(set_attr "type" "fpspc")
14096 (set_attr "mode" "XF")])
14098 (define_expand "atan2xf3"
14099 [(parallel [(set (match_operand:XF 0 "register_operand")
14100 (unspec:XF [(match_operand:XF 2 "register_operand")
14101 (match_operand:XF 1 "register_operand")]
14103 (clobber (match_scratch:XF 3))])]
14104 "TARGET_USE_FANCY_MATH_387
14105 && flag_unsafe_math_optimizations")
14107 (define_expand "atan2<mode>3"
14108 [(use (match_operand:MODEF 0 "register_operand"))
14109 (use (match_operand:MODEF 1 "register_operand"))
14110 (use (match_operand:MODEF 2 "register_operand"))]
14111 "TARGET_USE_FANCY_MATH_387
14112 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14113 || TARGET_MIX_SSE_I387)
14114 && flag_unsafe_math_optimizations"
14116 rtx op0 = gen_reg_rtx (XFmode);
14118 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14119 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14123 (define_expand "atanxf2"
14124 [(parallel [(set (match_operand:XF 0 "register_operand")
14125 (unspec:XF [(match_dup 2)
14126 (match_operand:XF 1 "register_operand")]
14128 (clobber (match_scratch:XF 3))])]
14129 "TARGET_USE_FANCY_MATH_387
14130 && flag_unsafe_math_optimizations"
14132 operands[2] = gen_reg_rtx (XFmode);
14133 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14136 (define_expand "atan<mode>2"
14137 [(use (match_operand:MODEF 0 "register_operand"))
14138 (use (match_operand:MODEF 1 "register_operand"))]
14139 "TARGET_USE_FANCY_MATH_387
14140 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14141 || TARGET_MIX_SSE_I387)
14142 && flag_unsafe_math_optimizations"
14144 rtx op0 = gen_reg_rtx (XFmode);
14146 rtx op2 = gen_reg_rtx (<MODE>mode);
14147 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14149 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14150 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14154 (define_expand "asinxf2"
14155 [(set (match_dup 2)
14156 (mult:XF (match_operand:XF 1 "register_operand")
14158 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14159 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14160 (parallel [(set (match_operand:XF 0 "register_operand")
14161 (unspec:XF [(match_dup 5) (match_dup 1)]
14163 (clobber (match_scratch:XF 6))])]
14164 "TARGET_USE_FANCY_MATH_387
14165 && flag_unsafe_math_optimizations"
14169 if (optimize_insn_for_size_p ())
14172 for (i = 2; i < 6; i++)
14173 operands[i] = gen_reg_rtx (XFmode);
14175 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14178 (define_expand "asin<mode>2"
14179 [(use (match_operand:MODEF 0 "register_operand"))
14180 (use (match_operand:MODEF 1 "general_operand"))]
14181 "TARGET_USE_FANCY_MATH_387
14182 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14183 || TARGET_MIX_SSE_I387)
14184 && flag_unsafe_math_optimizations"
14186 rtx op0 = gen_reg_rtx (XFmode);
14187 rtx op1 = gen_reg_rtx (XFmode);
14189 if (optimize_insn_for_size_p ())
14192 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14193 emit_insn (gen_asinxf2 (op0, op1));
14194 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14198 (define_expand "acosxf2"
14199 [(set (match_dup 2)
14200 (mult:XF (match_operand:XF 1 "register_operand")
14202 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14203 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14204 (parallel [(set (match_operand:XF 0 "register_operand")
14205 (unspec:XF [(match_dup 1) (match_dup 5)]
14207 (clobber (match_scratch:XF 6))])]
14208 "TARGET_USE_FANCY_MATH_387
14209 && flag_unsafe_math_optimizations"
14213 if (optimize_insn_for_size_p ())
14216 for (i = 2; i < 6; i++)
14217 operands[i] = gen_reg_rtx (XFmode);
14219 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14222 (define_expand "acos<mode>2"
14223 [(use (match_operand:MODEF 0 "register_operand"))
14224 (use (match_operand:MODEF 1 "general_operand"))]
14225 "TARGET_USE_FANCY_MATH_387
14226 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14227 || TARGET_MIX_SSE_I387)
14228 && flag_unsafe_math_optimizations"
14230 rtx op0 = gen_reg_rtx (XFmode);
14231 rtx op1 = gen_reg_rtx (XFmode);
14233 if (optimize_insn_for_size_p ())
14236 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14237 emit_insn (gen_acosxf2 (op0, op1));
14238 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14242 (define_insn "fyl2xxf3_i387"
14243 [(set (match_operand:XF 0 "register_operand" "=f")
14244 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14245 (match_operand:XF 2 "register_operand" "u")]
14247 (clobber (match_scratch:XF 3 "=2"))]
14248 "TARGET_USE_FANCY_MATH_387
14249 && flag_unsafe_math_optimizations"
14251 [(set_attr "type" "fpspc")
14252 (set_attr "mode" "XF")])
14254 (define_insn "fyl2x_extend<mode>xf3_i387"
14255 [(set (match_operand:XF 0 "register_operand" "=f")
14256 (unspec:XF [(float_extend:XF
14257 (match_operand:MODEF 1 "register_operand" "0"))
14258 (match_operand:XF 2 "register_operand" "u")]
14260 (clobber (match_scratch:XF 3 "=2"))]
14261 "TARGET_USE_FANCY_MATH_387
14262 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14263 || TARGET_MIX_SSE_I387)
14264 && flag_unsafe_math_optimizations"
14266 [(set_attr "type" "fpspc")
14267 (set_attr "mode" "XF")])
14269 (define_expand "logxf2"
14270 [(parallel [(set (match_operand:XF 0 "register_operand")
14271 (unspec:XF [(match_operand:XF 1 "register_operand")
14272 (match_dup 2)] UNSPEC_FYL2X))
14273 (clobber (match_scratch:XF 3))])]
14274 "TARGET_USE_FANCY_MATH_387
14275 && flag_unsafe_math_optimizations"
14277 operands[2] = gen_reg_rtx (XFmode);
14278 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14281 (define_expand "log<mode>2"
14282 [(use (match_operand:MODEF 0 "register_operand"))
14283 (use (match_operand:MODEF 1 "register_operand"))]
14284 "TARGET_USE_FANCY_MATH_387
14285 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14286 || TARGET_MIX_SSE_I387)
14287 && flag_unsafe_math_optimizations"
14289 rtx op0 = gen_reg_rtx (XFmode);
14291 rtx op2 = gen_reg_rtx (XFmode);
14292 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14294 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14295 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14299 (define_expand "log10xf2"
14300 [(parallel [(set (match_operand:XF 0 "register_operand")
14301 (unspec:XF [(match_operand:XF 1 "register_operand")
14302 (match_dup 2)] UNSPEC_FYL2X))
14303 (clobber (match_scratch:XF 3))])]
14304 "TARGET_USE_FANCY_MATH_387
14305 && flag_unsafe_math_optimizations"
14307 operands[2] = gen_reg_rtx (XFmode);
14308 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14311 (define_expand "log10<mode>2"
14312 [(use (match_operand:MODEF 0 "register_operand"))
14313 (use (match_operand:MODEF 1 "register_operand"))]
14314 "TARGET_USE_FANCY_MATH_387
14315 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14316 || TARGET_MIX_SSE_I387)
14317 && flag_unsafe_math_optimizations"
14319 rtx op0 = gen_reg_rtx (XFmode);
14321 rtx op2 = gen_reg_rtx (XFmode);
14322 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14324 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14325 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14329 (define_expand "log2xf2"
14330 [(parallel [(set (match_operand:XF 0 "register_operand")
14331 (unspec:XF [(match_operand:XF 1 "register_operand")
14332 (match_dup 2)] UNSPEC_FYL2X))
14333 (clobber (match_scratch:XF 3))])]
14334 "TARGET_USE_FANCY_MATH_387
14335 && flag_unsafe_math_optimizations"
14337 operands[2] = gen_reg_rtx (XFmode);
14338 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14341 (define_expand "log2<mode>2"
14342 [(use (match_operand:MODEF 0 "register_operand"))
14343 (use (match_operand:MODEF 1 "register_operand"))]
14344 "TARGET_USE_FANCY_MATH_387
14345 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14346 || TARGET_MIX_SSE_I387)
14347 && flag_unsafe_math_optimizations"
14349 rtx op0 = gen_reg_rtx (XFmode);
14351 rtx op2 = gen_reg_rtx (XFmode);
14352 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14354 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14355 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14359 (define_insn "fyl2xp1xf3_i387"
14360 [(set (match_operand:XF 0 "register_operand" "=f")
14361 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14362 (match_operand:XF 2 "register_operand" "u")]
14364 (clobber (match_scratch:XF 3 "=2"))]
14365 "TARGET_USE_FANCY_MATH_387
14366 && flag_unsafe_math_optimizations"
14368 [(set_attr "type" "fpspc")
14369 (set_attr "mode" "XF")])
14371 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14372 [(set (match_operand:XF 0 "register_operand" "=f")
14373 (unspec:XF [(float_extend:XF
14374 (match_operand:MODEF 1 "register_operand" "0"))
14375 (match_operand:XF 2 "register_operand" "u")]
14377 (clobber (match_scratch:XF 3 "=2"))]
14378 "TARGET_USE_FANCY_MATH_387
14379 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14380 || TARGET_MIX_SSE_I387)
14381 && flag_unsafe_math_optimizations"
14383 [(set_attr "type" "fpspc")
14384 (set_attr "mode" "XF")])
14386 (define_expand "log1pxf2"
14387 [(use (match_operand:XF 0 "register_operand"))
14388 (use (match_operand:XF 1 "register_operand"))]
14389 "TARGET_USE_FANCY_MATH_387
14390 && flag_unsafe_math_optimizations"
14392 if (optimize_insn_for_size_p ())
14395 ix86_emit_i387_log1p (operands[0], operands[1]);
14399 (define_expand "log1p<mode>2"
14400 [(use (match_operand:MODEF 0 "register_operand"))
14401 (use (match_operand:MODEF 1 "register_operand"))]
14402 "TARGET_USE_FANCY_MATH_387
14403 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14404 || TARGET_MIX_SSE_I387)
14405 && flag_unsafe_math_optimizations"
14409 if (optimize_insn_for_size_p ())
14412 op0 = gen_reg_rtx (XFmode);
14414 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14416 ix86_emit_i387_log1p (op0, operands[1]);
14417 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14421 (define_insn "fxtractxf3_i387"
14422 [(set (match_operand:XF 0 "register_operand" "=f")
14423 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14424 UNSPEC_XTRACT_FRACT))
14425 (set (match_operand:XF 1 "register_operand" "=u")
14426 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14427 "TARGET_USE_FANCY_MATH_387
14428 && flag_unsafe_math_optimizations"
14430 [(set_attr "type" "fpspc")
14431 (set_attr "mode" "XF")])
14433 (define_insn "fxtract_extend<mode>xf3_i387"
14434 [(set (match_operand:XF 0 "register_operand" "=f")
14435 (unspec:XF [(float_extend:XF
14436 (match_operand:MODEF 2 "register_operand" "0"))]
14437 UNSPEC_XTRACT_FRACT))
14438 (set (match_operand:XF 1 "register_operand" "=u")
14439 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14440 "TARGET_USE_FANCY_MATH_387
14441 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14442 || TARGET_MIX_SSE_I387)
14443 && flag_unsafe_math_optimizations"
14445 [(set_attr "type" "fpspc")
14446 (set_attr "mode" "XF")])
14448 (define_expand "logbxf2"
14449 [(parallel [(set (match_dup 2)
14450 (unspec:XF [(match_operand:XF 1 "register_operand")]
14451 UNSPEC_XTRACT_FRACT))
14452 (set (match_operand:XF 0 "register_operand")
14453 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14454 "TARGET_USE_FANCY_MATH_387
14455 && flag_unsafe_math_optimizations"
14456 "operands[2] = gen_reg_rtx (XFmode);")
14458 (define_expand "logb<mode>2"
14459 [(use (match_operand:MODEF 0 "register_operand"))
14460 (use (match_operand:MODEF 1 "register_operand"))]
14461 "TARGET_USE_FANCY_MATH_387
14462 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14463 || TARGET_MIX_SSE_I387)
14464 && flag_unsafe_math_optimizations"
14466 rtx op0 = gen_reg_rtx (XFmode);
14467 rtx op1 = gen_reg_rtx (XFmode);
14469 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14470 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14474 (define_expand "ilogbxf2"
14475 [(use (match_operand:SI 0 "register_operand"))
14476 (use (match_operand:XF 1 "register_operand"))]
14477 "TARGET_USE_FANCY_MATH_387
14478 && flag_unsafe_math_optimizations"
14482 if (optimize_insn_for_size_p ())
14485 op0 = gen_reg_rtx (XFmode);
14486 op1 = gen_reg_rtx (XFmode);
14488 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14489 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14493 (define_expand "ilogb<mode>2"
14494 [(use (match_operand:SI 0 "register_operand"))
14495 (use (match_operand:MODEF 1 "register_operand"))]
14496 "TARGET_USE_FANCY_MATH_387
14497 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14498 || TARGET_MIX_SSE_I387)
14499 && flag_unsafe_math_optimizations"
14503 if (optimize_insn_for_size_p ())
14506 op0 = gen_reg_rtx (XFmode);
14507 op1 = gen_reg_rtx (XFmode);
14509 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14510 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14514 (define_insn "*f2xm1xf2_i387"
14515 [(set (match_operand:XF 0 "register_operand" "=f")
14516 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14518 "TARGET_USE_FANCY_MATH_387
14519 && flag_unsafe_math_optimizations"
14521 [(set_attr "type" "fpspc")
14522 (set_attr "mode" "XF")])
14524 (define_insn "*fscalexf4_i387"
14525 [(set (match_operand:XF 0 "register_operand" "=f")
14526 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14527 (match_operand:XF 3 "register_operand" "1")]
14528 UNSPEC_FSCALE_FRACT))
14529 (set (match_operand:XF 1 "register_operand" "=u")
14530 (unspec:XF [(match_dup 2) (match_dup 3)]
14531 UNSPEC_FSCALE_EXP))]
14532 "TARGET_USE_FANCY_MATH_387
14533 && flag_unsafe_math_optimizations"
14535 [(set_attr "type" "fpspc")
14536 (set_attr "mode" "XF")])
14538 (define_expand "expNcorexf3"
14539 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14540 (match_operand:XF 2 "register_operand")))
14541 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14542 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14543 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14544 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14545 (parallel [(set (match_operand:XF 0 "register_operand")
14546 (unspec:XF [(match_dup 8) (match_dup 4)]
14547 UNSPEC_FSCALE_FRACT))
14549 (unspec:XF [(match_dup 8) (match_dup 4)]
14550 UNSPEC_FSCALE_EXP))])]
14551 "TARGET_USE_FANCY_MATH_387
14552 && flag_unsafe_math_optimizations"
14556 if (optimize_insn_for_size_p ())
14559 for (i = 3; i < 10; i++)
14560 operands[i] = gen_reg_rtx (XFmode);
14562 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14565 (define_expand "expxf2"
14566 [(use (match_operand:XF 0 "register_operand"))
14567 (use (match_operand:XF 1 "register_operand"))]
14568 "TARGET_USE_FANCY_MATH_387
14569 && flag_unsafe_math_optimizations"
14573 if (optimize_insn_for_size_p ())
14576 op2 = gen_reg_rtx (XFmode);
14577 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14579 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14583 (define_expand "exp<mode>2"
14584 [(use (match_operand:MODEF 0 "register_operand"))
14585 (use (match_operand:MODEF 1 "general_operand"))]
14586 "TARGET_USE_FANCY_MATH_387
14587 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14588 || TARGET_MIX_SSE_I387)
14589 && flag_unsafe_math_optimizations"
14593 if (optimize_insn_for_size_p ())
14596 op0 = gen_reg_rtx (XFmode);
14597 op1 = gen_reg_rtx (XFmode);
14599 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14600 emit_insn (gen_expxf2 (op0, op1));
14601 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14605 (define_expand "exp10xf2"
14606 [(use (match_operand:XF 0 "register_operand"))
14607 (use (match_operand:XF 1 "register_operand"))]
14608 "TARGET_USE_FANCY_MATH_387
14609 && flag_unsafe_math_optimizations"
14613 if (optimize_insn_for_size_p ())
14616 op2 = gen_reg_rtx (XFmode);
14617 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14619 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14623 (define_expand "exp10<mode>2"
14624 [(use (match_operand:MODEF 0 "register_operand"))
14625 (use (match_operand:MODEF 1 "general_operand"))]
14626 "TARGET_USE_FANCY_MATH_387
14627 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14628 || TARGET_MIX_SSE_I387)
14629 && flag_unsafe_math_optimizations"
14633 if (optimize_insn_for_size_p ())
14636 op0 = gen_reg_rtx (XFmode);
14637 op1 = gen_reg_rtx (XFmode);
14639 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14640 emit_insn (gen_exp10xf2 (op0, op1));
14641 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14645 (define_expand "exp2xf2"
14646 [(use (match_operand:XF 0 "register_operand"))
14647 (use (match_operand:XF 1 "register_operand"))]
14648 "TARGET_USE_FANCY_MATH_387
14649 && flag_unsafe_math_optimizations"
14653 if (optimize_insn_for_size_p ())
14656 op2 = gen_reg_rtx (XFmode);
14657 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14659 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14663 (define_expand "exp2<mode>2"
14664 [(use (match_operand:MODEF 0 "register_operand"))
14665 (use (match_operand:MODEF 1 "general_operand"))]
14666 "TARGET_USE_FANCY_MATH_387
14667 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14668 || TARGET_MIX_SSE_I387)
14669 && flag_unsafe_math_optimizations"
14673 if (optimize_insn_for_size_p ())
14676 op0 = gen_reg_rtx (XFmode);
14677 op1 = gen_reg_rtx (XFmode);
14679 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14680 emit_insn (gen_exp2xf2 (op0, op1));
14681 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14685 (define_expand "expm1xf2"
14686 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14688 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14689 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14690 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14691 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14692 (parallel [(set (match_dup 7)
14693 (unspec:XF [(match_dup 6) (match_dup 4)]
14694 UNSPEC_FSCALE_FRACT))
14696 (unspec:XF [(match_dup 6) (match_dup 4)]
14697 UNSPEC_FSCALE_EXP))])
14698 (parallel [(set (match_dup 10)
14699 (unspec:XF [(match_dup 9) (match_dup 8)]
14700 UNSPEC_FSCALE_FRACT))
14701 (set (match_dup 11)
14702 (unspec:XF [(match_dup 9) (match_dup 8)]
14703 UNSPEC_FSCALE_EXP))])
14704 (set (match_dup 12) (minus:XF (match_dup 10)
14705 (float_extend:XF (match_dup 13))))
14706 (set (match_operand:XF 0 "register_operand")
14707 (plus:XF (match_dup 12) (match_dup 7)))]
14708 "TARGET_USE_FANCY_MATH_387
14709 && flag_unsafe_math_optimizations"
14713 if (optimize_insn_for_size_p ())
14716 for (i = 2; i < 13; i++)
14717 operands[i] = gen_reg_rtx (XFmode);
14720 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14722 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14725 (define_expand "expm1<mode>2"
14726 [(use (match_operand:MODEF 0 "register_operand"))
14727 (use (match_operand:MODEF 1 "general_operand"))]
14728 "TARGET_USE_FANCY_MATH_387
14729 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14730 || TARGET_MIX_SSE_I387)
14731 && flag_unsafe_math_optimizations"
14735 if (optimize_insn_for_size_p ())
14738 op0 = gen_reg_rtx (XFmode);
14739 op1 = gen_reg_rtx (XFmode);
14741 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14742 emit_insn (gen_expm1xf2 (op0, op1));
14743 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14747 (define_expand "ldexpxf3"
14748 [(set (match_dup 3)
14749 (float:XF (match_operand:SI 2 "register_operand")))
14750 (parallel [(set (match_operand:XF 0 " register_operand")
14751 (unspec:XF [(match_operand:XF 1 "register_operand")
14753 UNSPEC_FSCALE_FRACT))
14755 (unspec:XF [(match_dup 1) (match_dup 3)]
14756 UNSPEC_FSCALE_EXP))])]
14757 "TARGET_USE_FANCY_MATH_387
14758 && flag_unsafe_math_optimizations"
14760 if (optimize_insn_for_size_p ())
14763 operands[3] = gen_reg_rtx (XFmode);
14764 operands[4] = gen_reg_rtx (XFmode);
14767 (define_expand "ldexp<mode>3"
14768 [(use (match_operand:MODEF 0 "register_operand"))
14769 (use (match_operand:MODEF 1 "general_operand"))
14770 (use (match_operand:SI 2 "register_operand"))]
14771 "TARGET_USE_FANCY_MATH_387
14772 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14773 || TARGET_MIX_SSE_I387)
14774 && flag_unsafe_math_optimizations"
14778 if (optimize_insn_for_size_p ())
14781 op0 = gen_reg_rtx (XFmode);
14782 op1 = gen_reg_rtx (XFmode);
14784 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14785 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14786 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14790 (define_expand "scalbxf3"
14791 [(parallel [(set (match_operand:XF 0 " register_operand")
14792 (unspec:XF [(match_operand:XF 1 "register_operand")
14793 (match_operand:XF 2 "register_operand")]
14794 UNSPEC_FSCALE_FRACT))
14796 (unspec:XF [(match_dup 1) (match_dup 2)]
14797 UNSPEC_FSCALE_EXP))])]
14798 "TARGET_USE_FANCY_MATH_387
14799 && flag_unsafe_math_optimizations"
14801 if (optimize_insn_for_size_p ())
14804 operands[3] = gen_reg_rtx (XFmode);
14807 (define_expand "scalb<mode>3"
14808 [(use (match_operand:MODEF 0 "register_operand"))
14809 (use (match_operand:MODEF 1 "general_operand"))
14810 (use (match_operand:MODEF 2 "general_operand"))]
14811 "TARGET_USE_FANCY_MATH_387
14812 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14813 || TARGET_MIX_SSE_I387)
14814 && flag_unsafe_math_optimizations"
14818 if (optimize_insn_for_size_p ())
14821 op0 = gen_reg_rtx (XFmode);
14822 op1 = gen_reg_rtx (XFmode);
14823 op2 = gen_reg_rtx (XFmode);
14825 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14826 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14827 emit_insn (gen_scalbxf3 (op0, op1, op2));
14828 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14832 (define_expand "significandxf2"
14833 [(parallel [(set (match_operand:XF 0 "register_operand")
14834 (unspec:XF [(match_operand:XF 1 "register_operand")]
14835 UNSPEC_XTRACT_FRACT))
14837 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14838 "TARGET_USE_FANCY_MATH_387
14839 && flag_unsafe_math_optimizations"
14840 "operands[2] = gen_reg_rtx (XFmode);")
14842 (define_expand "significand<mode>2"
14843 [(use (match_operand:MODEF 0 "register_operand"))
14844 (use (match_operand:MODEF 1 "register_operand"))]
14845 "TARGET_USE_FANCY_MATH_387
14846 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14847 || TARGET_MIX_SSE_I387)
14848 && flag_unsafe_math_optimizations"
14850 rtx op0 = gen_reg_rtx (XFmode);
14851 rtx op1 = gen_reg_rtx (XFmode);
14853 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14854 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14859 (define_insn "sse4_1_round<mode>2"
14860 [(set (match_operand:MODEF 0 "register_operand" "=x")
14861 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14862 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14865 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14866 [(set_attr "type" "ssecvt")
14867 (set_attr "prefix_extra" "1")
14868 (set_attr "prefix" "maybe_vex")
14869 (set_attr "mode" "<MODE>")])
14871 (define_insn "rintxf2"
14872 [(set (match_operand:XF 0 "register_operand" "=f")
14873 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14875 "TARGET_USE_FANCY_MATH_387
14876 && flag_unsafe_math_optimizations"
14878 [(set_attr "type" "fpspc")
14879 (set_attr "mode" "XF")])
14881 (define_expand "rint<mode>2"
14882 [(use (match_operand:MODEF 0 "register_operand"))
14883 (use (match_operand:MODEF 1 "register_operand"))]
14884 "(TARGET_USE_FANCY_MATH_387
14885 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14886 || TARGET_MIX_SSE_I387)
14887 && flag_unsafe_math_optimizations)
14888 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14889 && !flag_trapping_math)"
14891 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14892 && !flag_trapping_math)
14895 emit_insn (gen_sse4_1_round<mode>2
14896 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14897 else if (optimize_insn_for_size_p ())
14900 ix86_expand_rint (operands[0], operands[1]);
14904 rtx op0 = gen_reg_rtx (XFmode);
14905 rtx op1 = gen_reg_rtx (XFmode);
14907 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14908 emit_insn (gen_rintxf2 (op0, op1));
14910 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14915 (define_expand "round<mode>2"
14916 [(match_operand:X87MODEF 0 "register_operand")
14917 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14918 "(TARGET_USE_FANCY_MATH_387
14919 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14920 || TARGET_MIX_SSE_I387)
14921 && flag_unsafe_math_optimizations)
14922 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14923 && !flag_trapping_math && !flag_rounding_math)"
14925 if (optimize_insn_for_size_p ())
14928 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14929 && !flag_trapping_math && !flag_rounding_math)
14933 operands[1] = force_reg (<MODE>mode, operands[1]);
14934 ix86_expand_round_sse4 (operands[0], operands[1]);
14936 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14937 ix86_expand_round (operands[0], operands[1]);
14939 ix86_expand_rounddf_32 (operands[0], operands[1]);
14943 operands[1] = force_reg (<MODE>mode, operands[1]);
14944 ix86_emit_i387_round (operands[0], operands[1]);
14949 (define_insn_and_split "*fistdi2_1"
14950 [(set (match_operand:DI 0 "nonimmediate_operand")
14951 (unspec:DI [(match_operand:XF 1 "register_operand")]
14953 "TARGET_USE_FANCY_MATH_387
14954 && can_create_pseudo_p ()"
14959 if (memory_operand (operands[0], VOIDmode))
14960 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14963 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14964 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14969 [(set_attr "type" "fpspc")
14970 (set_attr "mode" "DI")])
14972 (define_insn "fistdi2"
14973 [(set (match_operand:DI 0 "memory_operand" "=m")
14974 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14976 (clobber (match_scratch:XF 2 "=&1f"))]
14977 "TARGET_USE_FANCY_MATH_387"
14978 "* return output_fix_trunc (insn, operands, false);"
14979 [(set_attr "type" "fpspc")
14980 (set_attr "mode" "DI")])
14982 (define_insn "fistdi2_with_temp"
14983 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14984 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14986 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14987 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14988 "TARGET_USE_FANCY_MATH_387"
14990 [(set_attr "type" "fpspc")
14991 (set_attr "mode" "DI")])
14994 [(set (match_operand:DI 0 "register_operand")
14995 (unspec:DI [(match_operand:XF 1 "register_operand")]
14997 (clobber (match_operand:DI 2 "memory_operand"))
14998 (clobber (match_scratch 3))]
15000 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15001 (clobber (match_dup 3))])
15002 (set (match_dup 0) (match_dup 2))])
15005 [(set (match_operand:DI 0 "memory_operand")
15006 (unspec:DI [(match_operand:XF 1 "register_operand")]
15008 (clobber (match_operand:DI 2 "memory_operand"))
15009 (clobber (match_scratch 3))]
15011 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15012 (clobber (match_dup 3))])])
15014 (define_insn_and_split "*fist<mode>2_1"
15015 [(set (match_operand:SWI24 0 "register_operand")
15016 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15018 "TARGET_USE_FANCY_MATH_387
15019 && can_create_pseudo_p ()"
15024 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15025 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15029 [(set_attr "type" "fpspc")
15030 (set_attr "mode" "<MODE>")])
15032 (define_insn "fist<mode>2"
15033 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15034 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15036 "TARGET_USE_FANCY_MATH_387"
15037 "* return output_fix_trunc (insn, operands, false);"
15038 [(set_attr "type" "fpspc")
15039 (set_attr "mode" "<MODE>")])
15041 (define_insn "fist<mode>2_with_temp"
15042 [(set (match_operand:SWI24 0 "register_operand" "=r")
15043 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15045 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15046 "TARGET_USE_FANCY_MATH_387"
15048 [(set_attr "type" "fpspc")
15049 (set_attr "mode" "<MODE>")])
15052 [(set (match_operand:SWI24 0 "register_operand")
15053 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15055 (clobber (match_operand:SWI24 2 "memory_operand"))]
15057 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15058 (set (match_dup 0) (match_dup 2))])
15061 [(set (match_operand:SWI24 0 "memory_operand")
15062 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15064 (clobber (match_operand:SWI24 2 "memory_operand"))]
15066 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15068 (define_expand "lrintxf<mode>2"
15069 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15070 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15072 "TARGET_USE_FANCY_MATH_387")
15074 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
15075 [(set (match_operand:SWI48x 0 "nonimmediate_operand")
15076 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand")]
15077 UNSPEC_FIX_NOTRUNC))]
15078 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15079 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
15081 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15082 [(match_operand:SWI248x 0 "nonimmediate_operand")
15083 (match_operand:X87MODEF 1 "register_operand")]
15084 "(TARGET_USE_FANCY_MATH_387
15085 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15086 || TARGET_MIX_SSE_I387)
15087 && flag_unsafe_math_optimizations)
15088 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15089 && <SWI248x:MODE>mode != HImode
15090 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15091 && !flag_trapping_math && !flag_rounding_math)"
15093 if (optimize_insn_for_size_p ())
15096 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15097 && <SWI248x:MODE>mode != HImode
15098 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15099 && !flag_trapping_math && !flag_rounding_math)
15100 ix86_expand_lround (operands[0], operands[1]);
15102 ix86_emit_i387_round (operands[0], operands[1]);
15106 (define_int_iterator FRNDINT_ROUNDING
15107 [UNSPEC_FRNDINT_FLOOR
15108 UNSPEC_FRNDINT_CEIL
15109 UNSPEC_FRNDINT_TRUNC])
15111 (define_int_iterator FIST_ROUNDING
15115 ;; Base name for define_insn
15116 (define_int_attr rounding_insn
15117 [(UNSPEC_FRNDINT_FLOOR "floor")
15118 (UNSPEC_FRNDINT_CEIL "ceil")
15119 (UNSPEC_FRNDINT_TRUNC "btrunc")
15120 (UNSPEC_FIST_FLOOR "floor")
15121 (UNSPEC_FIST_CEIL "ceil")])
15123 (define_int_attr rounding
15124 [(UNSPEC_FRNDINT_FLOOR "floor")
15125 (UNSPEC_FRNDINT_CEIL "ceil")
15126 (UNSPEC_FRNDINT_TRUNC "trunc")
15127 (UNSPEC_FIST_FLOOR "floor")
15128 (UNSPEC_FIST_CEIL "ceil")])
15130 (define_int_attr ROUNDING
15131 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15132 (UNSPEC_FRNDINT_CEIL "CEIL")
15133 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15134 (UNSPEC_FIST_FLOOR "FLOOR")
15135 (UNSPEC_FIST_CEIL "CEIL")])
15137 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15138 (define_insn_and_split "frndintxf2_<rounding>"
15139 [(set (match_operand:XF 0 "register_operand")
15140 (unspec:XF [(match_operand:XF 1 "register_operand")]
15142 (clobber (reg:CC FLAGS_REG))]
15143 "TARGET_USE_FANCY_MATH_387
15144 && flag_unsafe_math_optimizations
15145 && can_create_pseudo_p ()"
15150 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15152 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15153 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15155 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15156 operands[2], operands[3]));
15159 [(set_attr "type" "frndint")
15160 (set_attr "i387_cw" "<rounding>")
15161 (set_attr "mode" "XF")])
15163 (define_insn "frndintxf2_<rounding>_i387"
15164 [(set (match_operand:XF 0 "register_operand" "=f")
15165 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15167 (use (match_operand:HI 2 "memory_operand" "m"))
15168 (use (match_operand:HI 3 "memory_operand" "m"))]
15169 "TARGET_USE_FANCY_MATH_387
15170 && flag_unsafe_math_optimizations"
15171 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15172 [(set_attr "type" "frndint")
15173 (set_attr "i387_cw" "<rounding>")
15174 (set_attr "mode" "XF")])
15176 (define_expand "<rounding_insn>xf2"
15177 [(parallel [(set (match_operand:XF 0 "register_operand")
15178 (unspec:XF [(match_operand:XF 1 "register_operand")]
15180 (clobber (reg:CC FLAGS_REG))])]
15181 "TARGET_USE_FANCY_MATH_387
15182 && flag_unsafe_math_optimizations
15183 && !optimize_insn_for_size_p ()")
15185 (define_expand "<rounding_insn><mode>2"
15186 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15187 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15189 (clobber (reg:CC FLAGS_REG))])]
15190 "(TARGET_USE_FANCY_MATH_387
15191 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15192 || TARGET_MIX_SSE_I387)
15193 && flag_unsafe_math_optimizations)
15194 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15195 && !flag_trapping_math)"
15197 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15198 && !flag_trapping_math)
15201 emit_insn (gen_sse4_1_round<mode>2
15202 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15203 else if (optimize_insn_for_size_p ())
15205 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15207 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15208 ix86_expand_floorceil (operands[0], operands[1], true);
15209 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15210 ix86_expand_floorceil (operands[0], operands[1], false);
15211 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15212 ix86_expand_trunc (operands[0], operands[1]);
15214 gcc_unreachable ();
15218 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15219 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15220 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15221 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15222 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15223 ix86_expand_truncdf_32 (operands[0], operands[1]);
15225 gcc_unreachable ();
15232 if (optimize_insn_for_size_p ())
15235 op0 = gen_reg_rtx (XFmode);
15236 op1 = gen_reg_rtx (XFmode);
15237 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15238 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15240 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15245 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15246 (define_insn_and_split "frndintxf2_mask_pm"
15247 [(set (match_operand:XF 0 "register_operand")
15248 (unspec:XF [(match_operand:XF 1 "register_operand")]
15249 UNSPEC_FRNDINT_MASK_PM))
15250 (clobber (reg:CC FLAGS_REG))]
15251 "TARGET_USE_FANCY_MATH_387
15252 && flag_unsafe_math_optimizations
15253 && can_create_pseudo_p ()"
15258 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15260 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15261 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15263 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15264 operands[2], operands[3]));
15267 [(set_attr "type" "frndint")
15268 (set_attr "i387_cw" "mask_pm")
15269 (set_attr "mode" "XF")])
15271 (define_insn "frndintxf2_mask_pm_i387"
15272 [(set (match_operand:XF 0 "register_operand" "=f")
15273 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15274 UNSPEC_FRNDINT_MASK_PM))
15275 (use (match_operand:HI 2 "memory_operand" "m"))
15276 (use (match_operand:HI 3 "memory_operand" "m"))]
15277 "TARGET_USE_FANCY_MATH_387
15278 && flag_unsafe_math_optimizations"
15279 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15280 [(set_attr "type" "frndint")
15281 (set_attr "i387_cw" "mask_pm")
15282 (set_attr "mode" "XF")])
15284 (define_expand "nearbyintxf2"
15285 [(parallel [(set (match_operand:XF 0 "register_operand")
15286 (unspec:XF [(match_operand:XF 1 "register_operand")]
15287 UNSPEC_FRNDINT_MASK_PM))
15288 (clobber (reg:CC FLAGS_REG))])]
15289 "TARGET_USE_FANCY_MATH_387
15290 && flag_unsafe_math_optimizations")
15292 (define_expand "nearbyint<mode>2"
15293 [(use (match_operand:MODEF 0 "register_operand"))
15294 (use (match_operand:MODEF 1 "register_operand"))]
15295 "TARGET_USE_FANCY_MATH_387
15296 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15297 || TARGET_MIX_SSE_I387)
15298 && flag_unsafe_math_optimizations"
15300 rtx op0 = gen_reg_rtx (XFmode);
15301 rtx op1 = gen_reg_rtx (XFmode);
15303 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15304 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15306 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15310 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15311 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15312 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15313 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15315 (clobber (reg:CC FLAGS_REG))]
15316 "TARGET_USE_FANCY_MATH_387
15317 && flag_unsafe_math_optimizations
15318 && can_create_pseudo_p ()"
15323 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15325 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15326 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15327 if (memory_operand (operands[0], VOIDmode))
15328 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15329 operands[2], operands[3]));
15332 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15333 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15334 (operands[0], operands[1], operands[2],
15335 operands[3], operands[4]));
15339 [(set_attr "type" "fistp")
15340 (set_attr "i387_cw" "<rounding>")
15341 (set_attr "mode" "<MODE>")])
15343 (define_insn "fistdi2_<rounding>"
15344 [(set (match_operand:DI 0 "memory_operand" "=m")
15345 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15347 (use (match_operand:HI 2 "memory_operand" "m"))
15348 (use (match_operand:HI 3 "memory_operand" "m"))
15349 (clobber (match_scratch:XF 4 "=&1f"))]
15350 "TARGET_USE_FANCY_MATH_387
15351 && flag_unsafe_math_optimizations"
15352 "* return output_fix_trunc (insn, operands, false);"
15353 [(set_attr "type" "fistp")
15354 (set_attr "i387_cw" "<rounding>")
15355 (set_attr "mode" "DI")])
15357 (define_insn "fistdi2_<rounding>_with_temp"
15358 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15359 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15361 (use (match_operand:HI 2 "memory_operand" "m,m"))
15362 (use (match_operand:HI 3 "memory_operand" "m,m"))
15363 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15364 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15365 "TARGET_USE_FANCY_MATH_387
15366 && flag_unsafe_math_optimizations"
15368 [(set_attr "type" "fistp")
15369 (set_attr "i387_cw" "<rounding>")
15370 (set_attr "mode" "DI")])
15373 [(set (match_operand:DI 0 "register_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 4)
15382 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15383 (use (match_dup 2))
15384 (use (match_dup 3))
15385 (clobber (match_dup 5))])
15386 (set (match_dup 0) (match_dup 4))])
15389 [(set (match_operand:DI 0 "memory_operand")
15390 (unspec:DI [(match_operand:XF 1 "register_operand")]
15392 (use (match_operand:HI 2 "memory_operand"))
15393 (use (match_operand:HI 3 "memory_operand"))
15394 (clobber (match_operand:DI 4 "memory_operand"))
15395 (clobber (match_scratch 5))]
15397 [(parallel [(set (match_dup 0)
15398 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15399 (use (match_dup 2))
15400 (use (match_dup 3))
15401 (clobber (match_dup 5))])])
15403 (define_insn "fist<mode>2_<rounding>"
15404 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15405 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15407 (use (match_operand:HI 2 "memory_operand" "m"))
15408 (use (match_operand:HI 3 "memory_operand" "m"))]
15409 "TARGET_USE_FANCY_MATH_387
15410 && flag_unsafe_math_optimizations"
15411 "* return output_fix_trunc (insn, operands, false);"
15412 [(set_attr "type" "fistp")
15413 (set_attr "i387_cw" "<rounding>")
15414 (set_attr "mode" "<MODE>")])
15416 (define_insn "fist<mode>2_<rounding>_with_temp"
15417 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15418 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15420 (use (match_operand:HI 2 "memory_operand" "m,m"))
15421 (use (match_operand:HI 3 "memory_operand" "m,m"))
15422 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15423 "TARGET_USE_FANCY_MATH_387
15424 && flag_unsafe_math_optimizations"
15426 [(set_attr "type" "fistp")
15427 (set_attr "i387_cw" "<rounding>")
15428 (set_attr "mode" "<MODE>")])
15431 [(set (match_operand:SWI24 0 "register_operand")
15432 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15434 (use (match_operand:HI 2 "memory_operand"))
15435 (use (match_operand:HI 3 "memory_operand"))
15436 (clobber (match_operand:SWI24 4 "memory_operand"))]
15438 [(parallel [(set (match_dup 4)
15439 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15440 (use (match_dup 2))
15441 (use (match_dup 3))])
15442 (set (match_dup 0) (match_dup 4))])
15445 [(set (match_operand:SWI24 0 "memory_operand")
15446 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15448 (use (match_operand:HI 2 "memory_operand"))
15449 (use (match_operand:HI 3 "memory_operand"))
15450 (clobber (match_operand:SWI24 4 "memory_operand"))]
15452 [(parallel [(set (match_dup 0)
15453 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15454 (use (match_dup 2))
15455 (use (match_dup 3))])])
15457 (define_expand "l<rounding_insn>xf<mode>2"
15458 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15459 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15461 (clobber (reg:CC FLAGS_REG))])]
15462 "TARGET_USE_FANCY_MATH_387
15463 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15464 && flag_unsafe_math_optimizations")
15466 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15467 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15468 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15470 (clobber (reg:CC FLAGS_REG))])]
15471 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15472 && !flag_trapping_math"
15474 if (TARGET_64BIT && optimize_insn_for_size_p ())
15477 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15478 ix86_expand_lfloorceil (operands[0], operands[1], true);
15479 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15480 ix86_expand_lfloorceil (operands[0], operands[1], false);
15482 gcc_unreachable ();
15487 (define_insn "fxam<mode>2_i387"
15488 [(set (match_operand:HI 0 "register_operand" "=a")
15490 [(match_operand:X87MODEF 1 "register_operand" "f")]
15492 "TARGET_USE_FANCY_MATH_387"
15493 "fxam\n\tfnstsw\t%0"
15494 [(set_attr "type" "multi")
15495 (set_attr "length" "4")
15496 (set_attr "unit" "i387")
15497 (set_attr "mode" "<MODE>")])
15499 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15500 [(set (match_operand:HI 0 "register_operand")
15502 [(match_operand:MODEF 1 "memory_operand")]
15504 "TARGET_USE_FANCY_MATH_387
15505 && can_create_pseudo_p ()"
15508 [(set (match_dup 2)(match_dup 1))
15510 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15512 operands[2] = gen_reg_rtx (<MODE>mode);
15514 MEM_VOLATILE_P (operands[1]) = 1;
15516 [(set_attr "type" "multi")
15517 (set_attr "unit" "i387")
15518 (set_attr "mode" "<MODE>")])
15520 (define_expand "isinfxf2"
15521 [(use (match_operand:SI 0 "register_operand"))
15522 (use (match_operand:XF 1 "register_operand"))]
15523 "TARGET_USE_FANCY_MATH_387
15524 && TARGET_C99_FUNCTIONS"
15526 rtx mask = GEN_INT (0x45);
15527 rtx val = GEN_INT (0x05);
15531 rtx scratch = gen_reg_rtx (HImode);
15532 rtx res = gen_reg_rtx (QImode);
15534 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15536 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15537 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15538 cond = gen_rtx_fmt_ee (EQ, QImode,
15539 gen_rtx_REG (CCmode, FLAGS_REG),
15541 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15542 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15546 (define_expand "isinf<mode>2"
15547 [(use (match_operand:SI 0 "register_operand"))
15548 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15549 "TARGET_USE_FANCY_MATH_387
15550 && TARGET_C99_FUNCTIONS
15551 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15553 rtx mask = GEN_INT (0x45);
15554 rtx val = GEN_INT (0x05);
15558 rtx scratch = gen_reg_rtx (HImode);
15559 rtx res = gen_reg_rtx (QImode);
15561 /* Remove excess precision by forcing value through memory. */
15562 if (memory_operand (operands[1], VOIDmode))
15563 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15566 enum ix86_stack_slot slot = (virtuals_instantiated
15569 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15571 emit_move_insn (temp, operands[1]);
15572 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15575 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15576 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15577 cond = gen_rtx_fmt_ee (EQ, QImode,
15578 gen_rtx_REG (CCmode, FLAGS_REG),
15580 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15581 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15585 (define_expand "signbitxf2"
15586 [(use (match_operand:SI 0 "register_operand"))
15587 (use (match_operand:XF 1 "register_operand"))]
15588 "TARGET_USE_FANCY_MATH_387"
15590 rtx scratch = gen_reg_rtx (HImode);
15592 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15593 emit_insn (gen_andsi3 (operands[0],
15594 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15598 (define_insn "movmsk_df"
15599 [(set (match_operand:SI 0 "register_operand" "=r")
15601 [(match_operand:DF 1 "register_operand" "x")]
15603 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15604 "%vmovmskpd\t{%1, %0|%0, %1}"
15605 [(set_attr "type" "ssemov")
15606 (set_attr "prefix" "maybe_vex")
15607 (set_attr "mode" "DF")])
15609 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15610 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15611 (define_expand "signbitdf2"
15612 [(use (match_operand:SI 0 "register_operand"))
15613 (use (match_operand:DF 1 "register_operand"))]
15614 "TARGET_USE_FANCY_MATH_387
15615 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15617 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15619 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15620 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15624 rtx scratch = gen_reg_rtx (HImode);
15626 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15627 emit_insn (gen_andsi3 (operands[0],
15628 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15633 (define_expand "signbitsf2"
15634 [(use (match_operand:SI 0 "register_operand"))
15635 (use (match_operand:SF 1 "register_operand"))]
15636 "TARGET_USE_FANCY_MATH_387
15637 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15639 rtx scratch = gen_reg_rtx (HImode);
15641 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15642 emit_insn (gen_andsi3 (operands[0],
15643 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15647 ;; Block operation instructions
15650 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15653 [(set_attr "length" "1")
15654 (set_attr "length_immediate" "0")
15655 (set_attr "modrm" "0")])
15657 (define_expand "movmem<mode>"
15658 [(use (match_operand:BLK 0 "memory_operand"))
15659 (use (match_operand:BLK 1 "memory_operand"))
15660 (use (match_operand:SWI48 2 "nonmemory_operand"))
15661 (use (match_operand:SWI48 3 "const_int_operand"))
15662 (use (match_operand:SI 4 "const_int_operand"))
15663 (use (match_operand:SI 5 "const_int_operand"))]
15666 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15667 operands[4], operands[5]))
15673 ;; Most CPUs don't like single string operations
15674 ;; Handle this case here to simplify previous expander.
15676 (define_expand "strmov"
15677 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15678 (set (match_operand 1 "memory_operand") (match_dup 4))
15679 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15680 (clobber (reg:CC FLAGS_REG))])
15681 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15682 (clobber (reg:CC FLAGS_REG))])]
15685 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15687 /* If .md ever supports :P for Pmode, these can be directly
15688 in the pattern above. */
15689 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15690 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15692 /* Can't use this if the user has appropriated esi or edi. */
15693 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15694 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15696 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15697 operands[2], operands[3],
15698 operands[5], operands[6]));
15702 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15705 (define_expand "strmov_singleop"
15706 [(parallel [(set (match_operand 1 "memory_operand")
15707 (match_operand 3 "memory_operand"))
15708 (set (match_operand 0 "register_operand")
15710 (set (match_operand 2 "register_operand")
15711 (match_operand 5))])]
15713 "ix86_current_function_needs_cld = 1;")
15715 (define_insn "*strmovdi_rex_1"
15716 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15717 (mem:DI (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)
15725 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15727 [(set_attr "type" "str")
15728 (set_attr "memory" "both")
15729 (set_attr "mode" "DI")])
15731 (define_insn "*strmovsi_1"
15732 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15733 (mem:SI (match_operand:P 3 "register_operand" "1")))
15734 (set (match_operand:P 0 "register_operand" "=D")
15735 (plus:P (match_dup 2)
15737 (set (match_operand:P 1 "register_operand" "=S")
15738 (plus:P (match_dup 3)
15740 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15742 [(set_attr "type" "str")
15743 (set_attr "memory" "both")
15744 (set_attr "mode" "SI")])
15746 (define_insn "*strmovhi_1"
15747 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15748 (mem:HI (match_operand:P 3 "register_operand" "1")))
15749 (set (match_operand:P 0 "register_operand" "=D")
15750 (plus:P (match_dup 2)
15752 (set (match_operand:P 1 "register_operand" "=S")
15753 (plus:P (match_dup 3)
15755 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15757 [(set_attr "type" "str")
15758 (set_attr "memory" "both")
15759 (set_attr "mode" "HI")])
15761 (define_insn "*strmovqi_1"
15762 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15763 (mem:QI (match_operand:P 3 "register_operand" "1")))
15764 (set (match_operand:P 0 "register_operand" "=D")
15765 (plus:P (match_dup 2)
15767 (set (match_operand:P 1 "register_operand" "=S")
15768 (plus:P (match_dup 3)
15770 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15772 [(set_attr "type" "str")
15773 (set_attr "memory" "both")
15774 (set (attr "prefix_rex")
15776 (match_test "<P:MODE>mode == DImode")
15778 (const_string "*")))
15779 (set_attr "mode" "QI")])
15781 (define_expand "rep_mov"
15782 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15783 (set (match_operand 0 "register_operand")
15785 (set (match_operand 2 "register_operand")
15787 (set (match_operand 1 "memory_operand")
15788 (match_operand 3 "memory_operand"))
15789 (use (match_dup 4))])]
15791 "ix86_current_function_needs_cld = 1;")
15793 (define_insn "*rep_movdi_rex64"
15794 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15795 (set (match_operand:P 0 "register_operand" "=D")
15796 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15798 (match_operand:P 3 "register_operand" "0")))
15799 (set (match_operand:P 1 "register_operand" "=S")
15800 (plus:P (ashift:P (match_dup 5) (const_int 3))
15801 (match_operand:P 4 "register_operand" "1")))
15802 (set (mem:BLK (match_dup 3))
15803 (mem:BLK (match_dup 4)))
15804 (use (match_dup 5))]
15806 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15808 [(set_attr "type" "str")
15809 (set_attr "prefix_rep" "1")
15810 (set_attr "memory" "both")
15811 (set_attr "mode" "DI")])
15813 (define_insn "*rep_movsi"
15814 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15815 (set (match_operand:P 0 "register_operand" "=D")
15816 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15818 (match_operand:P 3 "register_operand" "0")))
15819 (set (match_operand:P 1 "register_operand" "=S")
15820 (plus:P (ashift:P (match_dup 5) (const_int 2))
15821 (match_operand:P 4 "register_operand" "1")))
15822 (set (mem:BLK (match_dup 3))
15823 (mem:BLK (match_dup 4)))
15824 (use (match_dup 5))]
15825 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15826 "%^rep{%;} movs{l|d}"
15827 [(set_attr "type" "str")
15828 (set_attr "prefix_rep" "1")
15829 (set_attr "memory" "both")
15830 (set_attr "mode" "SI")])
15832 (define_insn "*rep_movqi"
15833 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15834 (set (match_operand:P 0 "register_operand" "=D")
15835 (plus:P (match_operand:P 3 "register_operand" "0")
15836 (match_operand:P 5 "register_operand" "2")))
15837 (set (match_operand:P 1 "register_operand" "=S")
15838 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15839 (set (mem:BLK (match_dup 3))
15840 (mem:BLK (match_dup 4)))
15841 (use (match_dup 5))]
15842 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15844 [(set_attr "type" "str")
15845 (set_attr "prefix_rep" "1")
15846 (set_attr "memory" "both")
15847 (set_attr "mode" "QI")])
15849 (define_expand "setmem<mode>"
15850 [(use (match_operand:BLK 0 "memory_operand"))
15851 (use (match_operand:SWI48 1 "nonmemory_operand"))
15852 (use (match_operand:QI 2 "nonmemory_operand"))
15853 (use (match_operand 3 "const_int_operand"))
15854 (use (match_operand:SI 4 "const_int_operand"))
15855 (use (match_operand:SI 5 "const_int_operand"))]
15858 if (ix86_expand_setmem (operands[0], operands[1],
15859 operands[2], operands[3],
15860 operands[4], operands[5]))
15866 ;; Most CPUs don't like single string operations
15867 ;; Handle this case here to simplify previous expander.
15869 (define_expand "strset"
15870 [(set (match_operand 1 "memory_operand")
15871 (match_operand 2 "register_operand"))
15872 (parallel [(set (match_operand 0 "register_operand")
15874 (clobber (reg:CC FLAGS_REG))])]
15877 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15878 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15880 /* If .md ever supports :P for Pmode, this can be directly
15881 in the pattern above. */
15882 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15883 GEN_INT (GET_MODE_SIZE (GET_MODE
15885 /* Can't use this if the user has appropriated eax or edi. */
15886 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15887 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15889 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15895 (define_expand "strset_singleop"
15896 [(parallel [(set (match_operand 1 "memory_operand")
15897 (match_operand 2 "register_operand"))
15898 (set (match_operand 0 "register_operand")
15899 (match_operand 3))])]
15901 "ix86_current_function_needs_cld = 1;")
15903 (define_insn "*strsetdi_rex_1"
15904 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15905 (match_operand:DI 2 "register_operand" "a"))
15906 (set (match_operand:P 0 "register_operand" "=D")
15907 (plus:P (match_dup 1)
15910 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15912 [(set_attr "type" "str")
15913 (set_attr "memory" "store")
15914 (set_attr "mode" "DI")])
15916 (define_insn "*strsetsi_1"
15917 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15918 (match_operand:SI 2 "register_operand" "a"))
15919 (set (match_operand:P 0 "register_operand" "=D")
15920 (plus:P (match_dup 1)
15922 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15924 [(set_attr "type" "str")
15925 (set_attr "memory" "store")
15926 (set_attr "mode" "SI")])
15928 (define_insn "*strsethi_1"
15929 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15930 (match_operand:HI 2 "register_operand" "a"))
15931 (set (match_operand:P 0 "register_operand" "=D")
15932 (plus:P (match_dup 1)
15934 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15936 [(set_attr "type" "str")
15937 (set_attr "memory" "store")
15938 (set_attr "mode" "HI")])
15940 (define_insn "*strsetqi_1"
15941 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15942 (match_operand:QI 2 "register_operand" "a"))
15943 (set (match_operand:P 0 "register_operand" "=D")
15944 (plus:P (match_dup 1)
15946 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15948 [(set_attr "type" "str")
15949 (set_attr "memory" "store")
15950 (set (attr "prefix_rex")
15952 (match_test "<P:MODE>mode == DImode")
15954 (const_string "*")))
15955 (set_attr "mode" "QI")])
15957 (define_expand "rep_stos"
15958 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15959 (set (match_operand 0 "register_operand")
15961 (set (match_operand 2 "memory_operand") (const_int 0))
15962 (use (match_operand 3 "register_operand"))
15963 (use (match_dup 1))])]
15965 "ix86_current_function_needs_cld = 1;")
15967 (define_insn "*rep_stosdi_rex64"
15968 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15969 (set (match_operand:P 0 "register_operand" "=D")
15970 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15972 (match_operand:P 3 "register_operand" "0")))
15973 (set (mem:BLK (match_dup 3))
15975 (use (match_operand:DI 2 "register_operand" "a"))
15976 (use (match_dup 4))]
15978 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15980 [(set_attr "type" "str")
15981 (set_attr "prefix_rep" "1")
15982 (set_attr "memory" "store")
15983 (set_attr "mode" "DI")])
15985 (define_insn "*rep_stossi"
15986 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15987 (set (match_operand:P 0 "register_operand" "=D")
15988 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15990 (match_operand:P 3 "register_operand" "0")))
15991 (set (mem:BLK (match_dup 3))
15993 (use (match_operand:SI 2 "register_operand" "a"))
15994 (use (match_dup 4))]
15995 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15996 "%^rep{%;} stos{l|d}"
15997 [(set_attr "type" "str")
15998 (set_attr "prefix_rep" "1")
15999 (set_attr "memory" "store")
16000 (set_attr "mode" "SI")])
16002 (define_insn "*rep_stosqi"
16003 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16004 (set (match_operand:P 0 "register_operand" "=D")
16005 (plus:P (match_operand:P 3 "register_operand" "0")
16006 (match_operand:P 4 "register_operand" "1")))
16007 (set (mem:BLK (match_dup 3))
16009 (use (match_operand:QI 2 "register_operand" "a"))
16010 (use (match_dup 4))]
16011 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16013 [(set_attr "type" "str")
16014 (set_attr "prefix_rep" "1")
16015 (set_attr "memory" "store")
16016 (set (attr "prefix_rex")
16018 (match_test "<P:MODE>mode == DImode")
16020 (const_string "*")))
16021 (set_attr "mode" "QI")])
16023 (define_expand "cmpstrnsi"
16024 [(set (match_operand:SI 0 "register_operand")
16025 (compare:SI (match_operand:BLK 1 "general_operand")
16026 (match_operand:BLK 2 "general_operand")))
16027 (use (match_operand 3 "general_operand"))
16028 (use (match_operand 4 "immediate_operand"))]
16031 rtx addr1, addr2, out, outlow, count, countreg, align;
16033 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16036 /* Can't use this if the user has appropriated ecx, esi or edi. */
16037 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16042 out = gen_reg_rtx (SImode);
16044 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16045 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16046 if (addr1 != XEXP (operands[1], 0))
16047 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16048 if (addr2 != XEXP (operands[2], 0))
16049 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16051 count = operands[3];
16052 countreg = ix86_zero_extend_to_Pmode (count);
16054 /* %%% Iff we are testing strict equality, we can use known alignment
16055 to good advantage. This may be possible with combine, particularly
16056 once cc0 is dead. */
16057 align = operands[4];
16059 if (CONST_INT_P (count))
16061 if (INTVAL (count) == 0)
16063 emit_move_insn (operands[0], const0_rtx);
16066 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16067 operands[1], operands[2]));
16071 rtx (*gen_cmp) (rtx, rtx);
16073 gen_cmp = (TARGET_64BIT
16074 ? gen_cmpdi_1 : gen_cmpsi_1);
16076 emit_insn (gen_cmp (countreg, countreg));
16077 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16078 operands[1], operands[2]));
16081 outlow = gen_lowpart (QImode, out);
16082 emit_insn (gen_cmpintqi (outlow));
16083 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16085 if (operands[0] != out)
16086 emit_move_insn (operands[0], out);
16091 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16093 (define_expand "cmpintqi"
16094 [(set (match_dup 1)
16095 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16097 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16098 (parallel [(set (match_operand:QI 0 "register_operand")
16099 (minus:QI (match_dup 1)
16101 (clobber (reg:CC FLAGS_REG))])]
16104 operands[1] = gen_reg_rtx (QImode);
16105 operands[2] = gen_reg_rtx (QImode);
16108 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16109 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16111 (define_expand "cmpstrnqi_nz_1"
16112 [(parallel [(set (reg:CC FLAGS_REG)
16113 (compare:CC (match_operand 4 "memory_operand")
16114 (match_operand 5 "memory_operand")))
16115 (use (match_operand 2 "register_operand"))
16116 (use (match_operand:SI 3 "immediate_operand"))
16117 (clobber (match_operand 0 "register_operand"))
16118 (clobber (match_operand 1 "register_operand"))
16119 (clobber (match_dup 2))])]
16121 "ix86_current_function_needs_cld = 1;")
16123 (define_insn "*cmpstrnqi_nz_1"
16124 [(set (reg:CC FLAGS_REG)
16125 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16126 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16127 (use (match_operand:P 6 "register_operand" "2"))
16128 (use (match_operand:SI 3 "immediate_operand" "i"))
16129 (clobber (match_operand:P 0 "register_operand" "=S"))
16130 (clobber (match_operand:P 1 "register_operand" "=D"))
16131 (clobber (match_operand:P 2 "register_operand" "=c"))]
16132 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16134 [(set_attr "type" "str")
16135 (set_attr "mode" "QI")
16136 (set (attr "prefix_rex")
16138 (match_test "<P:MODE>mode == DImode")
16140 (const_string "*")))
16141 (set_attr "prefix_rep" "1")])
16143 ;; The same, but the count is not known to not be zero.
16145 (define_expand "cmpstrnqi_1"
16146 [(parallel [(set (reg:CC FLAGS_REG)
16147 (if_then_else:CC (ne (match_operand 2 "register_operand")
16149 (compare:CC (match_operand 4 "memory_operand")
16150 (match_operand 5 "memory_operand"))
16152 (use (match_operand:SI 3 "immediate_operand"))
16153 (use (reg:CC FLAGS_REG))
16154 (clobber (match_operand 0 "register_operand"))
16155 (clobber (match_operand 1 "register_operand"))
16156 (clobber (match_dup 2))])]
16158 "ix86_current_function_needs_cld = 1;")
16160 (define_insn "*cmpstrnqi_1"
16161 [(set (reg:CC FLAGS_REG)
16162 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16164 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16165 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16167 (use (match_operand:SI 3 "immediate_operand" "i"))
16168 (use (reg:CC FLAGS_REG))
16169 (clobber (match_operand:P 0 "register_operand" "=S"))
16170 (clobber (match_operand:P 1 "register_operand" "=D"))
16171 (clobber (match_operand:P 2 "register_operand" "=c"))]
16172 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16174 [(set_attr "type" "str")
16175 (set_attr "mode" "QI")
16176 (set (attr "prefix_rex")
16178 (match_test "<P:MODE>mode == DImode")
16180 (const_string "*")))
16181 (set_attr "prefix_rep" "1")])
16183 (define_expand "strlen<mode>"
16184 [(set (match_operand:P 0 "register_operand")
16185 (unspec:P [(match_operand:BLK 1 "general_operand")
16186 (match_operand:QI 2 "immediate_operand")
16187 (match_operand 3 "immediate_operand")]
16191 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16197 (define_expand "strlenqi_1"
16198 [(parallel [(set (match_operand 0 "register_operand")
16200 (clobber (match_operand 1 "register_operand"))
16201 (clobber (reg:CC FLAGS_REG))])]
16203 "ix86_current_function_needs_cld = 1;")
16205 (define_insn "*strlenqi_1"
16206 [(set (match_operand:P 0 "register_operand" "=&c")
16207 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16208 (match_operand:QI 2 "register_operand" "a")
16209 (match_operand:P 3 "immediate_operand" "i")
16210 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16211 (clobber (match_operand:P 1 "register_operand" "=D"))
16212 (clobber (reg:CC FLAGS_REG))]
16213 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16214 "%^repnz{%;} scasb"
16215 [(set_attr "type" "str")
16216 (set_attr "mode" "QI")
16217 (set (attr "prefix_rex")
16219 (match_test "<P:MODE>mode == DImode")
16221 (const_string "*")))
16222 (set_attr "prefix_rep" "1")])
16224 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16225 ;; handled in combine, but it is not currently up to the task.
16226 ;; When used for their truth value, the cmpstrn* expanders generate
16235 ;; The intermediate three instructions are unnecessary.
16237 ;; This one handles cmpstrn*_nz_1...
16240 (set (reg:CC FLAGS_REG)
16241 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16242 (mem:BLK (match_operand 5 "register_operand"))))
16243 (use (match_operand 6 "register_operand"))
16244 (use (match_operand:SI 3 "immediate_operand"))
16245 (clobber (match_operand 0 "register_operand"))
16246 (clobber (match_operand 1 "register_operand"))
16247 (clobber (match_operand 2 "register_operand"))])
16248 (set (match_operand:QI 7 "register_operand")
16249 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16250 (set (match_operand:QI 8 "register_operand")
16251 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16252 (set (reg FLAGS_REG)
16253 (compare (match_dup 7) (match_dup 8)))
16255 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16257 (set (reg:CC FLAGS_REG)
16258 (compare:CC (mem:BLK (match_dup 4))
16259 (mem:BLK (match_dup 5))))
16260 (use (match_dup 6))
16261 (use (match_dup 3))
16262 (clobber (match_dup 0))
16263 (clobber (match_dup 1))
16264 (clobber (match_dup 2))])])
16266 ;; ...and this one handles cmpstrn*_1.
16269 (set (reg:CC FLAGS_REG)
16270 (if_then_else:CC (ne (match_operand 6 "register_operand")
16272 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16273 (mem:BLK (match_operand 5 "register_operand")))
16275 (use (match_operand:SI 3 "immediate_operand"))
16276 (use (reg:CC FLAGS_REG))
16277 (clobber (match_operand 0 "register_operand"))
16278 (clobber (match_operand 1 "register_operand"))
16279 (clobber (match_operand 2 "register_operand"))])
16280 (set (match_operand:QI 7 "register_operand")
16281 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16282 (set (match_operand:QI 8 "register_operand")
16283 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16284 (set (reg FLAGS_REG)
16285 (compare (match_dup 7) (match_dup 8)))
16287 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16289 (set (reg:CC FLAGS_REG)
16290 (if_then_else:CC (ne (match_dup 6)
16292 (compare:CC (mem:BLK (match_dup 4))
16293 (mem:BLK (match_dup 5)))
16295 (use (match_dup 3))
16296 (use (reg:CC FLAGS_REG))
16297 (clobber (match_dup 0))
16298 (clobber (match_dup 1))
16299 (clobber (match_dup 2))])])
16301 ;; Conditional move instructions.
16303 (define_expand "mov<mode>cc"
16304 [(set (match_operand:SWIM 0 "register_operand")
16305 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator")
16306 (match_operand:SWIM 2 "<general_operand>")
16307 (match_operand:SWIM 3 "<general_operand>")))]
16309 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16311 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16312 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16313 ;; So just document what we're doing explicitly.
16315 (define_expand "x86_mov<mode>cc_0_m1"
16317 [(set (match_operand:SWI48 0 "register_operand")
16318 (if_then_else:SWI48
16319 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16320 [(match_operand 1 "flags_reg_operand")
16324 (clobber (reg:CC FLAGS_REG))])])
16326 (define_insn "*x86_mov<mode>cc_0_m1"
16327 [(set (match_operand:SWI48 0 "register_operand" "=r")
16328 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16329 [(reg FLAGS_REG) (const_int 0)])
16332 (clobber (reg:CC FLAGS_REG))]
16334 "sbb{<imodesuffix>}\t%0, %0"
16335 ; Since we don't have the proper number of operands for an alu insn,
16336 ; fill in all the blanks.
16337 [(set_attr "type" "alu")
16338 (set_attr "use_carry" "1")
16339 (set_attr "pent_pair" "pu")
16340 (set_attr "memory" "none")
16341 (set_attr "imm_disp" "false")
16342 (set_attr "mode" "<MODE>")
16343 (set_attr "length_immediate" "0")])
16345 (define_insn "*x86_mov<mode>cc_0_m1_se"
16346 [(set (match_operand:SWI48 0 "register_operand" "=r")
16347 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16348 [(reg FLAGS_REG) (const_int 0)])
16351 (clobber (reg:CC FLAGS_REG))]
16353 "sbb{<imodesuffix>}\t%0, %0"
16354 [(set_attr "type" "alu")
16355 (set_attr "use_carry" "1")
16356 (set_attr "pent_pair" "pu")
16357 (set_attr "memory" "none")
16358 (set_attr "imm_disp" "false")
16359 (set_attr "mode" "<MODE>")
16360 (set_attr "length_immediate" "0")])
16362 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16363 [(set (match_operand:SWI48 0 "register_operand" "=r")
16364 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16365 [(reg FLAGS_REG) (const_int 0)])))
16366 (clobber (reg:CC FLAGS_REG))]
16368 "sbb{<imodesuffix>}\t%0, %0"
16369 [(set_attr "type" "alu")
16370 (set_attr "use_carry" "1")
16371 (set_attr "pent_pair" "pu")
16372 (set_attr "memory" "none")
16373 (set_attr "imm_disp" "false")
16374 (set_attr "mode" "<MODE>")
16375 (set_attr "length_immediate" "0")])
16377 (define_insn "*mov<mode>cc_noc"
16378 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16379 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16380 [(reg FLAGS_REG) (const_int 0)])
16381 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16382 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16383 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16385 cmov%O2%C1\t{%2, %0|%0, %2}
16386 cmov%O2%c1\t{%3, %0|%0, %3}"
16387 [(set_attr "type" "icmov")
16388 (set_attr "mode" "<MODE>")])
16390 (define_insn "*movqicc_noc"
16391 [(set (match_operand:QI 0 "register_operand" "=r,r")
16392 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16393 [(reg FLAGS_REG) (const_int 0)])
16394 (match_operand:QI 2 "register_operand" "r,0")
16395 (match_operand:QI 3 "register_operand" "0,r")))]
16396 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16398 [(set_attr "type" "icmov")
16399 (set_attr "mode" "QI")])
16402 [(set (match_operand 0 "register_operand")
16403 (if_then_else (match_operator 1 "ix86_comparison_operator"
16404 [(reg FLAGS_REG) (const_int 0)])
16405 (match_operand 2 "register_operand")
16406 (match_operand 3 "register_operand")))]
16407 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16408 && (GET_MODE (operands[0]) == QImode
16409 || GET_MODE (operands[0]) == HImode)
16410 && reload_completed"
16411 [(set (match_dup 0)
16412 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16414 operands[0] = gen_lowpart (SImode, operands[0]);
16415 operands[2] = gen_lowpart (SImode, operands[2]);
16416 operands[3] = gen_lowpart (SImode, operands[3]);
16419 (define_expand "mov<mode>cc"
16420 [(set (match_operand:X87MODEF 0 "register_operand")
16421 (if_then_else:X87MODEF
16422 (match_operand 1 "ix86_fp_comparison_operator")
16423 (match_operand:X87MODEF 2 "register_operand")
16424 (match_operand:X87MODEF 3 "register_operand")))]
16425 "(TARGET_80387 && TARGET_CMOVE)
16426 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16427 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16429 (define_insn "*movxfcc_1"
16430 [(set (match_operand:XF 0 "register_operand" "=f,f")
16431 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16432 [(reg FLAGS_REG) (const_int 0)])
16433 (match_operand:XF 2 "register_operand" "f,0")
16434 (match_operand:XF 3 "register_operand" "0,f")))]
16435 "TARGET_80387 && TARGET_CMOVE"
16437 fcmov%F1\t{%2, %0|%0, %2}
16438 fcmov%f1\t{%3, %0|%0, %3}"
16439 [(set_attr "type" "fcmov")
16440 (set_attr "mode" "XF")])
16442 (define_insn "*movdfcc_1_rex64"
16443 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16444 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16445 [(reg FLAGS_REG) (const_int 0)])
16446 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16447 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16448 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16449 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16451 fcmov%F1\t{%2, %0|%0, %2}
16452 fcmov%f1\t{%3, %0|%0, %3}
16453 cmov%O2%C1\t{%2, %0|%0, %2}
16454 cmov%O2%c1\t{%3, %0|%0, %3}"
16455 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16456 (set_attr "mode" "DF,DF,DI,DI")])
16458 (define_insn "*movdfcc_1"
16459 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16460 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16461 [(reg FLAGS_REG) (const_int 0)])
16462 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16463 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16464 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16465 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16467 fcmov%F1\t{%2, %0|%0, %2}
16468 fcmov%f1\t{%3, %0|%0, %3}
16471 [(set_attr "type" "fcmov,fcmov,multi,multi")
16472 (set_attr "mode" "DF,DF,DI,DI")])
16475 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16476 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16477 [(reg FLAGS_REG) (const_int 0)])
16478 (match_operand:DF 2 "nonimmediate_operand")
16479 (match_operand:DF 3 "nonimmediate_operand")))]
16480 "!TARGET_64BIT && reload_completed"
16481 [(set (match_dup 2)
16482 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16484 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16486 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16487 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16490 (define_insn "*movsfcc_1_387"
16491 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16492 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16493 [(reg FLAGS_REG) (const_int 0)])
16494 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16495 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16496 "TARGET_80387 && TARGET_CMOVE
16497 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16499 fcmov%F1\t{%2, %0|%0, %2}
16500 fcmov%f1\t{%3, %0|%0, %3}
16501 cmov%O2%C1\t{%2, %0|%0, %2}
16502 cmov%O2%c1\t{%3, %0|%0, %3}"
16503 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16504 (set_attr "mode" "SF,SF,SI,SI")])
16506 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16507 ;; the scalar versions to have only XMM registers as operands.
16509 ;; XOP conditional move
16510 (define_insn "*xop_pcmov_<mode>"
16511 [(set (match_operand:MODEF 0 "register_operand" "=x")
16512 (if_then_else:MODEF
16513 (match_operand:MODEF 1 "register_operand" "x")
16514 (match_operand:MODEF 2 "register_operand" "x")
16515 (match_operand:MODEF 3 "register_operand" "x")))]
16517 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16518 [(set_attr "type" "sse4arg")])
16520 ;; These versions of the min/max patterns are intentionally ignorant of
16521 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16522 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16523 ;; are undefined in this condition, we're certain this is correct.
16525 (define_insn "<code><mode>3"
16526 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16528 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16529 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16530 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16532 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16533 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16534 [(set_attr "isa" "noavx,avx")
16535 (set_attr "prefix" "orig,vex")
16536 (set_attr "type" "sseadd")
16537 (set_attr "mode" "<MODE>")])
16539 ;; These versions of the min/max patterns implement exactly the operations
16540 ;; min = (op1 < op2 ? op1 : op2)
16541 ;; max = (!(op1 < op2) ? op1 : op2)
16542 ;; Their operands are not commutative, and thus they may be used in the
16543 ;; presence of -0.0 and NaN.
16545 (define_int_iterator IEEE_MAXMIN
16549 (define_int_attr ieee_maxmin
16550 [(UNSPEC_IEEE_MAX "max")
16551 (UNSPEC_IEEE_MIN "min")])
16553 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16554 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16556 [(match_operand:MODEF 1 "register_operand" "0,x")
16557 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16559 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16561 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16562 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16563 [(set_attr "isa" "noavx,avx")
16564 (set_attr "prefix" "orig,vex")
16565 (set_attr "type" "sseadd")
16566 (set_attr "mode" "<MODE>")])
16568 ;; Make two stack loads independent:
16570 ;; fld %st(0) -> fld bb
16571 ;; fmul bb fmul %st(1), %st
16573 ;; Actually we only match the last two instructions for simplicity.
16575 [(set (match_operand 0 "fp_register_operand")
16576 (match_operand 1 "fp_register_operand"))
16578 (match_operator 2 "binary_fp_operator"
16580 (match_operand 3 "memory_operand")]))]
16581 "REGNO (operands[0]) != REGNO (operands[1])"
16582 [(set (match_dup 0) (match_dup 3))
16583 (set (match_dup 0) (match_dup 4))]
16585 ;; The % modifier is not operational anymore in peephole2's, so we have to
16586 ;; swap the operands manually in the case of addition and multiplication.
16590 if (COMMUTATIVE_ARITH_P (operands[2]))
16591 op0 = operands[0], op1 = operands[1];
16593 op0 = operands[1], op1 = operands[0];
16595 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16596 GET_MODE (operands[2]),
16600 ;; Conditional addition patterns
16601 (define_expand "add<mode>cc"
16602 [(match_operand:SWI 0 "register_operand")
16603 (match_operand 1 "ordered_comparison_operator")
16604 (match_operand:SWI 2 "register_operand")
16605 (match_operand:SWI 3 "const_int_operand")]
16607 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16609 ;; Misc patterns (?)
16611 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16612 ;; Otherwise there will be nothing to keep
16614 ;; [(set (reg ebp) (reg esp))]
16615 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16616 ;; (clobber (eflags)]
16617 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16619 ;; in proper program order.
16621 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16622 [(set (match_operand:P 0 "register_operand" "=r,r")
16623 (plus:P (match_operand:P 1 "register_operand" "0,r")
16624 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16625 (clobber (reg:CC FLAGS_REG))
16626 (clobber (mem:BLK (scratch)))]
16629 switch (get_attr_type (insn))
16632 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16635 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16636 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16637 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16639 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16642 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16643 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16646 [(set (attr "type")
16647 (cond [(and (eq_attr "alternative" "0")
16648 (not (match_test "TARGET_OPT_AGU")))
16649 (const_string "alu")
16650 (match_operand:<MODE> 2 "const0_operand")
16651 (const_string "imov")
16653 (const_string "lea")))
16654 (set (attr "length_immediate")
16655 (cond [(eq_attr "type" "imov")
16657 (and (eq_attr "type" "alu")
16658 (match_operand 2 "const128_operand"))
16661 (const_string "*")))
16662 (set_attr "mode" "<MODE>")])
16664 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16665 [(set (match_operand:P 0 "register_operand" "=r")
16666 (minus:P (match_operand:P 1 "register_operand" "0")
16667 (match_operand:P 2 "register_operand" "r")))
16668 (clobber (reg:CC FLAGS_REG))
16669 (clobber (mem:BLK (scratch)))]
16671 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16672 [(set_attr "type" "alu")
16673 (set_attr "mode" "<MODE>")])
16675 (define_insn "allocate_stack_worker_probe_<mode>"
16676 [(set (match_operand:P 0 "register_operand" "=a")
16677 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16678 UNSPECV_STACK_PROBE))
16679 (clobber (reg:CC FLAGS_REG))]
16680 "ix86_target_stack_probe ()"
16681 "call\t___chkstk_ms"
16682 [(set_attr "type" "multi")
16683 (set_attr "length" "5")])
16685 (define_expand "allocate_stack"
16686 [(match_operand 0 "register_operand")
16687 (match_operand 1 "general_operand")]
16688 "ix86_target_stack_probe ()"
16692 #ifndef CHECK_STACK_LIMIT
16693 #define CHECK_STACK_LIMIT 0
16696 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16697 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16701 rtx (*insn) (rtx, rtx);
16703 x = copy_to_mode_reg (Pmode, operands[1]);
16705 insn = (TARGET_64BIT
16706 ? gen_allocate_stack_worker_probe_di
16707 : gen_allocate_stack_worker_probe_si);
16709 emit_insn (insn (x, x));
16712 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16713 stack_pointer_rtx, 0, OPTAB_DIRECT);
16715 if (x != stack_pointer_rtx)
16716 emit_move_insn (stack_pointer_rtx, x);
16718 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16722 ;; Use IOR for stack probes, this is shorter.
16723 (define_expand "probe_stack"
16724 [(match_operand 0 "memory_operand")]
16727 rtx (*gen_ior3) (rtx, rtx, rtx);
16729 gen_ior3 = (GET_MODE (operands[0]) == DImode
16730 ? gen_iordi3 : gen_iorsi3);
16732 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16736 (define_insn "adjust_stack_and_probe<mode>"
16737 [(set (match_operand:P 0 "register_operand" "=r")
16738 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16739 UNSPECV_PROBE_STACK_RANGE))
16740 (set (reg:P SP_REG)
16741 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16742 (clobber (reg:CC FLAGS_REG))
16743 (clobber (mem:BLK (scratch)))]
16745 "* return output_adjust_stack_and_probe (operands[0]);"
16746 [(set_attr "type" "multi")])
16748 (define_insn "probe_stack_range<mode>"
16749 [(set (match_operand:P 0 "register_operand" "=r")
16750 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16751 (match_operand:P 2 "const_int_operand" "n")]
16752 UNSPECV_PROBE_STACK_RANGE))
16753 (clobber (reg:CC FLAGS_REG))]
16755 "* return output_probe_stack_range (operands[0], operands[2]);"
16756 [(set_attr "type" "multi")])
16758 (define_expand "builtin_setjmp_receiver"
16759 [(label_ref (match_operand 0))]
16760 "!TARGET_64BIT && flag_pic"
16766 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16767 rtx label_rtx = gen_label_rtx ();
16768 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16769 xops[0] = xops[1] = picreg;
16770 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16771 ix86_expand_binary_operator (MINUS, SImode, xops);
16775 emit_insn (gen_set_got (pic_offset_table_rtx));
16779 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16782 [(set (match_operand 0 "register_operand")
16783 (match_operator 3 "promotable_binary_operator"
16784 [(match_operand 1 "register_operand")
16785 (match_operand 2 "aligned_operand")]))
16786 (clobber (reg:CC FLAGS_REG))]
16787 "! TARGET_PARTIAL_REG_STALL && reload_completed
16788 && ((GET_MODE (operands[0]) == HImode
16789 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16790 /* ??? next two lines just !satisfies_constraint_K (...) */
16791 || !CONST_INT_P (operands[2])
16792 || satisfies_constraint_K (operands[2])))
16793 || (GET_MODE (operands[0]) == QImode
16794 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16795 [(parallel [(set (match_dup 0)
16796 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16797 (clobber (reg:CC FLAGS_REG))])]
16799 operands[0] = gen_lowpart (SImode, operands[0]);
16800 operands[1] = gen_lowpart (SImode, operands[1]);
16801 if (GET_CODE (operands[3]) != ASHIFT)
16802 operands[2] = gen_lowpart (SImode, operands[2]);
16803 PUT_MODE (operands[3], SImode);
16806 ; Promote the QImode tests, as i386 has encoding of the AND
16807 ; instruction with 32-bit sign-extended immediate and thus the
16808 ; instruction size is unchanged, except in the %eax case for
16809 ; which it is increased by one byte, hence the ! optimize_size.
16811 [(set (match_operand 0 "flags_reg_operand")
16812 (match_operator 2 "compare_operator"
16813 [(and (match_operand 3 "aligned_operand")
16814 (match_operand 4 "const_int_operand"))
16816 (set (match_operand 1 "register_operand")
16817 (and (match_dup 3) (match_dup 4)))]
16818 "! TARGET_PARTIAL_REG_STALL && reload_completed
16819 && optimize_insn_for_speed_p ()
16820 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16821 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16822 /* Ensure that the operand will remain sign-extended immediate. */
16823 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16824 [(parallel [(set (match_dup 0)
16825 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16828 (and:SI (match_dup 3) (match_dup 4)))])]
16831 = gen_int_mode (INTVAL (operands[4])
16832 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16833 operands[1] = gen_lowpart (SImode, operands[1]);
16834 operands[3] = gen_lowpart (SImode, operands[3]);
16837 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16838 ; the TEST instruction with 32-bit sign-extended immediate and thus
16839 ; the instruction size would at least double, which is not what we
16840 ; want even with ! optimize_size.
16842 [(set (match_operand 0 "flags_reg_operand")
16843 (match_operator 1 "compare_operator"
16844 [(and (match_operand:HI 2 "aligned_operand")
16845 (match_operand:HI 3 "const_int_operand"))
16847 "! TARGET_PARTIAL_REG_STALL && reload_completed
16848 && ! TARGET_FAST_PREFIX
16849 && optimize_insn_for_speed_p ()
16850 /* Ensure that the operand will remain sign-extended immediate. */
16851 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16852 [(set (match_dup 0)
16853 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16857 = gen_int_mode (INTVAL (operands[3])
16858 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16859 operands[2] = gen_lowpart (SImode, operands[2]);
16863 [(set (match_operand 0 "register_operand")
16864 (neg (match_operand 1 "register_operand")))
16865 (clobber (reg:CC FLAGS_REG))]
16866 "! TARGET_PARTIAL_REG_STALL && reload_completed
16867 && (GET_MODE (operands[0]) == HImode
16868 || (GET_MODE (operands[0]) == QImode
16869 && (TARGET_PROMOTE_QImode
16870 || optimize_insn_for_size_p ())))"
16871 [(parallel [(set (match_dup 0)
16872 (neg:SI (match_dup 1)))
16873 (clobber (reg:CC FLAGS_REG))])]
16875 operands[0] = gen_lowpart (SImode, operands[0]);
16876 operands[1] = gen_lowpart (SImode, operands[1]);
16880 [(set (match_operand 0 "register_operand")
16881 (not (match_operand 1 "register_operand")))]
16882 "! TARGET_PARTIAL_REG_STALL && reload_completed
16883 && (GET_MODE (operands[0]) == HImode
16884 || (GET_MODE (operands[0]) == QImode
16885 && (TARGET_PROMOTE_QImode
16886 || optimize_insn_for_size_p ())))"
16887 [(set (match_dup 0)
16888 (not:SI (match_dup 1)))]
16890 operands[0] = gen_lowpart (SImode, operands[0]);
16891 operands[1] = gen_lowpart (SImode, operands[1]);
16894 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16895 ;; transform a complex memory operation into two memory to register operations.
16897 ;; Don't push memory operands
16899 [(set (match_operand:SWI 0 "push_operand")
16900 (match_operand:SWI 1 "memory_operand"))
16901 (match_scratch:SWI 2 "<r>")]
16902 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16903 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16904 [(set (match_dup 2) (match_dup 1))
16905 (set (match_dup 0) (match_dup 2))])
16907 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16910 [(set (match_operand:SF 0 "push_operand")
16911 (match_operand:SF 1 "memory_operand"))
16912 (match_scratch:SF 2 "r")]
16913 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16914 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16915 [(set (match_dup 2) (match_dup 1))
16916 (set (match_dup 0) (match_dup 2))])
16918 ;; Don't move an immediate directly to memory when the instruction
16919 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16921 [(match_scratch:SWI124 1 "<r>")
16922 (set (match_operand:SWI124 0 "memory_operand")
16924 "optimize_insn_for_speed_p ()
16925 && ((<MODE>mode == HImode
16926 && TARGET_LCP_STALL)
16927 || (!TARGET_USE_MOV0
16928 && TARGET_SPLIT_LONG_MOVES
16929 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16930 && peep2_regno_dead_p (0, FLAGS_REG)"
16931 [(parallel [(set (match_dup 2) (const_int 0))
16932 (clobber (reg:CC FLAGS_REG))])
16933 (set (match_dup 0) (match_dup 1))]
16934 "operands[2] = gen_lowpart (SImode, operands[1]);")
16937 [(match_scratch:SWI124 2 "<r>")
16938 (set (match_operand:SWI124 0 "memory_operand")
16939 (match_operand:SWI124 1 "immediate_operand"))]
16940 "optimize_insn_for_speed_p ()
16941 && ((<MODE>mode == HImode
16942 && TARGET_LCP_STALL)
16943 || (TARGET_SPLIT_LONG_MOVES
16944 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16945 [(set (match_dup 2) (match_dup 1))
16946 (set (match_dup 0) (match_dup 2))])
16948 ;; Don't compare memory with zero, load and use a test instead.
16950 [(set (match_operand 0 "flags_reg_operand")
16951 (match_operator 1 "compare_operator"
16952 [(match_operand:SI 2 "memory_operand")
16954 (match_scratch:SI 3 "r")]
16955 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16956 [(set (match_dup 3) (match_dup 2))
16957 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16959 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16960 ;; Don't split NOTs with a displacement operand, because resulting XOR
16961 ;; will not be pairable anyway.
16963 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16964 ;; represented using a modRM byte. The XOR replacement is long decoded,
16965 ;; so this split helps here as well.
16967 ;; Note: Can't do this as a regular split because we can't get proper
16968 ;; lifetime information then.
16971 [(set (match_operand:SWI124 0 "nonimmediate_operand")
16972 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16973 "optimize_insn_for_speed_p ()
16974 && ((TARGET_NOT_UNPAIRABLE
16975 && (!MEM_P (operands[0])
16976 || !memory_displacement_operand (operands[0], <MODE>mode)))
16977 || (TARGET_NOT_VECTORMODE
16978 && long_memory_operand (operands[0], <MODE>mode)))
16979 && peep2_regno_dead_p (0, FLAGS_REG)"
16980 [(parallel [(set (match_dup 0)
16981 (xor:SWI124 (match_dup 1) (const_int -1)))
16982 (clobber (reg:CC FLAGS_REG))])])
16984 ;; Non pairable "test imm, reg" instructions can be translated to
16985 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16986 ;; byte opcode instead of two, have a short form for byte operands),
16987 ;; so do it for other CPUs as well. Given that the value was dead,
16988 ;; this should not create any new dependencies. Pass on the sub-word
16989 ;; versions if we're concerned about partial register stalls.
16992 [(set (match_operand 0 "flags_reg_operand")
16993 (match_operator 1 "compare_operator"
16994 [(and:SI (match_operand:SI 2 "register_operand")
16995 (match_operand:SI 3 "immediate_operand"))
16997 "ix86_match_ccmode (insn, CCNOmode)
16998 && (true_regnum (operands[2]) != AX_REG
16999 || satisfies_constraint_K (operands[3]))
17000 && peep2_reg_dead_p (1, operands[2])"
17002 [(set (match_dup 0)
17003 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17006 (and:SI (match_dup 2) (match_dup 3)))])])
17008 ;; We don't need to handle HImode case, because it will be promoted to SImode
17009 ;; on ! TARGET_PARTIAL_REG_STALL
17012 [(set (match_operand 0 "flags_reg_operand")
17013 (match_operator 1 "compare_operator"
17014 [(and:QI (match_operand:QI 2 "register_operand")
17015 (match_operand:QI 3 "immediate_operand"))
17017 "! TARGET_PARTIAL_REG_STALL
17018 && ix86_match_ccmode (insn, CCNOmode)
17019 && true_regnum (operands[2]) != AX_REG
17020 && peep2_reg_dead_p (1, operands[2])"
17022 [(set (match_dup 0)
17023 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17026 (and:QI (match_dup 2) (match_dup 3)))])])
17029 [(set (match_operand 0 "flags_reg_operand")
17030 (match_operator 1 "compare_operator"
17033 (match_operand 2 "ext_register_operand")
17036 (match_operand 3 "const_int_operand"))
17038 "! TARGET_PARTIAL_REG_STALL
17039 && ix86_match_ccmode (insn, CCNOmode)
17040 && true_regnum (operands[2]) != AX_REG
17041 && peep2_reg_dead_p (1, operands[2])"
17042 [(parallel [(set (match_dup 0)
17051 (set (zero_extract:SI (match_dup 2)
17059 (match_dup 3)))])])
17061 ;; Don't do logical operations with memory inputs.
17063 [(match_scratch:SI 2 "r")
17064 (parallel [(set (match_operand:SI 0 "register_operand")
17065 (match_operator:SI 3 "arith_or_logical_operator"
17067 (match_operand:SI 1 "memory_operand")]))
17068 (clobber (reg:CC FLAGS_REG))])]
17069 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17070 [(set (match_dup 2) (match_dup 1))
17071 (parallel [(set (match_dup 0)
17072 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17073 (clobber (reg:CC FLAGS_REG))])])
17076 [(match_scratch:SI 2 "r")
17077 (parallel [(set (match_operand:SI 0 "register_operand")
17078 (match_operator:SI 3 "arith_or_logical_operator"
17079 [(match_operand:SI 1 "memory_operand")
17081 (clobber (reg:CC FLAGS_REG))])]
17082 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17083 [(set (match_dup 2) (match_dup 1))
17084 (parallel [(set (match_dup 0)
17085 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17086 (clobber (reg:CC FLAGS_REG))])])
17088 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17089 ;; refers to the destination of the load!
17092 [(set (match_operand:SI 0 "register_operand")
17093 (match_operand:SI 1 "register_operand"))
17094 (parallel [(set (match_dup 0)
17095 (match_operator:SI 3 "commutative_operator"
17097 (match_operand:SI 2 "memory_operand")]))
17098 (clobber (reg:CC FLAGS_REG))])]
17099 "REGNO (operands[0]) != REGNO (operands[1])
17100 && GENERAL_REGNO_P (REGNO (operands[0]))
17101 && GENERAL_REGNO_P (REGNO (operands[1]))"
17102 [(set (match_dup 0) (match_dup 4))
17103 (parallel [(set (match_dup 0)
17104 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17105 (clobber (reg:CC FLAGS_REG))])]
17106 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17109 [(set (match_operand 0 "register_operand")
17110 (match_operand 1 "register_operand"))
17112 (match_operator 3 "commutative_operator"
17114 (match_operand 2 "memory_operand")]))]
17115 "REGNO (operands[0]) != REGNO (operands[1])
17116 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17117 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17118 [(set (match_dup 0) (match_dup 2))
17120 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17122 ; Don't do logical operations with memory outputs
17124 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17125 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17126 ; the same decoder scheduling characteristics as the original.
17129 [(match_scratch:SI 2 "r")
17130 (parallel [(set (match_operand:SI 0 "memory_operand")
17131 (match_operator:SI 3 "arith_or_logical_operator"
17133 (match_operand:SI 1 "nonmemory_operand")]))
17134 (clobber (reg:CC FLAGS_REG))])]
17135 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17136 /* Do not split stack checking probes. */
17137 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17138 [(set (match_dup 2) (match_dup 0))
17139 (parallel [(set (match_dup 2)
17140 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17141 (clobber (reg:CC FLAGS_REG))])
17142 (set (match_dup 0) (match_dup 2))])
17145 [(match_scratch:SI 2 "r")
17146 (parallel [(set (match_operand:SI 0 "memory_operand")
17147 (match_operator:SI 3 "arith_or_logical_operator"
17148 [(match_operand:SI 1 "nonmemory_operand")
17150 (clobber (reg:CC FLAGS_REG))])]
17151 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17152 /* Do not split stack checking probes. */
17153 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17154 [(set (match_dup 2) (match_dup 0))
17155 (parallel [(set (match_dup 2)
17156 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17157 (clobber (reg:CC FLAGS_REG))])
17158 (set (match_dup 0) (match_dup 2))])
17160 ;; Attempt to use arith or logical operations with memory outputs with
17161 ;; setting of flags.
17163 [(set (match_operand:SWI 0 "register_operand")
17164 (match_operand:SWI 1 "memory_operand"))
17165 (parallel [(set (match_dup 0)
17166 (match_operator:SWI 3 "plusminuslogic_operator"
17168 (match_operand:SWI 2 "<nonmemory_operand>")]))
17169 (clobber (reg:CC FLAGS_REG))])
17170 (set (match_dup 1) (match_dup 0))
17171 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17172 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17173 && peep2_reg_dead_p (4, operands[0])
17174 && !reg_overlap_mentioned_p (operands[0], operands[1])
17175 && (<MODE>mode != QImode
17176 || immediate_operand (operands[2], QImode)
17177 || q_regs_operand (operands[2], QImode))
17178 && ix86_match_ccmode (peep2_next_insn (3),
17179 (GET_CODE (operands[3]) == PLUS
17180 || GET_CODE (operands[3]) == MINUS)
17181 ? CCGOCmode : CCNOmode)"
17182 [(parallel [(set (match_dup 4) (match_dup 5))
17183 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17184 (match_dup 2)]))])]
17186 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17187 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17188 copy_rtx (operands[1]),
17189 copy_rtx (operands[2]));
17190 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17191 operands[5], const0_rtx);
17195 [(parallel [(set (match_operand:SWI 0 "register_operand")
17196 (match_operator:SWI 2 "plusminuslogic_operator"
17198 (match_operand:SWI 1 "memory_operand")]))
17199 (clobber (reg:CC FLAGS_REG))])
17200 (set (match_dup 1) (match_dup 0))
17201 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17202 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17203 && GET_CODE (operands[2]) != MINUS
17204 && peep2_reg_dead_p (3, operands[0])
17205 && !reg_overlap_mentioned_p (operands[0], operands[1])
17206 && ix86_match_ccmode (peep2_next_insn (2),
17207 GET_CODE (operands[2]) == PLUS
17208 ? CCGOCmode : CCNOmode)"
17209 [(parallel [(set (match_dup 3) (match_dup 4))
17210 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17211 (match_dup 0)]))])]
17213 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17214 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17215 copy_rtx (operands[1]),
17216 copy_rtx (operands[0]));
17217 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17218 operands[4], const0_rtx);
17222 [(set (match_operand:SWI12 0 "register_operand")
17223 (match_operand:SWI12 1 "memory_operand"))
17224 (parallel [(set (match_operand:SI 4 "register_operand")
17225 (match_operator:SI 3 "plusminuslogic_operator"
17227 (match_operand:SI 2 "nonmemory_operand")]))
17228 (clobber (reg:CC FLAGS_REG))])
17229 (set (match_dup 1) (match_dup 0))
17230 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17231 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17232 && REG_P (operands[0]) && REG_P (operands[4])
17233 && REGNO (operands[0]) == REGNO (operands[4])
17234 && peep2_reg_dead_p (4, operands[0])
17235 && (<MODE>mode != QImode
17236 || immediate_operand (operands[2], SImode)
17237 || q_regs_operand (operands[2], SImode))
17238 && !reg_overlap_mentioned_p (operands[0], operands[1])
17239 && ix86_match_ccmode (peep2_next_insn (3),
17240 (GET_CODE (operands[3]) == PLUS
17241 || GET_CODE (operands[3]) == MINUS)
17242 ? CCGOCmode : CCNOmode)"
17243 [(parallel [(set (match_dup 4) (match_dup 5))
17244 (set (match_dup 1) (match_dup 6))])]
17246 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17247 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17248 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17249 copy_rtx (operands[1]), operands[2]);
17250 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17251 operands[5], const0_rtx);
17252 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17253 copy_rtx (operands[1]),
17254 copy_rtx (operands[2]));
17257 ;; Attempt to always use XOR for zeroing registers.
17259 [(set (match_operand 0 "register_operand")
17260 (match_operand 1 "const0_operand"))]
17261 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17262 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17263 && GENERAL_REG_P (operands[0])
17264 && peep2_regno_dead_p (0, FLAGS_REG)"
17265 [(parallel [(set (match_dup 0) (const_int 0))
17266 (clobber (reg:CC FLAGS_REG))])]
17267 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17270 [(set (strict_low_part (match_operand 0 "register_operand"))
17272 "(GET_MODE (operands[0]) == QImode
17273 || GET_MODE (operands[0]) == HImode)
17274 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17275 && peep2_regno_dead_p (0, FLAGS_REG)"
17276 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17277 (clobber (reg:CC FLAGS_REG))])])
17279 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17281 [(set (match_operand:SWI248 0 "register_operand")
17283 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17284 && peep2_regno_dead_p (0, FLAGS_REG)"
17285 [(parallel [(set (match_dup 0) (const_int -1))
17286 (clobber (reg:CC FLAGS_REG))])]
17288 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17289 operands[0] = gen_lowpart (SImode, operands[0]);
17292 ;; Attempt to convert simple lea to add/shift.
17293 ;; These can be created by move expanders.
17296 [(set (match_operand:SWI48 0 "register_operand")
17297 (plus:SWI48 (match_dup 0)
17298 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17299 "peep2_regno_dead_p (0, FLAGS_REG)"
17300 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17301 (clobber (reg:CC FLAGS_REG))])])
17304 [(set (match_operand:SWI48 0 "register_operand")
17305 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17307 "peep2_regno_dead_p (0, FLAGS_REG)"
17308 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17309 (clobber (reg:CC FLAGS_REG))])])
17312 [(set (match_operand:SI 0 "register_operand")
17313 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand")
17314 (match_operand:DI 2 "nonmemory_operand")) 0))]
17316 && peep2_regno_dead_p (0, FLAGS_REG)
17317 && REGNO (operands[0]) == REGNO (operands[1])"
17318 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17319 (clobber (reg:CC FLAGS_REG))])]
17320 "operands[2] = gen_lowpart (SImode, operands[2]);")
17323 [(set (match_operand:SI 0 "register_operand")
17324 (subreg:SI (plus:DI (match_operand:DI 1 "nonmemory_operand")
17325 (match_operand:DI 2 "register_operand")) 0))]
17327 && peep2_regno_dead_p (0, FLAGS_REG)
17328 && REGNO (operands[0]) == REGNO (operands[2])"
17329 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17330 (clobber (reg:CC FLAGS_REG))])]
17331 "operands[1] = gen_lowpart (SImode, operands[1]);")
17334 [(set (match_operand:SWI48 0 "register_operand")
17335 (mult:SWI48 (match_dup 0)
17336 (match_operand:SWI48 1 "const_int_operand")))]
17337 "exact_log2 (INTVAL (operands[1])) >= 0
17338 && peep2_regno_dead_p (0, FLAGS_REG)"
17339 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17340 (clobber (reg:CC FLAGS_REG))])]
17341 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17344 [(set (match_operand:SI 0 "register_operand")
17345 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand")
17346 (match_operand:DI 2 "const_int_operand")) 0))]
17348 && exact_log2 (INTVAL (operands[2])) >= 0
17349 && REGNO (operands[0]) == REGNO (operands[1])
17350 && peep2_regno_dead_p (0, FLAGS_REG)"
17351 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17352 (clobber (reg:CC FLAGS_REG))])]
17353 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17355 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17356 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17357 ;; On many CPUs it is also faster, since special hardware to avoid esp
17358 ;; dependencies is present.
17360 ;; While some of these conversions may be done using splitters, we use
17361 ;; peepholes in order to allow combine_stack_adjustments pass to see
17362 ;; nonobfuscated RTL.
17364 ;; Convert prologue esp subtractions to push.
17365 ;; We need register to push. In order to keep verify_flow_info happy we have
17367 ;; - use scratch and clobber it in order to avoid dependencies
17368 ;; - use already live register
17369 ;; We can't use the second way right now, since there is no reliable way how to
17370 ;; verify that given register is live. First choice will also most likely in
17371 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17372 ;; call clobbered registers are dead. We may want to use base pointer as an
17373 ;; alternative when no register is available later.
17376 [(match_scratch:W 1 "r")
17377 (parallel [(set (reg:P SP_REG)
17378 (plus:P (reg:P SP_REG)
17379 (match_operand:P 0 "const_int_operand")))
17380 (clobber (reg:CC FLAGS_REG))
17381 (clobber (mem:BLK (scratch)))])]
17382 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17383 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17384 [(clobber (match_dup 1))
17385 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17386 (clobber (mem:BLK (scratch)))])])
17389 [(match_scratch:W 1 "r")
17390 (parallel [(set (reg:P SP_REG)
17391 (plus:P (reg:P SP_REG)
17392 (match_operand:P 0 "const_int_operand")))
17393 (clobber (reg:CC FLAGS_REG))
17394 (clobber (mem:BLK (scratch)))])]
17395 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17396 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17397 [(clobber (match_dup 1))
17398 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17399 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17400 (clobber (mem:BLK (scratch)))])])
17402 ;; Convert esp subtractions to push.
17404 [(match_scratch:W 1 "r")
17405 (parallel [(set (reg:P SP_REG)
17406 (plus:P (reg:P SP_REG)
17407 (match_operand:P 0 "const_int_operand")))
17408 (clobber (reg:CC FLAGS_REG))])]
17409 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17410 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17411 [(clobber (match_dup 1))
17412 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17415 [(match_scratch:W 1 "r")
17416 (parallel [(set (reg:P SP_REG)
17417 (plus:P (reg:P SP_REG)
17418 (match_operand:P 0 "const_int_operand")))
17419 (clobber (reg:CC FLAGS_REG))])]
17420 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17421 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17422 [(clobber (match_dup 1))
17423 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17424 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17426 ;; Convert epilogue deallocator to pop.
17428 [(match_scratch:W 1 "r")
17429 (parallel [(set (reg:P SP_REG)
17430 (plus:P (reg:P SP_REG)
17431 (match_operand:P 0 "const_int_operand")))
17432 (clobber (reg:CC FLAGS_REG))
17433 (clobber (mem:BLK (scratch)))])]
17434 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17435 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17436 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17437 (clobber (mem:BLK (scratch)))])])
17439 ;; Two pops case is tricky, since pop causes dependency
17440 ;; on destination register. We use two registers if available.
17442 [(match_scratch:W 1 "r")
17443 (match_scratch:W 2 "r")
17444 (parallel [(set (reg:P SP_REG)
17445 (plus:P (reg:P SP_REG)
17446 (match_operand:P 0 "const_int_operand")))
17447 (clobber (reg:CC FLAGS_REG))
17448 (clobber (mem:BLK (scratch)))])]
17449 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17450 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17451 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17452 (clobber (mem:BLK (scratch)))])
17453 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17456 [(match_scratch:W 1 "r")
17457 (parallel [(set (reg:P SP_REG)
17458 (plus:P (reg:P SP_REG)
17459 (match_operand:P 0 "const_int_operand")))
17460 (clobber (reg:CC FLAGS_REG))
17461 (clobber (mem:BLK (scratch)))])]
17462 "optimize_insn_for_size_p ()
17463 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17464 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17465 (clobber (mem:BLK (scratch)))])
17466 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17468 ;; Convert esp additions to pop.
17470 [(match_scratch:W 1 "r")
17471 (parallel [(set (reg:P SP_REG)
17472 (plus:P (reg:P SP_REG)
17473 (match_operand:P 0 "const_int_operand")))
17474 (clobber (reg:CC FLAGS_REG))])]
17475 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17476 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17478 ;; Two pops case is tricky, since pop causes dependency
17479 ;; on destination register. We use two registers if available.
17481 [(match_scratch:W 1 "r")
17482 (match_scratch:W 2 "r")
17483 (parallel [(set (reg:P SP_REG)
17484 (plus:P (reg:P SP_REG)
17485 (match_operand:P 0 "const_int_operand")))
17486 (clobber (reg:CC FLAGS_REG))])]
17487 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17488 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17489 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17492 [(match_scratch:W 1 "r")
17493 (parallel [(set (reg:P SP_REG)
17494 (plus:P (reg:P SP_REG)
17495 (match_operand:P 0 "const_int_operand")))
17496 (clobber (reg:CC FLAGS_REG))])]
17497 "optimize_insn_for_size_p ()
17498 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17499 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17500 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17502 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17503 ;; required and register dies. Similarly for 128 to -128.
17505 [(set (match_operand 0 "flags_reg_operand")
17506 (match_operator 1 "compare_operator"
17507 [(match_operand 2 "register_operand")
17508 (match_operand 3 "const_int_operand")]))]
17509 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17510 && incdec_operand (operands[3], GET_MODE (operands[3])))
17511 || (!TARGET_FUSE_CMP_AND_BRANCH
17512 && INTVAL (operands[3]) == 128))
17513 && ix86_match_ccmode (insn, CCGCmode)
17514 && peep2_reg_dead_p (1, operands[2])"
17515 [(parallel [(set (match_dup 0)
17516 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17517 (clobber (match_dup 2))])])
17519 ;; Convert imul by three, five and nine into lea
17522 [(set (match_operand:SWI48 0 "register_operand")
17523 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17524 (match_operand:SWI48 2 "const359_operand")))
17525 (clobber (reg:CC FLAGS_REG))])]
17526 "!TARGET_PARTIAL_REG_STALL
17527 || <MODE>mode == SImode
17528 || optimize_function_for_size_p (cfun)"
17529 [(set (match_dup 0)
17530 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17532 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17536 [(set (match_operand:SWI48 0 "register_operand")
17537 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17538 (match_operand:SWI48 2 "const359_operand")))
17539 (clobber (reg:CC FLAGS_REG))])]
17540 "optimize_insn_for_speed_p ()
17541 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17542 [(set (match_dup 0) (match_dup 1))
17544 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17546 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17548 ;; imul $32bit_imm, mem, reg is vector decoded, while
17549 ;; imul $32bit_imm, reg, reg is direct decoded.
17551 [(match_scratch:SWI48 3 "r")
17552 (parallel [(set (match_operand:SWI48 0 "register_operand")
17553 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17554 (match_operand:SWI48 2 "immediate_operand")))
17555 (clobber (reg:CC FLAGS_REG))])]
17556 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17557 && !satisfies_constraint_K (operands[2])"
17558 [(set (match_dup 3) (match_dup 1))
17559 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17560 (clobber (reg:CC FLAGS_REG))])])
17563 [(match_scratch:SI 3 "r")
17564 (parallel [(set (match_operand:DI 0 "register_operand")
17566 (mult:SI (match_operand:SI 1 "memory_operand")
17567 (match_operand:SI 2 "immediate_operand"))))
17568 (clobber (reg:CC FLAGS_REG))])]
17570 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17571 && !satisfies_constraint_K (operands[2])"
17572 [(set (match_dup 3) (match_dup 1))
17573 (parallel [(set (match_dup 0)
17574 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17575 (clobber (reg:CC FLAGS_REG))])])
17577 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17578 ;; Convert it into imul reg, reg
17579 ;; It would be better to force assembler to encode instruction using long
17580 ;; immediate, but there is apparently no way to do so.
17582 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17584 (match_operand:SWI248 1 "nonimmediate_operand")
17585 (match_operand:SWI248 2 "const_int_operand")))
17586 (clobber (reg:CC FLAGS_REG))])
17587 (match_scratch:SWI248 3 "r")]
17588 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17589 && satisfies_constraint_K (operands[2])"
17590 [(set (match_dup 3) (match_dup 2))
17591 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17592 (clobber (reg:CC FLAGS_REG))])]
17594 if (!rtx_equal_p (operands[0], operands[1]))
17595 emit_move_insn (operands[0], operands[1]);
17598 ;; After splitting up read-modify operations, array accesses with memory
17599 ;; operands might end up in form:
17601 ;; movl 4(%esp), %edx
17603 ;; instead of pre-splitting:
17605 ;; addl 4(%esp), %eax
17607 ;; movl 4(%esp), %edx
17608 ;; leal (%edx,%eax,4), %eax
17611 [(match_scratch:W 5 "r")
17612 (parallel [(set (match_operand 0 "register_operand")
17613 (ashift (match_operand 1 "register_operand")
17614 (match_operand 2 "const_int_operand")))
17615 (clobber (reg:CC FLAGS_REG))])
17616 (parallel [(set (match_operand 3 "register_operand")
17617 (plus (match_dup 0)
17618 (match_operand 4 "x86_64_general_operand")))
17619 (clobber (reg:CC FLAGS_REG))])]
17620 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17621 /* Validate MODE for lea. */
17622 && ((!TARGET_PARTIAL_REG_STALL
17623 && (GET_MODE (operands[0]) == QImode
17624 || GET_MODE (operands[0]) == HImode))
17625 || GET_MODE (operands[0]) == SImode
17626 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17627 && (rtx_equal_p (operands[0], operands[3])
17628 || peep2_reg_dead_p (2, operands[0]))
17629 /* We reorder load and the shift. */
17630 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17631 [(set (match_dup 5) (match_dup 4))
17632 (set (match_dup 0) (match_dup 1))]
17634 enum machine_mode op1mode = GET_MODE (operands[1]);
17635 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17636 int scale = 1 << INTVAL (operands[2]);
17637 rtx index = gen_lowpart (word_mode, operands[1]);
17638 rtx base = gen_lowpart (word_mode, operands[5]);
17639 rtx dest = gen_lowpart (mode, operands[3]);
17641 operands[1] = gen_rtx_PLUS (word_mode, base,
17642 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17643 operands[5] = base;
17644 if (mode != word_mode)
17645 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17646 if (op1mode != word_mode)
17647 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17648 operands[0] = dest;
17651 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17652 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17653 ;; caught for use by garbage collectors and the like. Using an insn that
17654 ;; maps to SIGILL makes it more likely the program will rightfully die.
17655 ;; Keeping with tradition, "6" is in honor of #UD.
17656 (define_insn "trap"
17657 [(trap_if (const_int 1) (const_int 6))]
17659 { return ASM_SHORT "0x0b0f"; }
17660 [(set_attr "length" "2")])
17662 (define_expand "prefetch"
17663 [(prefetch (match_operand 0 "address_operand")
17664 (match_operand:SI 1 "const_int_operand")
17665 (match_operand:SI 2 "const_int_operand"))]
17666 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17668 int rw = INTVAL (operands[1]);
17669 int locality = INTVAL (operands[2]);
17671 gcc_assert (rw == 0 || rw == 1);
17672 gcc_assert (locality >= 0 && locality <= 3);
17673 gcc_assert (GET_MODE (operands[0]) == Pmode
17674 || GET_MODE (operands[0]) == VOIDmode);
17675 if (TARGET_PRFCHW && rw)
17676 operands[2] = GEN_INT (3);
17678 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17679 supported by SSE counterpart or the SSE prefetch is not available
17680 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17682 else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17683 operands[2] = GEN_INT (3);
17685 operands[1] = const0_rtx;
17688 (define_insn "*prefetch_sse_<mode>"
17689 [(prefetch (match_operand:P 0 "address_operand" "p")
17691 (match_operand:SI 1 "const_int_operand"))]
17692 "TARGET_PREFETCH_SSE"
17694 static const char * const patterns[4] = {
17695 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17698 int locality = INTVAL (operands[1]);
17699 gcc_assert (locality >= 0 && locality <= 3);
17701 return patterns[locality];
17703 [(set_attr "type" "sse")
17704 (set_attr "atom_sse_attr" "prefetch")
17705 (set (attr "length_address")
17706 (symbol_ref "memory_address_length (operands[0])"))
17707 (set_attr "memory" "none")])
17709 (define_insn "*prefetch_3dnow_<mode>"
17710 [(prefetch (match_operand:P 0 "address_operand" "p")
17711 (match_operand:SI 1 "const_int_operand" "n")
17713 "TARGET_3DNOW || TARGET_PRFCHW"
17715 if (INTVAL (operands[1]) == 0)
17716 return "prefetch\t%a0";
17718 return "prefetchw\t%a0";
17720 [(set_attr "type" "mmx")
17721 (set (attr "length_address")
17722 (symbol_ref "memory_address_length (operands[0])"))
17723 (set_attr "memory" "none")])
17725 (define_expand "stack_protect_set"
17726 [(match_operand 0 "memory_operand")
17727 (match_operand 1 "memory_operand")]
17728 "!TARGET_HAS_BIONIC"
17730 rtx (*insn)(rtx, rtx);
17732 #ifdef TARGET_THREAD_SSP_OFFSET
17733 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17734 insn = (TARGET_LP64
17735 ? gen_stack_tls_protect_set_di
17736 : gen_stack_tls_protect_set_si);
17738 insn = (TARGET_LP64
17739 ? gen_stack_protect_set_di
17740 : gen_stack_protect_set_si);
17743 emit_insn (insn (operands[0], operands[1]));
17747 (define_insn "stack_protect_set_<mode>"
17748 [(set (match_operand:PTR 0 "memory_operand" "=m")
17749 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17751 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17752 (clobber (reg:CC FLAGS_REG))]
17753 "!TARGET_HAS_BIONIC"
17754 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17755 [(set_attr "type" "multi")])
17757 (define_insn "stack_tls_protect_set_<mode>"
17758 [(set (match_operand:PTR 0 "memory_operand" "=m")
17759 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17760 UNSPEC_SP_TLS_SET))
17761 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17762 (clobber (reg:CC FLAGS_REG))]
17764 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17765 [(set_attr "type" "multi")])
17767 (define_expand "stack_protect_test"
17768 [(match_operand 0 "memory_operand")
17769 (match_operand 1 "memory_operand")
17771 "!TARGET_HAS_BIONIC"
17773 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17775 rtx (*insn)(rtx, rtx, rtx);
17777 #ifdef TARGET_THREAD_SSP_OFFSET
17778 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17779 insn = (TARGET_LP64
17780 ? gen_stack_tls_protect_test_di
17781 : gen_stack_tls_protect_test_si);
17783 insn = (TARGET_LP64
17784 ? gen_stack_protect_test_di
17785 : gen_stack_protect_test_si);
17788 emit_insn (insn (flags, operands[0], operands[1]));
17790 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17791 flags, const0_rtx, operands[2]));
17795 (define_insn "stack_protect_test_<mode>"
17796 [(set (match_operand:CCZ 0 "flags_reg_operand")
17797 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17798 (match_operand:PTR 2 "memory_operand" "m")]
17800 (clobber (match_scratch:PTR 3 "=&r"))]
17801 "!TARGET_HAS_BIONIC"
17802 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17803 [(set_attr "type" "multi")])
17805 (define_insn "stack_tls_protect_test_<mode>"
17806 [(set (match_operand:CCZ 0 "flags_reg_operand")
17807 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17808 (match_operand:PTR 2 "const_int_operand" "i")]
17809 UNSPEC_SP_TLS_TEST))
17810 (clobber (match_scratch:PTR 3 "=r"))]
17812 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17813 [(set_attr "type" "multi")])
17815 (define_insn "sse4_2_crc32<mode>"
17816 [(set (match_operand:SI 0 "register_operand" "=r")
17818 [(match_operand:SI 1 "register_operand" "0")
17819 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17821 "TARGET_SSE4_2 || TARGET_CRC32"
17822 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17823 [(set_attr "type" "sselog1")
17824 (set_attr "prefix_rep" "1")
17825 (set_attr "prefix_extra" "1")
17826 (set (attr "prefix_data16")
17827 (if_then_else (match_operand:HI 2)
17829 (const_string "*")))
17830 (set (attr "prefix_rex")
17831 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17833 (const_string "*")))
17834 (set_attr "mode" "SI")])
17836 (define_insn "sse4_2_crc32di"
17837 [(set (match_operand:DI 0 "register_operand" "=r")
17839 [(match_operand:DI 1 "register_operand" "0")
17840 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17842 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17843 "crc32{q}\t{%2, %0|%0, %2}"
17844 [(set_attr "type" "sselog1")
17845 (set_attr "prefix_rep" "1")
17846 (set_attr "prefix_extra" "1")
17847 (set_attr "mode" "DI")])
17849 (define_expand "rdpmc"
17850 [(match_operand:DI 0 "register_operand")
17851 (match_operand:SI 1 "register_operand")]
17854 rtx reg = gen_reg_rtx (DImode);
17857 /* Force operand 1 into ECX. */
17858 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17859 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17860 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17865 rtvec vec = rtvec_alloc (2);
17866 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17867 rtx upper = gen_reg_rtx (DImode);
17868 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17869 gen_rtvec (1, const0_rtx),
17871 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17872 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17874 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17875 NULL, 1, OPTAB_DIRECT);
17876 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17880 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17881 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17885 (define_insn "*rdpmc"
17886 [(set (match_operand:DI 0 "register_operand" "=A")
17887 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17891 [(set_attr "type" "other")
17892 (set_attr "length" "2")])
17894 (define_insn "*rdpmc_rex64"
17895 [(set (match_operand:DI 0 "register_operand" "=a")
17896 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17898 (set (match_operand:DI 1 "register_operand" "=d")
17899 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17902 [(set_attr "type" "other")
17903 (set_attr "length" "2")])
17905 (define_expand "rdtsc"
17906 [(set (match_operand:DI 0 "register_operand")
17907 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17912 rtvec vec = rtvec_alloc (2);
17913 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17914 rtx upper = gen_reg_rtx (DImode);
17915 rtx lower = gen_reg_rtx (DImode);
17916 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17917 gen_rtvec (1, const0_rtx),
17919 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17920 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17922 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17923 NULL, 1, OPTAB_DIRECT);
17924 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17926 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17931 (define_insn "*rdtsc"
17932 [(set (match_operand:DI 0 "register_operand" "=A")
17933 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17936 [(set_attr "type" "other")
17937 (set_attr "length" "2")])
17939 (define_insn "*rdtsc_rex64"
17940 [(set (match_operand:DI 0 "register_operand" "=a")
17941 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17942 (set (match_operand:DI 1 "register_operand" "=d")
17943 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17946 [(set_attr "type" "other")
17947 (set_attr "length" "2")])
17949 (define_expand "rdtscp"
17950 [(match_operand:DI 0 "register_operand")
17951 (match_operand:SI 1 "memory_operand")]
17954 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17955 gen_rtvec (1, const0_rtx),
17957 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17958 gen_rtvec (1, const0_rtx),
17960 rtx reg = gen_reg_rtx (DImode);
17961 rtx tmp = gen_reg_rtx (SImode);
17965 rtvec vec = rtvec_alloc (3);
17966 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17967 rtx upper = gen_reg_rtx (DImode);
17968 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17969 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17970 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17972 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17973 NULL, 1, OPTAB_DIRECT);
17974 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17979 rtvec vec = rtvec_alloc (2);
17980 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17981 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17982 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17985 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17986 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17990 (define_insn "*rdtscp"
17991 [(set (match_operand:DI 0 "register_operand" "=A")
17992 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17993 (set (match_operand:SI 1 "register_operand" "=c")
17994 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17997 [(set_attr "type" "other")
17998 (set_attr "length" "3")])
18000 (define_insn "*rdtscp_rex64"
18001 [(set (match_operand:DI 0 "register_operand" "=a")
18002 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18003 (set (match_operand:DI 1 "register_operand" "=d")
18004 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18005 (set (match_operand:SI 2 "register_operand" "=c")
18006 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18009 [(set_attr "type" "other")
18010 (set_attr "length" "3")])
18012 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18014 ;; LWP instructions
18016 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18018 (define_expand "lwp_llwpcb"
18019 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18020 UNSPECV_LLWP_INTRINSIC)]
18023 (define_insn "*lwp_llwpcb<mode>1"
18024 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18025 UNSPECV_LLWP_INTRINSIC)]
18028 [(set_attr "type" "lwp")
18029 (set_attr "mode" "<MODE>")
18030 (set_attr "length" "5")])
18032 (define_expand "lwp_slwpcb"
18033 [(set (match_operand 0 "register_operand" "=r")
18034 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18039 insn = (Pmode == DImode
18041 : gen_lwp_slwpcbsi);
18043 emit_insn (insn (operands[0]));
18047 (define_insn "lwp_slwpcb<mode>"
18048 [(set (match_operand:P 0 "register_operand" "=r")
18049 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18052 [(set_attr "type" "lwp")
18053 (set_attr "mode" "<MODE>")
18054 (set_attr "length" "5")])
18056 (define_expand "lwp_lwpval<mode>3"
18057 [(unspec_volatile [(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_LWPVAL_INTRINSIC)]
18062 ;; Avoid unused variable warning.
18063 "(void) operands[0];")
18065 (define_insn "*lwp_lwpval<mode>3_1"
18066 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18067 (match_operand:SI 1 "nonimmediate_operand" "rm")
18068 (match_operand:SI 2 "const_int_operand" "i")]
18069 UNSPECV_LWPVAL_INTRINSIC)]
18071 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18072 [(set_attr "type" "lwp")
18073 (set_attr "mode" "<MODE>")
18074 (set (attr "length")
18075 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18077 (define_expand "lwp_lwpins<mode>3"
18078 [(set (reg:CCC FLAGS_REG)
18079 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18080 (match_operand:SI 2 "nonimmediate_operand" "rm")
18081 (match_operand:SI 3 "const_int_operand" "i")]
18082 UNSPECV_LWPINS_INTRINSIC))
18083 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18084 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18087 (define_insn "*lwp_lwpins<mode>3_1"
18088 [(set (reg:CCC FLAGS_REG)
18089 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18090 (match_operand:SI 1 "nonimmediate_operand" "rm")
18091 (match_operand:SI 2 "const_int_operand" "i")]
18092 UNSPECV_LWPINS_INTRINSIC))]
18094 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18095 [(set_attr "type" "lwp")
18096 (set_attr "mode" "<MODE>")
18097 (set (attr "length")
18098 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18100 (define_int_iterator RDFSGSBASE
18104 (define_int_iterator WRFSGSBASE
18108 (define_int_attr fsgs
18109 [(UNSPECV_RDFSBASE "fs")
18110 (UNSPECV_RDGSBASE "gs")
18111 (UNSPECV_WRFSBASE "fs")
18112 (UNSPECV_WRGSBASE "gs")])
18114 (define_insn "rd<fsgs>base<mode>"
18115 [(set (match_operand:SWI48 0 "register_operand" "=r")
18116 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18117 "TARGET_64BIT && TARGET_FSGSBASE"
18119 [(set_attr "type" "other")
18120 (set_attr "prefix_extra" "2")])
18122 (define_insn "wr<fsgs>base<mode>"
18123 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18125 "TARGET_64BIT && TARGET_FSGSBASE"
18127 [(set_attr "type" "other")
18128 (set_attr "prefix_extra" "2")])
18130 (define_insn "rdrand<mode>_1"
18131 [(set (match_operand:SWI248 0 "register_operand" "=r")
18132 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18133 (set (reg:CCC FLAGS_REG)
18134 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18137 [(set_attr "type" "other")
18138 (set_attr "prefix_extra" "1")])
18140 (define_expand "pause"
18141 [(set (match_dup 0)
18142 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18145 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18146 MEM_VOLATILE_P (operands[0]) = 1;
18149 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18150 ;; They have the same encoding.
18151 (define_insn "*pause"
18152 [(set (match_operand:BLK 0)
18153 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18156 [(set_attr "length" "2")
18157 (set_attr "memory" "unknown")])
18159 (define_expand "xbegin"
18160 [(set (match_operand:SI 0 "register_operand")
18161 (unspec_volatile:SI [(match_dup 1)] UNSPECV_XBEGIN))]
18164 rtx label = gen_label_rtx ();
18166 operands[1] = force_reg (SImode, constm1_rtx);
18168 emit_jump_insn (gen_xbegin_1 (operands[1], label));
18170 emit_label (label);
18171 LABEL_NUSES (label) = 1;
18173 emit_move_insn (operands[0], operands[1]);
18178 (define_insn "xbegin_1"
18180 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18182 (label_ref (match_operand 1))
18184 (set (match_operand:SI 0 "register_operand" "+a")
18185 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18188 [(set_attr "type" "other")
18189 (set_attr "length" "6")])
18191 (define_insn "xend"
18192 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18195 [(set_attr "type" "other")
18196 (set_attr "length" "3")])
18198 (define_insn "xabort"
18199 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18203 [(set_attr "type" "other")
18204 (set_attr "length" "3")])
18206 (define_expand "xtest"
18207 [(set (match_operand:QI 0 "register_operand")
18208 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18211 emit_insn (gen_xtest_1 ());
18213 ix86_expand_setcc (operands[0], NE,
18214 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18218 (define_insn "xtest_1"
18219 [(set (reg:CCZ FLAGS_REG)
18220 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18223 [(set_attr "type" "other")
18224 (set_attr "length" "3")])
18228 (include "sync.md")